From d81e7dd3dc13c2f571a418201cf554392c5e1407 Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Fri, 4 Apr 2025 00:03:04 +0000 Subject: [PATCH] ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.528.1 --- .speakeasy/gen.lock | 63 +- .speakeasy/gen.yaml | 2 +- .speakeasy/workflow.lock | 14 +- README.md | 33 + RELEASES.md | 12 +- codeSamples.yaml | 76 ++ .../operations/getmediaartsmediacontainer.md | 12 + .../models/operations/getmediaartsmetadata.md | 12 + docs/models/operations/getmediaartsrequest.md | 8 + .../models/operations/getmediaartsresponse.md | 11 + .../operations/getmediaartsresponsebody.md | 10 + .../getmediapostersmediacontainer.md | 12 + .../operations/getmediapostersmetadata.md | 12 + .../operations/getmediapostersrequest.md | 8 + .../operations/getmediapostersresponse.md | 11 + .../operations/getmediapostersresponsebody.md | 10 + .../models/operations/postmediaartsrequest.md | 10 + .../operations/postmediaartsresponse.md | 10 + .../operations/postmediaposterrequest.md | 10 + .../operations/postmediaposterresponse.md | 10 + docs/sdks/library/README.md | 168 ++++ pyproject.toml | 2 +- src/plex_api_client/_version.py | 6 +- src/plex_api_client/library.py | 827 +++++++++++++++++- .../models/operations/__init__.py | 64 ++ .../models/operations/get_media_arts.py | 120 +++ .../models/operations/get_media_posters.py | 120 +++ .../models/operations/get_server_resources.py | 2 +- .../models/operations/get_users.py | 2 +- .../models/operations/getpin.py | 2 +- .../models/operations/gettokenbypinid.py | 2 +- .../models/operations/gettokendetails.py | 10 +- .../models/operations/getuserfriends.py | 2 +- .../models/operations/post_media_arts.py | 65 ++ .../models/operations/post_media_poster.py | 65 ++ .../operations/post_users_sign_in_data.py | 14 +- src/plex_api_client/utils/enums.py | 94 +- 37 files changed, 1846 insertions(+), 65 deletions(-) create mode 100644 docs/models/operations/getmediaartsmediacontainer.md create mode 100644 docs/models/operations/getmediaartsmetadata.md create mode 100644 docs/models/operations/getmediaartsrequest.md create mode 100644 docs/models/operations/getmediaartsresponse.md create mode 100644 docs/models/operations/getmediaartsresponsebody.md create mode 100644 docs/models/operations/getmediapostersmediacontainer.md create mode 100644 docs/models/operations/getmediapostersmetadata.md create mode 100644 docs/models/operations/getmediapostersrequest.md create mode 100644 docs/models/operations/getmediapostersresponse.md create mode 100644 docs/models/operations/getmediapostersresponsebody.md create mode 100644 docs/models/operations/postmediaartsrequest.md create mode 100644 docs/models/operations/postmediaartsresponse.md create mode 100644 docs/models/operations/postmediaposterrequest.md create mode 100644 docs/models/operations/postmediaposterresponse.md create mode 100644 src/plex_api_client/models/operations/get_media_arts.py create mode 100644 src/plex_api_client/models/operations/get_media_posters.py create mode 100644 src/plex_api_client/models/operations/post_media_arts.py create mode 100644 src/plex_api_client/models/operations/post_media_poster.py diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 221e05b..0ef1d0c 100755 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: 3eeea668-4ef4-464e-a888-bdfa023bedf5 management: - docChecksum: 68de03e6e877c4fc50ebfdd47bb117ac + docChecksum: bef8e84d4427234ae3242e247056ab4d docVersion: 0.0.3 - speakeasyVersion: 1.526.6 - generationVersion: 2.563.1 - releaseVersion: 0.24.2 - configChecksum: cd847372037eaec7014d8cd87c3e7029 + speakeasyVersion: 1.528.1 + generationVersion: 2.565.1 + releaseVersion: 0.25.0 + configChecksum: d8dfa4b36aec66843e9aa6b1774c2f0b repoURL: https://github.com/LukeHagar/plexpy.git repoSubDirectory: . installationURL: https://github.com/LukeHagar/plexpy.git @@ -15,7 +15,7 @@ features: python: additionalDependencies: 1.0.0 constsAndDefaults: 1.0.5 - core: 5.12.4 + core: 5.12.5 defaultEnabledRetries: 0.2.0 deprecations: 3.0.2 downloadStreams: 1.0.1 @@ -35,6 +35,7 @@ features: retries: 3.0.2 sdkHooks: 1.0.1 unions: 3.0.4 + uploadStreams: 1.0.0 generatedFiles: - .gitattributes - .python-version @@ -561,6 +562,11 @@ generatedFiles: - docs/models/operations/getlibraryitemstype.md - docs/models/operations/getlibraryitemsultrablurcolors.md - docs/models/operations/getlibraryitemswriter.md + - docs/models/operations/getmediaartsmediacontainer.md + - docs/models/operations/getmediaartsmetadata.md + - docs/models/operations/getmediaartsrequest.md + - docs/models/operations/getmediaartsresponse.md + - docs/models/operations/getmediaartsresponsebody.md - docs/models/operations/getmediametadatacountry.md - docs/models/operations/getmediametadatadirector.md - docs/models/operations/getmediametadatagenre.md @@ -585,6 +591,11 @@ generatedFiles: - docs/models/operations/getmediametadatastream.md - docs/models/operations/getmediametadataultrablurcolors.md - docs/models/operations/getmediametadatawriter.md + - docs/models/operations/getmediapostersmediacontainer.md + - docs/models/operations/getmediapostersmetadata.md + - docs/models/operations/getmediapostersrequest.md + - docs/models/operations/getmediapostersresponse.md + - docs/models/operations/getmediapostersresponsebody.md - docs/models/operations/getmediaprovidersdirectory.md - docs/models/operations/getmediaprovidersmediacontainer.md - docs/models/operations/getmediaprovidersrequest.md @@ -845,6 +856,10 @@ generatedFiles: - docs/models/operations/player.md - docs/models/operations/playlisttype.md - docs/models/operations/plexdevice.md + - docs/models/operations/postmediaartsrequest.md + - docs/models/operations/postmediaartsresponse.md + - docs/models/operations/postmediaposterrequest.md + - docs/models/operations/postmediaposterresponse.md - docs/models/operations/postuserssignindataauthenticationresponsestatus.md - docs/models/operations/postuserssignindataauthenticationstatus.md - docs/models/operations/postuserssignindataauthenticationsubscription.md @@ -1072,7 +1087,9 @@ generatedFiles: - src/plex_api_client/models/operations/get_genres_library.py - src/plex_api_client/models/operations/get_library_details.py - src/plex_api_client/models/operations/get_library_items.py + - src/plex_api_client/models/operations/get_media_arts.py - src/plex_api_client/models/operations/get_media_meta_data.py + - src/plex_api_client/models/operations/get_media_posters.py - src/plex_api_client/models/operations/get_media_providers.py - src/plex_api_client/models/operations/get_recently_added.py - src/plex_api_client/models/operations/get_recently_added_library.py @@ -1125,6 +1142,8 @@ generatedFiles: - src/plex_api_client/models/operations/markunplayed.py - src/plex_api_client/models/operations/performsearch.py - src/plex_api_client/models/operations/performvoicesearch.py + - src/plex_api_client/models/operations/post_media_arts.py + - src/plex_api_client/models/operations/post_media_poster.py - src/plex_api_client/models/operations/post_users_sign_in_data.py - src/plex_api_client/models/operations/startalltasks.py - src/plex_api_client/models/operations/starttask.py @@ -1534,7 +1553,7 @@ examples: X-Plex-Container-Size: 50 responses: "200": - application/json: {"MediaContainer": {"size": 50, "totalSize": 50, "offset": 0, "allowSync": false, "identifier": "com.plexapp.plugins.library", "Meta": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "filter", "subtype": "clip", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "filter", "subtype": "clip", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "filter", "subtype": "clip", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}]}, {"type": "tag", "Operator": []}, {"type": "tag", "Operator": []}]}, "Metadata": [{"addedAt": 1556281940, "art": "/library/metadata/58683/art/1703239236", "audienceRatingImage": "rottentomatoes://image.rating.upright", "audienceRating": 9.2, "chapterSource": "media", "childCount": 1, "contentRating": "PG-13", "createdAtAccuracy": "epoch,local", "createdAtTZOffset": "0", "duration": 11558112, "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentRatingKey": "66", "grandparentSlug": "alice-in-borderland-2020", "grandparentTheme": "/library/metadata/66/theme/1705716261", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "grandparentTitle": "Caprica", "guid": "plex://movie/5d7768ba96b655001fdc0408", "index": 1, "key": "/library/metadata/58683", "lastRatedAt": 1721813113, "lastViewedAt": 1682752242, "leafCount": 14, "librarySectionID": 1, "librarySectionKey": "/library/sections/1", "librarySectionTitle": "Movies", "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "originallyAvailableAt": "2022-12-14", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentIndex": 1, "parentKey": "/library/metadata/66", "parentRatingKey": "66", "parentSlug": "alice-in-borderland-2020", "parentStudio": "UCP", "parentTheme": "/library/metadata/66/theme/1705716261", "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTitle": "Caprica", "parentYear": 2010, "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "ratingKey": "58683", "rating": 7.6, "seasonCount": 2022, "skipCount": 1, "slug": "4-for-texas", "studio": "20th Century Studios", "subtype": "clip", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora.\nOnce a familiar threat returns to finish what was previously started, Jake must\nwork with Neytiri and the army of the Na'vi race to protect their home.\n", "tagline": "Return to Pandora.", "theme": "/library/metadata/1/theme/1705636920", "thumb": "/library/metadata/58683/thumb/1703239236", "titleSort": "Whale", "title": "Avatar: The Way of Water", "type": "movie", "updatedAt": 1556281940, "userRating": 10, "viewCount": 1, "viewOffset": 5222500, "viewedLeafCount": 0, "year": 2022, "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Media": [{"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": 1, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}, {"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": true, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}]}], "Genre": [{"id": 259, "filter": "genre=19", "tag": "Crime"}], "Country": [{"id": 259, "tag": "United States of America", "filter": "country=19"}], "Director": [{"tag": "Danny Boyle"}, {"tag": "Danny Boyle"}], "Writer": [{"id": 126522, "filter": "writer=126522", "tag": "Jamie P. Hanson", "tagKey": "5d77683d85719b001f3a535e"}], "Role": [{"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Producer": [{"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Rating": [{"image": "imdb://image.rating", "value": 5.1, "type": "audience"}, {"image": "imdb://image.rating", "value": 5.1, "type": "audience"}, {"image": "imdb://image.rating", "value": 5.1, "type": "audience"}], "Similar": [{"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}, {"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}, {"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}], "Location": [{"path": "/TV Shows/Clarkson's Farm"}, {"path": "/TV Shows/Clarkson's Farm"}, {"path": "/TV Shows/Clarkson's Farm"}], "Guid": [{"id": "tvdb://2337"}], "Collection": [{"tag": "My Awesome Collection"}]}, {"addedAt": 1556281940, "art": "/library/metadata/58683/art/1703239236", "audienceRatingImage": "rottentomatoes://image.rating.upright", "audienceRating": 9.2, "chapterSource": "media", "childCount": 1, "contentRating": "PG-13", "createdAtAccuracy": "epoch,local", "createdAtTZOffset": "0", "duration": 11558112, "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentRatingKey": "66", "grandparentSlug": "alice-in-borderland-2020", "grandparentTheme": "/library/metadata/66/theme/1705716261", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "grandparentTitle": "Caprica", "guid": "plex://movie/5d7768ba96b655001fdc0408", "index": 1, "key": "/library/metadata/58683", "lastRatedAt": 1721813113, "lastViewedAt": 1682752242, "leafCount": 14, "librarySectionID": 1, "librarySectionKey": "/library/sections/1", "librarySectionTitle": "Movies", "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "originallyAvailableAt": "2022-12-14", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentIndex": 1, "parentKey": "/library/metadata/66", "parentRatingKey": "66", "parentSlug": "alice-in-borderland-2020", "parentStudio": "UCP", "parentTheme": "/library/metadata/66/theme/1705716261", "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTitle": "Caprica", "parentYear": 2010, "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "ratingKey": "58683", "rating": 7.6, "seasonCount": 2022, "skipCount": 1, "slug": "4-for-texas", "studio": "20th Century Studios", "subtype": "clip", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora.\nOnce a familiar threat returns to finish what was previously started, Jake must\nwork with Neytiri and the army of the Na'vi race to protect their home.\n", "tagline": "Return to Pandora.", "theme": "/library/metadata/1/theme/1705636920", "thumb": "/library/metadata/58683/thumb/1703239236", "titleSort": "Whale", "title": "Avatar: The Way of Water", "type": "movie", "updatedAt": 1556281940, "userRating": 10, "viewCount": 1, "viewOffset": 5222500, "viewedLeafCount": 0, "year": 2022, "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Media": [{"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": []}, {"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": 1, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}, {"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": true, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}]}, {"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}, {"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}]}], "Genre": [{"id": 259, "filter": "genre=19", "tag": "Crime"}], "Country": [{"id": 259, "tag": "United States of America", "filter": "country=19"}], "Director": [{"tag": "Danny Boyle"}, {"tag": "Danny Boyle"}], "Writer": [{"id": 126522, "filter": "writer=126522", "tag": "Jamie P. Hanson", "tagKey": "5d77683d85719b001f3a535e"}], "Role": [{"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Producer": [{"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Rating": [{"image": "imdb://image.rating", "value": 5.1, "type": "audience"}], "Similar": [{"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}, {"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}], "Location": [{"path": "/TV Shows/Clarkson's Farm"}], "Guid": [{"id": "tvdb://2337"}, {"id": "tvdb://2337"}], "Collection": [{"tag": "My Awesome Collection"}, {"tag": "My Awesome Collection"}]}]}} + application/json: {"MediaContainer": {"size": 50, "totalSize": 50, "offset": 0, "allowSync": false, "identifier": "com.plexapp.plugins.library", "Meta": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "filter", "subtype": "clip", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "filter", "subtype": "clip", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "filter", "subtype": "clip", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter", "advanced": true}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}]}, {"type": "tag", "Operator": []}, {"type": "tag", "Operator": []}]}, "Metadata": [{"addedAt": 1556281940, "art": "/library/metadata/58683/art/1703239236", "audienceRatingImage": "rottentomatoes://image.rating.upright", "audienceRating": 9.2, "chapterSource": "media", "childCount": 1, "contentRating": "PG-13", "createdAtAccuracy": "epoch,local", "createdAtTZOffset": "0", "duration": 11558112, "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentRatingKey": "66", "grandparentSlug": "alice-in-borderland-2020", "grandparentTheme": "/library/metadata/66/theme/1705716261", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "grandparentTitle": "Caprica", "guid": "plex://movie/5d7768ba96b655001fdc0408", "index": 1, "key": "/library/metadata/58683", "lastRatedAt": 1721813113, "lastViewedAt": 1682752242, "leafCount": 14, "librarySectionID": 1, "librarySectionKey": "/library/sections/1", "librarySectionTitle": "Movies", "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "originallyAvailableAt": "2022-12-14", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentIndex": 1, "parentKey": "/library/metadata/66", "parentRatingKey": "66", "parentSlug": "alice-in-borderland-2020", "parentStudio": "UCP", "parentTheme": "/library/metadata/66/theme/1705716261", "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTitle": "Caprica", "parentYear": 2010, "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "ratingKey": "58683", "rating": 7.6, "seasonCount": 2022, "skipCount": 1, "slug": "4-for-texas", "studio": "20th Century Studios", "subtype": "clip", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora.\nOnce a familiar threat returns to finish what was previously started, Jake must\nwork with Neytiri and the army of the Na'vi race to protect their home.\n", "tagline": "Return to Pandora.", "theme": "/library/metadata/1/theme/1705636920", "thumb": "/library/metadata/58683/thumb/1703239236", "titleSort": "Whale", "title": "Avatar: The Way of Water", "type": "movie", "updatedAt": 1556281940, "userRating": 10, "viewCount": 1, "viewOffset": 5222500, "viewedLeafCount": 0, "year": 2022, "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Media": [{"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": 1, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}, {"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": true, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}]}], "Genre": [{"id": 259, "filter": "genre=19", "tag": "Crime"}], "Country": [{"id": 259, "tag": "United States of America", "filter": "country=19"}], "Director": [{"tag": "Danny Boyle"}, {"tag": "Danny Boyle"}], "Writer": [{"id": 126522, "filter": "writer=126522", "tag": "Jamie P. Hanson", "tagKey": "5d77683d85719b001f3a535e"}], "Role": [{"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Producer": [{"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Rating": [{"image": "imdb://image.rating", "value": 5.1, "type": "audience"}, {"image": "imdb://image.rating", "value": 5.1, "type": "audience"}, {"image": "imdb://image.rating", "value": 5.1, "type": "audience"}], "Similar": [{"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}, {"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}, {"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}], "Location": [{"path": "/TV Shows/Clarkson's Farm"}, {"path": "/TV Shows/Clarkson's Farm"}, {"path": "/TV Shows/Clarkson's Farm"}], "Guid": [{"id": "tvdb://2337"}], "Collection": [{"tag": "My Awesome Collection"}]}, {"addedAt": 1556281940, "art": "/library/metadata/58683/art/1703239236", "audienceRatingImage": "rottentomatoes://image.rating.upright", "audienceRating": 9.2, "chapterSource": "media", "childCount": 1, "contentRating": "PG-13", "createdAtAccuracy": "epoch,local", "createdAtTZOffset": "0", "duration": 11558112, "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentRatingKey": "66", "grandparentSlug": "alice-in-borderland-2020", "grandparentTheme": "/library/metadata/66/theme/1705716261", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "grandparentTitle": "Caprica", "guid": "plex://movie/5d7768ba96b655001fdc0408", "index": 1, "key": "/library/metadata/58683", "lastRatedAt": 1721813113, "lastViewedAt": 1682752242, "leafCount": 14, "librarySectionID": 1, "librarySectionKey": "/library/sections/1", "librarySectionTitle": "Movies", "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "originallyAvailableAt": "2022-12-14", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentIndex": 1, "parentKey": "/library/metadata/66", "parentRatingKey": "66", "parentSlug": "alice-in-borderland-2020", "parentStudio": "UCP", "parentTheme": "/library/metadata/66/theme/1705716261", "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTitle": "Caprica", "parentYear": 2010, "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "ratingKey": "58683", "rating": 7.6, "seasonCount": 2022, "skipCount": 1, "slug": "4-for-texas", "studio": "20th Century Studios", "subtype": "clip", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora.\nOnce a familiar threat returns to finish what was previously started, Jake must\nwork with Neytiri and the army of the Na'vi race to protect their home.\n", "tagline": "Return to Pandora.", "theme": "/library/metadata/1/theme/1705636920", "thumb": "/library/metadata/58683/thumb/1703239236", "titleSort": "Whale", "title": "Avatar: The Way of Water", "type": "movie", "updatedAt": 1556281940, "userRating": 10, "viewCount": 1, "viewOffset": 5222500, "viewedLeafCount": 0, "year": 2022, "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Media": [{"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": []}, {"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": 1, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}, {"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": true, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}]}, {"id": 387322, "duration": 9610350, "bitrate": 25512, "width": 3840, "height": 1602, "aspectRatio": 2.35, "audioChannels": 6, "displayOffset": 50, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "audioProfile": "dts", "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": 1, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}, {"accessible": true, "exists": true, "id": 418385, "key": "/library/parts/418385/1735864239/file.mkv", "indexes": "sd", "duration": 9610350, "file": "/mnt/Movies_1/W/Wicked (2024).mkv", "size": 30649952104, "packetLength": 188, "container": "mkv", "videoProfile": "main 10", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": true, "hasThumbnail": "1", "Stream": [{"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}, {"id": 1002625, "streamType": 1, "default": true, "codec": "hevc", "index": 0, "bitrate": 24743, "language": "English", "languageTag": "en", "languageCode": "eng", "headerCompression": true, "DOVIBLCompatID": 1, "DOVIBLPresent": true, "DOVIELPresent": false, "DOVILevel": 6, "DOVIPresent": true, "DOVIProfile": 8, "DOVIRPUPresent": true, "DOVIVersion": "1.0", "bitDepth": 10, "chromaLocation": "topleft", "chromaSubsampling": "4:2:0", "codedHeight": 1608, "codedWidth": 3840, "closedCaptions": true, "colorPrimaries": "bt2020", "colorRange": "tv", "colorSpace": "bt2020nc", "colorTrc": "smpte2084", "frameRate": 23.976, "height": 1602, "level": 150, "original": true, "hasScalingMatrix": false, "profile": "main 10", "scanType": "progressive", "embeddedInVideo": "progressive", "refFrames": 1, "width": 3840, "displayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "extendedDisplayTitle": "4K DoVi/HDR10 (HEVC Main 10)", "selected": true, "forced": true, "channels": 6, "audioChannelLayout": "5.1(side)", "samplingRate": 48000, "canAutoSync": false, "hearingImpaired": true, "dub": true, "title": "SDH"}]}]}], "Genre": [{"id": 259, "filter": "genre=19", "tag": "Crime"}], "Country": [{"id": 259, "tag": "United States of America", "filter": "country=19"}], "Director": [{"tag": "Danny Boyle"}, {"tag": "Danny Boyle"}], "Writer": [{"id": 126522, "filter": "writer=126522", "tag": "Jamie P. Hanson", "tagKey": "5d77683d85719b001f3a535e"}], "Role": [{"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}, {"id": 126522, "filter": "actor=126522", "tag": "Teller", "tagKey": "5d77683d85719b001f3a535e", "role": "Self - Judge", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Producer": [{"id": 126522, "filter": "producer=126522", "tag": "Amelia Knapp", "tagKey": "5d77683d85719b001f3a535e", "thumb": "https://metadata-static.plex.tv/7/people/708568fd018d7aa8b1032dcf867747e8.jpg"}], "Rating": [{"image": "imdb://image.rating", "value": 5.1, "type": "audience"}], "Similar": [{"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}, {"id": 259, "filter": "similar=259", "tag": "Criss Angel Mindfreak"}], "Location": [{"path": "/TV Shows/Clarkson's Farm"}], "Guid": [{"id": "tvdb://2337"}, {"id": "tvdb://2337"}], "Collection": [{"tag": "My Awesome Collection"}, {"tag": "My Awesome Collection"}]}]}} getLibraryHubs: speakeasy-default-get-library-hubs: parameters: @@ -2264,5 +2283,35 @@ examples: application/json: {"errors": [{"code": 1000, "message": "X-Plex-Client-Identifier is missing", "status": 400}]} "401": application/json: {"errors": [{"code": 1001, "message": "User could not be authenticated", "status": 401}, {"code": 1001, "message": "User could not be authenticated", "status": 401}]} + get-media-arts: + speakeasy-default-get-media-arts: + parameters: + path: + ratingKey: 16099 + responses: + "200": + application/json: {"MediaContainer": {"size": 50, "mediaTagVersion": 1734362201, "mediaTagPrefix": "/system/bundle/media/flags/", "identifier": "com.plexapp.plugins.library", "Metadata": [{"key": "https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg", "provider": "tmdb", "ratingKey": "https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg", "selected": true, "thumb": "https://images.plex.tv/photo?height=270&width=480&minSize=1&upscale=1&url=https%3A%2F%2Fimage%2Etmdb%2Eorg%2Ft%2Fp%2Foriginal%2FixgFmf1X59PUZam2qbAfskx2gQr%2Ejpg"}, {"key": "https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg", "provider": "tmdb", "ratingKey": "https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg", "selected": true, "thumb": "https://images.plex.tv/photo?height=270&width=480&minSize=1&upscale=1&url=https%3A%2F%2Fimage%2Etmdb%2Eorg%2Ft%2Fp%2Foriginal%2FixgFmf1X59PUZam2qbAfskx2gQr%2Ejpg"}, {"key": "https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg", "provider": "tmdb", "ratingKey": "https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg", "selected": true, "thumb": "https://images.plex.tv/photo?height=270&width=480&minSize=1&upscale=1&url=https%3A%2F%2Fimage%2Etmdb%2Eorg%2Ft%2Fp%2Foriginal%2FixgFmf1X59PUZam2qbAfskx2gQr%2Ejpg"}]}} + post-media-arts: + speakeasy-default-post-media-arts: + parameters: + path: + ratingKey: 2268 + query: + url: "https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b" + get-media-posters: + speakeasy-default-get-media-posters: + parameters: + path: + ratingKey: 16099 + responses: + "200": + application/json: {"MediaContainer": {"size": 50, "mediaTagVersion": 1734362201, "mediaTagPrefix": "/system/bundle/media/flags/", "identifier": "com.plexapp.plugins.library", "Metadata": [{"key": "https://image.tmdb.org/t/p/original/hntBJjqbv4m0Iyniqaztv9xaudI.jpg", "provider": "tmdb", "ratingKey": "https://image.tmdb.org/t/p/original/hntBJjqbv4m0Iyniqaztv9xaudI.jpg", "selected": true, "thumb": "https://images.plex.tv/photo?height=336&width=225&minSize=1&upscale=1&url=https%3A%2F%2Fimage%2Etmdb%2Eorg%2Ft%2Fp%2Foriginal%2FhntBJjqbv4m0Iyniqaztv9xaudI%2Ejpg"}, {"key": "https://image.tmdb.org/t/p/original/hntBJjqbv4m0Iyniqaztv9xaudI.jpg", "provider": "tmdb", "ratingKey": "https://image.tmdb.org/t/p/original/hntBJjqbv4m0Iyniqaztv9xaudI.jpg", "selected": true, "thumb": "https://images.plex.tv/photo?height=336&width=225&minSize=1&upscale=1&url=https%3A%2F%2Fimage%2Etmdb%2Eorg%2Ft%2Fp%2Foriginal%2FhntBJjqbv4m0Iyniqaztv9xaudI%2Ejpg"}]}} + post-media-poster: + speakeasy-default-post-media-poster: + parameters: + path: + ratingKey: 2268 + query: + url: "https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b" examplesVersion: 1.0.0 generatedTests: {} diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 8890142..ede4e97 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -15,7 +15,7 @@ generation: oAuth2ClientCredentialsEnabled: true oAuth2PasswordEnabled: false python: - version: 0.24.2 + version: 0.25.0 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 683e365..3502e71 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,4 +1,4 @@ -speakeasyVersion: 1.526.6 +speakeasyVersion: 1.528.1 sources: my-source: sourceNamespace: my-source @@ -8,19 +8,19 @@ sources: - latest plexapi: sourceNamespace: plexapi - sourceRevisionDigest: sha256:cffb18feaa0523b300655a6f0073caad99133b143f5a420fddbb1e1efe47bcaf - sourceBlobDigest: sha256:1737023e29cd9cf36c07ccd8c8c48c47e14f47ce22b4d6ba9ee241afbbd8f351 + sourceRevisionDigest: sha256:b5580df6ec4a386e12249ff13f35b916fe5559e101de4a816b53e47d6947f1a5 + sourceBlobDigest: sha256:6108b6c35fbe7e9163ffe0c804170f5e3a6edb63b8e745454ea8ee249bd790c3 tags: - latest - - speakeasy-sdk-regen-1743442213 + - speakeasy-sdk-regen-1743724902 targets: plexpy: source: plexapi sourceNamespace: plexapi - sourceRevisionDigest: sha256:cffb18feaa0523b300655a6f0073caad99133b143f5a420fddbb1e1efe47bcaf - sourceBlobDigest: sha256:1737023e29cd9cf36c07ccd8c8c48c47e14f47ce22b4d6ba9ee241afbbd8f351 + sourceRevisionDigest: sha256:b5580df6ec4a386e12249ff13f35b916fe5559e101de4a816b53e47d6947f1a5 + sourceBlobDigest: sha256:6108b6c35fbe7e9163ffe0c804170f5e3a6edb63b8e745454ea8ee249bd790c3 codeSamplesNamespace: code-samples-python-plexpy - codeSamplesRevisionDigest: sha256:d602934f4341a648a4103c552a490196fb79cd628acf88f190268d7ea57d98e1 + codeSamplesRevisionDigest: sha256:a778abbffccd815f66b90209260b64dfecf0e7d4fb1d145cec800eabe371a550 workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/README.md b/README.md index ce728bd..52a20ca 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ The following SDKs are generated from the OpenAPI Specification. They are automa * [IDE Support](#ide-support) * [SDK Example Usage](#sdk-example-usage) * [Available Resources and Operations](#available-resources-and-operations) + * [File uploads](#file-uploads) * [Retries](#retries) * [Error Handling](#error-handling) * [Server Selection](#server-selection) @@ -225,6 +226,10 @@ asyncio.run(main()) * [get_actors_library](docs/sdks/library/README.md#get_actors_library) - Get Actors of library media * [get_search_all_libraries](docs/sdks/library/README.md#get_search_all_libraries) - Search All Libraries * [get_media_meta_data](docs/sdks/library/README.md#get_media_meta_data) - Get Media Metadata +* [get_media_arts](docs/sdks/library/README.md#get_media_arts) - Get Media Background Artwork +* [post_media_arts](docs/sdks/library/README.md#post_media_arts) - Upload Media Background Artwork +* [get_media_posters](docs/sdks/library/README.md#get_media_posters) - Get Media Posters +* [post_media_poster](docs/sdks/library/README.md#post_media_poster) - Upload Media Poster * [get_metadata_children](docs/sdks/library/README.md#get_metadata_children) - Get Items Children * [get_top_watched_content](docs/sdks/library/README.md#get_top_watched_content) - Get Top Watched Content @@ -318,6 +323,34 @@ asyncio.run(main()) + +## File uploads + +Certain SDK methods accept file objects as part of a request body or multi-part request. It is possible and typically recommended to upload files as a stream rather than reading the entire contents into memory. This avoids excessive memory consumption and potentially crashing with out-of-memory errors when working with very large files. The following example demonstrates how to attach a file stream to a request. + +> [!TIP] +> +> For endpoints that handle file uploads bytes arrays can also be used. However, using streams is recommended for large files. +> + +```python +from plex_api_client import PlexAPI + + +with PlexAPI( + access_token="", +) as plex_api: + + res = plex_api.library.post_media_arts(rating_key=2268, url="https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b") + + assert res is not None + + # Handle response + print(res) + +``` + + ## Retries diff --git a/RELEASES.md b/RELEASES.md index 14eef0b..e964c95 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -978,4 +978,14 @@ Based on: ### Generated - [python v0.24.2] . ### Releases -- [PyPI v0.24.2] https://pypi.org/project/plex-api-client/0.24.2 - . \ No newline at end of file +- [PyPI v0.24.2] https://pypi.org/project/plex-api-client/0.24.2 - . + +## 2025-04-04 00:01:27 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.528.1 (2.565.1) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.25.0] . +### Releases +- [PyPI v0.25.0] https://pypi.org/project/plex-api-client/0.25.0 - . \ No newline at end of file diff --git a/codeSamples.yaml b/codeSamples.yaml index 09af4b4..277723b 100644 --- a/codeSamples.yaml +++ b/codeSamples.yaml @@ -566,6 +566,44 @@ actions: # Handle response print(res.object) + - target: $["paths"]["/library/metadata/{ratingKey}/arts"]["get"] + update: + x-codeSamples: + - lang: python + label: PlexPy + source: |- + from plex_api_client import PlexAPI + + + with PlexAPI( + access_token="", + ) as plex_api: + + res = plex_api.library.get_media_arts(rating_key=16099) + + assert res.object is not None + + # Handle response + print(res.object) + - target: $["paths"]["/library/metadata/{ratingKey}/arts"]["post"] + update: + x-codeSamples: + - lang: python + label: PlexPy + source: |- + from plex_api_client import PlexAPI + + + with PlexAPI( + access_token="", + ) as plex_api: + + res = plex_api.library.post_media_arts(rating_key=2268, url="https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b") + + assert res is not None + + # Handle response + print(res) - target: $["paths"]["/library/metadata/{ratingKey}/banner"]["get"] update: x-codeSamples: @@ -611,6 +649,44 @@ actions: # Handle response print(res.object) + - target: $["paths"]["/library/metadata/{ratingKey}/posters"]["get"] + update: + x-codeSamples: + - lang: python + label: PlexPy + source: |- + from plex_api_client import PlexAPI + + + with PlexAPI( + access_token="", + ) as plex_api: + + res = plex_api.library.get_media_posters(rating_key=16099) + + assert res.object is not None + + # Handle response + print(res.object) + - target: $["paths"]["/library/metadata/{ratingKey}/posters"]["post"] + update: + x-codeSamples: + - lang: python + label: PlexPy + source: |- + from plex_api_client import PlexAPI + + + with PlexAPI( + access_token="", + ) as plex_api: + + res = plex_api.library.post_media_poster(rating_key=2268, url="https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b") + + assert res is not None + + # Handle response + print(res) - target: $["paths"]["/library/metadata/{ratingKey}/thumb"]["get"] update: x-codeSamples: diff --git a/docs/models/operations/getmediaartsmediacontainer.md b/docs/models/operations/getmediaartsmediacontainer.md new file mode 100644 index 0000000..cb9861d --- /dev/null +++ b/docs/models/operations/getmediaartsmediacontainer.md @@ -0,0 +1,12 @@ +# GetMediaArtsMediaContainer + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| `size` | *int* | :heavy_check_mark: | Number of media items returned in this response. | 50 | +| `media_tag_version` | *int* | :heavy_check_mark: | The version number for media tags. | 1734362201 | +| `media_tag_prefix` | *str* | :heavy_check_mark: | The prefix used for media tag resource paths. | /system/bundle/media/flags/ | +| `identifier` | *str* | :heavy_check_mark: | An plugin identifier for the media container. | com.plexapp.plugins.library | +| `metadata` | List[[operations.GetMediaArtsMetadata](../../models/operations/getmediaartsmetadata.md)] | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/getmediaartsmetadata.md b/docs/models/operations/getmediaartsmetadata.md new file mode 100644 index 0000000..447eda5 --- /dev/null +++ b/docs/models/operations/getmediaartsmetadata.md @@ -0,0 +1,12 @@ +# GetMediaArtsMetadata + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `key` | *str* | :heavy_check_mark: | The URL of the artwork. | https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg | +| `rating_key` | *str* | :heavy_check_mark: | The URL of the artwork. | https://image.tmdb.org/t/p/original/ixgFmf1X59PUZam2qbAfskx2gQr.jpg | +| `selected` | *bool* | :heavy_check_mark: | Whether this is the selected artwork. | true | +| `thumb` | *str* | :heavy_check_mark: | The URL of the artwork thumbnail. | https://images.plex.tv/photo?height=270&width=480&minSize=1&upscale=1&url=https%3A%2F%2Fimage%2Etmdb%2Eorg%2Ft%2Fp%2Foriginal%2FixgFmf1X59PUZam2qbAfskx2gQr%2Ejpg | +| `provider` | *Optional[str]* | :heavy_minus_sign: | The provider of the artwork. | tmdb | \ No newline at end of file diff --git a/docs/models/operations/getmediaartsrequest.md b/docs/models/operations/getmediaartsrequest.md new file mode 100644 index 0000000..ebb24a4 --- /dev/null +++ b/docs/models/operations/getmediaartsrequest.md @@ -0,0 +1,8 @@ +# GetMediaArtsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the artwork of. | 16099 | \ No newline at end of file diff --git a/docs/models/operations/getmediaartsresponse.md b/docs/models/operations/getmediaartsresponse.md new file mode 100644 index 0000000..ecbb406 --- /dev/null +++ b/docs/models/operations/getmediaartsresponse.md @@ -0,0 +1,11 @@ +# GetMediaArtsResponse + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `content_type` | *str* | :heavy_check_mark: | HTTP response content type for this operation | +| `status_code` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `raw_response` | [httpx.Response](https://www.python-httpx.org/api/#response) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | +| `object` | [Optional[operations.GetMediaArtsResponseBody]](../../models/operations/getmediaartsresponsebody.md) | :heavy_minus_sign: | The available background artwork for the library item. | \ No newline at end of file diff --git a/docs/models/operations/getmediaartsresponsebody.md b/docs/models/operations/getmediaartsresponsebody.md new file mode 100644 index 0000000..38cd0dd --- /dev/null +++ b/docs/models/operations/getmediaartsresponsebody.md @@ -0,0 +1,10 @@ +# GetMediaArtsResponseBody + +The available background artwork for the library item. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `media_container` | [Optional[operations.GetMediaArtsMediaContainer]](../../models/operations/getmediaartsmediacontainer.md) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/operations/getmediapostersmediacontainer.md b/docs/models/operations/getmediapostersmediacontainer.md new file mode 100644 index 0000000..070073e --- /dev/null +++ b/docs/models/operations/getmediapostersmediacontainer.md @@ -0,0 +1,12 @@ +# GetMediaPostersMediaContainer + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `size` | *int* | :heavy_check_mark: | Number of media items returned in this response. | 50 | +| `media_tag_version` | *int* | :heavy_check_mark: | The version number for media tags. | 1734362201 | +| `media_tag_prefix` | *str* | :heavy_check_mark: | The prefix used for media tag resource paths. | /system/bundle/media/flags/ | +| `identifier` | *str* | :heavy_check_mark: | An plugin identifier for the media container. | com.plexapp.plugins.library | +| `metadata` | List[[operations.GetMediaPostersMetadata](../../models/operations/getmediapostersmetadata.md)] | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/getmediapostersmetadata.md b/docs/models/operations/getmediapostersmetadata.md new file mode 100644 index 0000000..1d7f0b6 --- /dev/null +++ b/docs/models/operations/getmediapostersmetadata.md @@ -0,0 +1,12 @@ +# GetMediaPostersMetadata + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `key` | *str* | :heavy_check_mark: | The URL of the poster. | https://image.tmdb.org/t/p/original/hntBJjqbv4m0Iyniqaztv9xaudI.jpg | +| `rating_key` | *str* | :heavy_check_mark: | The URL of the poster. | https://image.tmdb.org/t/p/original/hntBJjqbv4m0Iyniqaztv9xaudI.jpg | +| `selected` | *bool* | :heavy_check_mark: | Whether this is the selected poster. | true | +| `thumb` | *str* | :heavy_check_mark: | The URL of the poster thumbnail. | https://images.plex.tv/photo?height=336&width=225&minSize=1&upscale=1&url=https%3A%2F%2Fimage%2Etmdb%2Eorg%2Ft%2Fp%2Foriginal%2FhntBJjqbv4m0Iyniqaztv9xaudI%2Ejpg | +| `provider` | *Optional[str]* | :heavy_minus_sign: | The provider of the poster. | tmdb | \ No newline at end of file diff --git a/docs/models/operations/getmediapostersrequest.md b/docs/models/operations/getmediapostersrequest.md new file mode 100644 index 0000000..e25fa9c --- /dev/null +++ b/docs/models/operations/getmediapostersrequest.md @@ -0,0 +1,8 @@ +# GetMediaPostersRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the posters of. | 16099 | \ No newline at end of file diff --git a/docs/models/operations/getmediapostersresponse.md b/docs/models/operations/getmediapostersresponse.md new file mode 100644 index 0000000..1b8f72d --- /dev/null +++ b/docs/models/operations/getmediapostersresponse.md @@ -0,0 +1,11 @@ +# GetMediaPostersResponse + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| `content_type` | *str* | :heavy_check_mark: | HTTP response content type for this operation | +| `status_code` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `raw_response` | [httpx.Response](https://www.python-httpx.org/api/#response) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | +| `object` | [Optional[operations.GetMediaPostersResponseBody]](../../models/operations/getmediapostersresponsebody.md) | :heavy_minus_sign: | The available posters for the library item. | \ No newline at end of file diff --git a/docs/models/operations/getmediapostersresponsebody.md b/docs/models/operations/getmediapostersresponsebody.md new file mode 100644 index 0000000..cf8ee59 --- /dev/null +++ b/docs/models/operations/getmediapostersresponsebody.md @@ -0,0 +1,10 @@ +# GetMediaPostersResponseBody + +The available posters for the library item. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| `media_container` | [Optional[operations.GetMediaPostersMediaContainer]](../../models/operations/getmediapostersmediacontainer.md) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/operations/postmediaartsrequest.md b/docs/models/operations/postmediaartsrequest.md new file mode 100644 index 0000000..e0c4e42 --- /dev/null +++ b/docs/models/operations/postmediaartsrequest.md @@ -0,0 +1,10 @@ +# PostMediaArtsRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the posters of. | 2268 | +| `url` | *Optional[str]* | :heavy_minus_sign: | The URL of the image, if uploading a remote image | https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b | +| `request_body` | *Optional[Union[bytes, IO[bytes], io.BufferedReader]]* | :heavy_minus_sign: | The contents of the image, if uploading a local file | | \ No newline at end of file diff --git a/docs/models/operations/postmediaartsresponse.md b/docs/models/operations/postmediaartsresponse.md new file mode 100644 index 0000000..09b7cd1 --- /dev/null +++ b/docs/models/operations/postmediaartsresponse.md @@ -0,0 +1,10 @@ +# PostMediaArtsResponse + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| `content_type` | *str* | :heavy_check_mark: | HTTP response content type for this operation | +| `status_code` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `raw_response` | [httpx.Response](https://www.python-httpx.org/api/#response) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | \ No newline at end of file diff --git a/docs/models/operations/postmediaposterrequest.md b/docs/models/operations/postmediaposterrequest.md new file mode 100644 index 0000000..bc255bd --- /dev/null +++ b/docs/models/operations/postmediaposterrequest.md @@ -0,0 +1,10 @@ +# PostMediaPosterRequest + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the posters of. | 2268 | +| `url` | *Optional[str]* | :heavy_minus_sign: | The URL of the image, if uploading a remote image | https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b | +| `request_body` | *Optional[Union[bytes, IO[bytes], io.BufferedReader]]* | :heavy_minus_sign: | The contents of the image, if uploading a local file | | \ No newline at end of file diff --git a/docs/models/operations/postmediaposterresponse.md b/docs/models/operations/postmediaposterresponse.md new file mode 100644 index 0000000..577b9f0 --- /dev/null +++ b/docs/models/operations/postmediaposterresponse.md @@ -0,0 +1,10 @@ +# PostMediaPosterResponse + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| `content_type` | *str* | :heavy_check_mark: | HTTP response content type for this operation | +| `status_code` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `raw_response` | [httpx.Response](https://www.python-httpx.org/api/#response) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | \ No newline at end of file diff --git a/docs/sdks/library/README.md b/docs/sdks/library/README.md index 352b26e..e847088 100644 --- a/docs/sdks/library/README.md +++ b/docs/sdks/library/README.md @@ -22,6 +22,10 @@ API Calls interacting with Plex Media Server Libraries * [get_actors_library](#get_actors_library) - Get Actors of library media * [get_search_all_libraries](#get_search_all_libraries) - Search All Libraries * [get_media_meta_data](#get_media_meta_data) - Get Media Metadata +* [get_media_arts](#get_media_arts) - Get Media Background Artwork +* [post_media_arts](#post_media_arts) - Upload Media Background Artwork +* [get_media_posters](#get_media_posters) - Get Media Posters +* [post_media_poster](#post_media_poster) - Upload Media Poster * [get_metadata_children](#get_metadata_children) - Get Items Children * [get_top_watched_content](#get_top_watched_content) - Get Top Watched Content @@ -766,6 +770,170 @@ with PlexAPI( | errors.GetMediaMetaDataUnauthorized | 401 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | +## get_media_arts + +Returns the background artwork for a library item. + +### Example Usage + +```python +from plex_api_client import PlexAPI + + +with PlexAPI( + access_token="", +) as plex_api: + + res = plex_api.library.get_media_arts(rating_key=16099) + + assert res.object is not None + + # Handle response + print(res.object) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the artwork of. | 16099 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[operations.GetMediaArtsResponse](../../models/operations/getmediaartsresponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| errors.SDKError | 4XX, 5XX | \*/\* | + +## post_media_arts + +Uploads an image to use as the background artwork for a library item, either from a local file or a remote URL + +### Example Usage + +```python +from plex_api_client import PlexAPI + + +with PlexAPI( + access_token="", +) as plex_api: + + res = plex_api.library.post_media_arts(rating_key=2268, url="https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b") + + assert res is not None + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the posters of. | 2268 | +| `url` | *Optional[str]* | :heavy_minus_sign: | The URL of the image, if uploading a remote image | https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b | +| `request_body` | *Optional[Union[bytes, IO[bytes], io.BufferedReader]]* | :heavy_minus_sign: | The contents of the image, if uploading a local file | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[operations.PostMediaArtsResponse](../../models/operations/postmediaartsresponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| errors.SDKError | 4XX, 5XX | \*/\* | + +## get_media_posters + +Returns the available posters for a library item. + +### Example Usage + +```python +from plex_api_client import PlexAPI + + +with PlexAPI( + access_token="", +) as plex_api: + + res = plex_api.library.get_media_posters(rating_key=16099) + + assert res.object is not None + + # Handle response + print(res.object) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the posters of. | 16099 | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[operations.GetMediaPostersResponse](../../models/operations/getmediapostersresponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| errors.SDKError | 4XX, 5XX | \*/\* | + +## post_media_poster + +Uploads a poster to a library item, either from a local file or a remote URL + +### Example Usage + +```python +from plex_api_client import PlexAPI + + +with PlexAPI( + access_token="", +) as plex_api: + + res = plex_api.library.post_media_poster(rating_key=2268, url="https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b") + + assert res is not None + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `rating_key` | *int* | :heavy_check_mark: | the id of the library item to return the posters of. | 2268 | +| `url` | *Optional[str]* | :heavy_minus_sign: | The URL of the image, if uploading a remote image | https://api.mediux.pro/assets/fcfdc487-dd07-4993-a0c1-0a3015362e5b | +| `request_body` | *Optional[Union[bytes, IO[bytes], io.BufferedReader]]* | :heavy_minus_sign: | The contents of the image, if uploading a local file | | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[operations.PostMediaPosterResponse](../../models/operations/postmediaposterresponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| errors.SDKError | 4XX, 5XX | \*/\* | + ## get_metadata_children This endpoint will return the children of of a library item specified with the ratingKey. diff --git a/pyproject.toml b/pyproject.toml index c6f450d..a7a0a49 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "plex-api-client" -version = "0.24.2" +version = "0.25.0" description = "Python Client SDK Generated by Speakeasy" authors = [{ name = "Speakeasy" },] readme = "README-PYPI.md" diff --git a/src/plex_api_client/_version.py b/src/plex_api_client/_version.py index 84183f9..f7ea4c3 100644 --- a/src/plex_api_client/_version.py +++ b/src/plex_api_client/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "plex-api-client" -__version__: str = "0.24.2" +__version__: str = "0.25.0" __openapi_doc_version__: str = "0.0.3" -__gen_version__: str = "2.563.1" -__user_agent__: str = "speakeasy-sdk/python 0.24.2 2.563.1 0.0.3 plex-api-client" +__gen_version__: str = "2.565.1" +__user_agent__: str = "speakeasy-sdk/python 0.25.0 2.565.1 0.0.3 plex-api-client" try: if __package__ is not None: diff --git a/src/plex_api_client/library.py b/src/plex_api_client/library.py index 9b1a3b4..09c870e 100644 --- a/src/plex_api_client/library.py +++ b/src/plex_api_client/library.py @@ -1,11 +1,12 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from .basesdk import BaseSDK +import io from plex_api_client import utils from plex_api_client._hooks import HookContext from plex_api_client.models import errors, operations from plex_api_client.types import BaseModel, OptionalNullable, UNSET -from typing import Any, Mapping, Optional, Union, cast +from typing import Any, IO, Mapping, Optional, Union, cast class Library(BaseSDK): @@ -3355,6 +3356,830 @@ class Library(BaseSDK): http_res, ) + def get_media_arts( + self, + *, + rating_key: int, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.GetMediaArtsResponse: + r"""Get Media Background Artwork + + Returns the background artwork for a library item. + + :param rating_key: the id of the library item to return the artwork of. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetMediaArtsRequest( + rating_key=rating_key, + ) + + req = self._build_request( + method="GET", + path="/library/metadata/{ratingKey}/arts", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + security=self.sdk_configuration.security, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = self.do_request( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="get-media-arts", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "application/json"): + return operations.GetMediaArtsResponse( + object=utils.unmarshal_json( + http_res.text, Optional[operations.GetMediaArtsResponseBody] + ), + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + async def get_media_arts_async( + self, + *, + rating_key: int, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.GetMediaArtsResponse: + r"""Get Media Background Artwork + + Returns the background artwork for a library item. + + :param rating_key: the id of the library item to return the artwork of. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetMediaArtsRequest( + rating_key=rating_key, + ) + + req = self._build_request_async( + method="GET", + path="/library/metadata/{ratingKey}/arts", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + security=self.sdk_configuration.security, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="get-media-arts", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "application/json"): + return operations.GetMediaArtsResponse( + object=utils.unmarshal_json( + http_res.text, Optional[operations.GetMediaArtsResponseBody] + ), + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + def post_media_arts( + self, + *, + rating_key: int, + url: Optional[str] = None, + request_body: Optional[Union[bytes, IO[bytes], io.BufferedReader]] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.PostMediaArtsResponse: + r"""Upload Media Background Artwork + + Uploads an image to use as the background artwork for a library item, either from a local file or a remote URL + + :param rating_key: the id of the library item to return the posters of. + :param url: The URL of the image, if uploading a remote image + :param request_body: The contents of the image, if uploading a local file + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.PostMediaArtsRequest( + rating_key=rating_key, + url=url, + request_body=request_body, + ) + + req = self._build_request( + method="POST", + path="/library/metadata/{ratingKey}/arts", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + http_headers=http_headers, + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.request_body, + False, + True, + "raw", + Optional[Union[bytes, IO[bytes], io.BufferedReader]], + ), + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = self.do_request( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="post-media-arts", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "*"): + return operations.PostMediaArtsResponse( + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + async def post_media_arts_async( + self, + *, + rating_key: int, + url: Optional[str] = None, + request_body: Optional[Union[bytes, IO[bytes], io.BufferedReader]] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.PostMediaArtsResponse: + r"""Upload Media Background Artwork + + Uploads an image to use as the background artwork for a library item, either from a local file or a remote URL + + :param rating_key: the id of the library item to return the posters of. + :param url: The URL of the image, if uploading a remote image + :param request_body: The contents of the image, if uploading a local file + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.PostMediaArtsRequest( + rating_key=rating_key, + url=url, + request_body=request_body, + ) + + req = self._build_request_async( + method="POST", + path="/library/metadata/{ratingKey}/arts", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + http_headers=http_headers, + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.request_body, + False, + True, + "raw", + Optional[Union[bytes, IO[bytes], io.BufferedReader]], + ), + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="post-media-arts", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "*"): + return operations.PostMediaArtsResponse( + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + def get_media_posters( + self, + *, + rating_key: int, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.GetMediaPostersResponse: + r"""Get Media Posters + + Returns the available posters for a library item. + + :param rating_key: the id of the library item to return the posters of. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetMediaPostersRequest( + rating_key=rating_key, + ) + + req = self._build_request( + method="GET", + path="/library/metadata/{ratingKey}/posters", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + security=self.sdk_configuration.security, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = self.do_request( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="get-media-posters", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "application/json"): + return operations.GetMediaPostersResponse( + object=utils.unmarshal_json( + http_res.text, Optional[operations.GetMediaPostersResponseBody] + ), + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + async def get_media_posters_async( + self, + *, + rating_key: int, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.GetMediaPostersResponse: + r"""Get Media Posters + + Returns the available posters for a library item. + + :param rating_key: the id of the library item to return the posters of. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetMediaPostersRequest( + rating_key=rating_key, + ) + + req = self._build_request_async( + method="GET", + path="/library/metadata/{ratingKey}/posters", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + security=self.sdk_configuration.security, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="get-media-posters", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "application/json"): + return operations.GetMediaPostersResponse( + object=utils.unmarshal_json( + http_res.text, Optional[operations.GetMediaPostersResponseBody] + ), + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + def post_media_poster( + self, + *, + rating_key: int, + url: Optional[str] = None, + request_body: Optional[Union[bytes, IO[bytes], io.BufferedReader]] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.PostMediaPosterResponse: + r"""Upload Media Poster + + Uploads a poster to a library item, either from a local file or a remote URL + + :param rating_key: the id of the library item to return the posters of. + :param url: The URL of the image, if uploading a remote image + :param request_body: The contents of the image, if uploading a local file + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.PostMediaPosterRequest( + rating_key=rating_key, + url=url, + request_body=request_body, + ) + + req = self._build_request( + method="POST", + path="/library/metadata/{ratingKey}/posters", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + http_headers=http_headers, + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.request_body, + False, + True, + "raw", + Optional[Union[bytes, IO[bytes], io.BufferedReader]], + ), + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = self.do_request( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="post-media-poster", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "*"): + return operations.PostMediaPosterResponse( + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + async def post_media_poster_async( + self, + *, + rating_key: int, + url: Optional[str] = None, + request_body: Optional[Union[bytes, IO[bytes], io.BufferedReader]] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> operations.PostMediaPosterResponse: + r"""Upload Media Poster + + Uploads a poster to a library item, either from a local file or a remote URL + + :param rating_key: the id of the library item to return the posters of. + :param url: The URL of the image, if uploading a remote image + :param request_body: The contents of the image, if uploading a local file + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.PostMediaPosterRequest( + rating_key=rating_key, + url=url, + request_body=request_body, + ) + + req = self._build_request_async( + method="POST", + path="/library/metadata/{ratingKey}/posters", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="*/*", + http_headers=http_headers, + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.request_body, + False, + True, + "raw", + Optional[Union[bytes, IO[bytes], io.BufferedReader]], + ), + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + base_url=base_url or "", + operation_id="post-media-poster", + oauth2_scopes=[], + security_source=self.sdk_configuration.security, + ), + request=req, + error_status_codes=["404", "4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "*"): + return operations.PostMediaPosterResponse( + status_code=http_res.status_code, + content_type=http_res.headers.get("Content-Type") or "", + raw_response=http_res, + ) + if utils.match_response(http_res, ["404", "4XX"], "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + def get_metadata_children( self, *, diff --git a/src/plex_api_client/models/operations/__init__.py b/src/plex_api_client/models/operations/__init__.py index abca277..dbb9a77 100644 --- a/src/plex_api_client/models/operations/__init__.py +++ b/src/plex_api_client/models/operations/__init__.py @@ -300,6 +300,18 @@ from .get_library_items import ( ShowOrdering, Tag, ) +from .get_media_arts import ( + GetMediaArtsMediaContainer, + GetMediaArtsMediaContainerTypedDict, + GetMediaArtsMetadata, + GetMediaArtsMetadataTypedDict, + GetMediaArtsRequest, + GetMediaArtsRequestTypedDict, + GetMediaArtsResponse, + GetMediaArtsResponseBody, + GetMediaArtsResponseBodyTypedDict, + GetMediaArtsResponseTypedDict, +) from .get_media_meta_data import ( GetMediaMetaDataCountry, GetMediaMetaDataCountryTypedDict, @@ -349,6 +361,18 @@ from .get_media_meta_data import ( Ratings, RatingsTypedDict, ) +from .get_media_posters import ( + GetMediaPostersMediaContainer, + GetMediaPostersMediaContainerTypedDict, + GetMediaPostersMetadata, + GetMediaPostersMetadataTypedDict, + GetMediaPostersRequest, + GetMediaPostersRequestTypedDict, + GetMediaPostersResponse, + GetMediaPostersResponseBody, + GetMediaPostersResponseBodyTypedDict, + GetMediaPostersResponseTypedDict, +) from .get_media_providers import ( Action, ActionTypedDict, @@ -1114,6 +1138,18 @@ from .performvoicesearch import ( PerformVoiceSearchResponse, PerformVoiceSearchResponseTypedDict, ) +from .post_media_arts import ( + PostMediaArtsRequest, + PostMediaArtsRequestTypedDict, + PostMediaArtsResponse, + PostMediaArtsResponseTypedDict, +) +from .post_media_poster import ( + PostMediaPosterRequest, + PostMediaPosterRequestTypedDict, + PostMediaPosterResponse, + PostMediaPosterResponseTypedDict, +) from .post_users_sign_in_data import ( Billing, BillingTypedDict, @@ -1589,6 +1625,16 @@ __all__ = [ "GetLibraryItemsUltraBlurColorsTypedDict", "GetLibraryItemsWriter", "GetLibraryItemsWriterTypedDict", + "GetMediaArtsMediaContainer", + "GetMediaArtsMediaContainerTypedDict", + "GetMediaArtsMetadata", + "GetMediaArtsMetadataTypedDict", + "GetMediaArtsRequest", + "GetMediaArtsRequestTypedDict", + "GetMediaArtsResponse", + "GetMediaArtsResponseBody", + "GetMediaArtsResponseBodyTypedDict", + "GetMediaArtsResponseTypedDict", "GetMediaMetaDataCountry", "GetMediaMetaDataCountryTypedDict", "GetMediaMetaDataDirector", @@ -1634,6 +1680,16 @@ __all__ = [ "GetMediaMetaDataUltraBlurColorsTypedDict", "GetMediaMetaDataWriter", "GetMediaMetaDataWriterTypedDict", + "GetMediaPostersMediaContainer", + "GetMediaPostersMediaContainerTypedDict", + "GetMediaPostersMetadata", + "GetMediaPostersMetadataTypedDict", + "GetMediaPostersRequest", + "GetMediaPostersRequestTypedDict", + "GetMediaPostersResponse", + "GetMediaPostersResponseBody", + "GetMediaPostersResponseBodyTypedDict", + "GetMediaPostersResponseTypedDict", "GetMediaProvidersDirectory", "GetMediaProvidersDirectoryTypedDict", "GetMediaProvidersMediaContainer", @@ -2110,6 +2166,14 @@ __all__ = [ "PlaylistType", "PlexDevice", "PlexDeviceTypedDict", + "PostMediaArtsRequest", + "PostMediaArtsRequestTypedDict", + "PostMediaArtsResponse", + "PostMediaArtsResponseTypedDict", + "PostMediaPosterRequest", + "PostMediaPosterRequestTypedDict", + "PostMediaPosterResponse", + "PostMediaPosterResponseTypedDict", "PostUsersSignInDataAuthenticationResponseStatus", "PostUsersSignInDataAuthenticationStatus", "PostUsersSignInDataAuthenticationSubscription", diff --git a/src/plex_api_client/models/operations/get_media_arts.py b/src/plex_api_client/models/operations/get_media_arts.py new file mode 100644 index 0000000..970f837 --- /dev/null +++ b/src/plex_api_client/models/operations/get_media_arts.py @@ -0,0 +1,120 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +import httpx +from plex_api_client.types import BaseModel +from plex_api_client.utils import FieldMetadata, PathParamMetadata +import pydantic +from typing import List, Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class GetMediaArtsRequestTypedDict(TypedDict): + rating_key: int + r"""the id of the library item to return the artwork of.""" + + +class GetMediaArtsRequest(BaseModel): + rating_key: Annotated[ + int, + pydantic.Field(alias="ratingKey"), + FieldMetadata(path=PathParamMetadata(style="simple", explode=False)), + ] + r"""the id of the library item to return the artwork of.""" + + +class GetMediaArtsMetadataTypedDict(TypedDict): + key: str + r"""The URL of the artwork.""" + rating_key: str + r"""The URL of the artwork.""" + selected: bool + r"""Whether this is the selected artwork.""" + thumb: str + r"""The URL of the artwork thumbnail.""" + provider: NotRequired[str] + r"""The provider of the artwork.""" + + +class GetMediaArtsMetadata(BaseModel): + key: str + r"""The URL of the artwork.""" + + rating_key: Annotated[str, pydantic.Field(alias="ratingKey")] + r"""The URL of the artwork.""" + + selected: bool + r"""Whether this is the selected artwork.""" + + thumb: str + r"""The URL of the artwork thumbnail.""" + + provider: Optional[str] = None + r"""The provider of the artwork.""" + + +class GetMediaArtsMediaContainerTypedDict(TypedDict): + size: int + r"""Number of media items returned in this response.""" + media_tag_version: int + r"""The version number for media tags.""" + media_tag_prefix: str + r"""The prefix used for media tag resource paths.""" + identifier: str + r"""An plugin identifier for the media container.""" + metadata: List[GetMediaArtsMetadataTypedDict] + + +class GetMediaArtsMediaContainer(BaseModel): + size: int + r"""Number of media items returned in this response.""" + + media_tag_version: Annotated[int, pydantic.Field(alias="mediaTagVersion")] + r"""The version number for media tags.""" + + media_tag_prefix: Annotated[str, pydantic.Field(alias="mediaTagPrefix")] + r"""The prefix used for media tag resource paths.""" + + identifier: str + r"""An plugin identifier for the media container.""" + + metadata: Annotated[List[GetMediaArtsMetadata], pydantic.Field(alias="Metadata")] + + +class GetMediaArtsResponseBodyTypedDict(TypedDict): + r"""The available background artwork for the library item.""" + + media_container: NotRequired[GetMediaArtsMediaContainerTypedDict] + + +class GetMediaArtsResponseBody(BaseModel): + r"""The available background artwork for the library item.""" + + media_container: Annotated[ + Optional[GetMediaArtsMediaContainer], pydantic.Field(alias="MediaContainer") + ] = None + + +class GetMediaArtsResponseTypedDict(TypedDict): + content_type: str + r"""HTTP response content type for this operation""" + status_code: int + r"""HTTP response status code for this operation""" + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" + object: NotRequired[GetMediaArtsResponseBodyTypedDict] + r"""The available background artwork for the library item.""" + + +class GetMediaArtsResponse(BaseModel): + content_type: str + r"""HTTP response content type for this operation""" + + status_code: int + r"""HTTP response status code for this operation""" + + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" + + object: Optional[GetMediaArtsResponseBody] = None + r"""The available background artwork for the library item.""" diff --git a/src/plex_api_client/models/operations/get_media_posters.py b/src/plex_api_client/models/operations/get_media_posters.py new file mode 100644 index 0000000..70198e0 --- /dev/null +++ b/src/plex_api_client/models/operations/get_media_posters.py @@ -0,0 +1,120 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +import httpx +from plex_api_client.types import BaseModel +from plex_api_client.utils import FieldMetadata, PathParamMetadata +import pydantic +from typing import List, Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class GetMediaPostersRequestTypedDict(TypedDict): + rating_key: int + r"""the id of the library item to return the posters of.""" + + +class GetMediaPostersRequest(BaseModel): + rating_key: Annotated[ + int, + pydantic.Field(alias="ratingKey"), + FieldMetadata(path=PathParamMetadata(style="simple", explode=False)), + ] + r"""the id of the library item to return the posters of.""" + + +class GetMediaPostersMetadataTypedDict(TypedDict): + key: str + r"""The URL of the poster.""" + rating_key: str + r"""The URL of the poster.""" + selected: bool + r"""Whether this is the selected poster.""" + thumb: str + r"""The URL of the poster thumbnail.""" + provider: NotRequired[str] + r"""The provider of the poster.""" + + +class GetMediaPostersMetadata(BaseModel): + key: str + r"""The URL of the poster.""" + + rating_key: Annotated[str, pydantic.Field(alias="ratingKey")] + r"""The URL of the poster.""" + + selected: bool + r"""Whether this is the selected poster.""" + + thumb: str + r"""The URL of the poster thumbnail.""" + + provider: Optional[str] = None + r"""The provider of the poster.""" + + +class GetMediaPostersMediaContainerTypedDict(TypedDict): + size: int + r"""Number of media items returned in this response.""" + media_tag_version: int + r"""The version number for media tags.""" + media_tag_prefix: str + r"""The prefix used for media tag resource paths.""" + identifier: str + r"""An plugin identifier for the media container.""" + metadata: List[GetMediaPostersMetadataTypedDict] + + +class GetMediaPostersMediaContainer(BaseModel): + size: int + r"""Number of media items returned in this response.""" + + media_tag_version: Annotated[int, pydantic.Field(alias="mediaTagVersion")] + r"""The version number for media tags.""" + + media_tag_prefix: Annotated[str, pydantic.Field(alias="mediaTagPrefix")] + r"""The prefix used for media tag resource paths.""" + + identifier: str + r"""An plugin identifier for the media container.""" + + metadata: Annotated[List[GetMediaPostersMetadata], pydantic.Field(alias="Metadata")] + + +class GetMediaPostersResponseBodyTypedDict(TypedDict): + r"""The available posters for the library item.""" + + media_container: NotRequired[GetMediaPostersMediaContainerTypedDict] + + +class GetMediaPostersResponseBody(BaseModel): + r"""The available posters for the library item.""" + + media_container: Annotated[ + Optional[GetMediaPostersMediaContainer], pydantic.Field(alias="MediaContainer") + ] = None + + +class GetMediaPostersResponseTypedDict(TypedDict): + content_type: str + r"""HTTP response content type for this operation""" + status_code: int + r"""HTTP response status code for this operation""" + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" + object: NotRequired[GetMediaPostersResponseBodyTypedDict] + r"""The available posters for the library item.""" + + +class GetMediaPostersResponse(BaseModel): + content_type: str + r"""HTTP response content type for this operation""" + + status_code: int + r"""HTTP response status code for this operation""" + + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" + + object: Optional[GetMediaPostersResponseBody] = None + r"""The available posters for the library item.""" diff --git a/src/plex_api_client/models/operations/get_server_resources.py b/src/plex_api_client/models/operations/get_server_resources.py index 19c981e..8730a28 100644 --- a/src/plex_api_client/models/operations/get_server_resources.py +++ b/src/plex_api_client/models/operations/get_server_resources.py @@ -235,7 +235,7 @@ class PlexDevice(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) diff --git a/src/plex_api_client/models/operations/get_users.py b/src/plex_api_client/models/operations/get_users.py index b49e7e1..1bbd24e 100644 --- a/src/plex_api_client/models/operations/get_users.py +++ b/src/plex_api_client/models/operations/get_users.py @@ -382,7 +382,7 @@ class User(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) diff --git a/src/plex_api_client/models/operations/getpin.py b/src/plex_api_client/models/operations/getpin.py index a09ca65..e55bb06 100644 --- a/src/plex_api_client/models/operations/getpin.py +++ b/src/plex_api_client/models/operations/getpin.py @@ -216,7 +216,7 @@ class GetPinAuthPinContainer(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) diff --git a/src/plex_api_client/models/operations/gettokenbypinid.py b/src/plex_api_client/models/operations/gettokenbypinid.py index 158ec67..31ca5a2 100644 --- a/src/plex_api_client/models/operations/gettokenbypinid.py +++ b/src/plex_api_client/models/operations/gettokenbypinid.py @@ -209,7 +209,7 @@ class GetTokenByPinIDAuthPinContainer(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) diff --git a/src/plex_api_client/models/operations/gettokendetails.py b/src/plex_api_client/models/operations/gettokendetails.py index 89fbd6e..adc4485 100644 --- a/src/plex_api_client/models/operations/gettokendetails.py +++ b/src/plex_api_client/models/operations/gettokendetails.py @@ -131,7 +131,7 @@ class UserProfile(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -186,7 +186,7 @@ class Services(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -273,7 +273,7 @@ class Subscription(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -356,7 +356,7 @@ class GetTokenDetailsSubscription(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -638,7 +638,7 @@ class GetTokenDetailsUserPlexAccount(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) diff --git a/src/plex_api_client/models/operations/getuserfriends.py b/src/plex_api_client/models/operations/getuserfriends.py index 30dc184..054a83a 100644 --- a/src/plex_api_client/models/operations/getuserfriends.py +++ b/src/plex_api_client/models/operations/getuserfriends.py @@ -111,7 +111,7 @@ class Friend(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) diff --git a/src/plex_api_client/models/operations/post_media_arts.py b/src/plex_api_client/models/operations/post_media_arts.py new file mode 100644 index 0000000..34a88e1 --- /dev/null +++ b/src/plex_api_client/models/operations/post_media_arts.py @@ -0,0 +1,65 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +import httpx +import io +from plex_api_client.types import BaseModel +from plex_api_client.utils import ( + FieldMetadata, + PathParamMetadata, + QueryParamMetadata, + RequestMetadata, +) +import pydantic +from typing import IO, Optional, Union +from typing_extensions import Annotated, NotRequired, TypedDict + + +class PostMediaArtsRequestTypedDict(TypedDict): + rating_key: int + r"""the id of the library item to return the posters of.""" + url: NotRequired[str] + r"""The URL of the image, if uploading a remote image""" + request_body: NotRequired[Union[bytes, IO[bytes], io.BufferedReader]] + r"""The contents of the image, if uploading a local file""" + + +class PostMediaArtsRequest(BaseModel): + rating_key: Annotated[ + int, + pydantic.Field(alias="ratingKey"), + FieldMetadata(path=PathParamMetadata(style="simple", explode=False)), + ] + r"""the id of the library item to return the posters of.""" + + url: Annotated[ + Optional[str], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""The URL of the image, if uploading a remote image""" + + request_body: Annotated[ + Optional[Union[bytes, IO[bytes], io.BufferedReader]], + FieldMetadata(request=RequestMetadata(media_type="image/*")), + ] = None + r"""The contents of the image, if uploading a local file""" + + +class PostMediaArtsResponseTypedDict(TypedDict): + content_type: str + r"""HTTP response content type for this operation""" + status_code: int + r"""HTTP response status code for this operation""" + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" + + +class PostMediaArtsResponse(BaseModel): + content_type: str + r"""HTTP response content type for this operation""" + + status_code: int + r"""HTTP response status code for this operation""" + + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" diff --git a/src/plex_api_client/models/operations/post_media_poster.py b/src/plex_api_client/models/operations/post_media_poster.py new file mode 100644 index 0000000..d86c274 --- /dev/null +++ b/src/plex_api_client/models/operations/post_media_poster.py @@ -0,0 +1,65 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +import httpx +import io +from plex_api_client.types import BaseModel +from plex_api_client.utils import ( + FieldMetadata, + PathParamMetadata, + QueryParamMetadata, + RequestMetadata, +) +import pydantic +from typing import IO, Optional, Union +from typing_extensions import Annotated, NotRequired, TypedDict + + +class PostMediaPosterRequestTypedDict(TypedDict): + rating_key: int + r"""the id of the library item to return the posters of.""" + url: NotRequired[str] + r"""The URL of the image, if uploading a remote image""" + request_body: NotRequired[Union[bytes, IO[bytes], io.BufferedReader]] + r"""The contents of the image, if uploading a local file""" + + +class PostMediaPosterRequest(BaseModel): + rating_key: Annotated[ + int, + pydantic.Field(alias="ratingKey"), + FieldMetadata(path=PathParamMetadata(style="simple", explode=False)), + ] + r"""the id of the library item to return the posters of.""" + + url: Annotated[ + Optional[str], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""The URL of the image, if uploading a remote image""" + + request_body: Annotated[ + Optional[Union[bytes, IO[bytes], io.BufferedReader]], + FieldMetadata(request=RequestMetadata(media_type="image/*")), + ] = None + r"""The contents of the image, if uploading a local file""" + + +class PostMediaPosterResponseTypedDict(TypedDict): + content_type: str + r"""HTTP response content type for this operation""" + status_code: int + r"""HTTP response status code for this operation""" + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" + + +class PostMediaPosterResponse(BaseModel): + content_type: str + r"""HTTP response content type for this operation""" + + status_code: int + r"""HTTP response status code for this operation""" + + raw_response: httpx.Response + r"""Raw HTTP response; suitable for custom response parsing""" diff --git a/src/plex_api_client/models/operations/post_users_sign_in_data.py b/src/plex_api_client/models/operations/post_users_sign_in_data.py index ef514a6..a3bcd64 100644 --- a/src/plex_api_client/models/operations/post_users_sign_in_data.py +++ b/src/plex_api_client/models/operations/post_users_sign_in_data.py @@ -225,7 +225,7 @@ class PostUsersSignInDataUserProfile(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -280,7 +280,7 @@ class PostUsersSignInDataServices(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -367,7 +367,7 @@ class PostUsersSignInDataSubscription(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -450,7 +450,7 @@ class PostUsersSignInDataAuthenticationSubscription(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -505,7 +505,7 @@ class Billing(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -597,7 +597,7 @@ class PastSubscription(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) @@ -897,7 +897,7 @@ class PostUsersSignInDataUserPlexAccount(BaseModel): m = {} - for n, f in self.model_fields.items(): + for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) diff --git a/src/plex_api_client/utils/enums.py b/src/plex_api_client/utils/enums.py index c650b10..c3bc13c 100644 --- a/src/plex_api_client/utils/enums.py +++ b/src/plex_api_client/utils/enums.py @@ -1,34 +1,74 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" import enum - +import sys class OpenEnumMeta(enum.EnumMeta): - def __call__( - cls, value, names=None, *, module=None, qualname=None, type=None, start=1 - ): - # The `type` kwarg also happens to be a built-in that pylint flags as - # redeclared. Safe to ignore this lint rule with this scope. - # pylint: disable=redefined-builtin + # The __call__ method `boundary` kwarg was added in 3.11 and must be present + # for pyright. Refer also: https://github.com/pylint-dev/pylint/issues/9622 + # pylint: disable=unexpected-keyword-arg + # The __call__ method `values` varg must be named for pyright. + # pylint: disable=keyword-arg-before-vararg - if names is not None: - return super().__call__( - value, - names=names, - module=module, - qualname=qualname, - type=type, - start=start, - ) + if sys.version_info >= (3, 11): + def __call__( + cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None + ): + # The `type` kwarg also happens to be a built-in that pylint flags as + # redeclared. Safe to ignore this lint rule with this scope. + # pylint: disable=redefined-builtin - try: - return super().__call__( - value, - names=names, # pyright: ignore[reportArgumentType] - module=module, - qualname=qualname, - type=type, - start=start, - ) - except ValueError: - return value + if names is not None: + return super().__call__( + value, + names=names, + *values, + module=module, + qualname=qualname, + type=type, + start=start, + boundary=boundary, + ) + + try: + return super().__call__( + value, + names=names, # pyright: ignore[reportArgumentType] + *values, + module=module, + qualname=qualname, + type=type, + start=start, + boundary=boundary, + ) + except ValueError: + return value + else: + def __call__( + cls, value, names=None, *, module=None, qualname=None, type=None, start=1 + ): + # The `type` kwarg also happens to be a built-in that pylint flags as + # redeclared. Safe to ignore this lint rule with this scope. + # pylint: disable=redefined-builtin + + if names is not None: + return super().__call__( + value, + names=names, + module=module, + qualname=qualname, + type=type, + start=start, + ) + + try: + return super().__call__( + value, + names=names, # pyright: ignore[reportArgumentType] + module=module, + qualname=qualname, + type=type, + start=start, + ) + except ValueError: + return value