diff --git a/README.md b/README.md index 60cadaa..deea919 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,16 @@ 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: , "address": }]}, discover=False) +``` + ### API The API is accessed via the `jellyfin` attribute of the client. Return values @@ -74,6 +84,7 @@ For details on what the individual API calls do or how to do a certain task, you - Add timesync manager and SyncPlay API methods. - Remove usage of `six` module. - Add group of `remote_` API calls to remote control another session + - Add support for authenticating via an API key ## Contributing diff --git a/jellyfin_apiclient_python/api.py b/jellyfin_apiclient_python/api.py index 63dc7d7..c58b5ee 100644 --- a/jellyfin_apiclient_python/api.py +++ b/jellyfin_apiclient_python/api.py @@ -568,7 +568,8 @@ def login(self, server_url, username, password=""): def validate_authentication_token(self, server): headers = self.get_default_headers() - headers["Authorization"] += f", Token=\"{server['AccessToken']}\"" + comma = "," if "app.device_name" in self.config.data else "" + headers["Authorization"] += f"{comma} Token=\"{server['AccessToken']}\"" response = self.send_request(server['address'], "system/info", headers=headers) return response.json() if response.status_code == 200 else {} diff --git a/jellyfin_apiclient_python/connection_manager.py b/jellyfin_apiclient_python/connection_manager.py index 3566b16..1bb1384 100644 --- a/jellyfin_apiclient_python/connection_manager.py +++ b/jellyfin_apiclient_python/connection_manager.py @@ -85,7 +85,8 @@ def get_available_servers(self, discover=True): except KeyError: continue - servers.sort(key=itemgetter('DateLastAccessed'), reverse=True) + if len(servers) > 1: + servers.sort(key=itemgetter('DateLastAccessed'), reverse=True) credentials['Servers'] = servers self.credentials.set(credentials) @@ -336,7 +337,8 @@ def _after_connect_validated(self, server, credentials, system_info, verify_auth if system_info: self._update_server_info(server, system_info) - self.config.data['auth.user_id'] = server['UserId'] + if "UserId" in server: + self.config.data['auth.user_id'] = server['UserId'] self.config.data['auth.token'] = server['AccessToken'] return self._after_connect_validated(server, credentials, system_info, False, options) diff --git a/jellyfin_apiclient_python/credentials.py b/jellyfin_apiclient_python/credentials.py index b03f7fc..94beb2e 100644 --- a/jellyfin_apiclient_python/credentials.py +++ b/jellyfin_apiclient_python/credentials.py @@ -90,6 +90,8 @@ def add_update_server(self, servers, server): if server.get('AccessToken'): existing['AccessToken'] = server['AccessToken'] + + if server.get('UserId'): existing['UserId'] = server['UserId'] if server.get('ExchangeToken'): diff --git a/jellyfin_apiclient_python/http.py b/jellyfin_apiclient_python/http.py index 73a4b33..7768337 100644 --- a/jellyfin_apiclient_python/http.py +++ b/jellyfin_apiclient_python/http.py @@ -220,12 +220,14 @@ def _process_params(self, params): params[key] = self._replace_user_info(value) def _get_authenication_header(self): - params = { - "Client": self.config.data['app.name'], - "Device": self.config.data['app.device_name'], - "DeviceId": self.config.data['app.device_id'], - "Version": self.config.data['app.version'] - } + params = {} + if "app.device_name" in self.config.data: + params.update({ + "Client": self.config.data['app.name'], + "Device": self.config.data['app.device_name'], + "DeviceId": self.config.data['app.device_id'], + "Version": self.config.data['app.version'] + }) if "auth.token" in self.config.data: params["Token"] = self.config.data['auth.token'] param_line = ", ".join(f'{k}="{v}"' for k, v in params.items())