jellyfin/jellyfin-apiclient-python

cannot authenticate with API key per README example: 400 Client Error: Bad Request for url

Closed this issue · 6 comments

hi,
i'm having some trouble getting started.
i tried to follow the README.md, and to access my server with an API token.

i assumed that if i use an API key i could skip over the user/password and api token part...

from jellyfin_apiclient_python import JellyfinClient
client = JellyfinClient()

client.config.data["app.name"] = 'your_brilliant_app'
client.config.data["app.version"] = '0.0.1'
client.authenticate({"Servers": [{"AccessToken": "9954bae757ad4889865ba998217a9e0c", "address": "http://jellyfin.myserver.com"}]}, discover=False)

client.jellyfin.search_media_items(
    term="Berlin", media="Videos")

with this i get the following error on the client.jellyfin.search_media_items line:

Exception has occurred: HTTPException
(400, HTTPError('400 Client Error: Bad Request for url: http://jellyfin.myserver.com/Users/%7BUserId%7D/Items?searchTerm=Berlin&Recursive=True&IncludeItemTypes=Videos&Limit=20'))
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: http://jellyfin.myserver.com/Users/%7BUserId%7D/Items?searchTerm=Berlin&Recursive=True&IncludeItemTypes=Videos&Limit=20

During handling of the above exception, another exception occurred:

  File "/home/fuchsi3010/dev/projects/python/jf-api-client/jf-api-client.py", line 8, in <module>
    client.jellyfin.search_media_items(
jellyfin_apiclient_python.exceptions.HTTPException: (400, HTTPError('400 Client Error: Bad Request for url: http://jellyfin.myserver.com/Users/%7BUserId%7D/Items?searchTerm=Berlin&Recursive=True&IncludeItemTypes=Videos&Limit=20'))

the traceback is:

Traceback (most recent call last):
  File "/home/fuchsi3010/dev/projects/python/jf-api-client/lib/python3.12/site-packages/jellyfin_apiclient_python/connection_manager.py", line 189, in connect_to_server
    return self._after_connect_validated(server, credentials, result, True, options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/fuchsi3010/dev/projects/python/jf-api-client/lib/python3.12/site-packages/jellyfin_apiclient_python/connection_manager.py", line 346, in _after_connect_validated
    return self._after_connect_validated(server, credentials, system_info, False, options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/fuchsi3010/dev/projects/python/jf-api-client/lib/python3.12/site-packages/jellyfin_apiclient_python/connection_manager.py", line 363, in _after_connect_validated
    self.config.data['auth.ssl'] = options.get('ssl', self.config.data['auth.ssl'])
                                                      ~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'auth.ssl'

Failing server connection. ERROR msg: 'auth.ssl'
400 Client Error: Bad Request for url: http://jellyfin.myserver.com/Users/%7BUserId%7D/Items?searchTerm=Berlin&Recursive=True&IncludeItemTypes=Videos&Limit=20

this does not change, even if i add client.config.data["auth.ssl"] = False before the request is being made.

any help would be appreciated, thanks!

/Users/%7BUserId%7D/Items

Is this literally the URL path you're going to? That's not an acceptable path. Pretty sure you need to provide a valid user id to use endpoints under /Users/.

hi, thanks for you reply!

Is this literally the URL path you're going to?

it's what's produced by the code i posted, i'm not running anything else. i see that it tries to build a path with {UserId}, but i don't want to provide a user or password, only the API Key (which has no username, right?).

also, i don't want to query anything user-specific, search_media_items() should just return info for media files on the server.

This doesn't appear to be possible currently. This api client is very incomplete and largely meant to be used with an actual user account. I believe you'd need to call the /Items endpoint, not /Users/{user_id}/Items, while this client is hardcoded to the latter.

hi, ok, thank you, then i'll just stick with a simpler script using only the requests package.

for other people looking here: after reading up a little bit i got my usecase to work.
problem i'm trying to solve: i want to get all the favorited media's paths for 2 of the servers users.
i got their user_id from 'Dashboard' > 'Users' > clicking the User > looking in the URL bar
then i get their favorites like this:

import requests
import json

# Define connection details
server_url = 'http://jellyfin.myserver.com'
apiKey = '9954banabu98ha0dn1ba998217a9e0c'

users = {
    "user1": "e280na0a8sdnin12wd0asdni87ffda9a",
    "user2": "83c91fae76834asn80d8nasdn1nds5a"
}

# set up headers
headers = {'Authorization': f'MediaBrowser Token="{apiKey}"'}

for name, userid in users.items():
    favorites = requests.get(f'{server_url}/Users/{userid}/Items?Recursive=True&Filters=IsFavorite&Fields=Path', headers=headers)
    json_object = json.loads(favorites.text)

    for j in range (0, len(json_object['Items'])):
        print(json_object['Items'][j]['Path'])

my json parsing may or may not be quite shit... but that's enough for this :-)

thanks to https://www.reddit.com/r/jellyfin/comments/vi6jvv/getting_all_favorites_of_an_user/

for other people looking here: after reading up a little bit i got my usecase to work.
problem i'm trying to solve: i want to get all the favorited media's paths for 2 of the servers users.
i got their user_id from 'Dashboard' > 'Users' > clicking the User > looking in the URL bar
then i get their favorites like this:

import requests
import json

# Define connection details
server_url = 'http://jellyfin.myserver.com'
apiKey = '9954banabu98ha0dn1ba998217a9e0c'

users = {
    "user1": "e280na0a8sdnin12wd0asdni87ffda9a",
    "user2": "83c91fae76834asn80d8nasdn1nds5a"
}

# set up headers
headers = {'Authorization': f'MediaBrowser Token="{apiKey}"'}

for name, userid in users.items():
    favorites = requests.get(f'{server_url}/Users/{userid}/Items?Recursive=True&Filters=IsFavorite&Fields=Path', headers=headers)
    json_object = json.loads(favorites.text)

    for j in range (0, len(json_object['Items'])):
        print(json_object['Items'][j]['Path'])

my json parsing may or may not be quite shit... but that's enough for this :-)

thanks to https://www.reddit.com/r/jellyfin/comments/vi6jvv/getting_all_favorites_of_an_user/

You can also retrieve user id by using the Users endpoint.
I do this in my project to programmatically get user id.