This is the API client from Jellyfin Kodi extracted as a python package so that other users may use the API without maintaining a fork of the API client. Please note that this API client is not complete. You may have to add API calls to perform certain tasks. Please see Contributing below.
This client can be installed with pip3 install jellyfin-apiclient-python and imported with import jellyfin_apiclient_python.
from jellyfin_apiclient_python import JellyfinClient
client = JellyfinClient()
You need to set some configuration values before you can connect a server:
client.config.app('your_brilliant_app', '0.0.1', 'machine_name', 'unique_id')
client.config.data["auth.ssl"] = True
from jellyfin_apiclient_python.discovery import discover_servers
servers = discover_servers(timeout=1.0) # [{'Id': ..., 'Name': ..., 'Address': ...}, ...]
This blocks for the whole timeout, so call it off your UI thread. The replies
are not authenticated: anything on the network can answer with any name and
address, and a real server usually advertises plain http://. Show the address
and let the user choose it rather than signing in to one automatically.
If you do not have a token, you will need to connect via username and password:
client.auth.connect_to_address('server_url')
client.auth.login('server_url', 'username', 'password')
You can then generate a token:
credentials = client.auth.credentials.get_credentials()
server = credentials["Servers"][0]
server["username"] = 'username'
json.dumps(server)
And if you wish then use that token to authenticate in future:
json.loads(credentials)
client.authenticate({"Servers": [credentials]}, discover=False)
You can also authenticate using an API key, which is generated on the server. This is different to a device AccessToken, and is set by not configuring a device name, or a device id:
client.config.data["app.name"] = 'your_brilliant_app'
client.config.data["app.version"] = '0.0.1'
client.authenticate({"Servers": [{"AccessToken": '<API key here>', "address": '<Server Address>'}]}, discover=False)
# Some endpoint require a user context event using API Key.
client.config.data["auth.user_id"] = '<UserID here>'
client.authenticate({"Servers": [{"AccessToken": '<API key here>', "address": '<Server Address>'}]}, discover=False)
The API is accessed via the jellyfin attribute of the client. Return values
are a dictionary with 3 members, "Items", "TotalRecordCount" and "StartIndex"
The easiest way to fetch media objects is by calling search_media_items, like
so:
client.jellyfin.search_media_items(term="And Now for Something Completely Different", media="Videos")
For details on what the individual API calls do or how to do a certain task, you will probably find the Jellyfin MPV Shim and Jellyfin Kodi repositories useful.
The test suite is run via tox, and you can install it from PyPi.
tox -elinttox -epy39tox -elint,py311websocket.py (now a dependency to websocket_client).helper (from Jellyfin Kodi) and kodi_six.has_attribute directly to __init__.py.get_season for fetching season metadata.get_audio_stream to read an audio stream into a filesearch_media_items to search for media itemsaudio_url to return the URL to an audio fileaid=None, sid=None, start_time_ticks=None, is_playback=True to API call get_play_info.six module.remote_ API calls to remote control another sessionitem_played API methodget_userdata_for_item and update_userdata_for_itemget_playlist_items for fetching a playlist's contents in orderidentify API call to include all parameters supported by Jellyfinclose_live_stream sending the stream id as a JSON body; the server binds
it from the query string, so the call always failed and leaked the tunerget_user_items, a named-argument form of the general item query
(GET Users/{UserId}/Items) that browse UIs otherwise had to build by handget_resume_items, get_random_items,
get_items_by_person, get_album_tracks, get_artist_albums,
get_artist_songs, get_genre_songs and get_playlistsget_programs and get_recommended_programs, and add
paging/field/add_current_program parameters to get_channels, which was
previously unbounded (note that LiveTv/Channels has no way to skip the
total record count, unlike the item endpoints)get_endpoint_info (System/Endpoint) and
update_user_settings, the write side of get_user_settingsget_chapter_image and get_trickplay_tile for downloading
chapter thumbnails and scrubbing-preview tilesfields, enable_image_types, image_type_limit and
enable_total_record_count to get_recently_added, fields to get_items,
and paging/sorting parameters to get_collections, get_artists and
get_album_artiststimeout and retry to sessions, so a health check can
fail fast instead of waiting out the client-wide defaultsinclude_segment_types to get_media_segmentsdiscovery.discover_servers, public server discovery with one deadline
for the whole wait and one entry per server; ConnectionManager now uses it,
and it closes its socketget_live_tv_info (LiveTv/Info), whose EnabledUsers is the
only way to tell whether Live TV is actually available to a user before
showing a guide or recordings viewWhen contributing, please maintain backward compatibility with existing calls in the API. Adding parameters is fine, but please make sure that they have default options to prevent existing software from breaking. Please also add your changes to the Changes from Jellyfin Kodi section.
If you would like to produce documentation for this API, I would also be interested in accepting pull requests for documentation.
11 followers · starred Feb 2022
25 followers · starred Feb 2025
26 followers · starred Oct 2023
3 followers · starred May 2025
This is the API client from Jellyfin Kodi extracted as a python package so that other users may use the API without maintaining a fork of the API client. Please note that this API client is not complete. You may have to add API calls to perform certain tasks. Please see Contributing below.
This client can be installed with pip3 install jellyfin-apiclient-python and imported with import jellyfin_apiclient_python.
from jellyfin_apiclient_python import JellyfinClient
client = JellyfinClient()
You need to set some configuration values before you can connect a server:
client.config.app('your_brilliant_app', '0.0.1', 'machine_name', 'unique_id')
client.config.data["auth.ssl"] = True
from jellyfin_apiclient_python.discovery import discover_servers
servers = discover_servers(timeout=1.0) # [{'Id': ..., 'Name': ..., 'Address': ...}, ...]
This blocks for the whole timeout, so call it off your UI thread. The replies
are not authenticated: anything on the network can answer with any name and
address, and a real server usually advertises plain http://. Show the address
and let the user choose it rather than signing in to one automatically.
If you do not have a token, you will need to connect via username and password:
client.auth.connect_to_address('server_url')
client.auth.login('server_url', 'username', 'password')
You can then generate a token:
credentials = client.auth.credentials.get_credentials()
server = credentials["Servers"][0]
server["username"] = 'username'
json.dumps(server)
And if you wish then use that token to authenticate in future:
json.loads(credentials)
client.authenticate({"Servers": [credentials]}, discover=False)
You can also authenticate using an API key, which is generated on the server. This is different to a device AccessToken, and is set by not configuring a device name, or a device id:
client.config.data["app.name"] = 'your_brilliant_app'
client.config.data["app.version"] = '0.0.1'
client.authenticate({"Servers": [{"AccessToken": '<API key here>', "address": '<Server Address>'}]}, discover=False)
# Some endpoint require a user context event using API Key.
client.config.data["auth.user_id"] = '<UserID here>'
client.authenticate({"Servers": [{"AccessToken": '<API key here>', "address": '<Server Address>'}]}, discover=False)
The API is accessed via the jellyfin attribute of the client. Return values
are a dictionary with 3 members, "Items", "TotalRecordCount" and "StartIndex"
The easiest way to fetch media objects is by calling search_media_items, like
so:
client.jellyfin.search_media_items(term="And Now for Something Completely Different", media="Videos")
For details on what the individual API calls do or how to do a certain task, you will probably find the Jellyfin MPV Shim and Jellyfin Kodi repositories useful.
The test suite is run via tox, and you can install it from PyPi.
tox -elinttox -epy39tox -elint,py311websocket.py (now a dependency to websocket_client).helper (from Jellyfin Kodi) and kodi_six.has_attribute directly to __init__.py.get_season for fetching season metadata.get_audio_stream to read an audio stream into a filesearch_media_items to search for media itemsaudio_url to return the URL to an audio fileaid=None, sid=None, start_time_ticks=None, is_playback=True to API call get_play_info.six module.remote_ API calls to remote control another sessionitem_played API methodget_userdata_for_item and update_userdata_for_itemget_playlist_items for fetching a playlist's contents in orderidentify API call to include all parameters supported by Jellyfinclose_live_stream sending the stream id as a JSON body; the server binds
it from the query string, so the call always failed and leaked the tunerget_user_items, a named-argument form of the general item query
(GET Users/{UserId}/Items) that browse UIs otherwise had to build by handget_resume_items, get_random_items,
get_items_by_person, get_album_tracks, get_artist_albums,
get_artist_songs, get_genre_songs and get_playlistsget_programs and get_recommended_programs, and add
paging/field/add_current_program parameters to get_channels, which was
previously unbounded (note that LiveTv/Channels has no way to skip the
total record count, unlike the item endpoints)get_endpoint_info (System/Endpoint) and
update_user_settings, the write side of get_user_settingsget_chapter_image and get_trickplay_tile for downloading
chapter thumbnails and scrubbing-preview tilesfields, enable_image_types, image_type_limit and
enable_total_record_count to get_recently_added, fields to get_items,
and paging/sorting parameters to get_collections, get_artists and
get_album_artiststimeout and retry to sessions, so a health check can
fail fast instead of waiting out the client-wide defaultsinclude_segment_types to get_media_segmentsdiscovery.discover_servers, public server discovery with one deadline
for the whole wait and one entry per server; ConnectionManager now uses it,
and it closes its socketget_live_tv_info (LiveTv/Info), whose EnabledUsers is the
only way to tell whether Live TV is actually available to a user before
showing a guide or recordings viewWhen contributing, please maintain backward compatibility with existing calls in the API. Adding parameters is fine, but please make sure that they have default options to prevent existing software from breaking. Please also add your changes to the Changes from Jellyfin Kodi section.
If you would like to produce documentation for this API, I would also be interested in accepting pull requests for documentation.
11 followers · starred Feb 2022
25 followers · starred Feb 2025
26 followers · starred Oct 2023
3 followers · starred May 2025