jellyfin / jellyfin-apiclient-python

Python API Client for Jellyfin
GNU General Public License v3.0
94 stars 32 forks source link

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

Closed fuchsi3010 closed 1 month ago

fuchsi3010 commented 1 month ago

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!

mcarlton00 commented 1 month ago

/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/.

fuchsi3010 commented 1 month ago

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.

mcarlton00 commented 1 month ago

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.

fuchsi3010 commented 1 month ago

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

fuchsi3010 commented 1 month ago

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/

Xaque8787 commented 1 month ago

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.