From 090b2373f67b9c9b5073f8e760d76b3201a906ce Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Tue, 9 Apr 2024 01:14:08 +0000 Subject: [PATCH] ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.244.0 --- .speakeasy/gen.lock | 15 +- .speakeasy/gen.yaml | 2 +- RELEASES.md | 12 +- docs/models/internal/globals.md | 8 + docs/models/operations/getpinglobals.md | 8 + docs/models/operations/gettokenglobals.md | 8 + setup.py | 2 +- src/plex_api/activities.py | 2 +- src/plex_api/authentication.py | 4 +- src/plex_api/butler.py | 4 +- src/plex_api/hubs.py | 6 +- src/plex_api/library.py | 20 +- src/plex_api/log.py | 2 +- src/plex_api/media.py | 6 +- src/plex_api/models/internal/__init__.py | 5 + src/plex_api/models/internal/globals.py | 15 + src/plex_api/models/operations/__init__.py | 2 +- src/plex_api/models/operations/getpin.py | 11 + src/plex_api/models/operations/gettoken.py | 11 + src/plex_api/playlists.py | 24 +- src/plex_api/plex.py | 22 +- src/plex_api/sdk.py | 21 +- src/plex_api/sdkconfiguration.py | 16 +- src/plex_api/search.py | 6 +- src/plex_api/server.py | 2 +- src/plex_api/sessions.py | 2 +- src/plex_api/statistics.py | 2 +- src/plex_api/updater.py | 4 +- src/plex_api/utils/utils.py | 652 +++++++++++++-------- src/plex_api/video.py | 4 +- 30 files changed, 573 insertions(+), 325 deletions(-) create mode 100644 docs/models/internal/globals.md create mode 100644 docs/models/operations/getpinglobals.md create mode 100644 docs/models/operations/gettokenglobals.md create mode 100644 src/plex_api/models/internal/__init__.py create mode 100644 src/plex_api/models/internal/globals.py diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 687c709..bf3ec89 100755 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -3,10 +3,10 @@ id: 3eeea668-4ef4-464e-a888-bdfa023bedf5 management: docChecksum: a91eaf9ec1e6a3a6f4bf0571f5b18bae docVersion: 0.0.3 - speakeasyVersion: 1.241.0 - generationVersion: 2.300.0 - releaseVersion: 0.6.2 - configChecksum: 851d34f876d9ce54e1b12fc835ec6001 + speakeasyVersion: 1.244.0 + generationVersion: 2.301.0 + releaseVersion: 0.6.3 + configChecksum: c086e0f69d05e9b8941493ca71fc23a3 repoURL: https://github.com/LukeHagar/plexpy.git repoSubDirectory: . installationURL: https://github.com/LukeHagar/plexpy.git @@ -14,7 +14,7 @@ management: features: python: constsAndDefaults: 0.1.3 - core: 4.6.3 + core: 4.6.4 flattening: 2.81.1 globalSecurity: 2.83.5 globalServerURLs: 2.82.2 @@ -168,10 +168,12 @@ generatedFiles: - src/plex_api/models/errors/checkforupdates.py - src/plex_api/models/errors/applyupdates.py - src/plex_api/models/components/security.py + - src/plex_api/models/internal/globals.py - src/plex_api/models/__init__.py - src/plex_api/models/errors/__init__.py - src/plex_api/models/operations/__init__.py - src/plex_api/models/components/__init__.py + - src/plex_api/models/internal/__init__.py - docs/models/operations/directory.md - docs/models/operations/mediacontainer.md - docs/models/operations/getservercapabilitiesresponsebody.md @@ -358,10 +360,12 @@ generatedFiles: - docs/models/operations/loglineresponse.md - docs/models/operations/logmultilineresponse.md - docs/models/operations/enablepapertrailresponse.md + - docs/models/operations/getpinglobals.md - docs/models/operations/getpinrequest.md - docs/models/operations/location.md - docs/models/operations/getpinresponsebody.md - docs/models/operations/getpinresponse.md + - docs/models/operations/gettokenglobals.md - docs/models/operations/gettokenrequest.md - docs/models/operations/gettokenresponse.md - docs/models/operations/queryparamtype.md @@ -570,6 +574,7 @@ generatedFiles: - docs/models/errors/applyupdateserrors.md - docs/models/errors/applyupdatesresponsebody.md - docs/models/components/security.md + - docs/models/internal/globals.md - docs/sdks/plexapi/README.md - docs/sdks/server/README.md - docs/sdks/media/README.md diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 7e6e0e6..081d8f3 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -12,7 +12,7 @@ generation: auth: oAuth2ClientCredentialsEnabled: false python: - version: 0.6.2 + version: 0.6.3 additionalDependencies: dependencies: {} extraDependencies: diff --git a/RELEASES.md b/RELEASES.md index bd515c7..157b922 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -148,4 +148,14 @@ Based on: ### Generated - [python v0.6.2] . ### Releases -- [PyPI v0.6.2] https://pypi.org/project/plex-api-client/0.6.2 - . \ No newline at end of file +- [PyPI v0.6.2] https://pypi.org/project/plex-api-client/0.6.2 - . + +## 2024-04-09 01:13:12 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.244.0 (2.301.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.6.3] . +### Releases +- [PyPI v0.6.3] https://pypi.org/project/plex-api-client/0.6.3 - . \ No newline at end of file diff --git a/docs/models/internal/globals.md b/docs/models/internal/globals.md new file mode 100644 index 0000000..dd4395c --- /dev/null +++ b/docs/models/internal/globals.md @@ -0,0 +1,8 @@ +# Globals + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `x_plex_client_identifier` | *str* | :heavy_check_mark: | The unique identifier for the client application
This is used to track the client application and its usage
(UUID, serial number, or other number unique per device)
| \ No newline at end of file diff --git a/docs/models/operations/getpinglobals.md b/docs/models/operations/getpinglobals.md new file mode 100644 index 0000000..1677b60 --- /dev/null +++ b/docs/models/operations/getpinglobals.md @@ -0,0 +1,8 @@ +# GetPinGlobals + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `x_plex_client_identifier` | *str* | :heavy_check_mark: | The unique identifier for the client application
This is used to track the client application and its usage
(UUID, serial number, or other number unique per device)
| \ No newline at end of file diff --git a/docs/models/operations/gettokenglobals.md b/docs/models/operations/gettokenglobals.md new file mode 100644 index 0000000..ffbdcfb --- /dev/null +++ b/docs/models/operations/gettokenglobals.md @@ -0,0 +1,8 @@ +# GetTokenGlobals + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `x_plex_client_identifier` | *str* | :heavy_check_mark: | The unique identifier for the client application
This is used to track the client application and its usage
(UUID, serial number, or other number unique per device)
| \ No newline at end of file diff --git a/setup.py b/setup.py index f861a7b..284c8f3 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ except FileNotFoundError: setuptools.setup( name='plex-api-client', - version='0.6.2', + version='0.6.3', author='LukeHagar', description='Python Client SDK Generated by Speakeasy', url='https://github.com/LukeHagar/plexpy.git', diff --git a/src/plex_api/activities.py b/src/plex_api/activities.py index cd6956a..b0061a6 100644 --- a/src/plex_api/activities.py +++ b/src/plex_api/activities.py @@ -98,7 +98,7 @@ class Activities: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.CancelServerActivitiesRequest, base_url, '/activities/{activityUUID}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/activities/{activityUUID}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) diff --git a/src/plex_api/authentication.py b/src/plex_api/authentication.py index 7f441b5..f803cf0 100644 --- a/src/plex_api/authentication.py +++ b/src/plex_api/authentication.py @@ -34,7 +34,7 @@ class Authentication: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetTransientTokenRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -99,7 +99,7 @@ class Authentication: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetSourceConnectionInformationRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/butler.py b/src/plex_api/butler.py index 4b8e427..89f17bf 100644 --- a/src/plex_api/butler.py +++ b/src/plex_api/butler.py @@ -217,7 +217,7 @@ class Butler: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.StartTaskRequest, base_url, '/butler/{taskName}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/butler/{taskName}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -280,7 +280,7 @@ class Butler: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.StopTaskRequest, base_url, '/butler/{taskName}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/butler/{taskName}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) diff --git a/src/plex_api/hubs.py b/src/plex_api/hubs.py index d35749e..2650b6d 100644 --- a/src/plex_api/hubs.py +++ b/src/plex_api/hubs.py @@ -35,7 +35,7 @@ class Hubs: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetGlobalHubsRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -99,14 +99,14 @@ class Hubs: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetLibraryHubsRequest, base_url, '/hubs/sections/{sectionId}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/hubs/sections/{sectionId}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetLibraryHubsRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/library.py b/src/plex_api/library.py index 6619469..2145148 100644 --- a/src/plex_api/library.py +++ b/src/plex_api/library.py @@ -35,7 +35,7 @@ class Library: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetFileHashRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -264,14 +264,14 @@ class Library: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetLibraryRequest, base_url, '/library/sections/{sectionId}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/library/sections/{sectionId}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetLibraryRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -333,7 +333,7 @@ class Library: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.DeleteLibraryRequest, base_url, '/library/sections/{sectionId}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/library/sections/{sectionId}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -416,7 +416,7 @@ class Library: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetLibraryItemsRequest, base_url, '/library/sections/{sectionId}/{tag}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/library/sections/{sectionId}/{tag}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -476,7 +476,7 @@ class Library: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.RefreshLibraryRequest, base_url, '/library/sections/{sectionId}/refresh', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/library/sections/{sectionId}/refresh', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -557,14 +557,14 @@ class Library: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.SearchLibraryRequest, base_url, '/library/sections/{sectionId}/search', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/library/sections/{sectionId}/search', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.SearchLibraryRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -618,7 +618,7 @@ class Library: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetMetadataRequest, base_url, '/library/metadata/{ratingKey}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/library/metadata/{ratingKey}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -686,7 +686,7 @@ class Library: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetMetadataChildrenRequest, base_url, '/library/metadata/{ratingKey}/children', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/library/metadata/{ratingKey}/children', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) diff --git a/src/plex_api/log.py b/src/plex_api/log.py index e5b4360..dc1ab55 100644 --- a/src/plex_api/log.py +++ b/src/plex_api/log.py @@ -35,7 +35,7 @@ class Log: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.LogLineRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/media.py b/src/plex_api/media.py index 718d3f5..61f037e 100644 --- a/src/plex_api/media.py +++ b/src/plex_api/media.py @@ -33,7 +33,7 @@ class Media: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.MarkPlayedRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -97,7 +97,7 @@ class Media: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.MarkUnplayedRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -163,7 +163,7 @@ class Media: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.UpdatePlayProgressRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/models/internal/__init__.py b/src/plex_api/models/internal/__init__.py new file mode 100644 index 0000000..51f9e9d --- /dev/null +++ b/src/plex_api/models/internal/__init__.py @@ -0,0 +1,5 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from .globals import * + +__all__ = ["Globals"] diff --git a/src/plex_api/models/internal/globals.py b/src/plex_api/models/internal/globals.py new file mode 100644 index 0000000..05f8737 --- /dev/null +++ b/src/plex_api/models/internal/globals.py @@ -0,0 +1,15 @@ +"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.""" + +from __future__ import annotations +import dataclasses + + +@dataclasses.dataclass +class Globals: + x_plex_client_identifier: str = dataclasses.field(metadata={'header': { 'field_name': 'X-Plex-Client-Identifier', 'style': 'simple', 'explode': False }}) + r"""The unique identifier for the client application + This is used to track the client application and its usage + (UUID, serial number, or other number unique per device) + """ + + diff --git a/src/plex_api/models/operations/__init__.py b/src/plex_api/models/operations/__init__.py index 0cdd8ef..a3afee5 100644 --- a/src/plex_api/models/operations/__init__.py +++ b/src/plex_api/models/operations/__init__.py @@ -61,4 +61,4 @@ from .updateplaylist import * from .updateplayprogress import * from .uploadplaylist import * -__all__ = ["Account","Activity","AddPlaylistContentsMediaContainer","AddPlaylistContentsMetadata","AddPlaylistContentsRequest","AddPlaylistContentsResponse","AddPlaylistContentsResponseBody","ApplyUpdatesRequest","ApplyUpdatesResponse","ButlerTask","ButlerTasks","CancelServerActivitiesRequest","CancelServerActivitiesResponse","CheckForUpdatesRequest","CheckForUpdatesResponse","ClearPlaylistContentsRequest","ClearPlaylistContentsResponse","Context","Country","CreatePlaylistMediaContainer","CreatePlaylistMetadata","CreatePlaylistRequest","CreatePlaylistResponse","CreatePlaylistResponseBody","DeleteLibraryRequest","DeleteLibraryResponse","DeletePlaylistRequest","DeletePlaylistResponse","Device","Director","Directory","Download","EnablePaperTrailResponse","Field","FieldType","Filter","Force","GET_PIN_SERVERS","GET_TOKEN_SERVERS","Genre","GetAvailableClientsMediaContainer","GetAvailableClientsResponse","GetAvailableClientsResponseBody","GetButlerTasksResponse","GetButlerTasksResponseBody","GetDevicesMediaContainer","GetDevicesResponse","GetDevicesResponseBody","GetFileHashRequest","GetFileHashResponse","GetGlobalHubsMediaContainer","GetGlobalHubsMetadata","GetGlobalHubsRequest","GetGlobalHubsResponse","GetGlobalHubsResponseBody","GetLibrariesDirectory","GetLibrariesLocation","GetLibrariesMediaContainer","GetLibrariesResponse","GetLibrariesResponseBody","GetLibraryDirectory","GetLibraryHubsCountry","GetLibraryHubsDirector","GetLibraryHubsGenre","GetLibraryHubsHub","GetLibraryHubsMedia","GetLibraryHubsMediaContainer","GetLibraryHubsMetadata","GetLibraryHubsPart","GetLibraryHubsRequest","GetLibraryHubsResponse","GetLibraryHubsResponseBody","GetLibraryHubsRole","GetLibraryHubsWriter","GetLibraryItemsCountry","GetLibraryItemsDirector","GetLibraryItemsGenre","GetLibraryItemsMedia","GetLibraryItemsMediaContainer","GetLibraryItemsMetadata","GetLibraryItemsPart","GetLibraryItemsRequest","GetLibraryItemsResponse","GetLibraryItemsResponseBody","GetLibraryItemsRole","GetLibraryItemsWriter","GetLibraryMediaContainer","GetLibraryRequest","GetLibraryResponse","GetLibraryResponseBody","GetLibraryType","GetMetadataChildrenDirectory","GetMetadataChildrenMediaContainer","GetMetadataChildrenMetadata","GetMetadataChildrenRequest","GetMetadataChildrenResponse","GetMetadataChildrenResponseBody","GetMetadataCountry","GetMetadataDirector","GetMetadataGenre","GetMetadataMedia","GetMetadataMediaContainer","GetMetadataMetadata","GetMetadataPart","GetMetadataRequest","GetMetadataResponse","GetMetadataResponseBody","GetMetadataRole","GetMetadataWriter","GetMyPlexAccountResponse","GetMyPlexAccountResponseBody","GetOnDeckGuids","GetOnDeckMedia","GetOnDeckMediaContainer","GetOnDeckMetadata","GetOnDeckPart","GetOnDeckResponse","GetOnDeckResponseBody","GetOnDeckStream","GetPinRequest","GetPinResponse","GetPinResponseBody","GetPlaylistContentsCountry","GetPlaylistContentsDirector","GetPlaylistContentsGenre","GetPlaylistContentsMedia","GetPlaylistContentsMediaContainer","GetPlaylistContentsMetadata","GetPlaylistContentsPart","GetPlaylistContentsRequest","GetPlaylistContentsResponse","GetPlaylistContentsResponseBody","GetPlaylistContentsRole","GetPlaylistContentsWriter","GetPlaylistMediaContainer","GetPlaylistMetadata","GetPlaylistRequest","GetPlaylistResponse","GetPlaylistResponseBody","GetPlaylistsMediaContainer","GetPlaylistsMetadata","GetPlaylistsRequest","GetPlaylistsResponse","GetPlaylistsResponseBody","GetRecentlyAddedMediaContainer","GetRecentlyAddedResponse","GetRecentlyAddedResponseBody","GetResizedPhotoRequest","GetResizedPhotoResponse","GetSearchResultsCountry","GetSearchResultsDirector","GetSearchResultsGenre","GetSearchResultsMedia","GetSearchResultsMediaContainer","GetSearchResultsMetadata","GetSearchResultsPart","GetSearchResultsRequest","GetSearchResultsResponse","GetSearchResultsResponseBody","GetSearchResultsRole","GetSearchResultsWriter","GetServerActivitiesMediaContainer","GetServerActivitiesResponse","GetServerActivitiesResponseBody","GetServerCapabilitiesResponse","GetServerCapabilitiesResponseBody","GetServerIdentityMediaContainer","GetServerIdentityResponse","GetServerIdentityResponseBody","GetServerListMediaContainer","GetServerListResponse","GetServerListResponseBody","GetServerListServer","GetServerPreferencesMediaContainer","GetServerPreferencesResponse","GetServerPreferencesResponseBody","GetSessionHistoryMediaContainer","GetSessionHistoryMetadata","GetSessionHistoryResponse","GetSessionHistoryResponseBody","GetSessionsMedia","GetSessionsMediaContainer","GetSessionsMetadata","GetSessionsPart","GetSessionsResponse","GetSessionsResponseBody","GetSessionsStream","GetSourceConnectionInformationRequest","GetSourceConnectionInformationResponse","GetStatisticsDevice","GetStatisticsMediaContainer","GetStatisticsRequest","GetStatisticsResponse","GetStatisticsResponseBody","GetTimelineRequest","GetTimelineResponse","GetTokenRequest","GetTokenResponse","GetTranscodeSessionsMediaContainer","GetTranscodeSessionsResponse","GetTranscodeSessionsResponseBody","GetTransientTokenQueryParamType","GetTransientTokenRequest","GetTransientTokenResponse","GetUpdateStatusMediaContainer","GetUpdateStatusResponse","GetUpdateStatusResponseBody","Guids","Hub","IncludeDetails","Level","Location","LogLineRequest","LogLineResponse","LogMultiLineResponse","MarkPlayedRequest","MarkPlayedResponse","MarkUnplayedRequest","MarkUnplayedResponse","Media","MediaContainer","Metadata","MinSize","MyPlex","OnlyTransient","Operator","Part","PathParamTaskName","PerformSearchRequest","PerformSearchResponse","PerformVoiceSearchRequest","PerformVoiceSearchResponse","Player","PlaylistType","Producer","Provider","QueryParamOnlyTransient","QueryParamSmart","QueryParamType","Ratings","RefreshLibraryRequest","RefreshLibraryResponse","Release","Role","Scope","SearchLibraryMediaContainer","SearchLibraryMetadata","SearchLibraryRequest","SearchLibraryResponse","SearchLibraryResponseBody","Server","Session","Setting","Skip","Smart","Sort","StartAllTasksResponse","StartTaskRequest","StartTaskResponse","StartUniversalTranscodeRequest","StartUniversalTranscodeResponse","State","StatisticsMedia","StopAllTasksResponse","StopTaskRequest","StopTaskResponse","StopTranscodeSessionRequest","StopTranscodeSessionResponse","Stream","Tag","TaskName","Tonight","TranscodeSession","Type","UpdatePlayProgressRequest","UpdatePlayProgressResponse","UpdatePlaylistRequest","UpdatePlaylistResponse","UploadPlaylistRequest","UploadPlaylistResponse","Upscale","User","Writer"] +__all__ = ["Account","Activity","AddPlaylistContentsMediaContainer","AddPlaylistContentsMetadata","AddPlaylistContentsRequest","AddPlaylistContentsResponse","AddPlaylistContentsResponseBody","ApplyUpdatesRequest","ApplyUpdatesResponse","ButlerTask","ButlerTasks","CancelServerActivitiesRequest","CancelServerActivitiesResponse","CheckForUpdatesRequest","CheckForUpdatesResponse","ClearPlaylistContentsRequest","ClearPlaylistContentsResponse","Context","Country","CreatePlaylistMediaContainer","CreatePlaylistMetadata","CreatePlaylistRequest","CreatePlaylistResponse","CreatePlaylistResponseBody","DeleteLibraryRequest","DeleteLibraryResponse","DeletePlaylistRequest","DeletePlaylistResponse","Device","Director","Directory","Download","EnablePaperTrailResponse","Field","FieldType","Filter","Force","GET_PIN_SERVERS","GET_TOKEN_SERVERS","Genre","GetAvailableClientsMediaContainer","GetAvailableClientsResponse","GetAvailableClientsResponseBody","GetButlerTasksResponse","GetButlerTasksResponseBody","GetDevicesMediaContainer","GetDevicesResponse","GetDevicesResponseBody","GetFileHashRequest","GetFileHashResponse","GetGlobalHubsMediaContainer","GetGlobalHubsMetadata","GetGlobalHubsRequest","GetGlobalHubsResponse","GetGlobalHubsResponseBody","GetLibrariesDirectory","GetLibrariesLocation","GetLibrariesMediaContainer","GetLibrariesResponse","GetLibrariesResponseBody","GetLibraryDirectory","GetLibraryHubsCountry","GetLibraryHubsDirector","GetLibraryHubsGenre","GetLibraryHubsHub","GetLibraryHubsMedia","GetLibraryHubsMediaContainer","GetLibraryHubsMetadata","GetLibraryHubsPart","GetLibraryHubsRequest","GetLibraryHubsResponse","GetLibraryHubsResponseBody","GetLibraryHubsRole","GetLibraryHubsWriter","GetLibraryItemsCountry","GetLibraryItemsDirector","GetLibraryItemsGenre","GetLibraryItemsMedia","GetLibraryItemsMediaContainer","GetLibraryItemsMetadata","GetLibraryItemsPart","GetLibraryItemsRequest","GetLibraryItemsResponse","GetLibraryItemsResponseBody","GetLibraryItemsRole","GetLibraryItemsWriter","GetLibraryMediaContainer","GetLibraryRequest","GetLibraryResponse","GetLibraryResponseBody","GetLibraryType","GetMetadataChildrenDirectory","GetMetadataChildrenMediaContainer","GetMetadataChildrenMetadata","GetMetadataChildrenRequest","GetMetadataChildrenResponse","GetMetadataChildrenResponseBody","GetMetadataCountry","GetMetadataDirector","GetMetadataGenre","GetMetadataMedia","GetMetadataMediaContainer","GetMetadataMetadata","GetMetadataPart","GetMetadataRequest","GetMetadataResponse","GetMetadataResponseBody","GetMetadataRole","GetMetadataWriter","GetMyPlexAccountResponse","GetMyPlexAccountResponseBody","GetOnDeckGuids","GetOnDeckMedia","GetOnDeckMediaContainer","GetOnDeckMetadata","GetOnDeckPart","GetOnDeckResponse","GetOnDeckResponseBody","GetOnDeckStream","GetPinGlobals","GetPinRequest","GetPinResponse","GetPinResponseBody","GetPlaylistContentsCountry","GetPlaylistContentsDirector","GetPlaylistContentsGenre","GetPlaylistContentsMedia","GetPlaylistContentsMediaContainer","GetPlaylistContentsMetadata","GetPlaylistContentsPart","GetPlaylistContentsRequest","GetPlaylistContentsResponse","GetPlaylistContentsResponseBody","GetPlaylistContentsRole","GetPlaylistContentsWriter","GetPlaylistMediaContainer","GetPlaylistMetadata","GetPlaylistRequest","GetPlaylistResponse","GetPlaylistResponseBody","GetPlaylistsMediaContainer","GetPlaylistsMetadata","GetPlaylistsRequest","GetPlaylistsResponse","GetPlaylistsResponseBody","GetRecentlyAddedMediaContainer","GetRecentlyAddedResponse","GetRecentlyAddedResponseBody","GetResizedPhotoRequest","GetResizedPhotoResponse","GetSearchResultsCountry","GetSearchResultsDirector","GetSearchResultsGenre","GetSearchResultsMedia","GetSearchResultsMediaContainer","GetSearchResultsMetadata","GetSearchResultsPart","GetSearchResultsRequest","GetSearchResultsResponse","GetSearchResultsResponseBody","GetSearchResultsRole","GetSearchResultsWriter","GetServerActivitiesMediaContainer","GetServerActivitiesResponse","GetServerActivitiesResponseBody","GetServerCapabilitiesResponse","GetServerCapabilitiesResponseBody","GetServerIdentityMediaContainer","GetServerIdentityResponse","GetServerIdentityResponseBody","GetServerListMediaContainer","GetServerListResponse","GetServerListResponseBody","GetServerListServer","GetServerPreferencesMediaContainer","GetServerPreferencesResponse","GetServerPreferencesResponseBody","GetSessionHistoryMediaContainer","GetSessionHistoryMetadata","GetSessionHistoryResponse","GetSessionHistoryResponseBody","GetSessionsMedia","GetSessionsMediaContainer","GetSessionsMetadata","GetSessionsPart","GetSessionsResponse","GetSessionsResponseBody","GetSessionsStream","GetSourceConnectionInformationRequest","GetSourceConnectionInformationResponse","GetStatisticsDevice","GetStatisticsMediaContainer","GetStatisticsRequest","GetStatisticsResponse","GetStatisticsResponseBody","GetTimelineRequest","GetTimelineResponse","GetTokenGlobals","GetTokenRequest","GetTokenResponse","GetTranscodeSessionsMediaContainer","GetTranscodeSessionsResponse","GetTranscodeSessionsResponseBody","GetTransientTokenQueryParamType","GetTransientTokenRequest","GetTransientTokenResponse","GetUpdateStatusMediaContainer","GetUpdateStatusResponse","GetUpdateStatusResponseBody","Guids","Hub","IncludeDetails","Level","Location","LogLineRequest","LogLineResponse","LogMultiLineResponse","MarkPlayedRequest","MarkPlayedResponse","MarkUnplayedRequest","MarkUnplayedResponse","Media","MediaContainer","Metadata","MinSize","MyPlex","OnlyTransient","Operator","Part","PathParamTaskName","PerformSearchRequest","PerformSearchResponse","PerformVoiceSearchRequest","PerformVoiceSearchResponse","Player","PlaylistType","Producer","Provider","QueryParamOnlyTransient","QueryParamSmart","QueryParamType","Ratings","RefreshLibraryRequest","RefreshLibraryResponse","Release","Role","Scope","SearchLibraryMediaContainer","SearchLibraryMetadata","SearchLibraryRequest","SearchLibraryResponse","SearchLibraryResponseBody","Server","Session","Setting","Skip","Smart","Sort","StartAllTasksResponse","StartTaskRequest","StartTaskResponse","StartUniversalTranscodeRequest","StartUniversalTranscodeResponse","State","StatisticsMedia","StopAllTasksResponse","StopTaskRequest","StopTaskResponse","StopTranscodeSessionRequest","StopTranscodeSessionResponse","Stream","Tag","TaskName","Tonight","TranscodeSession","Type","UpdatePlayProgressRequest","UpdatePlayProgressResponse","UpdatePlaylistRequest","UpdatePlaylistResponse","UploadPlaylistRequest","UploadPlaylistResponse","Upscale","User","Writer"] diff --git a/src/plex_api/models/operations/getpin.py b/src/plex_api/models/operations/getpin.py index 93fc9d6..5944bce 100644 --- a/src/plex_api/models/operations/getpin.py +++ b/src/plex_api/models/operations/getpin.py @@ -14,6 +14,17 @@ GET_PIN_SERVERS = [ ] +@dataclasses.dataclass +class GetPinGlobals: + x_plex_client_identifier: str = dataclasses.field(metadata={'header': { 'field_name': 'X-Plex-Client-Identifier', 'style': 'simple', 'explode': False }}) + r"""The unique identifier for the client application + This is used to track the client application and its usage + (UUID, serial number, or other number unique per device) + """ + + + + @dataclasses.dataclass class GetPinRequest: strong: Optional[bool] = dataclasses.field(default=False, metadata={'query_param': { 'field_name': 'strong', 'style': 'form', 'explode': True }}) diff --git a/src/plex_api/models/operations/gettoken.py b/src/plex_api/models/operations/gettoken.py index 1191872..3d67d6a 100644 --- a/src/plex_api/models/operations/gettoken.py +++ b/src/plex_api/models/operations/gettoken.py @@ -10,6 +10,17 @@ GET_TOKEN_SERVERS = [ ] +@dataclasses.dataclass +class GetTokenGlobals: + x_plex_client_identifier: str = dataclasses.field(metadata={'header': { 'field_name': 'X-Plex-Client-Identifier', 'style': 'simple', 'explode': False }}) + r"""The unique identifier for the client application + This is used to track the client application and its usage + (UUID, serial number, or other number unique per device) + """ + + + + @dataclasses.dataclass class GetTokenRequest: pin_id: str = dataclasses.field(metadata={'path_param': { 'field_name': 'pinID', 'style': 'simple', 'explode': False }}) diff --git a/src/plex_api/playlists.py b/src/plex_api/playlists.py index 11061bc..6385fec 100644 --- a/src/plex_api/playlists.py +++ b/src/plex_api/playlists.py @@ -36,7 +36,7 @@ class Playlists: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.CreatePlaylistRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -106,7 +106,7 @@ class Playlists: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetPlaylistsRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -169,7 +169,7 @@ class Playlists: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetPlaylistRequest, base_url, '/playlists/{playlistID}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/playlists/{playlistID}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -237,7 +237,7 @@ class Playlists: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.DeletePlaylistRequest, base_url, '/playlists/{playlistID}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/playlists/{playlistID}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -302,14 +302,14 @@ class Playlists: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.UpdatePlaylistRequest, base_url, '/playlists/{playlistID}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/playlists/{playlistID}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.UpdatePlaylistRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -370,14 +370,14 @@ class Playlists: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.GetPlaylistContentsRequest, base_url, '/playlists/{playlistID}/items', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/playlists/{playlistID}/items', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetPlaylistContentsRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -439,7 +439,7 @@ class Playlists: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.ClearPlaylistContentsRequest, base_url, '/playlists/{playlistID}/items', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/playlists/{playlistID}/items', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) @@ -505,14 +505,14 @@ class Playlists: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.AddPlaylistContentsRequest, base_url, '/playlists/{playlistID}/items', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/playlists/{playlistID}/items', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.AddPlaylistContentsRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -582,7 +582,7 @@ class Playlists: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.UploadPlaylistRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/plex.py b/src/plex_api/plex.py index 202a6c1..c3d3d19 100644 --- a/src/plex_api/plex.py +++ b/src/plex_api/plex.py @@ -26,18 +26,22 @@ class Plex: x_plex_client_identifier=x_plex_client_identifier, ) + _globals = operations.GetPinGlobals( + x_plex_client_identifier=self.sdk_configuration.globals.x_plex_client_identifier, + ) + base_url = utils.template_url(operations.GET_PIN_SERVERS[0], { }) if server_url is not None: base_url = server_url - url = base_url + '/pins' + url = utils.generate_url(base_url, '/pins', request, _globals) headers = {} query_params = {} - headers = { **utils.get_headers(request, self.sdk_configuration.globals), **headers } - query_params = { **utils.get_query_params(operations.GetPinRequest, request, self.sdk_configuration.globals), **query_params } + headers = { **utils.get_headers(request, _globals), **headers } + query_params = { **utils.get_query_params(request, _globals), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -98,22 +102,28 @@ class Plex: x_plex_client_identifier=x_plex_client_identifier, ) + _globals = operations.GetTokenGlobals( + x_plex_client_identifier=self.sdk_configuration.globals.x_plex_client_identifier, + ) + base_url = utils.template_url(operations.GET_TOKEN_SERVERS[0], { }) if server_url is not None: base_url = server_url - url = utils.generate_url(operations.GetTokenRequest, base_url, '/pins/{pinID}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/pins/{pinID}', request, _globals) headers = {} + query_params = {} - headers = { **utils.get_headers(request, self.sdk_configuration.globals), **headers } + headers = { **utils.get_headers(request, _globals), **headers } + query_params = { **utils.get_query_params(request, _globals), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client try: - req = client.prepare_request(requests_http.Request('GET', url, headers=headers)) + req = client.prepare_request(requests_http.Request('GET', url, params=query_params, headers=headers)) req = self.sdk_configuration.get_hooks().before_request(BeforeRequestContext(hook_ctx), req) http_res = client.send(req) except Exception as e: diff --git a/src/plex_api/sdk.py b/src/plex_api/sdk.py index e1bd7d7..ed51dd8 100644 --- a/src/plex_api/sdk.py +++ b/src/plex_api/sdk.py @@ -20,7 +20,7 @@ from .utils.retries import RetryConfig from .video import Video from plex_api import utils from plex_api._hooks import SDKHooks -from plex_api.models import components +from plex_api.models import components, internal from typing import Callable, Dict, Optional, Union class PlexAPI: @@ -127,25 +127,18 @@ class PlexAPI: 'port': port or '32400', }, ] - global_params = { - 'parameters': { - 'queryParam': { - }, - 'pathParam': { - }, - 'header': { - 'x_plex_client_identifier': x_plex_client_identifier, - }, - }, - } + + _globals = internal.Globals( + x_plex_client_identifier=x_plex_client_identifier, + ) self.sdk_configuration = SDKConfiguration( client, + _globals, security, server_url, server_idx, server_defaults, - global_params, retry_config=retry_config ) @@ -157,7 +150,7 @@ class PlexAPI: self.sdk_configuration.server_url = server_url # pylint: disable=protected-access - self.sdk_configuration._hooks = hooks + self.sdk_configuration.__dict__['_hooks'] = hooks self._init_sdks() diff --git a/src/plex_api/sdkconfiguration.py b/src/plex_api/sdkconfiguration.py index 7a06006..0c08aab 100644 --- a/src/plex_api/sdkconfiguration.py +++ b/src/plex_api/sdkconfiguration.py @@ -7,8 +7,8 @@ from .utils import utils from .utils.retries import RetryConfig from dataclasses import dataclass, field from enum import Enum -from plex_api.models import components -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from plex_api.models import components, internal +from typing import Callable, Dict, List, Optional, Tuple, Union SERVERS = [ @@ -26,18 +26,20 @@ class ServerProtocol(str, Enum): @dataclass class SDKConfiguration: client: requests_http.Session + globals: internal.Globals security: Union[components.Security,Callable[[], components.Security]] = None server_url: Optional[str] = '' server_idx: Optional[int] = 0 server_defaults: List[Dict[str, str]] = field(default_factory=List) - globals: Dict[str, Dict[str, Dict[str, Any]]] = field(default_factory=Dict) language: str = 'python' openapi_doc_version: str = '0.0.3' - sdk_version: str = '0.6.2' - gen_version: str = '2.300.0' - user_agent: str = 'speakeasy-sdk/python 0.6.2 2.300.0 0.0.3 plex-api-client' + sdk_version: str = '0.6.3' + gen_version: str = '2.301.0' + user_agent: str = 'speakeasy-sdk/python 0.6.3 2.301.0 0.0.3 plex-api-client' retry_config: Optional[RetryConfig] = None - _hooks: Optional[SDKHooks] = None + + def __post_init__(self): + self._hooks = SDKHooks() def get_server_details(self) -> Tuple[str, Dict[str, str]]: if self.server_url is not None and self.server_url != '': diff --git a/src/plex_api/search.py b/src/plex_api/search.py index a1afe2a..41f63eb 100644 --- a/src/plex_api/search.py +++ b/src/plex_api/search.py @@ -47,7 +47,7 @@ class Search: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.PerformSearchRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -116,7 +116,7 @@ class Search: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.PerformVoiceSearchRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -180,7 +180,7 @@ class Search: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetSearchResultsRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/server.py b/src/plex_api/server.py index 82164ad..198cc17 100644 --- a/src/plex_api/server.py +++ b/src/plex_api/server.py @@ -414,7 +414,7 @@ class Server: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetResizedPhotoRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/sessions.py b/src/plex_api/sessions.py index 36a4323..a3a8643 100644 --- a/src/plex_api/sessions.py +++ b/src/plex_api/sessions.py @@ -219,7 +219,7 @@ class Sessions: base_url = utils.template_url(*self.sdk_configuration.get_server_details()) - url = utils.generate_url(operations.StopTranscodeSessionRequest, base_url, '/transcode/sessions/{sessionKey}', request, self.sdk_configuration.globals) + url = utils.generate_url(base_url, '/transcode/sessions/{sessionKey}', request) if callable(self.sdk_configuration.security): headers, query_params = utils.get_security(self.sdk_configuration.security()) diff --git a/src/plex_api/statistics.py b/src/plex_api/statistics.py index 8504909..e4a6822 100644 --- a/src/plex_api/statistics.py +++ b/src/plex_api/statistics.py @@ -34,7 +34,7 @@ class Statistics: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetStatisticsRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/updater.py b/src/plex_api/updater.py index 04c8a7a..2817946 100644 --- a/src/plex_api/updater.py +++ b/src/plex_api/updater.py @@ -100,7 +100,7 @@ class Updater: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.CheckForUpdatesRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -165,7 +165,7 @@ class Updater: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.ApplyUpdatesRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client diff --git a/src/plex_api/utils/utils.py b/src/plex_api/utils/utils.py index db4406a..b238ff2 100644 --- a/src/plex_api/utils/utils.py +++ b/src/plex_api/utils/utils.py @@ -9,8 +9,17 @@ from datetime import date, datetime from decimal import Decimal from email.message import Message from enum import Enum -from typing import (Any, Callable, Dict, List, Optional, Tuple, Union, - get_args, get_origin) +from typing import ( + Any, + Callable, + Dict, + List, + Optional, + Tuple, + Union, + get_args, + get_origin, +) from xmlrpc.client import boolean from typing_inspect import is_optional_type import dateutil.parser @@ -30,13 +39,13 @@ def get_security(security: Any) -> Tuple[Dict[str, str], Dict[str, str]]: if value is None: continue - metadata = sec_field.metadata.get('security') + metadata = sec_field.metadata.get("security") if metadata is None: continue - if metadata.get('option'): + if metadata.get("option"): _parse_security_option(headers, query_params, value) return headers, query_params - if metadata.get('scheme'): + if metadata.get("scheme"): # Special case for basic auth which could be a flattened struct if metadata.get("sub_type") == "basic" and not is_dataclass(value): _parse_security_scheme(headers, query_params, metadata, security) @@ -46,69 +55,85 @@ def get_security(security: Any) -> Tuple[Dict[str, str], Dict[str, str]]: return headers, query_params -def _parse_security_option(headers: Dict[str, str], query_params: Dict[str, str], option: Any): +def _parse_security_option( + headers: Dict[str, str], query_params: Dict[str, str], option: Any +): opt_fields: Tuple[Field, ...] = fields(option) for opt_field in opt_fields: - metadata = opt_field.metadata.get('security') - if metadata is None or metadata.get('scheme') is None: + metadata = opt_field.metadata.get("security") + if metadata is None or metadata.get("scheme") is None: continue _parse_security_scheme( - headers, query_params, metadata, getattr(option, opt_field.name)) + headers, query_params, metadata, getattr(option, opt_field.name) + ) -def _parse_security_scheme(headers: Dict[str, str], query_params: Dict[str, str], scheme_metadata: Dict, scheme: Any): - scheme_type = scheme_metadata.get('type') - sub_type = scheme_metadata.get('sub_type') +def _parse_security_scheme( + headers: Dict[str, str], + query_params: Dict[str, str], + scheme_metadata: Dict, + scheme: Any, +): + scheme_type = scheme_metadata.get("type") + sub_type = scheme_metadata.get("sub_type") if is_dataclass(scheme): - if scheme_type == 'http' and sub_type == 'basic': + if scheme_type == "http" and sub_type == "basic": _parse_basic_auth_scheme(headers, scheme) return scheme_fields: Tuple[Field, ...] = fields(scheme) for scheme_field in scheme_fields: - metadata = scheme_field.metadata.get('security') - if metadata is None or metadata.get('field_name') is None: + metadata = scheme_field.metadata.get("security") + if metadata is None or metadata.get("field_name") is None: continue value = getattr(scheme, scheme_field.name) _parse_security_scheme_value( - headers, query_params, scheme_metadata, metadata, value) + headers, query_params, scheme_metadata, metadata, value + ) else: _parse_security_scheme_value( - headers, query_params, scheme_metadata, scheme_metadata, scheme) + headers, query_params, scheme_metadata, scheme_metadata, scheme + ) -def _parse_security_scheme_value(headers: Dict[str, str], query_params: Dict[str, str], scheme_metadata: Dict, security_metadata: Dict, value: Any): - scheme_type = scheme_metadata.get('type') - sub_type = scheme_metadata.get('sub_type') +def _parse_security_scheme_value( + headers: Dict[str, str], + query_params: Dict[str, str], + scheme_metadata: Dict, + security_metadata: Dict, + value: Any, +): + scheme_type = scheme_metadata.get("type") + sub_type = scheme_metadata.get("sub_type") - header_name = str(security_metadata.get('field_name')) + header_name = str(security_metadata.get("field_name")) if scheme_type == "apiKey": - if sub_type == 'header': + if sub_type == "header": headers[header_name] = value - elif sub_type == 'query': + elif sub_type == "query": query_params[header_name] = value else: - raise Exception('not supported') + raise Exception("not supported") elif scheme_type == "openIdConnect": headers[header_name] = _apply_bearer(value) - elif scheme_type == 'oauth2': - if sub_type != 'client_credentials': + elif scheme_type == "oauth2": + if sub_type != "client_credentials": headers[header_name] = _apply_bearer(value) - elif scheme_type == 'http': - if sub_type == 'bearer': + elif scheme_type == "http": + if sub_type == "bearer": headers[header_name] = _apply_bearer(value) else: - raise Exception('not supported') + raise Exception("not supported") else: - raise Exception('not supported') + raise Exception("not supported") def _apply_bearer(token: str) -> str: - return token.lower().startswith('bearer ') and token or f'Bearer {token}' + return token.lower().startswith("bearer ") and token or f"Bearer {token}" def _parse_basic_auth_scheme(headers: Dict[str, str], scheme: Any): @@ -117,101 +142,130 @@ def _parse_basic_auth_scheme(headers: Dict[str, str], scheme: Any): scheme_fields: Tuple[Field, ...] = fields(scheme) for scheme_field in scheme_fields: - metadata = scheme_field.metadata.get('security') - if metadata is None or metadata.get('field_name') is None: + metadata = scheme_field.metadata.get("security") + if metadata is None or metadata.get("field_name") is None: continue - field_name = metadata.get('field_name') + field_name = metadata.get("field_name") value = getattr(scheme, scheme_field.name) - if field_name == 'username': + if field_name == "username": username = value - if field_name == 'password': + if field_name == "password": password = value - data = f'{username}:{password}'.encode() - headers['Authorization'] = f'Basic {base64.b64encode(data).decode()}' + data = f"{username}:{password}".encode() + headers["Authorization"] = f"Basic {base64.b64encode(data).decode()}" -def generate_url(clazz: type, server_url: str, path: str, path_params: Any, - gbls: Optional[Dict[str, Dict[str, Dict[str, Any]]]] = None) -> str: - path_param_fields: Tuple[Field, ...] = fields(clazz) +def generate_url( + server_url: str, + path: str, + path_params: Any, + gbls: Optional[Any] = None, +) -> str: + path_param_values: Dict[str, str] = {} + + globals_already_populated = _populate_path_params( + path_params, gbls, path_param_values, [] + ) + if gbls is not None: + _populate_path_params(gbls, None, path_param_values, globals_already_populated) + + for key, value in path_param_values.items(): + path = path.replace("{" + key + "}", value, 1) + + return remove_suffix(server_url, "/") + path + + +def _populate_path_params( + path_params: Any, + gbls: Any, + path_param_values: Dict[str, str], + skip_fields: List[str], +) -> List[str]: + globals_already_populated: List[str] = [] + + path_param_fields: Tuple[Field, ...] = fields(path_params) for field in path_param_fields: - request_metadata = field.metadata.get('request') - if request_metadata is not None: + if field.name in skip_fields: continue - param_metadata = field.metadata.get('path_param') + param_metadata = field.metadata.get("path_param") if param_metadata is None: continue - param = getattr( - path_params, field.name) if path_params is not None else None - param = _populate_from_globals( - field.name, param, 'pathParam', gbls) + param = getattr(path_params, field.name) if path_params is not None else None + param, global_found = _populate_from_globals( + field.name, param, "path_param", gbls + ) + if global_found: + globals_already_populated.append(field.name) if param is None: continue f_name = param_metadata.get("field_name", field.name) - serialization = param_metadata.get('serialization', '') - if serialization != '': + serialization = param_metadata.get("serialization", "") + if serialization != "": serialized_params = _get_serialized_params( - param_metadata, field.type, f_name, param) + param_metadata, field.type, f_name, param + ) for key, value in serialized_params.items(): - path = path.replace( - '{' + key + '}', value, 1) + path_param_values[key] = value else: - if param_metadata.get('style', 'simple') == 'simple': + if param_metadata.get("style", "simple") == "simple": if isinstance(param, List): pp_vals: List[str] = [] for pp_val in param: if pp_val is None: continue pp_vals.append(_val_to_string(pp_val)) - path = path.replace( - '{' + param_metadata.get('field_name', field.name) + '}', ",".join(pp_vals), 1) + path_param_values[param_metadata.get("field_name", field.name)] = ( + ",".join(pp_vals) + ) elif isinstance(param, Dict): pp_vals: List[str] = [] for pp_key in param: if param[pp_key] is None: continue - if param_metadata.get('explode'): - pp_vals.append( - f"{pp_key}={_val_to_string(param[pp_key])}") + if param_metadata.get("explode"): + pp_vals.append(f"{pp_key}={_val_to_string(param[pp_key])}") else: - pp_vals.append( - f"{pp_key},{_val_to_string(param[pp_key])}") - path = path.replace( - '{' + param_metadata.get('field_name', field.name) + '}', ",".join(pp_vals), 1) + pp_vals.append(f"{pp_key},{_val_to_string(param[pp_key])}") + path_param_values[param_metadata.get("field_name", field.name)] = ( + ",".join(pp_vals) + ) elif not isinstance(param, (str, int, float, complex, bool, Decimal)): pp_vals: List[str] = [] param_fields: Tuple[Field, ...] = fields(param) for param_field in param_fields: - param_value_metadata = param_field.metadata.get( - 'path_param') + param_value_metadata = param_field.metadata.get("path_param") if not param_value_metadata: continue - parm_name = param_value_metadata.get( - 'field_name', field.name) + param_name = param_value_metadata.get("field_name", field.name) param_field_val = getattr(param, param_field.name) if param_field_val is None: continue - if param_metadata.get('explode'): + if param_metadata.get("explode"): pp_vals.append( - f"{parm_name}={_val_to_string(param_field_val)}") + f"{param_name}={_val_to_string(param_field_val)}" + ) else: pp_vals.append( - f"{parm_name},{_val_to_string(param_field_val)}") - path = path.replace( - '{' + param_metadata.get('field_name', field.name) + '}', ",".join(pp_vals), 1) + f"{param_name},{_val_to_string(param_field_val)}" + ) + path_param_values[param_metadata.get("field_name", field.name)] = ( + ",".join(pp_vals) + ) else: - path = path.replace( - '{' + param_metadata.get('field_name', field.name) + '}', _val_to_string(param), 1) + path_param_values[param_metadata.get("field_name", field.name)] = ( + _val_to_string(param) + ) - return remove_suffix(server_url, '/') + path + return globals_already_populated def is_optional(field): @@ -220,100 +274,145 @@ def is_optional(field): def template_url(url_with_params: str, params: Dict[str, str]) -> str: for key, value in params.items(): - url_with_params = url_with_params.replace( - '{' + key + '}', value) + url_with_params = url_with_params.replace("{" + key + "}", value) return url_with_params -def get_query_params(clazz: type, query_params: Any, gbls: Optional[Dict[str, Dict[str, Dict[str, Any]]]] = None) -> Dict[ - str, List[str]]: +def get_query_params( + query_params: Any, + gbls: Optional[Any] = None, +) -> Dict[str, List[str]]: params: Dict[str, List[str]] = {} - param_fields: Tuple[Field, ...] = fields(clazz) + globals_already_populated = _populate_query_params(query_params, gbls, params, []) + if gbls is not None: + _populate_query_params(gbls, None, params, globals_already_populated) + + return params + + +def _populate_query_params( + query_params: Any, + gbls: Any, + query_param_values: Dict[str, List[str]], + skip_fields: List[str], +) -> List[str]: + globals_already_populated: List[str] = [] + + param_fields: Tuple[Field, ...] = fields(query_params) for field in param_fields: - request_metadata = field.metadata.get('request') - if request_metadata is not None: + if field.name in skip_fields: continue - metadata = field.metadata.get('query_param') + metadata = field.metadata.get("query_param") if not metadata: continue param_name = field.name - value = getattr( - query_params, param_name) if query_params is not None else None + value = getattr(query_params, param_name) if query_params is not None else None - value = _populate_from_globals(param_name, value, 'queryParam', gbls) + value, global_found = _populate_from_globals( + param_name, value, "query_param", gbls + ) + if global_found: + globals_already_populated.append(param_name) f_name = metadata.get("field_name") - serialization = metadata.get('serialization', '') - if serialization != '': + serialization = metadata.get("serialization", "") + if serialization != "": serialized_parms = _get_serialized_params( - metadata, field.type, f_name, value) + metadata, field.type, f_name, value + ) for key, value in serialized_parms.items(): - if key in params: - params[key].extend(value) + if key in query_param_values: + query_param_values[key].extend(value) else: - params[key] = [value] + query_param_values[key] = [value] else: - style = metadata.get('style', 'form') - if style == 'deepObject': - params = {**params, **_get_deep_object_query_params( - metadata, f_name, value)} - elif style == 'form': - params = {**params, **_get_delimited_query_params( - metadata, f_name, value, ",")} - elif style == 'pipeDelimited': - params = {**params, **_get_delimited_query_params( - metadata, f_name, value, "|")} + style = metadata.get("style", "form") + if style == "deepObject": + _populate_deep_object_query_params( + metadata, f_name, value, query_param_values + ) + elif style == "form": + _populate_delimited_query_params( + metadata, f_name, value, ",", query_param_values + ) + elif style == "pipeDelimited": + _populate_delimited_query_params( + metadata, f_name, value, "|", query_param_values + ) else: - raise Exception('not yet implemented') - return params + raise Exception("not yet implemented") + + return globals_already_populated -def get_headers(headers_params: Any, gbls: Optional[Dict[str, Dict[str, Dict[str, Any]]]] = None) -> Dict[str, str]: - if headers_params is None: - return {} - +def get_headers(headers_params: Any, gbls: Optional[Any] = None) -> Dict[str, str]: headers: Dict[str, str] = {} - param_fields: Tuple[Field, ...] = fields(headers_params) - for field in param_fields: - metadata = field.metadata.get('header') - if not metadata: - continue - - value = _populate_from_globals(field.name, getattr(headers_params, field.name), 'header', gbls) - value = _serialize_header(metadata.get('explode', False), value) - - if value != '': - headers[metadata.get('field_name', field.name)] = value + globals_already_populated = [] + if headers_params is not None: + globals_already_populated = _populate_headers(headers_params, gbls, headers, []) + if gbls is not None: + _populate_headers(gbls, None, headers, globals_already_populated) return headers -def _get_serialized_params(metadata: Dict, field_type: type, field_name: str, obj: Any) -> Dict[str, str]: +def _populate_headers( + headers_params: Any, + gbls: Any, + header_values: Dict[str, str], + skip_fields: List[str], +) -> List[str]: + globals_already_populated: List[str] = [] + + param_fields: Tuple[Field, ...] = fields(headers_params) + for field in param_fields: + if field.name in skip_fields: + continue + + metadata = field.metadata.get("header") + if not metadata: + continue + + value, global_found = _populate_from_globals( + field.name, getattr(headers_params, field.name), "header", gbls + ) + if global_found: + globals_already_populated.append(field.name) + value = _serialize_header(metadata.get("explode", False), value) + + if value != "": + header_values[metadata.get("field_name", field.name)] = value + + return globals_already_populated + + +def _get_serialized_params( + metadata: Dict, field_type: type, field_name: str, obj: Any +) -> Dict[str, str]: params: Dict[str, str] = {} - serialization = metadata.get('serialization', '') - if serialization == 'json': - params[metadata.get("field_name", field_name) - ] = marshal_json(obj, field_type) + serialization = metadata.get("serialization", "") + if serialization == "json": + params[metadata.get("field_name", field_name)] = marshal_json(obj, field_type) return params -def _get_deep_object_query_params(metadata: Dict, field_name: str, obj: Any) -> Dict[str, List[str]]: - params: Dict[str, List[str]] = {} - +def _populate_deep_object_query_params( + metadata: Dict, field_name: str, obj: Any, params: Dict[str, List[str]] +): if obj is None: - return params + return if is_dataclass(obj): obj_fields: Tuple[Field, ...] = fields(obj) for obj_field in obj_fields: - obj_param_metadata = obj_field.metadata.get('query_param') + obj_param_metadata = obj_field.metadata.get("query_param") if not obj_param_metadata: continue @@ -326,19 +425,23 @@ def _get_deep_object_query_params(metadata: Dict, field_name: str, obj: Any) -> if val is None: continue - if params.get( - f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]') is None: + if ( + params.get( + f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]' + ) + is None + ): params[ - f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]'] = [ - ] + f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]' + ] = [] params[ - f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]'].append( - _val_to_string(val)) + f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]' + ].append(_val_to_string(val)) else: params[ - f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]'] = [ - _val_to_string(obj_val)] + f'{metadata.get("field_name", field_name)}[{obj_param_metadata.get("field_name", obj_field.name)}]' + ] = [_val_to_string(obj_val)] elif isinstance(obj, Dict): for key, value in obj.items(): if value is None: @@ -349,20 +452,23 @@ def _get_deep_object_query_params(metadata: Dict, field_name: str, obj: Any) -> if val is None: continue - if params.get(f'{metadata.get("field_name", field_name)}[{key}]') is None: - params[f'{metadata.get("field_name", field_name)}[{key}]'] = [ - ] + if ( + params.get(f'{metadata.get("field_name", field_name)}[{key}]') + is None + ): + params[f'{metadata.get("field_name", field_name)}[{key}]'] = [] - params[ - f'{metadata.get("field_name", field_name)}[{key}]'].append(_val_to_string(val)) + params[f'{metadata.get("field_name", field_name)}[{key}]'].append( + _val_to_string(val) + ) else: params[f'{metadata.get("field_name", field_name)}[{key}]'] = [ - _val_to_string(value)] - return params + _val_to_string(value) + ] def _get_query_param_field_name(obj_field: Field) -> str: - obj_param_metadata = obj_field.metadata.get('query_param') + obj_param_metadata = obj_field.metadata.get("query_param") if not obj_param_metadata: return "" @@ -370,29 +476,53 @@ def _get_query_param_field_name(obj_field: Field) -> str: return obj_param_metadata.get("field_name", obj_field.name) -def _get_delimited_query_params(metadata: Dict, field_name: str, obj: Any, delimiter: str) -> Dict[ - str, List[str]]: - return _populate_form(field_name, metadata.get("explode", True), obj, _get_query_param_field_name, delimiter) +def _populate_delimited_query_params( + metadata: Dict, + field_name: str, + obj: Any, + delimiter: str, + query_param_values: Dict[str, List[str]], +): + _populate_form( + field_name, + metadata.get("explode", True), + obj, + _get_query_param_field_name, + delimiter, + query_param_values, + ) SERIALIZATION_METHOD_TO_CONTENT_TYPE = { - 'json': 'application/json', - 'form': 'application/x-www-form-urlencoded', - 'multipart': 'multipart/form-data', - 'raw': 'application/octet-stream', - 'string': 'text/plain', + "json": "application/json", + "form": "application/x-www-form-urlencoded", + "multipart": "multipart/form-data", + "raw": "application/octet-stream", + "string": "text/plain", } -def serialize_request_body(request: Any, request_type: type, request_field_name: str, nullable: bool, optional: bool, serialization_method: str, encoder=None) -> Tuple[ - Optional[str], Optional[Any], Optional[Any]]: +def serialize_request_body( + request: Any, + request_type: type, + request_field_name: str, + nullable: bool, + optional: bool, + serialization_method: str, + encoder=None, +) -> Tuple[Optional[str], Optional[Any], Optional[Any]]: if request is None: if not nullable and optional: return None, None, None if not is_dataclass(request) or not hasattr(request, request_field_name): - return serialize_content_type(request_field_name, request_type, SERIALIZATION_METHOD_TO_CONTENT_TYPE[serialization_method], - request, encoder) + return serialize_content_type( + request_field_name, + request_type, + SERIALIZATION_METHOD_TO_CONTENT_TYPE[serialization_method], + request, + encoder, + ) request_val = getattr(request, request_field_name) @@ -405,22 +535,28 @@ def serialize_request_body(request: Any, request_type: type, request_field_name: for field in request_fields: if field.name == request_field_name: - request_metadata = field.metadata.get('request') + request_metadata = field.metadata.get("request") break if request_metadata is None: - raise Exception('invalid request type') + raise Exception("invalid request type") - return serialize_content_type(request_field_name, request_type, request_metadata.get('media_type', 'application/octet-stream'), - request_val) + return serialize_content_type( + request_field_name, + request_type, + request_metadata.get("media_type", "application/octet-stream"), + request_val, + ) -def serialize_content_type(field_name: str, request_type: Any, media_type: str, request: Any, encoder=None) -> Tuple[Optional[str], Optional[Any], Optional[List[List[Any]]]]: - if re.match(r'(application|text)\/.*?\+*json.*', media_type) is not None: +def serialize_content_type( + field_name: str, request_type: Any, media_type: str, request: Any, encoder=None +) -> Tuple[Optional[str], Optional[Any], Optional[List[List[Any]]]]: + if re.match(r"(application|text)\/.*?\+*json.*", media_type) is not None: return media_type, marshal_json(request, request_type, encoder), None - if re.match(r'multipart\/.*', media_type) is not None: + if re.match(r"multipart\/.*", media_type) is not None: return serialize_multipart_form(media_type, request) - if re.match(r'application\/x-www-form-urlencoded.*', media_type) is not None: + if re.match(r"application\/x-www-form-urlencoded.*", media_type) is not None: return media_type, serialize_form_data(field_name, request), None if isinstance(request, (bytes, bytearray)): return media_type, request, None @@ -428,10 +564,13 @@ def serialize_content_type(field_name: str, request_type: Any, media_type: str, return media_type, request, None raise Exception( - f"invalid request body type {type(request)} for mediaType {media_type}") + f"invalid request body type {type(request)} for mediaType {media_type}" + ) -def serialize_multipart_form(media_type: str, request: Any) -> Tuple[str, Any, List[List[Any]]]: +def serialize_multipart_form( + media_type: str, request: Any +) -> Tuple[str, Any, List[List[Any]]]: form: List[List[Any]] = [] request_fields = fields(request) @@ -440,7 +579,7 @@ def serialize_multipart_form(media_type: str, request: Any) -> Tuple[str, Any, L if val is None: continue - field_metadata = field.metadata.get('multipart_form') + field_metadata = field.metadata.get("multipart_form") if not field_metadata: continue @@ -452,40 +591,40 @@ def serialize_multipart_form(media_type: str, request: Any) -> Tuple[str, Any, L content = bytes() for file_field in file_fields: - file_metadata = file_field.metadata.get('multipart_form') + file_metadata = file_field.metadata.get("multipart_form") if file_metadata is None: continue if file_metadata.get("content") is True: content = getattr(val, file_field.name) else: - field_name = file_metadata.get( - "field_name", file_field.name) + field_name = file_metadata.get("field_name", file_field.name) file_name = getattr(val, file_field.name) if field_name == "" or file_name == "" or content == bytes(): - raise Exception('invalid multipart/form-data file') + raise Exception("invalid multipart/form-data file") form.append([field_name, [file_name, content]]) elif field_metadata.get("json") is True: - to_append = [field_metadata.get("field_name", field.name), [ - None, marshal_json(val, field.type), "application/json"]] + to_append = [ + field_metadata.get("field_name", field.name), + [None, marshal_json(val, field.type), "application/json"], + ] form.append(to_append) else: - field_name = field_metadata.get( - "field_name", field.name) + field_name = field_metadata.get("field_name", field.name) if isinstance(val, List): for value in val: if value is None: continue - form.append( - [field_name + "[]", [None, _val_to_string(value)]]) + form.append([field_name + "[]", [None, _val_to_string(value)]]) else: form.append([field_name, [None, _val_to_string(val)]]) return media_type, None, form -def serialize_dict(original: Dict, explode: bool, field_name, existing: Optional[Dict[str, List[str]]]) -> Dict[ - str, List[str]]: +def serialize_dict( + original: Dict, explode: bool, field_name, existing: Optional[Dict[str, List[str]]] +) -> Dict[str, List[str]]: if existing is None: existing = {} @@ -514,32 +653,37 @@ def serialize_form_data(field_name: str, data: Any) -> Dict[str, Any]: if val is None: continue - metadata = field.metadata.get('form') + metadata = field.metadata.get("form") if metadata is None: continue - field_name = metadata.get('field_name', field.name) + field_name = metadata.get("field_name", field.name) - if metadata.get('json'): + if metadata.get("json"): form[field_name] = [marshal_json(val, field.type)] else: - if metadata.get('style', 'form') == 'form': - form = {**form, **_populate_form( - field_name, metadata.get('explode', True), val, _get_form_field_name, ",")} + if metadata.get("style", "form") == "form": + _populate_form( + field_name, + metadata.get("explode", True), + val, + _get_form_field_name, + ",", + form, + ) else: - raise Exception( - f'Invalid form style for field {field.name}') + raise Exception(f"Invalid form style for field {field.name}") elif isinstance(data, Dict): for key, value in data.items(): form[key] = [_val_to_string(value)] else: - raise Exception(f'Invalid request body type for field {field_name}') + raise Exception(f"Invalid request body type for field {field_name}") return form def _get_form_field_name(obj_field: Field) -> str: - obj_param_metadata = obj_field.metadata.get('form') + obj_param_metadata = obj_field.metadata.get("form") if not obj_param_metadata: return "" @@ -547,12 +691,16 @@ def _get_form_field_name(obj_field: Field) -> str: return obj_param_metadata.get("field_name", obj_field.name) -def _populate_form(field_name: str, explode: boolean, obj: Any, get_field_name_func: Callable, delimiter: str) -> \ - Dict[str, List[str]]: - params: Dict[str, List[str]] = {} - +def _populate_form( + field_name: str, + explode: boolean, + obj: Any, + get_field_name_func: Callable, + delimiter: str, + form: Dict[str, List[str]], +): if obj is None: - return params + return form if is_dataclass(obj): items = [] @@ -560,7 +708,7 @@ def _populate_form(field_name: str, explode: boolean, obj: Any, get_field_name_f obj_fields: Tuple[Field, ...] = fields(obj) for obj_field in obj_fields: obj_field_name = get_field_name_func(obj_field) - if obj_field_name == '': + if obj_field_name == "": continue val = getattr(obj, obj_field.name) @@ -568,13 +716,12 @@ def _populate_form(field_name: str, explode: boolean, obj: Any, get_field_name_f continue if explode: - params[obj_field_name] = [_val_to_string(val)] + form[obj_field_name] = [_val_to_string(val)] else: - items.append( - f'{obj_field_name}{delimiter}{_val_to_string(val)}') + items.append(f"{obj_field_name}{delimiter}{_val_to_string(val)}") if len(items) > 0: - params[field_name] = [delimiter.join(items)] + form[field_name] = [delimiter.join(items)] elif isinstance(obj, Dict): items = [] for key, value in obj.items(): @@ -582,12 +729,12 @@ def _populate_form(field_name: str, explode: boolean, obj: Any, get_field_name_f continue if explode: - params[key] = [_val_to_string(value)] + form[key] = [_val_to_string(value)] else: - items.append(f'{key}{delimiter}{_val_to_string(value)}') + items.append(f"{key}{delimiter}{_val_to_string(value)}") if len(items) > 0: - params[field_name] = [delimiter.join(items)] + form[field_name] = [delimiter.join(items)] elif isinstance(obj, List): items = [] @@ -596,37 +743,35 @@ def _populate_form(field_name: str, explode: boolean, obj: Any, get_field_name_f continue if explode: - if not field_name in params: - params[field_name] = [] - params[field_name].append(_val_to_string(value)) + if not field_name in form: + form[field_name] = [] + form[field_name].append(_val_to_string(value)) else: items.append(_val_to_string(value)) if len(items) > 0: - params[field_name] = [delimiter.join( - [str(item) for item in items])] + form[field_name] = [delimiter.join([str(item) for item in items])] else: - params[field_name] = [_val_to_string(obj)] + form[field_name] = [_val_to_string(obj)] - return params + return form def _serialize_header(explode: bool, obj: Any) -> str: if obj is None: - return '' + return "" if is_dataclass(obj): items = [] obj_fields: Tuple[Field, ...] = fields(obj) for obj_field in obj_fields: - obj_param_metadata = obj_field.metadata.get('header') + obj_param_metadata = obj_field.metadata.get("header") if not obj_param_metadata: continue - obj_field_name = obj_param_metadata.get( - 'field_name', obj_field.name) - if obj_field_name == '': + obj_field_name = obj_param_metadata.get("field_name", obj_field.name) + if obj_field_name == "": continue val = getattr(obj, obj_field.name) @@ -634,14 +779,13 @@ def _serialize_header(explode: bool, obj: Any) -> str: continue if explode: - items.append( - f'{obj_field_name}={_val_to_string(val)}') + items.append(f"{obj_field_name}={_val_to_string(val)}") else: items.append(obj_field_name) items.append(_val_to_string(val)) if len(items) > 0: - return ','.join(items) + return ",".join(items) elif isinstance(obj, Dict): items = [] @@ -650,13 +794,13 @@ def _serialize_header(explode: bool, obj: Any) -> str: continue if explode: - items.append(f'{key}={_val_to_string(value)}') + items.append(f"{key}={_val_to_string(value)}") else: items.append(key) items.append(_val_to_string(value)) if len(items) > 0: - return ','.join([str(item) for item in items]) + return ",".join([str(item) for item in items]) elif isinstance(obj, List): items = [] @@ -667,38 +811,36 @@ def _serialize_header(explode: bool, obj: Any) -> str: items.append(_val_to_string(value)) if len(items) > 0: - return ','.join(items) + return ",".join(items) else: - return f'{_val_to_string(obj)}' + return f"{_val_to_string(obj)}" - return '' + return "" def unmarshal_json(data, typ, decoder=None): - unmarshal = make_dataclass('Unmarshal', [('res', typ)], - bases=(DataClassJsonMixin,)) + unmarshal = make_dataclass("Unmarshal", [("res", typ)], bases=(DataClassJsonMixin,)) json_dict = json.loads(data) try: out = unmarshal.from_dict({"res": json_dict}) except AttributeError as attr_err: raise AttributeError( - f'unable to unmarshal {data} as {typ} - {attr_err}') from attr_err + f"unable to unmarshal {data} as {typ} - {attr_err}" + ) from attr_err return out.res if decoder is None else decoder(out.res) def marshal_json(val, typ, encoder=None): if not is_optional_type(typ) and val is None: - raise ValueError( - f"Could not marshal None into non-optional type: {typ}") + raise ValueError(f"Could not marshal None into non-optional type: {typ}") - marshal = make_dataclass('Marshal', [('res', typ)], - bases=(DataClassJsonMixin,)) + marshal = make_dataclass("Marshal", [("res", typ)], bases=(DataClassJsonMixin,)) marshaller = marshal(res=val) json_dict = marshaller.to_dict() val = json_dict["res"] if encoder is None else encoder(json_dict["res"]) - return json.dumps(val, separators=(',', ':'), sort_keys=True) + return json.dumps(val, separators=(",", ":"), sort_keys=True) def match_content_type(content_type: str, pattern: str) -> boolean: @@ -706,7 +848,7 @@ def match_content_type(content_type: str, pattern: str) -> boolean: return True msg = Message() - msg['content-type'] = content_type + msg["content-type"] = content_type media_type = msg.get_content_type() if media_type == pattern: @@ -714,7 +856,7 @@ def match_content_type(content_type: str, pattern: str) -> boolean: parts = media_type.split("/") if len(parts) == 2: - if pattern in (f'{parts[0]}/*', f'*/{parts[1]}'): + if pattern in (f"{parts[0]}/*", f"*/{parts[1]}"): return True return False @@ -839,6 +981,7 @@ def union_encoder(all_encoders: Dict[str, Callable]): if type(val) in all_encoders: return all_encoders[type(val)](val) return val + return selective_encoder @@ -852,6 +995,7 @@ def union_decoder(all_decoders: List[Callable]): except (TypeError, ValueError): continue return decoded + return selective_decoder @@ -866,33 +1010,51 @@ def _val_to_string(val) -> str: if isinstance(val, bool): return str(val).lower() if isinstance(val, datetime): - return str(val.isoformat().replace('+00:00', 'Z')) + return str(val.isoformat().replace("+00:00", "Z")) if isinstance(val, Enum): return str(val.value) return str(val) -def _populate_from_globals(param_name: str, value: Any, param_type: str, gbls: Optional[Dict[str, Dict[str, Dict[str, Any]]]]): - if value is None and gbls is not None: - if 'parameters' in gbls: - if param_type in gbls['parameters']: - if param_name in gbls['parameters'][param_type]: - global_value = gbls['parameters'][param_type][param_name] - if global_value is not None: - value = global_value +def _populate_from_globals( + param_name: str, value: Any, param_type: str, gbls: Any +) -> Tuple[Any, bool]: + if gbls is None: + return value, False - return value + global_fields = fields(gbls) + + found = False + for field in global_fields: + if field.name is not param_name: + continue + + found = True + + if value is not None: + return value, True + + global_value = getattr(gbls, field.name) + + param_metadata = field.metadata.get(param_type) + if param_metadata is None: + return value, True + + return global_value, True + + return value, found def decoder_with_discriminator(field_name): def decode_fx(obj): - kls = getattr(sys.modules['sdk.models.components'], obj[field_name]) + kls = getattr(sys.modules["sdk.models.components"], obj[field_name]) return unmarshal_json(json.dumps(obj), kls) + return decode_fx def remove_suffix(input_string, suffix): if suffix and input_string.endswith(suffix): - return input_string[:-len(suffix)] + return input_string[: -len(suffix)] return input_string diff --git a/src/plex_api/video.py b/src/plex_api/video.py index 4ed0722..f98f111 100644 --- a/src/plex_api/video.py +++ b/src/plex_api/video.py @@ -29,7 +29,7 @@ class Video: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.GetTimelineRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client @@ -89,7 +89,7 @@ class Video: else: headers, query_params = utils.get_security(self.sdk_configuration.security) - query_params = { **utils.get_query_params(operations.StartUniversalTranscodeRequest, request, self.sdk_configuration.globals), **query_params } + query_params = { **utils.get_query_params(request), **query_params } headers['Accept'] = 'application/json' headers['user-agent'] = self.sdk_configuration.user_agent client = self.sdk_configuration.client