mirror of
https://github.com/LukeHagar/plexpy.git
synced 2025-12-06 04:20:52 +00:00
ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.404.5
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
lockVersion: 2.0.0
|
||||
id: 3eeea668-4ef4-464e-a888-bdfa023bedf5
|
||||
management:
|
||||
docChecksum: 5e039359563b41bbe118fc6701ba22dc
|
||||
docChecksum: e7673f3f46e5b0bf495c378378aa7ad6
|
||||
docVersion: 0.0.3
|
||||
speakeasyVersion: 1.402.14
|
||||
generationVersion: 2.422.22
|
||||
releaseVersion: 0.14.0
|
||||
configChecksum: 94801fc942959dabbfcbcced5032a59f
|
||||
speakeasyVersion: 1.404.5
|
||||
generationVersion: 2.426.2
|
||||
releaseVersion: 0.15.0
|
||||
configChecksum: 00ba481709bd16a8c4a80705655f6e3d
|
||||
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.3
|
||||
core: 5.5.5
|
||||
core: 5.5.6
|
||||
defaultEnabledRetries: 0.2.0
|
||||
deprecations: 3.0.0
|
||||
downloadStreams: 1.0.1
|
||||
@@ -32,9 +32,10 @@ features:
|
||||
methodServerURLs: 3.0.0
|
||||
nameOverrides: 3.0.0
|
||||
nullables: 1.0.0
|
||||
responseFormat: 1.0.0
|
||||
responseFormat: 1.0.1
|
||||
retries: 3.0.2
|
||||
sdkHooks: 1.0.0
|
||||
tests: 1.6.0
|
||||
generatedFiles:
|
||||
- .gitattributes
|
||||
- .vscode/settings.json
|
||||
@@ -645,6 +646,7 @@ generatedFiles:
|
||||
- docs/models/operations/gettimelineresponse.md
|
||||
- docs/models/operations/gettokenbypinidauthpincontainer.md
|
||||
- docs/models/operations/gettokenbypinidgeodata.md
|
||||
- docs/models/operations/gettokenbypinidglobals.md
|
||||
- docs/models/operations/gettokenbypinidrequest.md
|
||||
- docs/models/operations/gettokenbypinidresponse.md
|
||||
- docs/models/operations/gettokendetailsauthenticationresponsestatus.md
|
||||
@@ -1028,6 +1030,23 @@ generatedFiles:
|
||||
- src/plex_api_client/utils/values.py
|
||||
- src/plex_api_client/video.py
|
||||
- src/plex_api_client/watchlist.py
|
||||
- tests/__init__.py
|
||||
- tests/test_activities.py
|
||||
- tests/test_authentication.py
|
||||
- tests/test_butler.py
|
||||
- tests/test_hubs.py
|
||||
- tests/test_library.py
|
||||
- tests/test_log.py
|
||||
- tests/test_media.py
|
||||
- tests/test_playlists.py
|
||||
- tests/test_plex.py
|
||||
- tests/test_search.py
|
||||
- tests/test_server.py
|
||||
- tests/test_sessions.py
|
||||
- tests/test_statistics.py
|
||||
- tests/test_updater.py
|
||||
- tests/test_video.py
|
||||
- tests/test_watchlist.py
|
||||
examples:
|
||||
getServerCapabilities:
|
||||
speakeasy-default-get-server-capabilities:
|
||||
@@ -1360,7 +1379,12 @@ examples:
|
||||
parameters:
|
||||
path:
|
||||
pinID: 408895
|
||||
query: {}
|
||||
query:
|
||||
X-Plex-Client-Identifier: "gcgzw5rz2xovp84b4vha3a40"
|
||||
X-Plex-Product: "Plex Web"
|
||||
X-Plex-Device: "Linux"
|
||||
X-Plex-Version: "4.133.0"
|
||||
X-Plex-Platform: "Chrome"
|
||||
responses:
|
||||
"404":
|
||||
application/json: {"errors": [{"code": 1020, "message": "Code not found or expired"}]}
|
||||
@@ -2000,7 +2024,7 @@ examples:
|
||||
speakeasy-default-get-token-details:
|
||||
responses:
|
||||
"200":
|
||||
application/json: {"adsConsent": true, "adsConsentReminderAt": "2019-08-24T14:15:22Z", "adsConsentSetAt": "2019-08-24T14:15:22Z", "anonymous": false, "authToken": "CxoUzBTSV5hsxjTpFKaf", "backupCodesCreated": false, "confirmed": false, "country": "US", "email": "username@email.com", "emailOnlyAuth": false, "experimentalFeatures": false, "friendlyName": "friendlyUsername", "entitlements": ["[]"], "guest": false, "hasPassword": true, "home": false, "homeAdmin": false, "homeSize": 1, "id": 13692262, "joinedAt": 1556281940, "locale": null, "mailingListActive": false, "mailingListStatus": "unsubscribed", "maxHomeSize": 15, "pin": "string", "profile": {"autoSelectAudio": true, "defaultAudioLanguage": "ja", "defaultSubtitleLanguage": "en", "autoSelectSubtitle": 1, "defaultSubtitleAccessibility": 1, "defaultSubtitleForced": 1, "watchedIndicator": 1, "mediaReviewsVisibility": 1}, "protected": false, "rememberExpiresAt": 1556281940, "restricted": false, "roles": ["string"], "scrobbleTypes": "", "services": [{"identifier": "metadata-dev", "endpoint": "https://epg.provider.plex.tv", "token": "DjoMtqFAGRL1uVtCyF1dKIorTbShJeqv", "secret": "string", "status": "online"}], "subscription": {"features": ["Android - Dolby Vision"], "active": true, "subscribedAt": "2021-04-12T18:21:12Z", "status": "Inactive", "paymentService": "string", "plan": "string"}, "subscriptionDescription": "string", "subscriptions": [{"features": ["Android - Dolby Vision"], "active": true, "subscribedAt": "2021-04-12T18:21:12Z", "status": "Inactive", "paymentService": "string", "plan": "string"}], "thumb": "https://plex.tv/users/a4f43c1ebfde43a5/avatar?c=8372075101", "title": "UsernameTitle", "twoFactorEnabled": false, "username": "Username", "uuid": "dae343c1f45beb4f", "attributionPartner": null}
|
||||
application/json: {"adsConsent": true, "adsConsentReminderAt": "2019-08-24T14:15:22Z", "adsConsentSetAt": "2019-08-24T14:15:22Z", "anonymous": false, "authToken": "CxoUzBTSV5hsxjTpFKaf", "backupCodesCreated": false, "confirmed": false, "country": "US", "email": "username@email.com", "emailOnlyAuth": false, "experimentalFeatures": false, "friendlyName": "friendlyUsername", "entitlements": ["[]"], "guest": false, "hasPassword": true, "home": false, "homeAdmin": false, "homeSize": 1, "id": 13692262, "joinedAt": 1556281940, "locale": null, "mailingListActive": false, "mailingListStatus": "active", "maxHomeSize": 15, "pin": "string", "profile": {"autoSelectAudio": true, "defaultAudioLanguage": "ja", "defaultSubtitleLanguage": "en", "autoSelectSubtitle": 1, "defaultSubtitleAccessibility": 1, "defaultSubtitleForced": 1, "watchedIndicator": 1, "mediaReviewsVisibility": 1}, "protected": false, "rememberExpiresAt": 1556281940, "restricted": false, "roles": ["string"], "scrobbleTypes": "", "services": [{"identifier": "metadata-dev", "endpoint": "https://epg.provider.plex.tv", "token": "DjoMtqFAGRL1uVtCyF1dKIorTbShJeqv", "secret": "string", "status": "online"}], "subscription": {"features": ["Android - Dolby Vision"], "active": true, "subscribedAt": "2021-04-12T18:21:12Z", "status": "Inactive", "paymentService": "string", "plan": "string"}, "subscriptionDescription": "string", "subscriptions": [{"features": ["Android - Dolby Vision"], "active": true, "subscribedAt": "2021-04-12T18:21:12Z", "status": "Inactive", "paymentService": "string", "plan": "string"}], "thumb": "https://plex.tv/users/a4f43c1ebfde43a5/avatar?c=8372075101", "title": "UsernameTitle", "twoFactorEnabled": false, "username": "Username", "uuid": "dae343c1f45beb4f", "attributionPartner": null}
|
||||
"400":
|
||||
application/json: {"errors": []}
|
||||
"401":
|
||||
|
||||
@@ -12,7 +12,7 @@ generation:
|
||||
auth:
|
||||
oAuth2ClientCredentialsEnabled: true
|
||||
python:
|
||||
version: 0.14.0
|
||||
version: 0.15.0
|
||||
additionalDependencies:
|
||||
dev: {}
|
||||
main: {}
|
||||
@@ -22,6 +22,8 @@ python:
|
||||
clientServerStatusCodesAsErrors: true
|
||||
description: Python Client SDK Generated by Speakeasy
|
||||
enumFormat: enum
|
||||
fixFlags:
|
||||
responseRequiredSep2024: false
|
||||
flattenGlobalSecurity: true
|
||||
flattenRequests: false
|
||||
imports:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
speakeasyVersion: 1.402.14
|
||||
speakeasyVersion: 1.404.5
|
||||
sources:
|
||||
my-source:
|
||||
sourceNamespace: my-source
|
||||
@@ -8,8 +8,8 @@ sources:
|
||||
- latest
|
||||
plexapi:
|
||||
sourceNamespace: plexapi
|
||||
sourceRevisionDigest: sha256:b7081644a59eca24a22b8009506fcf459bf18b07dce0462b39bc36c40d94862e
|
||||
sourceBlobDigest: sha256:6b822f23afbc630bbc0fc12299316ea03d3671a2c2a81241ad4caa49022b430e
|
||||
sourceRevisionDigest: sha256:276a31ab98595ebaf2b1fac4b4f5c3c1c7b55e0431f9074c89b8fbcb55b52d3f
|
||||
sourceBlobDigest: sha256:2bc9e816db669d609d8a5988ebb629578dc5cbbaff191d260b5c63b7ba1bd59b
|
||||
tags:
|
||||
- latest
|
||||
- main
|
||||
@@ -17,10 +17,10 @@ targets:
|
||||
plexpy:
|
||||
source: plexapi
|
||||
sourceNamespace: plexapi
|
||||
sourceRevisionDigest: sha256:b7081644a59eca24a22b8009506fcf459bf18b07dce0462b39bc36c40d94862e
|
||||
sourceBlobDigest: sha256:6b822f23afbc630bbc0fc12299316ea03d3671a2c2a81241ad4caa49022b430e
|
||||
sourceRevisionDigest: sha256:276a31ab98595ebaf2b1fac4b4f5c3c1c7b55e0431f9074c89b8fbcb55b52d3f
|
||||
sourceBlobDigest: sha256:2bc9e816db669d609d8a5988ebb629578dc5cbbaff191d260b5c63b7ba1bd59b
|
||||
codeSamplesNamespace: code-samples-python-plexpy
|
||||
codeSamplesRevisionDigest: sha256:a9cb66019954437cc4933b5f6fa4c53227010c792f21c62a5498bec77afe2b2e
|
||||
codeSamplesRevisionDigest: sha256:5edcf369d886cffd0ba4f8017fb3f9a9737667556a38dfc626089f4599bc5e3c
|
||||
workflow:
|
||||
workflowVersion: 1.0.0
|
||||
speakeasyVersion: latest
|
||||
|
||||
27
README.md
27
README.md
@@ -11,6 +11,31 @@
|
||||
## Summary
|
||||
|
||||
Plex-API: An Open API Spec for interacting with Plex.tv and Plex Media Server
|
||||
|
||||
# Plex Media Server OpenAPI Specification
|
||||
|
||||
An Open Source OpenAPI Specification for Plex Media Server
|
||||
|
||||
Automation and SDKs provided by [Speakeasy](https://speakeasyapi.dev/)
|
||||
|
||||
## Documentation
|
||||
|
||||
[API Documentation](https://plexapi.dev)
|
||||
|
||||
## SDKs
|
||||
|
||||
The following SDKs are generated from the OpenAPI Specification. They are automatically generated and may not be fully tested. If you find any issues, please open an issue on the respective repository.
|
||||
|
||||
| Language | Repository | Releases | Other |
|
||||
| --------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------- |
|
||||
| Python | [GitHub](https://github.com/LukeHagar/plexpy) | [PyPI](https://pypi.org/project/plex-api-client/) | - |
|
||||
| JavaScript/TypeScript | [GitHub](https://github.com/LukeHagar/plexjs) | [NPM](https://www.npmjs.com/package/@lukehagar/plexjs) \ [JSR](https://jsr.io/@lukehagar/plexjs) | - |
|
||||
| Go | [GitHub](https://github.com/LukeHagar/plexgo) | [Releases](https://github.com/LukeHagar/plexgo/releases) | [GoDoc](https://pkg.go.dev/github.com/LukeHagar/plexgo) |
|
||||
| Ruby | [GitHub](https://github.com/LukeHagar/plexruby) | [Releases](https://github.com/LukeHagar/plexruby/releases) | - |
|
||||
| Swift | [GitHub](https://github.com/LukeHagar/plexswift) | [Releases](https://github.com/LukeHagar/plexswift/releases) | - |
|
||||
| PHP | [GitHub](https://github.com/LukeHagar/plexphp) | [Releases](https://github.com/LukeHagar/plexphp/releases) | - |
|
||||
| Java | [GitHub](https://github.com/LukeHagar/plexjava) | [Releases](https://github.com/LukeHagar/plexjava/releases) | - |
|
||||
| C# | [GitHub](https://github.com/LukeHagar/plexcsharp) | [Releases](https://github.com/LukeHagar/plexcsharp/releases) | -
|
||||
<!-- End Summary [summary] -->
|
||||
|
||||
<!-- Start Table of Contents [toc] -->
|
||||
@@ -423,7 +448,7 @@ s = PlexAPI(
|
||||
device_name="Linux",
|
||||
)
|
||||
|
||||
res = s.plex.get_companions_data(server_url="https://plex.tv/api/v2/")
|
||||
res = s.plex.get_companions_data(server_url="https://plex.tv/api/v2")
|
||||
|
||||
if res.response_bodies is not None:
|
||||
# handle response
|
||||
|
||||
12
RELEASES.md
12
RELEASES.md
@@ -778,4 +778,14 @@ Based on:
|
||||
### Generated
|
||||
- [python v0.14.0] .
|
||||
### Releases
|
||||
- [PyPI v0.14.0] https://pypi.org/project/plex-api-client/0.14.0 - .
|
||||
- [PyPI v0.14.0] https://pypi.org/project/plex-api-client/0.14.0 - .
|
||||
|
||||
## 2024-09-28 00:01:22
|
||||
### Changes
|
||||
Based on:
|
||||
- OpenAPI Doc
|
||||
- Speakeasy CLI 1.404.5 (2.426.2) https://github.com/speakeasy-api/speakeasy
|
||||
### Generated
|
||||
- [python v0.15.0] .
|
||||
### Releases
|
||||
- [PyPI v0.15.0] https://pypi.org/project/plex-api-client/0.15.0 - .
|
||||
@@ -1138,7 +1138,9 @@ actions:
|
||||
device_name="Linux",
|
||||
)
|
||||
|
||||
res = s.plex.get_token_by_pin_id(pin_id=408895)
|
||||
res = s.plex.get_token_by_pin_id(request={
|
||||
"pin_id": 408895,
|
||||
})
|
||||
|
||||
if res.auth_pin_container is not None:
|
||||
# handle response
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
## Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| `protocol` | [operations.Protocol](../../models/operations/protocol.md) | :heavy_check_mark: | The protocol used for the connection (http, https, etc) |
|
||||
| `address` | *str* | :heavy_check_mark: | The (ip) address or domain name used for the connection |
|
||||
| `port` | *int* | :heavy_check_mark: | The port used for the connection |
|
||||
| `uri` | *str* | :heavy_check_mark: | The full URI of the connection |
|
||||
| `local` | *bool* | :heavy_check_mark: | If the connection is local address |
|
||||
| `relay` | *bool* | :heavy_check_mark: | If the connection is relayed through plex.direct |
|
||||
| `i_pv6` | *bool* | :heavy_check_mark: | If the connection is using IPv6 |
|
||||
| Field | Type | Required | Description | Example |
|
||||
| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| `protocol` | [operations.Protocol](../../models/operations/protocol.md) | :heavy_check_mark: | The protocol used for the connection (http, https, etc) | http |
|
||||
| `address` | *str* | :heavy_check_mark: | The (ip) address or domain name used for the connection | |
|
||||
| `port` | *int* | :heavy_check_mark: | The port used for the connection | |
|
||||
| `uri` | *str* | :heavy_check_mark: | The full URI of the connection | |
|
||||
| `local` | *bool* | :heavy_check_mark: | If the connection is local address | |
|
||||
| `relay` | *bool* | :heavy_check_mark: | If the connection is relayed through plex.direct | |
|
||||
| `i_pv6` | *bool* | :heavy_check_mark: | If the connection is using IPv6 | |
|
||||
12
docs/models/operations/gettokenbypinidglobals.md
Normal file
12
docs/models/operations/gettokenbypinidglobals.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# GetTokenByPinIDGlobals
|
||||
|
||||
|
||||
## Fields
|
||||
|
||||
| Field | Type | Required | Description | Example |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `client_id` | *Optional[str]* | :heavy_minus_sign: | The unique identifier for the client application<br/>This is used to track the client application and its usage<br/>(UUID, serial number, or other number unique per device)<br/> | gcgzw5rz2xovp84b4vha3a40 |
|
||||
| `client_name` | *Optional[str]* | :heavy_minus_sign: | N/A | Plex Web |
|
||||
| `device_name` | *Optional[str]* | :heavy_minus_sign: | N/A | Linux |
|
||||
| `client_version` | *Optional[str]* | :heavy_minus_sign: | N/A | 4.133.0 |
|
||||
| `client_platform` | *Optional[str]* | :heavy_minus_sign: | N/A | Chrome |
|
||||
@@ -3,6 +3,11 @@
|
||||
|
||||
## Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- |
|
||||
| `pin_id` | *int* | :heavy_check_mark: | The PinID to retrieve an access token for |
|
||||
| Field | Type | Required | Description | Example |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `pin_id` | *int* | :heavy_check_mark: | The PinID to retrieve an access token for | |
|
||||
| `client_id` | *Optional[str]* | :heavy_minus_sign: | The unique identifier for the client application<br/>This is used to track the client application and its usage<br/>(UUID, serial number, or other number unique per device)<br/> | gcgzw5rz2xovp84b4vha3a40 |
|
||||
| `client_name` | *Optional[str]* | :heavy_minus_sign: | N/A | Plex Web |
|
||||
| `device_name` | *Optional[str]* | :heavy_minus_sign: | N/A | Linux |
|
||||
| `client_version` | *Optional[str]* | :heavy_minus_sign: | N/A | 4.133.0 |
|
||||
| `client_platform` | *Optional[str]* | :heavy_minus_sign: | N/A | Chrome |
|
||||
@@ -19,7 +19,7 @@ Logged in user details
|
||||
| `id` | *int* | :heavy_check_mark: | The Plex account ID | 13692262 |
|
||||
| `joined_at` | *int* | :heavy_check_mark: | Unix epoch datetime in seconds | 1556281940 |
|
||||
| `locale` | *Nullable[str]* | :heavy_check_mark: | The account locale | |
|
||||
| `mailing_list_status` | [operations.MailingListStatus](../../models/operations/mailingliststatus.md) | :heavy_check_mark: | Your current mailing list status | |
|
||||
| `mailing_list_status` | [operations.MailingListStatus](../../models/operations/mailingliststatus.md) | :heavy_check_mark: | Your current mailing list status (active or unsubscribed) | active |
|
||||
| `max_home_size` | *int* | :heavy_check_mark: | The maximum number of accounts allowed in the Plex Home | 15 |
|
||||
| `profile` | [operations.UserProfile](../../models/operations/userprofile.md) | :heavy_check_mark: | N/A | |
|
||||
| `remember_expires_at` | *int* | :heavy_check_mark: | Unix epoch datetime in seconds | 1556281940 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# MailingListStatus
|
||||
|
||||
Your current mailing list status
|
||||
Your current mailing list status (active or unsubscribed)
|
||||
|
||||
|
||||
## Values
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# PostUsersSignInDataMailingListStatus
|
||||
|
||||
Your current mailing list status
|
||||
Your current mailing list status (active or unsubscribed)
|
||||
|
||||
|
||||
## Values
|
||||
|
||||
@@ -19,7 +19,7 @@ Returns the user account data with a valid auth token
|
||||
| `id` | *int* | :heavy_check_mark: | The Plex account ID | 13692262 |
|
||||
| `joined_at` | *int* | :heavy_check_mark: | Unix epoch datetime in seconds | 1556281940 |
|
||||
| `locale` | *Nullable[str]* | :heavy_check_mark: | The account locale | |
|
||||
| `mailing_list_status` | [operations.PostUsersSignInDataMailingListStatus](../../models/operations/postuserssignindatamailingliststatus.md) | :heavy_check_mark: | Your current mailing list status | |
|
||||
| `mailing_list_status` | [operations.PostUsersSignInDataMailingListStatus](../../models/operations/postuserssignindatamailingliststatus.md) | :heavy_check_mark: | Your current mailing list status (active or unsubscribed) | active |
|
||||
| `max_home_size` | *int* | :heavy_check_mark: | The maximum number of accounts allowed in the Plex Home | 15 |
|
||||
| `profile` | [operations.PostUsersSignInDataUserProfile](../../models/operations/postuserssignindatauserprofile.md) | :heavy_check_mark: | N/A | |
|
||||
| `remember_expires_at` | *int* | :heavy_check_mark: | Unix epoch datetime in seconds | 1556281940 |
|
||||
|
||||
@@ -310,7 +310,9 @@ s = PlexAPI(
|
||||
device_name="Linux",
|
||||
)
|
||||
|
||||
res = s.plex.get_token_by_pin_id(pin_id=408895)
|
||||
res = s.plex.get_token_by_pin_id(request={
|
||||
"pin_id": 408895,
|
||||
})
|
||||
|
||||
if res.auth_pin_container is not None:
|
||||
# handle response
|
||||
@@ -320,11 +322,11 @@ if res.auth_pin_container is not None:
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
||||
| `pin_id` | *int* | :heavy_check_mark: | The PinID to retrieve an access token for |
|
||||
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
|
||||
| `server_url` | *Optional[str]* | :heavy_minus_sign: | An optional server URL to use. |
|
||||
| Parameter | Type | Required | Description |
|
||||
| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
||||
| `request` | [operations.GetTokenByPinIDRequest](../../models/operations/gettokenbypinidrequest.md) | :heavy_check_mark: | The request object to use for the request. |
|
||||
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
|
||||
| `server_url` | *Optional[str]* | :heavy_minus_sign: | An optional server URL to use. |
|
||||
|
||||
### Response
|
||||
|
||||
|
||||
@@ -2,4 +2,27 @@
|
||||
|
||||
## Overview
|
||||
|
||||
Plex-API: An Open API Spec for interacting with Plex.tv and Plex Media Server
|
||||
# Plex Media Server OpenAPI Specification
|
||||
|
||||
An Open Source OpenAPI Specification for Plex Media Server
|
||||
|
||||
Automation and SDKs provided by [Speakeasy](https://speakeasyapi.dev/)
|
||||
|
||||
## Documentation
|
||||
|
||||
[API Documentation](https://plexapi.dev)
|
||||
|
||||
## SDKs
|
||||
|
||||
The following SDKs are generated from the OpenAPI Specification. They are automatically generated and may not be fully tested. If you find any issues, please open an issue on the respective repository.
|
||||
|
||||
| Language | Repository | Releases | Other |
|
||||
| --------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------- |
|
||||
| Python | [GitHub](https://github.com/LukeHagar/plexpy) | [PyPI](https://pypi.org/project/plex-api-client/) | - |
|
||||
| JavaScript/TypeScript | [GitHub](https://github.com/LukeHagar/plexjs) | [NPM](https://www.npmjs.com/package/@lukehagar/plexjs) \ [JSR](https://jsr.io/@lukehagar/plexjs) | - |
|
||||
| Go | [GitHub](https://github.com/LukeHagar/plexgo) | [Releases](https://github.com/LukeHagar/plexgo/releases) | [GoDoc](https://pkg.go.dev/github.com/LukeHagar/plexgo) |
|
||||
| Ruby | [GitHub](https://github.com/LukeHagar/plexruby) | [Releases](https://github.com/LukeHagar/plexruby/releases) | - |
|
||||
| Swift | [GitHub](https://github.com/LukeHagar/plexswift) | [Releases](https://github.com/LukeHagar/plexswift/releases) | - |
|
||||
| PHP | [GitHub](https://github.com/LukeHagar/plexphp) | [Releases](https://github.com/LukeHagar/plexphp/releases) | - |
|
||||
| Java | [GitHub](https://github.com/LukeHagar/plexjava) | [Releases](https://github.com/LukeHagar/plexjava/releases) | - |
|
||||
| C# | [GitHub](https://github.com/LukeHagar/plexcsharp) | [Releases](https://github.com/LukeHagar/plexcsharp/releases) | -
|
||||
|
||||
113
poetry.lock
generated
113
poetry.lock
generated
@@ -115,6 +115,20 @@ files = [
|
||||
[package.extras]
|
||||
test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "execnet"
|
||||
version = "2.1.1"
|
||||
description = "execnet: rapid multi-Python deployment"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"},
|
||||
{file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
testing = ["hatch", "pre-commit", "pytest", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.14.0"
|
||||
@@ -183,6 +197,17 @@ files = [
|
||||
{file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
|
||||
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "5.13.2"
|
||||
@@ -277,6 +302,17 @@ files = [
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "24.1"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
|
||||
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.3.2"
|
||||
@@ -293,6 +329,21 @@ docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-a
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
|
||||
type = ["mypy (>=1.11.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.5.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
|
||||
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.9.1"
|
||||
@@ -447,6 +498,66 @@ typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""
|
||||
spelling = ["pyenchant (>=3.2,<4.0)"]
|
||||
testutils = ["gitpython (>3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.3.3"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
|
||||
{file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=1.5,<2"
|
||||
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-asyncio"
|
||||
version = "0.23.8"
|
||||
description = "Pytest support for asyncio"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"},
|
||||
{file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=7.0.0,<9"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
|
||||
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-xdist"
|
||||
version = "3.6.1"
|
||||
description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"},
|
||||
{file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
execnet = ">=2.1"
|
||||
pytest = ">=7.0.0"
|
||||
|
||||
[package.extras]
|
||||
psutil = ["psutil (>=3.0)"]
|
||||
setproctitle = ["setproctitle"]
|
||||
testing = ["filelock"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
@@ -545,4 +656,4 @@ typing-extensions = ">=3.7.4"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "6bb5f77afb8fcbe7327ccd1fcc33f5c279c6a2582d43be73b69c2a94b836b85d"
|
||||
content-hash = "64b571d1265d39cbac4d15b70fb840ff13ba2ee2dc4f08cbaf8118f2a07e4490"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "plex-api-client"
|
||||
version = "0.14.0"
|
||||
version = "0.15.0"
|
||||
description = "Python Client SDK Generated by Speakeasy"
|
||||
authors = ["Speakeasy",]
|
||||
readme = "README-PYPI.md"
|
||||
@@ -28,6 +28,9 @@ typing-inspect = "^0.9.0"
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
mypy = "==1.10.1"
|
||||
pylint = "==3.2.3"
|
||||
pytest = "^8.2.0"
|
||||
pytest-asyncio = "^0.23.7"
|
||||
pytest-xdist = "^3.6.1"
|
||||
types-python-dateutil = "^2.9.0.20240316"
|
||||
|
||||
[build-system]
|
||||
|
||||
@@ -797,6 +797,8 @@ from .gettokenbypinid import (
|
||||
GetTokenByPinIDAuthPinContainerTypedDict,
|
||||
GetTokenByPinIDGeoData,
|
||||
GetTokenByPinIDGeoDataTypedDict,
|
||||
GetTokenByPinIDGlobals,
|
||||
GetTokenByPinIDGlobalsTypedDict,
|
||||
GetTokenByPinIDRequest,
|
||||
GetTokenByPinIDRequestTypedDict,
|
||||
GetTokenByPinIDResponse,
|
||||
@@ -1616,6 +1618,8 @@ __all__ = [
|
||||
"GetTokenByPinIDAuthPinContainerTypedDict",
|
||||
"GetTokenByPinIDGeoData",
|
||||
"GetTokenByPinIDGeoDataTypedDict",
|
||||
"GetTokenByPinIDGlobals",
|
||||
"GetTokenByPinIDGlobalsTypedDict",
|
||||
"GetTokenByPinIDRequest",
|
||||
"GetTokenByPinIDRequestTypedDict",
|
||||
"GetTokenByPinIDResponse",
|
||||
|
||||
@@ -12,7 +12,7 @@ from typing import List, Optional, TypedDict
|
||||
from typing_extensions import Annotated, NotRequired
|
||||
|
||||
GET_SERVER_RESOURCES_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from typing import List, Optional, TypedDict
|
||||
from typing_extensions import Annotated, NotRequired
|
||||
|
||||
GET_COMPANIONS_DATA_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from typing import Optional, TypedDict
|
||||
from typing_extensions import NotRequired
|
||||
|
||||
GET_GEO_DATA_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ from typing import Any, Optional, TypedDict
|
||||
from typing_extensions import Annotated, NotRequired
|
||||
|
||||
GET_PIN_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -10,20 +10,80 @@ from plex_api_client.types import (
|
||||
UNSET,
|
||||
UNSET_SENTINEL,
|
||||
)
|
||||
from plex_api_client.utils import FieldMetadata, PathParamMetadata
|
||||
from plex_api_client.utils import FieldMetadata, PathParamMetadata, QueryParamMetadata
|
||||
import pydantic
|
||||
from pydantic import model_serializer
|
||||
from typing import Any, Optional, TypedDict
|
||||
from typing_extensions import Annotated, NotRequired
|
||||
|
||||
GET_TOKEN_BY_PIN_ID_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
class GetTokenByPinIDGlobalsTypedDict(TypedDict):
|
||||
client_id: NotRequired[str]
|
||||
r"""The unique identifier for the client application
|
||||
This is used to track the client application and its usage
|
||||
(UUID, serial number, or other number unique per device)
|
||||
|
||||
"""
|
||||
client_name: NotRequired[str]
|
||||
device_name: NotRequired[str]
|
||||
client_version: NotRequired[str]
|
||||
client_platform: NotRequired[str]
|
||||
|
||||
|
||||
class GetTokenByPinIDGlobals(BaseModel):
|
||||
client_id: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Client-Identifier"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
r"""The unique identifier for the client application
|
||||
This is used to track the client application and its usage
|
||||
(UUID, serial number, or other number unique per device)
|
||||
|
||||
"""
|
||||
|
||||
client_name: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Product"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
device_name: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Device"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
client_version: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Version"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
client_platform: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Platform"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
|
||||
class GetTokenByPinIDRequestTypedDict(TypedDict):
|
||||
pin_id: int
|
||||
r"""The PinID to retrieve an access token for"""
|
||||
client_id: NotRequired[str]
|
||||
r"""The unique identifier for the client application
|
||||
This is used to track the client application and its usage
|
||||
(UUID, serial number, or other number unique per device)
|
||||
|
||||
"""
|
||||
client_name: NotRequired[str]
|
||||
device_name: NotRequired[str]
|
||||
client_version: NotRequired[str]
|
||||
client_platform: NotRequired[str]
|
||||
|
||||
|
||||
class GetTokenByPinIDRequest(BaseModel):
|
||||
@@ -34,6 +94,41 @@ class GetTokenByPinIDRequest(BaseModel):
|
||||
]
|
||||
r"""The PinID to retrieve an access token for"""
|
||||
|
||||
client_id: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Client-Identifier"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
r"""The unique identifier for the client application
|
||||
This is used to track the client application and its usage
|
||||
(UUID, serial number, or other number unique per device)
|
||||
|
||||
"""
|
||||
|
||||
client_name: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Product"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
device_name: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Device"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
client_version: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Version"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
client_platform: Annotated[
|
||||
Optional[str],
|
||||
pydantic.Field(alias="X-Plex-Platform"),
|
||||
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
||||
] = None
|
||||
|
||||
|
||||
class GetTokenByPinIDGeoDataTypedDict(TypedDict):
|
||||
r"""Geo location data"""
|
||||
|
||||
@@ -17,12 +17,12 @@ from typing import List, Optional, TypedDict
|
||||
from typing_extensions import Annotated, NotRequired
|
||||
|
||||
GET_TOKEN_DETAILS_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
class MailingListStatus(str, Enum):
|
||||
r"""Your current mailing list status"""
|
||||
r"""Your current mailing list status (active or unsubscribed)"""
|
||||
|
||||
ACTIVE = "active"
|
||||
UNSUBSCRIBED = "unsubscribed"
|
||||
@@ -529,7 +529,7 @@ class GetTokenDetailsUserPlexAccountTypedDict(TypedDict):
|
||||
locale: Nullable[str]
|
||||
r"""The account locale"""
|
||||
mailing_list_status: MailingListStatus
|
||||
r"""Your current mailing list status"""
|
||||
r"""Your current mailing list status (active or unsubscribed)"""
|
||||
max_home_size: int
|
||||
r"""The maximum number of accounts allowed in the Plex Home"""
|
||||
profile: UserProfileTypedDict
|
||||
@@ -630,7 +630,7 @@ class GetTokenDetailsUserPlexAccount(BaseModel):
|
||||
mailing_list_status: Annotated[
|
||||
MailingListStatus, pydantic.Field(alias="mailingListStatus")
|
||||
]
|
||||
r"""Your current mailing list status"""
|
||||
r"""Your current mailing list status (active or unsubscribed)"""
|
||||
|
||||
max_home_size: Annotated[int, pydantic.Field(alias="maxHomeSize")]
|
||||
r"""The maximum number of accounts allowed in the Plex Home"""
|
||||
|
||||
@@ -10,7 +10,7 @@ from typing import List, Optional, TypedDict
|
||||
from typing_extensions import Annotated, NotRequired
|
||||
|
||||
GET_USER_FRIENDS_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ from typing import List, Optional, TypedDict
|
||||
from typing_extensions import Annotated, NotRequired
|
||||
|
||||
POST_USERS_SIGN_IN_DATA_SERVERS = [
|
||||
"https://plex.tv/api/v2/",
|
||||
"https://plex.tv/api/v2",
|
||||
]
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ class PostUsersSignInDataRequest(BaseModel):
|
||||
|
||||
|
||||
class PostUsersSignInDataMailingListStatus(str, Enum):
|
||||
r"""Your current mailing list status"""
|
||||
r"""Your current mailing list status (active or unsubscribed)"""
|
||||
|
||||
ACTIVE = "active"
|
||||
UNSUBSCRIBED = "unsubscribed"
|
||||
@@ -828,7 +828,7 @@ class PostUsersSignInDataUserPlexAccountTypedDict(TypedDict):
|
||||
locale: Nullable[str]
|
||||
r"""The account locale"""
|
||||
mailing_list_status: PostUsersSignInDataMailingListStatus
|
||||
r"""Your current mailing list status"""
|
||||
r"""Your current mailing list status (active or unsubscribed)"""
|
||||
max_home_size: int
|
||||
r"""The maximum number of accounts allowed in the Plex Home"""
|
||||
profile: PostUsersSignInDataUserProfileTypedDict
|
||||
@@ -931,7 +931,7 @@ class PostUsersSignInDataUserPlexAccount(BaseModel):
|
||||
mailing_list_status: Annotated[
|
||||
PostUsersSignInDataMailingListStatus, pydantic.Field(alias="mailingListStatus")
|
||||
]
|
||||
r"""Your current mailing list status"""
|
||||
r"""Your current mailing list status (active or unsubscribed)"""
|
||||
|
||||
max_home_size: Annotated[int, pydantic.Field(alias="maxHomeSize")]
|
||||
r"""The maximum number of accounts allowed in the Plex Home"""
|
||||
|
||||
@@ -1156,7 +1156,10 @@ class Plex(BaseSDK):
|
||||
def get_token_by_pin_id(
|
||||
self,
|
||||
*,
|
||||
pin_id: int,
|
||||
request: Union[
|
||||
operations.GetTokenByPinIDRequest,
|
||||
operations.GetTokenByPinIDRequestTypedDict,
|
||||
],
|
||||
retries: OptionalNullable[utils.RetryConfig] = UNSET,
|
||||
server_url: Optional[str] = None,
|
||||
timeout_ms: Optional[int] = None,
|
||||
@@ -1165,7 +1168,7 @@ class Plex(BaseSDK):
|
||||
|
||||
Retrieve an Access Token from Plex.tv after the Pin has been authenticated
|
||||
|
||||
:param pin_id: The PinID to retrieve an access token for
|
||||
:param request: The request object to send.
|
||||
: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
|
||||
@@ -1180,9 +1183,9 @@ class Plex(BaseSDK):
|
||||
else:
|
||||
base_url = operations.GET_TOKEN_BY_PIN_ID_SERVERS[0]
|
||||
|
||||
request = operations.GetTokenByPinIDRequest(
|
||||
pin_id=pin_id,
|
||||
)
|
||||
if not isinstance(request, BaseModel):
|
||||
request = utils.unmarshal(request, operations.GetTokenByPinIDRequest)
|
||||
request = cast(operations.GetTokenByPinIDRequest, request)
|
||||
|
||||
req = self.build_request(
|
||||
method="GET",
|
||||
@@ -1192,9 +1195,16 @@ class Plex(BaseSDK):
|
||||
request=request,
|
||||
request_body_required=False,
|
||||
request_has_path_params=True,
|
||||
request_has_query_params=False,
|
||||
request_has_query_params=True,
|
||||
user_agent_header="user-agent",
|
||||
accept_header_value="application/json",
|
||||
_globals=operations.GetTokenByPinIDGlobals(
|
||||
client_id=self.sdk_configuration.globals.client_id,
|
||||
client_name=self.sdk_configuration.globals.client_name,
|
||||
device_name=self.sdk_configuration.globals.device_name,
|
||||
client_version=self.sdk_configuration.globals.client_version,
|
||||
client_platform=self.sdk_configuration.globals.client_platform,
|
||||
),
|
||||
timeout_ms=timeout_ms,
|
||||
)
|
||||
|
||||
@@ -1253,7 +1263,10 @@ class Plex(BaseSDK):
|
||||
async def get_token_by_pin_id_async(
|
||||
self,
|
||||
*,
|
||||
pin_id: int,
|
||||
request: Union[
|
||||
operations.GetTokenByPinIDRequest,
|
||||
operations.GetTokenByPinIDRequestTypedDict,
|
||||
],
|
||||
retries: OptionalNullable[utils.RetryConfig] = UNSET,
|
||||
server_url: Optional[str] = None,
|
||||
timeout_ms: Optional[int] = None,
|
||||
@@ -1262,7 +1275,7 @@ class Plex(BaseSDK):
|
||||
|
||||
Retrieve an Access Token from Plex.tv after the Pin has been authenticated
|
||||
|
||||
:param pin_id: The PinID to retrieve an access token for
|
||||
:param request: The request object to send.
|
||||
: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
|
||||
@@ -1277,9 +1290,9 @@ class Plex(BaseSDK):
|
||||
else:
|
||||
base_url = operations.GET_TOKEN_BY_PIN_ID_SERVERS[0]
|
||||
|
||||
request = operations.GetTokenByPinIDRequest(
|
||||
pin_id=pin_id,
|
||||
)
|
||||
if not isinstance(request, BaseModel):
|
||||
request = utils.unmarshal(request, operations.GetTokenByPinIDRequest)
|
||||
request = cast(operations.GetTokenByPinIDRequest, request)
|
||||
|
||||
req = self.build_request_async(
|
||||
method="GET",
|
||||
@@ -1289,9 +1302,16 @@ class Plex(BaseSDK):
|
||||
request=request,
|
||||
request_body_required=False,
|
||||
request_has_path_params=True,
|
||||
request_has_query_params=False,
|
||||
request_has_query_params=True,
|
||||
user_agent_header="user-agent",
|
||||
accept_header_value="application/json",
|
||||
_globals=operations.GetTokenByPinIDGlobals(
|
||||
client_id=self.sdk_configuration.globals.client_id,
|
||||
client_name=self.sdk_configuration.globals.client_name,
|
||||
device_name=self.sdk_configuration.globals.device_name,
|
||||
client_version=self.sdk_configuration.globals.client_version,
|
||||
client_platform=self.sdk_configuration.globals.client_platform,
|
||||
),
|
||||
timeout_ms=timeout_ms,
|
||||
)
|
||||
|
||||
|
||||
@@ -30,7 +30,34 @@ from typing import Any, Callable, Dict, List, Optional, Union
|
||||
|
||||
|
||||
class PlexAPI(BaseSDK):
|
||||
r"""Plex-API: An Open API Spec for interacting with Plex.tv and Plex Media Server"""
|
||||
r"""Plex-API: An Open API Spec for interacting with Plex.tv and Plex Media Server
|
||||
|
||||
# Plex Media Server OpenAPI Specification
|
||||
|
||||
An Open Source OpenAPI Specification for Plex Media Server
|
||||
|
||||
Automation and SDKs provided by [Speakeasy](https://speakeasyapi.dev/)
|
||||
|
||||
## Documentation
|
||||
|
||||
[API Documentation](https://plexapi.dev)
|
||||
|
||||
## SDKs
|
||||
|
||||
The following SDKs are generated from the OpenAPI Specification. They are automatically generated and may not be fully tested. If you find any issues, please open an issue on the respective repository.
|
||||
|
||||
| Language | Repository | Releases | Other |
|
||||
| --------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------- |
|
||||
| Python | [GitHub](https://github.com/LukeHagar/plexpy) | [PyPI](https://pypi.org/project/plex-api-client/) | - |
|
||||
| JavaScript/TypeScript | [GitHub](https://github.com/LukeHagar/plexjs) | [NPM](https://www.npmjs.com/package/@lukehagar/plexjs) \ [JSR](https://jsr.io/@lukehagar/plexjs) | - |
|
||||
| Go | [GitHub](https://github.com/LukeHagar/plexgo) | [Releases](https://github.com/LukeHagar/plexgo/releases) | [GoDoc](https://pkg.go.dev/github.com/LukeHagar/plexgo) |
|
||||
| Ruby | [GitHub](https://github.com/LukeHagar/plexruby) | [Releases](https://github.com/LukeHagar/plexruby/releases) | - |
|
||||
| Swift | [GitHub](https://github.com/LukeHagar/plexswift) | [Releases](https://github.com/LukeHagar/plexswift/releases) | - |
|
||||
| PHP | [GitHub](https://github.com/LukeHagar/plexphp) | [Releases](https://github.com/LukeHagar/plexphp/releases) | - |
|
||||
| Java | [GitHub](https://github.com/LukeHagar/plexjava) | [Releases](https://github.com/LukeHagar/plexjava/releases) | - |
|
||||
| C# | [GitHub](https://github.com/LukeHagar/plexcsharp) | [Releases](https://github.com/LukeHagar/plexcsharp/releases) | -
|
||||
|
||||
"""
|
||||
|
||||
server: Server
|
||||
r"""Operations against the Plex Media Server System.
|
||||
|
||||
@@ -39,9 +39,9 @@ class SDKConfiguration:
|
||||
server_defaults: List[Dict[str, str]] = field(default_factory=List)
|
||||
language: str = "python"
|
||||
openapi_doc_version: str = "0.0.3"
|
||||
sdk_version: str = "0.14.0"
|
||||
gen_version: str = "2.422.22"
|
||||
user_agent: str = "speakeasy-sdk/python 0.14.0 2.422.22 0.0.3 plex-api-client"
|
||||
sdk_version: str = "0.15.0"
|
||||
gen_version: str = "2.426.2"
|
||||
user_agent: str = "speakeasy-sdk/python 0.15.0 2.426.2 0.0.3 plex-api-client"
|
||||
retry_config: OptionalNullable[RetryConfig] = Field(default_factory=lambda: UNSET)
|
||||
timeout_ms: Optional[int] = None
|
||||
|
||||
|
||||
3
tests/__init__.py
Normal file
3
tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
# tests/__init__.py
|
||||
27
tests/test_activities.py
Normal file
27
tests/test_activities.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
|
||||
|
||||
def test_activities_get_server_activities():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.activities.get_server_activities()
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_activities_cancel_server_activities_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.activities.cancel_server_activities(
|
||||
activity_uuid="25b71ed5-0f9d-461c-baa7-d404e9e10d3e"
|
||||
)
|
||||
assert res.status_code == 200
|
||||
382
tests/test_authentication.py
Normal file
382
tests/test_authentication.py
Normal file
@@ -0,0 +1,382 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
import dateutil.parser
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_authentication_get_transient_token():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.authentication.get_transient_token(
|
||||
type_=operations.GetTransientTokenQueryParamType.DELEGATION,
|
||||
scope=operations.Scope.ALL,
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_authentication_get_source_connection_information():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.authentication.get_source_connection_information(
|
||||
source="provider://provider-identifier"
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_authentication_get_token_details():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.authentication.get_token_details()
|
||||
assert res.status_code == 200
|
||||
assert res.user_plex_account is not None
|
||||
assert res.user_plex_account == operations.GetTokenDetailsUserPlexAccount(
|
||||
ads_consent=True,
|
||||
ads_consent_reminder_at=dateutil.parser.isoparse("2019-08-24T14:15:22Z"),
|
||||
ads_consent_set_at=dateutil.parser.isoparse("2019-08-24T14:15:22Z"),
|
||||
anonymous=False,
|
||||
auth_token="CxoUzBTSV5hsxjTpFKaf",
|
||||
backup_codes_created=False,
|
||||
confirmed=False,
|
||||
country="US",
|
||||
email="username@email.com",
|
||||
email_only_auth=False,
|
||||
experimental_features=False,
|
||||
friendly_name="friendlyUsername",
|
||||
entitlements=[
|
||||
"[]",
|
||||
],
|
||||
guest=False,
|
||||
has_password=True,
|
||||
home=False,
|
||||
home_admin=False,
|
||||
home_size=1,
|
||||
id=13692262,
|
||||
joined_at=1556281940,
|
||||
locale=None,
|
||||
mailing_list_active=False,
|
||||
mailing_list_status=operations.MailingListStatus.ACTIVE,
|
||||
max_home_size=15,
|
||||
pin="string",
|
||||
profile=operations.UserProfile(
|
||||
auto_select_audio=True,
|
||||
default_audio_language="ja",
|
||||
default_subtitle_language="en",
|
||||
auto_select_subtitle=operations.AutoSelectSubtitle.ENABLE,
|
||||
default_subtitle_accessibility=operations.DefaultSubtitleAccessibility.ENABLE,
|
||||
default_subtitle_forced=operations.DefaultSubtitleForced.ENABLE,
|
||||
watched_indicator=operations.WatchedIndicator.ENABLE,
|
||||
media_reviews_visibility=operations.MediaReviewsVisibility.ENABLE,
|
||||
),
|
||||
protected=False,
|
||||
remember_expires_at=1556281940,
|
||||
restricted=False,
|
||||
roles=[
|
||||
"string",
|
||||
],
|
||||
scrobble_types="",
|
||||
services=[
|
||||
operations.Services(
|
||||
identifier="metadata-dev",
|
||||
endpoint="https://epg.provider.plex.tv",
|
||||
token="DjoMtqFAGRL1uVtCyF1dKIorTbShJeqv",
|
||||
secret="string",
|
||||
status=operations.GetTokenDetailsStatus.ONLINE,
|
||||
),
|
||||
],
|
||||
subscription=operations.Subscription(
|
||||
features=[
|
||||
operations.Features.ANDROID_DOLBY_VISION,
|
||||
],
|
||||
active=True,
|
||||
subscribed_at="2021-04-12T18:21:12Z",
|
||||
status=operations.GetTokenDetailsAuthenticationStatus.INACTIVE,
|
||||
payment_service="string",
|
||||
plan="string",
|
||||
),
|
||||
subscription_description="string",
|
||||
subscriptions=[
|
||||
operations.GetTokenDetailsSubscription(
|
||||
features=[
|
||||
operations.GetTokenDetailsFeatures.ANDROID_DOLBY_VISION,
|
||||
],
|
||||
active=True,
|
||||
subscribed_at="2021-04-12T18:21:12Z",
|
||||
status=operations.GetTokenDetailsAuthenticationResponseStatus.INACTIVE,
|
||||
payment_service="string",
|
||||
plan="string",
|
||||
),
|
||||
],
|
||||
thumb="https://plex.tv/users/a4f43c1ebfde43a5/avatar?c=8372075101",
|
||||
title="UsernameTitle",
|
||||
two_factor_enabled=False,
|
||||
username="Username",
|
||||
uuid="dae343c1f45beb4f",
|
||||
attribution_partner=None,
|
||||
)
|
||||
|
||||
|
||||
def test_authentication_post_users_sign_in_data():
|
||||
s = PlexAPI()
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.authentication.post_users_sign_in_data(
|
||||
request={
|
||||
"request_body": {
|
||||
"login": "username@email.com",
|
||||
"password": "password123",
|
||||
"verification_code": "123456",
|
||||
},
|
||||
}
|
||||
)
|
||||
assert res.status_code == 201
|
||||
assert res.user_plex_account is not None
|
||||
assert res.user_plex_account == operations.PostUsersSignInDataUserPlexAccount(
|
||||
ads_consent=True,
|
||||
ads_consent_reminder_at=dateutil.parser.isoparse("2019-08-24T14:15:22Z"),
|
||||
ads_consent_set_at=dateutil.parser.isoparse("2019-08-24T14:15:22Z"),
|
||||
anonymous=False,
|
||||
auth_token="CxoUzBTSV5hsxjTpFKaf",
|
||||
backup_codes_created=False,
|
||||
confirmed=False,
|
||||
country="US",
|
||||
email="username@email.com",
|
||||
email_only_auth=False,
|
||||
experimental_features=False,
|
||||
friendly_name="friendlyUsername",
|
||||
entitlements=[
|
||||
"[]",
|
||||
],
|
||||
guest=False,
|
||||
has_password=True,
|
||||
home=False,
|
||||
home_admin=False,
|
||||
home_size=1,
|
||||
id=13692262,
|
||||
joined_at=1556281940,
|
||||
locale=None,
|
||||
mailing_list_active=False,
|
||||
mailing_list_status=operations.PostUsersSignInDataMailingListStatus.UNSUBSCRIBED,
|
||||
max_home_size=15,
|
||||
pin="string",
|
||||
profile=operations.PostUsersSignInDataUserProfile(
|
||||
auto_select_audio=True,
|
||||
default_audio_language="ja",
|
||||
default_subtitle_language="en",
|
||||
auto_select_subtitle=operations.PostUsersSignInDataAutoSelectSubtitle.ENABLE,
|
||||
default_subtitle_accessibility=operations.PostUsersSignInDataDefaultSubtitleAccessibility.ENABLE,
|
||||
default_subtitle_forced=operations.PostUsersSignInDataDefaultSubtitleForced.ENABLE,
|
||||
watched_indicator=operations.PostUsersSignInDataWatchedIndicator.ENABLE,
|
||||
media_reviews_visibility=operations.PostUsersSignInDataMediaReviewsVisibility.ENABLE,
|
||||
),
|
||||
protected=False,
|
||||
remember_expires_at=1556281940,
|
||||
restricted=False,
|
||||
roles=[
|
||||
"string",
|
||||
],
|
||||
scrobble_types="",
|
||||
services=[
|
||||
operations.PostUsersSignInDataServices(
|
||||
identifier="metadata-dev",
|
||||
endpoint="https://epg.provider.plex.tv",
|
||||
token="DjoMtqFAGRL1uVtCyF1dKIorTbShJeqv",
|
||||
secret="string",
|
||||
status=operations.PostUsersSignInDataStatus.ONLINE,
|
||||
),
|
||||
],
|
||||
subscription=operations.PostUsersSignInDataSubscription(
|
||||
features=[
|
||||
operations.PostUsersSignInDataFeatures.ANDROID_DOLBY_VISION,
|
||||
],
|
||||
active=True,
|
||||
subscribed_at="2021-04-12T18:21:12Z",
|
||||
status=operations.PostUsersSignInDataAuthenticationStatus.INACTIVE,
|
||||
payment_service="string",
|
||||
plan="string",
|
||||
),
|
||||
subscription_description="string",
|
||||
subscriptions=[
|
||||
operations.PostUsersSignInDataAuthenticationSubscription(
|
||||
features=[
|
||||
operations.PostUsersSignInDataAuthenticationFeatures.ANDROID_DOLBY_VISION,
|
||||
],
|
||||
active=True,
|
||||
subscribed_at="2021-04-12T18:21:12Z",
|
||||
status=operations.PostUsersSignInDataAuthenticationResponseStatus.INACTIVE,
|
||||
payment_service="string",
|
||||
plan="string",
|
||||
),
|
||||
],
|
||||
thumb="https://plex.tv/users/a4f43c1ebfde43a5/avatar?c=8372075101",
|
||||
title="UsernameTitle",
|
||||
two_factor_enabled=False,
|
||||
username="Username",
|
||||
uuid="dae343c1f45beb4f",
|
||||
attribution_partner=None,
|
||||
past_subscriptions=[
|
||||
operations.PastSubscription(
|
||||
id="string",
|
||||
mode="string",
|
||||
renews_at=1556281940,
|
||||
ends_at=1556281940,
|
||||
canceled=False,
|
||||
grace_period=False,
|
||||
on_hold=False,
|
||||
can_reactivate=False,
|
||||
can_upgrade=False,
|
||||
can_downgrade=False,
|
||||
can_convert=False,
|
||||
type="plexpass",
|
||||
transfer="string",
|
||||
state=operations.PostUsersSignInDataState.ENDED,
|
||||
billing=operations.Billing(
|
||||
internal_payment_method=operations.InternalPaymentMethod(),
|
||||
payment_method_id=481656,
|
||||
),
|
||||
),
|
||||
],
|
||||
trials=[
|
||||
operations.Trials(),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_authentication_post_users_sign_in_data_():
|
||||
s = PlexAPI()
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.authentication.post_users_sign_in_data(
|
||||
request={
|
||||
"request_body": {
|
||||
"login": "username@email.com",
|
||||
"password": "password123",
|
||||
"verification_code": "123456",
|
||||
},
|
||||
}
|
||||
)
|
||||
assert res.status_code == 201
|
||||
assert res.user_plex_account is not None
|
||||
assert res.user_plex_account == operations.PostUsersSignInDataUserPlexAccount(
|
||||
ads_consent=True,
|
||||
ads_consent_reminder_at=dateutil.parser.isoparse("2019-08-24T14:15:22Z"),
|
||||
ads_consent_set_at=dateutil.parser.isoparse("2019-08-24T14:15:22Z"),
|
||||
anonymous=False,
|
||||
auth_token="CxoUzBTSV5hsxjTpFKaf",
|
||||
backup_codes_created=False,
|
||||
confirmed=False,
|
||||
country="US",
|
||||
email="username@email.com",
|
||||
email_only_auth=False,
|
||||
experimental_features=False,
|
||||
friendly_name="friendlyUsername",
|
||||
entitlements=[
|
||||
"[]",
|
||||
],
|
||||
guest=False,
|
||||
has_password=True,
|
||||
home=False,
|
||||
home_admin=False,
|
||||
home_size=1,
|
||||
id=13692262,
|
||||
joined_at=1721154902,
|
||||
locale=None,
|
||||
mailing_list_active=False,
|
||||
mailing_list_status=operations.PostUsersSignInDataMailingListStatus.UNSUBSCRIBED,
|
||||
max_home_size=15,
|
||||
pin="string",
|
||||
profile=operations.PostUsersSignInDataUserProfile(
|
||||
auto_select_audio=True,
|
||||
default_audio_language="ja",
|
||||
default_subtitle_language="en",
|
||||
auto_select_subtitle=operations.PostUsersSignInDataAutoSelectSubtitle.ENABLE,
|
||||
default_subtitle_accessibility=operations.PostUsersSignInDataDefaultSubtitleAccessibility.ENABLE,
|
||||
default_subtitle_forced=operations.PostUsersSignInDataDefaultSubtitleForced.ENABLE,
|
||||
watched_indicator=operations.PostUsersSignInDataWatchedIndicator.ENABLE,
|
||||
media_reviews_visibility=operations.PostUsersSignInDataMediaReviewsVisibility.ENABLE,
|
||||
),
|
||||
protected=False,
|
||||
remember_expires_at=1722364046,
|
||||
restricted=False,
|
||||
roles=[
|
||||
"string",
|
||||
],
|
||||
scrobble_types="",
|
||||
services=[
|
||||
operations.PostUsersSignInDataServices(
|
||||
identifier="metadata-dev",
|
||||
endpoint="https://epg.provider.plex.tv",
|
||||
token="DjoMtqFAGRL1uVtCyF1dKIorTbShJeqv",
|
||||
secret="string",
|
||||
status=operations.PostUsersSignInDataStatus.ONLINE,
|
||||
),
|
||||
],
|
||||
subscription=operations.PostUsersSignInDataSubscription(
|
||||
features=[
|
||||
operations.PostUsersSignInDataFeatures.ANDROID_DOLBY_VISION,
|
||||
],
|
||||
active=True,
|
||||
subscribed_at="2021-04-12T18:21:12Z",
|
||||
status=operations.PostUsersSignInDataAuthenticationStatus.INACTIVE,
|
||||
payment_service="string",
|
||||
plan="string",
|
||||
),
|
||||
subscription_description="string",
|
||||
subscriptions=[
|
||||
operations.PostUsersSignInDataAuthenticationSubscription(
|
||||
features=[
|
||||
operations.PostUsersSignInDataAuthenticationFeatures.ANDROID_DOLBY_VISION,
|
||||
],
|
||||
active=True,
|
||||
subscribed_at="2021-04-12T18:21:12Z",
|
||||
status=operations.PostUsersSignInDataAuthenticationResponseStatus.INACTIVE,
|
||||
payment_service="string",
|
||||
plan="string",
|
||||
),
|
||||
],
|
||||
thumb="https://plex.tv/users/a4f43c1ebfde43a5/avatar?c=8372075101",
|
||||
title="UsernameTitle",
|
||||
two_factor_enabled=False,
|
||||
username="Username",
|
||||
uuid="dae343c1f45beb4f",
|
||||
attribution_partner=None,
|
||||
past_subscriptions=[
|
||||
operations.PastSubscription(
|
||||
id="string",
|
||||
mode="string",
|
||||
renews_at=string,
|
||||
ends_at=1556281940,
|
||||
canceled=True,
|
||||
grace_period=True,
|
||||
on_hold=True,
|
||||
can_reactivate=True,
|
||||
can_upgrade=True,
|
||||
can_downgrade=True,
|
||||
can_convert=True,
|
||||
type="plexpass",
|
||||
transfer="string",
|
||||
state=operations.PostUsersSignInDataState.ENDED,
|
||||
billing=operations.Billing(
|
||||
internal_payment_method=operations.InternalPaymentMethod(),
|
||||
payment_method_id=481656,
|
||||
),
|
||||
),
|
||||
],
|
||||
trials=[
|
||||
operations.Trials(),
|
||||
],
|
||||
)
|
||||
72
tests/test_butler.py
Normal file
72
tests/test_butler.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_butler_get_butler_tasks():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.butler.get_butler_tasks()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetButlerTasksResponseBody(
|
||||
butler_tasks=operations.ButlerTasks(
|
||||
butler_task=[
|
||||
operations.ButlerTask(
|
||||
name="BackupDatabase",
|
||||
interval=3,
|
||||
title="Backup Database",
|
||||
description="Create a backup copy of the server's database in the configured backup directory",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_butler_start_all_tasks():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.butler.start_all_tasks()
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_butler_stop_all_tasks():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.butler.stop_all_tasks()
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_butler_start_task():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.butler.start_task(task_name=operations.TaskName.CLEAN_OLD_BUNDLES)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_butler_stop_task():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.butler.stop_task(task_name=operations.PathParamTaskName.BACKUP_DATABASE)
|
||||
assert res.status_code == 200
|
||||
760
tests/test_hubs.py
Normal file
760
tests/test_hubs.py
Normal file
@@ -0,0 +1,760 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
import dateutil.parser
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_hubs_get_global_hubs():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.hubs.get_global_hubs()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetGlobalHubsResponseBody(
|
||||
media_container=operations.GetGlobalHubsMediaContainer(
|
||||
size=8,
|
||||
allow_sync=True,
|
||||
identifier="com.plexapp.plugins.library",
|
||||
hub=[
|
||||
operations.Hub(
|
||||
hub_key="/library/metadata/50768,65523,58188,57341,57302,57070",
|
||||
key="/playlists/all?type=15&sort=lastViewedAt:desc&playlistType=video,audio",
|
||||
title="Recent Playlists",
|
||||
type="playlist",
|
||||
hub_identifier="home.playlists",
|
||||
context="hub.home.playlists",
|
||||
size=6,
|
||||
more=True,
|
||||
style="shelf",
|
||||
promoted=True,
|
||||
metadata=[
|
||||
operations.GetGlobalHubsMetadata(
|
||||
rating_key="57070",
|
||||
key="/playlists/57070/items",
|
||||
guid="com.plexapp.agents.none://9fee6c5b-3143-4923-813e-57bd0190056c",
|
||||
type="playlist",
|
||||
title="November Movie Day",
|
||||
title_sort="Tracks",
|
||||
summary="",
|
||||
smart=False,
|
||||
playlist_type="video",
|
||||
composite="/playlists/57070/composite/1668787730",
|
||||
icon="playlist://image.smart",
|
||||
view_count=2,
|
||||
last_viewed_at=1668787732,
|
||||
duration=16873000,
|
||||
leaf_count=3,
|
||||
added_at=1668779618,
|
||||
updated_at=1668787730,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_hubs_get_recently_added():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.hubs.get_recently_added(
|
||||
request={
|
||||
"content_directory_id": 470161,
|
||||
"section_id": 2,
|
||||
"type": operations.Type.TV_SHOW,
|
||||
"include_meta": operations.IncludeMeta.ENABLE,
|
||||
"x_plex_container_start": 0,
|
||||
"x_plex_container_size": 50,
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetRecentlyAddedResponseBody(
|
||||
media_container=operations.GetRecentlyAddedMediaContainer(
|
||||
size=50,
|
||||
identifier="com.plexapp.plugins.library",
|
||||
meta=operations.Meta(
|
||||
type=[
|
||||
operations.GetRecentlyAddedType(
|
||||
key="/library/sections/2/all?type=2",
|
||||
type="show",
|
||||
title="TV Shows",
|
||||
active=False,
|
||||
filter_=[
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
],
|
||||
sort=[
|
||||
operations.GetRecentlyAddedSort(
|
||||
default="asc",
|
||||
active=False,
|
||||
active_direction=operations.GetRecentlyAddedActiveDirection.ASCENDING,
|
||||
default_direction=operations.GetRecentlyAddedDefaultDirection.ASCENDING,
|
||||
desc_key="titleSort:desc",
|
||||
first_character_key="/library/sections/2/firstCharacter",
|
||||
key="titleSort",
|
||||
title="Title",
|
||||
),
|
||||
],
|
||||
field=[
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
],
|
||||
),
|
||||
operations.GetRecentlyAddedType(
|
||||
key="/library/sections/2/all?type=2",
|
||||
type="show",
|
||||
title="TV Shows",
|
||||
active=False,
|
||||
filter_=[
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
],
|
||||
sort=[
|
||||
operations.GetRecentlyAddedSort(
|
||||
default="asc",
|
||||
active=False,
|
||||
active_direction=operations.GetRecentlyAddedActiveDirection.ASCENDING,
|
||||
default_direction=operations.GetRecentlyAddedDefaultDirection.ASCENDING,
|
||||
desc_key="titleSort:desc",
|
||||
first_character_key="/library/sections/2/firstCharacter",
|
||||
key="titleSort",
|
||||
title="Title",
|
||||
),
|
||||
operations.GetRecentlyAddedSort(
|
||||
default="asc",
|
||||
active=False,
|
||||
active_direction=operations.GetRecentlyAddedActiveDirection.ASCENDING,
|
||||
default_direction=operations.GetRecentlyAddedDefaultDirection.ASCENDING,
|
||||
desc_key="titleSort:desc",
|
||||
first_character_key="/library/sections/2/firstCharacter",
|
||||
key="titleSort",
|
||||
title="Title",
|
||||
),
|
||||
operations.GetRecentlyAddedSort(
|
||||
default="asc",
|
||||
active=False,
|
||||
active_direction=operations.GetRecentlyAddedActiveDirection.ASCENDING,
|
||||
default_direction=operations.GetRecentlyAddedDefaultDirection.ASCENDING,
|
||||
desc_key="titleSort:desc",
|
||||
first_character_key="/library/sections/2/firstCharacter",
|
||||
key="titleSort",
|
||||
title="Title",
|
||||
),
|
||||
],
|
||||
field=[
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
],
|
||||
),
|
||||
operations.GetRecentlyAddedType(
|
||||
key="/library/sections/2/all?type=2",
|
||||
type="show",
|
||||
title="TV Shows",
|
||||
active=False,
|
||||
filter_=[
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
operations.GetRecentlyAddedFilter(
|
||||
filter_="genre",
|
||||
filter_type="string",
|
||||
key="/library/sections/2/genre?type=2",
|
||||
title="Genre",
|
||||
type="filter",
|
||||
),
|
||||
],
|
||||
sort=[
|
||||
operations.GetRecentlyAddedSort(
|
||||
default="asc",
|
||||
active=False,
|
||||
active_direction=operations.GetRecentlyAddedActiveDirection.ASCENDING,
|
||||
default_direction=operations.GetRecentlyAddedDefaultDirection.ASCENDING,
|
||||
desc_key="titleSort:desc",
|
||||
first_character_key="/library/sections/2/firstCharacter",
|
||||
key="titleSort",
|
||||
title="Title",
|
||||
),
|
||||
operations.GetRecentlyAddedSort(
|
||||
default="asc",
|
||||
active=False,
|
||||
active_direction=operations.GetRecentlyAddedActiveDirection.ASCENDING,
|
||||
default_direction=operations.GetRecentlyAddedDefaultDirection.ASCENDING,
|
||||
desc_key="titleSort:desc",
|
||||
first_character_key="/library/sections/2/firstCharacter",
|
||||
key="titleSort",
|
||||
title="Title",
|
||||
),
|
||||
],
|
||||
field=[
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
operations.GetRecentlyAddedField(
|
||||
key="show.title",
|
||||
title="Show Title",
|
||||
type="string",
|
||||
sub_type="rating",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
field_type=[
|
||||
operations.GetRecentlyAddedFieldType(
|
||||
type="tag",
|
||||
operator=[
|
||||
operations.GetRecentlyAddedOperator(
|
||||
key="=",
|
||||
title="is",
|
||||
),
|
||||
],
|
||||
),
|
||||
operations.GetRecentlyAddedFieldType(
|
||||
type="tag",
|
||||
operator=[
|
||||
operations.GetRecentlyAddedOperator(
|
||||
key="=",
|
||||
title="is",
|
||||
),
|
||||
],
|
||||
),
|
||||
operations.GetRecentlyAddedFieldType(
|
||||
type="tag",
|
||||
operator=[
|
||||
operations.GetRecentlyAddedOperator(
|
||||
key="=",
|
||||
title="is",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
metadata=[
|
||||
operations.GetRecentlyAddedMetadata(
|
||||
rating_key="58683",
|
||||
key="/library/metadata/58683",
|
||||
guid="plex://movie/5d7768ba96b655001fdc0408",
|
||||
studio="20th Century Studios",
|
||||
skip_children=False,
|
||||
library_section_id=1,
|
||||
library_section_title="Movies",
|
||||
library_section_key="/library/sections/1",
|
||||
type=operations.GetRecentlyAddedHubsType.MOVIE,
|
||||
title="Avatar: The Way of Water",
|
||||
slug="4-for-texas",
|
||||
content_rating="PG-13",
|
||||
summary="Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.",
|
||||
rating=7.6,
|
||||
audience_rating=9.2,
|
||||
year=2022,
|
||||
season_count=2022,
|
||||
tagline="Return to Pandora.",
|
||||
flatten_seasons=operations.FlattenSeasons.TRUE,
|
||||
show_ordering=operations.ShowOrdering.DVD,
|
||||
thumb="/library/metadata/58683/thumb/1703239236",
|
||||
art="/library/metadata/58683/art/1703239236",
|
||||
banner="/library/metadata/58683/banner/1703239236",
|
||||
duration=11558112,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2022-12-14T00:00:00Z"
|
||||
).date(),
|
||||
added_at=1556281940,
|
||||
updated_at=1556281940,
|
||||
audience_rating_image="rottentomatoes://image.rating.upright",
|
||||
chapter_source="media",
|
||||
primary_extra_key="/library/metadata/58684",
|
||||
rating_image="rottentomatoes://image.rating.ripe",
|
||||
grandparent_rating_key="66",
|
||||
grandparent_guid="plex://show/5d9c081b170e24001f2a7be4",
|
||||
grandparent_key="/library/metadata/66",
|
||||
grandparent_title="Caprica",
|
||||
grandparent_thumb="/library/metadata/66/thumb/1705716261",
|
||||
parent_slug="alice-in-borderland-2020",
|
||||
grandparent_slug="alice-in-borderland-2020",
|
||||
grandparent_art="/library/metadata/66/art/1705716261",
|
||||
grandparent_theme="/library/metadata/66/theme/1705716261",
|
||||
media=[
|
||||
operations.Media(
|
||||
id=119534,
|
||||
duration=11558112,
|
||||
bitrate=25025,
|
||||
width=3840,
|
||||
height=2072,
|
||||
aspect_ratio=1.85,
|
||||
audio_profile="dts",
|
||||
audio_channels=6,
|
||||
audio_codec="eac3",
|
||||
video_codec="hevc",
|
||||
video_resolution="4k",
|
||||
container="mkv",
|
||||
video_frame_rate="24p",
|
||||
video_profile="main 10",
|
||||
has_voice_activity=False,
|
||||
optimized_for_streaming=operations.OptimizedForStreaming.ENABLE,
|
||||
has64bit_offsets=False,
|
||||
part=[
|
||||
operations.Part(
|
||||
id=119542,
|
||||
key="/library/parts/119542/1680457526/file.mkv",
|
||||
duration=11558112,
|
||||
file="/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv",
|
||||
size=36158371307,
|
||||
container="mkv",
|
||||
audio_profile="dts",
|
||||
has64bit_offsets=False,
|
||||
optimized_for_streaming=False,
|
||||
video_profile="main 10",
|
||||
indexes="sd",
|
||||
has_thumbnail=operations.HasThumbnail.TRUE,
|
||||
stream=[
|
||||
operations.Stream(
|
||||
id=272796,
|
||||
stream_type=1,
|
||||
default=True,
|
||||
selected=True,
|
||||
codec="h264",
|
||||
index=0,
|
||||
bitrate=6273,
|
||||
color_primaries="bt709",
|
||||
color_range="tv",
|
||||
color_space="bt709",
|
||||
color_trc="bt709",
|
||||
bit_depth=8,
|
||||
chroma_location="left",
|
||||
stream_identifier="2",
|
||||
chroma_subsampling="4:2:0",
|
||||
coded_height=1088,
|
||||
coded_width=1920,
|
||||
frame_rate=29.97,
|
||||
has_scaling_matrix=False,
|
||||
hearing_impaired=False,
|
||||
closed_captions=False,
|
||||
embedded_in_video="1",
|
||||
height=1080,
|
||||
level=40,
|
||||
profile="main",
|
||||
ref_frames=4,
|
||||
scan_type="progressive",
|
||||
width=1920,
|
||||
display_title="1080p (H.264)",
|
||||
extended_display_title="1080p (H.264)",
|
||||
channels=2,
|
||||
language="English",
|
||||
language_tag="en",
|
||||
language_code="eng",
|
||||
audio_channel_layout="stereo",
|
||||
sampling_rate=48000,
|
||||
title="English",
|
||||
can_auto_sync=False,
|
||||
),
|
||||
],
|
||||
),
|
||||
operations.Part(
|
||||
id=119542,
|
||||
key="/library/parts/119542/1680457526/file.mkv",
|
||||
duration=11558112,
|
||||
file="/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv",
|
||||
size=36158371307,
|
||||
container="mkv",
|
||||
audio_profile="dts",
|
||||
has64bit_offsets=False,
|
||||
optimized_for_streaming=False,
|
||||
video_profile="main 10",
|
||||
indexes="sd",
|
||||
has_thumbnail=operations.HasThumbnail.TRUE,
|
||||
stream=[
|
||||
operations.Stream(
|
||||
id=272796,
|
||||
stream_type=1,
|
||||
default=True,
|
||||
selected=True,
|
||||
codec="h264",
|
||||
index=0,
|
||||
bitrate=6273,
|
||||
color_primaries="bt709",
|
||||
color_range="tv",
|
||||
color_space="bt709",
|
||||
color_trc="bt709",
|
||||
bit_depth=8,
|
||||
chroma_location="left",
|
||||
stream_identifier="2",
|
||||
chroma_subsampling="4:2:0",
|
||||
coded_height=1088,
|
||||
coded_width=1920,
|
||||
frame_rate=29.97,
|
||||
has_scaling_matrix=False,
|
||||
hearing_impaired=False,
|
||||
closed_captions=False,
|
||||
embedded_in_video="1",
|
||||
height=1080,
|
||||
level=40,
|
||||
profile="main",
|
||||
ref_frames=4,
|
||||
scan_type="progressive",
|
||||
width=1920,
|
||||
display_title="1080p (H.264)",
|
||||
extended_display_title="1080p (H.264)",
|
||||
channels=2,
|
||||
language="English",
|
||||
language_tag="en",
|
||||
language_code="eng",
|
||||
audio_channel_layout="stereo",
|
||||
sampling_rate=48000,
|
||||
title="English",
|
||||
can_auto_sync=False,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
genre=[
|
||||
operations.Genre(
|
||||
tag="Adventure",
|
||||
),
|
||||
],
|
||||
country=[
|
||||
operations.Country(
|
||||
tag="United States of America",
|
||||
),
|
||||
],
|
||||
director=[
|
||||
operations.Director(
|
||||
tag="James Cameron",
|
||||
),
|
||||
operations.Director(
|
||||
tag="James Cameron",
|
||||
),
|
||||
],
|
||||
writer=[
|
||||
operations.Writer(
|
||||
tag="James Cameron",
|
||||
),
|
||||
],
|
||||
collection=[
|
||||
operations.Collection(
|
||||
tag="Working NL Subs",
|
||||
),
|
||||
],
|
||||
role=[
|
||||
operations.Role(
|
||||
id=294129,
|
||||
filter_="actor=294129",
|
||||
thumb="https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg",
|
||||
tag="Mike Smith",
|
||||
tag_key="668e7e7b22bcad9064350c91",
|
||||
role="Self",
|
||||
),
|
||||
operations.Role(
|
||||
id=294129,
|
||||
filter_="actor=294129",
|
||||
thumb="https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg",
|
||||
tag="Mike Smith",
|
||||
tag_key="668e7e7b22bcad9064350c91",
|
||||
role="Self",
|
||||
),
|
||||
operations.Role(
|
||||
id=294129,
|
||||
filter_="actor=294129",
|
||||
thumb="https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg",
|
||||
tag="Mike Smith",
|
||||
tag_key="668e7e7b22bcad9064350c91",
|
||||
role="Self",
|
||||
),
|
||||
],
|
||||
media_guid=[
|
||||
operations.MediaGUID(
|
||||
id="imdb://tt13015952",
|
||||
),
|
||||
operations.MediaGUID(
|
||||
id="imdb://tt13015952",
|
||||
),
|
||||
operations.MediaGUID(
|
||||
id="imdb://tt13015952",
|
||||
),
|
||||
],
|
||||
ultra_blur_colors=operations.UltraBlurColors(
|
||||
top_left="11333b",
|
||||
top_right="0a232d",
|
||||
bottom_right="73958",
|
||||
bottom_left="1f5066",
|
||||
),
|
||||
meta_data_rating=[
|
||||
operations.MetaDataRating(
|
||||
image="themoviedb://image.rating",
|
||||
value=3,
|
||||
type="audience",
|
||||
),
|
||||
],
|
||||
image=[
|
||||
operations.GetRecentlyAddedImage(
|
||||
alt="Episode 1",
|
||||
type=operations.GetRecentlyAddedHubsResponseType.BACKGROUND,
|
||||
url="/library/metadata/45521/thumb/1644710589",
|
||||
),
|
||||
operations.GetRecentlyAddedImage(
|
||||
alt="Episode 1",
|
||||
type=operations.GetRecentlyAddedHubsResponseType.BACKGROUND,
|
||||
url="/library/metadata/45521/thumb/1644710589",
|
||||
),
|
||||
operations.GetRecentlyAddedImage(
|
||||
alt="Episode 1",
|
||||
type=operations.GetRecentlyAddedHubsResponseType.BACKGROUND,
|
||||
url="/library/metadata/45521/thumb/1644710589",
|
||||
),
|
||||
],
|
||||
title_sort="Whale",
|
||||
view_count=1,
|
||||
last_viewed_at=1682752242,
|
||||
original_title="映画 ブラッククローバー 魔法帝の剣",
|
||||
view_offset=5222500,
|
||||
skip_count=1,
|
||||
index=1,
|
||||
theme="/library/metadata/1/theme/1705636920",
|
||||
leaf_count=14,
|
||||
viewed_leaf_count=0,
|
||||
child_count=1,
|
||||
has_premium_extras="1",
|
||||
has_premium_primary_extra="1",
|
||||
parent_rating_key="66",
|
||||
parent_guid="plex://show/5d9c081b170e24001f2a7be4",
|
||||
parent_studio="UCP",
|
||||
parent_key="/library/metadata/66",
|
||||
parent_title="Caprica",
|
||||
parent_index=1,
|
||||
parent_year=2010,
|
||||
parent_thumb="/library/metadata/66/thumb/1705716261",
|
||||
parent_theme="/library/metadata/66/theme/1705716261",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_hubs_get_library_hubs():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.hubs.get_library_hubs(section_id=6728.76)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetLibraryHubsResponseBody(
|
||||
media_container=operations.GetLibraryHubsMediaContainer(
|
||||
size=7,
|
||||
allow_sync=True,
|
||||
identifier="com.plexapp.plugins.library",
|
||||
library_section_id=1,
|
||||
library_section_title="Movies",
|
||||
library_section_uuid="322a231a-b7f7-49f5-920f-14c61199cd30",
|
||||
hub=[
|
||||
operations.GetLibraryHubsHub(
|
||||
key="/library/sections/1/all?sort=lastViewedAt:desc&unwatched=0&viewOffset=0",
|
||||
title="Recently Played Movies",
|
||||
type="movie",
|
||||
hub_identifier="movie.recentlyviewed.1",
|
||||
context="hub.movie.recentlyviewed",
|
||||
size=6,
|
||||
more=True,
|
||||
style="shelf",
|
||||
hub_key="/library/metadata/66485,66098,57249,11449,5858,14944",
|
||||
metadata=[
|
||||
operations.GetLibraryHubsMetadata(
|
||||
rating_key="14944",
|
||||
key="/library/metadata/14944",
|
||||
guid="plex://movie/5d77686eeb5d26001f1eb339",
|
||||
studio="Walt Disney Animation Studios",
|
||||
type="movie",
|
||||
title="Tangled",
|
||||
library_section_title="Movies",
|
||||
library_section_id=1,
|
||||
library_section_key="/library/sections/1",
|
||||
content_rating="PG",
|
||||
summary="The magically long-haired Rapunzel has spent her entire life in a tower, but now that a runaway thief has stumbled upon her, she is about to discover the world for the first time, and who she really is.",
|
||||
rating=8.9,
|
||||
audience_rating=8.7,
|
||||
view_count=1,
|
||||
last_viewed_at=1704936047,
|
||||
year=2010,
|
||||
tagline="They're taking adventure to new lengths.",
|
||||
thumb="/library/metadata/14944/thumb/1705739847",
|
||||
art="/library/metadata/14944/art/1705739847",
|
||||
duration=6017237,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2010-11-24T00:00:00Z"
|
||||
).date(),
|
||||
added_at=1589412494,
|
||||
updated_at=1705739847,
|
||||
audience_rating_image="rottentomatoes://image.rating.upright",
|
||||
primary_extra_key="/library/metadata/14952",
|
||||
rating_image="rottentomatoes://image.rating.ripe",
|
||||
media=[
|
||||
operations.GetLibraryHubsMedia(
|
||||
id=38247,
|
||||
duration=6017237,
|
||||
bitrate=2051,
|
||||
width=1920,
|
||||
height=1080,
|
||||
aspect_ratio=1.78,
|
||||
audio_channels=2,
|
||||
audio_codec="aac",
|
||||
video_codec="h264",
|
||||
video_resolution="1080",
|
||||
container="mp4",
|
||||
video_frame_rate="24p",
|
||||
optimized_for_streaming=1,
|
||||
audio_profile="lc",
|
||||
has64bit_offsets=False,
|
||||
video_profile="high",
|
||||
part=[
|
||||
operations.GetLibraryHubsPart(
|
||||
id=38247,
|
||||
key="/library/parts/38247/1589412494/file.mp4",
|
||||
duration=6017237,
|
||||
file="/movies/Tangled (2010)/Tangled (2010) Bluray-1080p.mp4",
|
||||
size=1545647447,
|
||||
audio_profile="lc",
|
||||
container="mp4",
|
||||
has64bit_offsets=False,
|
||||
optimized_for_streaming=True,
|
||||
video_profile="high",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
genre=[
|
||||
operations.GetLibraryHubsGenre(
|
||||
tag="Animation",
|
||||
),
|
||||
],
|
||||
country=[
|
||||
operations.GetLibraryHubsCountry(
|
||||
tag="United States of America",
|
||||
),
|
||||
],
|
||||
director=[
|
||||
operations.GetLibraryHubsDirector(
|
||||
tag="Nathan Greno",
|
||||
),
|
||||
],
|
||||
role=[
|
||||
operations.GetLibraryHubsRole(
|
||||
tag="Donna Murphy",
|
||||
),
|
||||
],
|
||||
writer=[
|
||||
operations.GetLibraryHubsWriter(
|
||||
tag="Wilhelm Grimm",
|
||||
),
|
||||
],
|
||||
skip_count=1,
|
||||
chapter_source="media",
|
||||
),
|
||||
],
|
||||
promoted=True,
|
||||
random=True,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
2427
tests/test_library.py
Normal file
2427
tests/test_library.py
Normal file
File diff suppressed because it is too large
Load Diff
43
tests/test_log.py
Normal file
43
tests/test_log.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_log_log_line():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.log.log_line(
|
||||
level=operations.Level.THREE, message="Test log message", source="Postman"
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_log_log_multi_line():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.log.log_multi_line(
|
||||
request="level=4&message=Test%20message%201&source=postman\n"
|
||||
+ "level=3&message=Test%20message%202&source=postman\n"
|
||||
+ "level=1&message=Test%20message%203&source=postman"
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_log_enable_paper_trail():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.log.enable_paper_trail()
|
||||
assert res.status_code == 200
|
||||
76
tests/test_media.py
Normal file
76
tests/test_media.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
|
||||
|
||||
def test_media_mark_played():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.media.mark_played(key=59398)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_media_mark_unplayed():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.media.mark_unplayed(key=59398)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_media_update_play_progress_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.media.update_play_progress(key="<key>", time=90000, state="played")
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_media_get_banner_image():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.media.get_banner_image(
|
||||
request={
|
||||
"rating_key": 9518,
|
||||
"width": 396,
|
||||
"height": 396,
|
||||
"min_size": 1,
|
||||
"upscale": 1,
|
||||
"x_plex_token": "CV5xoxjTpFKUzBTShsaf",
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_media_get_thumb_image():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.media.get_thumb_image(
|
||||
request={
|
||||
"rating_key": 9518,
|
||||
"width": 396,
|
||||
"height": 396,
|
||||
"min_size": 1,
|
||||
"upscale": 1,
|
||||
"x_plex_token": "CV5xoxjTpFKUzBTShsaf",
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
327
tests/test_playlists.py
Normal file
327
tests/test_playlists.py
Normal file
@@ -0,0 +1,327 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
import dateutil.parser
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_playlists_create_playlist():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.create_playlist(
|
||||
request={
|
||||
"title": "<value>",
|
||||
"type": operations.CreatePlaylistQueryParamType.PHOTO,
|
||||
"smart": operations.Smart.ONE,
|
||||
"uri": "https://inborn-brochure.biz",
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.CreatePlaylistResponseBody(
|
||||
media_container=operations.CreatePlaylistMediaContainer(
|
||||
size=7,
|
||||
metadata=[
|
||||
operations.CreatePlaylistMetadata(
|
||||
rating_key="96",
|
||||
key="/playlists/96/items",
|
||||
guid="com.plexapp.agents.none://a2f92937-1408-40e2-b022-63a8a9377e55",
|
||||
type="playlist",
|
||||
title="A Great Playlist",
|
||||
summary="What a great playlist",
|
||||
smart=False,
|
||||
playlist_type="video",
|
||||
icon="playlist://image.smart",
|
||||
view_count=1,
|
||||
last_viewed_at=1705719589,
|
||||
leaf_count=1,
|
||||
added_at=1705719589,
|
||||
updated_at=1705724593,
|
||||
composite="/playlists/96/composite/1705724593",
|
||||
duration=141000,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_playlists_get_playlists():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.get_playlists()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetPlaylistsResponseBody(
|
||||
media_container=operations.GetPlaylistsMediaContainer(
|
||||
size=4,
|
||||
metadata=[
|
||||
operations.GetPlaylistsMetadata(
|
||||
rating_key="92",
|
||||
key="/playlists/92/items",
|
||||
guid="com.plexapp.agents.none://7ca5aaef-58e8-4828-9e21-c009c97f2903",
|
||||
type="playlist",
|
||||
title="Static Playlist",
|
||||
summary="A Great Playlist",
|
||||
smart=False,
|
||||
playlist_type="video",
|
||||
composite="/playlists/92/composite/1705716440",
|
||||
icon="playlist://image.smart",
|
||||
view_count=1,
|
||||
last_viewed_at=1705716298,
|
||||
duration=7328000,
|
||||
leaf_count=32,
|
||||
added_at=1705716298,
|
||||
updated_at=1705716440,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_playlists_get_playlist():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.get_playlist(playlist_id=4109.48)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetPlaylistResponseBody(
|
||||
media_container=operations.GetPlaylistMediaContainer(
|
||||
size=1,
|
||||
metadata=[
|
||||
operations.GetPlaylistMetadata(
|
||||
content="library://x/directory/%2Flibrary%2Fsections%2F1%2Fall%3Ftype%3D1%26push%3D1%26title%3D2%26or%3D1%26title%3DSerenity%26pop%3D1",
|
||||
rating_key="95",
|
||||
key="/playlists/95/items",
|
||||
guid="com.plexapp.agents.none://87425529-380f-44b8-a689-9a0537e7ec91",
|
||||
type="playlist",
|
||||
title="Smart Movie Playlist",
|
||||
summary="",
|
||||
smart=True,
|
||||
playlist_type="video",
|
||||
composite="/playlists/95/composite/1705717387",
|
||||
icon="playlist://image.smart",
|
||||
duration=282000,
|
||||
leaf_count=2,
|
||||
added_at=1705716493,
|
||||
updated_at=1705717387,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_playlists_delete_playlist():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.delete_playlist(playlist_id=216.22)
|
||||
assert res.status_code == 204
|
||||
|
||||
|
||||
def test_playlists_update_playlist():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.update_playlist(playlist_id=3915)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_playlists_get_playlist_contents():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.get_playlist_contents(
|
||||
playlist_id=5004.46, type_=operations.GetPlaylistContentsQueryParamType.TV_SHOW
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetPlaylistContentsResponseBody(
|
||||
media_container=operations.GetPlaylistContentsMediaContainer(
|
||||
size=2,
|
||||
composite="/playlists/95/composite/1705717521",
|
||||
duration=282,
|
||||
leaf_count=2,
|
||||
playlist_type="video",
|
||||
rating_key="95",
|
||||
smart=True,
|
||||
title="Smart Movie Playlist",
|
||||
metadata=[
|
||||
operations.GetPlaylistContentsMetadata(
|
||||
rating_key="17",
|
||||
key="/library/metadata/17",
|
||||
guid="plex://movie/5d77683f6f4521001ea9dc53",
|
||||
studio="Universal Pictures",
|
||||
type="movie",
|
||||
title="Serenity",
|
||||
title_sort="Amazing Spider-Man 2",
|
||||
library_section_title="Movies",
|
||||
library_section_id=1,
|
||||
library_section_key="/library/sections/1",
|
||||
content_rating="PG-13",
|
||||
summary="Serenity continues the story of the TV series it was based upon (\"Firefly\"). River Tam had a secret - one in which she's not even aware - so dangerous, no one's safe, as an Alliance operative's sent to capture her, and all others are considered irrelevant to his job.",
|
||||
rating=8.2,
|
||||
audience_rating=9.1,
|
||||
year=2005,
|
||||
tagline="They aim to misbehave.",
|
||||
thumb="/library/metadata/17/thumb/1705637165",
|
||||
art="/library/metadata/17/art/1705637165",
|
||||
duration=141416,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2005-09-29T00:00:00Z"
|
||||
).date(),
|
||||
added_at=1705637164,
|
||||
updated_at=1705637165,
|
||||
audience_rating_image="rottentomatoes://image.rating.upright",
|
||||
has_premium_extras="1",
|
||||
has_premium_primary_extra="1",
|
||||
rating_image="rottentomatoes://image.rating.ripe",
|
||||
media=[
|
||||
operations.GetPlaylistContentsMedia(
|
||||
id=15,
|
||||
duration=141416,
|
||||
bitrate=2273,
|
||||
width=1920,
|
||||
height=814,
|
||||
aspect_ratio=2.35,
|
||||
audio_channels=2,
|
||||
audio_codec="aac",
|
||||
video_codec="h264",
|
||||
video_resolution="1080",
|
||||
container="mp4",
|
||||
video_frame_rate="24p",
|
||||
optimized_for_streaming=0,
|
||||
audio_profile="lc",
|
||||
has64bit_offsets=False,
|
||||
video_profile="high",
|
||||
part=[
|
||||
operations.GetPlaylistContentsPart(
|
||||
id=15,
|
||||
key="/library/parts/15/1705637151/file.mp4",
|
||||
duration=141416,
|
||||
file="/movies/Serenity (2005)/Serenity (2005).mp4",
|
||||
size=40271948,
|
||||
audio_profile="lc",
|
||||
container="mp4",
|
||||
has64bit_offsets=False,
|
||||
optimized_for_streaming=False,
|
||||
video_profile="high",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
genre=[
|
||||
operations.GetPlaylistContentsGenre(
|
||||
tag="Action",
|
||||
),
|
||||
],
|
||||
country=[
|
||||
operations.GetPlaylistContentsCountry(
|
||||
tag="United States of America",
|
||||
),
|
||||
],
|
||||
director=[
|
||||
operations.GetPlaylistContentsDirector(
|
||||
tag="Joss Whedon",
|
||||
),
|
||||
],
|
||||
writer=[
|
||||
operations.GetPlaylistContentsWriter(
|
||||
tag="Joss Whedon",
|
||||
),
|
||||
],
|
||||
role=[
|
||||
operations.GetPlaylistContentsRole(
|
||||
tag="Gina Torres",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_playlists_clear_playlist_contents():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.clear_playlist_contents(playlist_id=1893.18)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_playlists_add_playlist_contents():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.add_playlist_contents(
|
||||
playlist_id=8502.01,
|
||||
uri="server://12345/com.plexapp.plugins.library/library/metadata/1",
|
||||
play_queue_id=123,
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.AddPlaylistContentsResponseBody(
|
||||
media_container=operations.AddPlaylistContentsMediaContainer(
|
||||
size=1,
|
||||
leaf_count_added=1,
|
||||
leaf_count_requested=1,
|
||||
metadata=[
|
||||
operations.AddPlaylistContentsMetadata(
|
||||
rating_key="94",
|
||||
key="/playlists/94/items",
|
||||
guid="com.plexapp.agents.none://972e3047-83d6-4848-a000-261f0af26ba2",
|
||||
type="playlist",
|
||||
title="A great playlist",
|
||||
summary="One of my great playlists",
|
||||
smart=False,
|
||||
playlist_type="video",
|
||||
composite="/playlists/94/composite/1705800070",
|
||||
duration=423000,
|
||||
leaf_count=3,
|
||||
added_at=1705716458,
|
||||
updated_at=1705800070,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_playlists_upload_playlist():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.playlists.upload_playlist(
|
||||
path="/home/barkley/playlist.m3u",
|
||||
force=operations.QueryParamForce.ONE,
|
||||
section_id=1,
|
||||
)
|
||||
assert res.status_code == 200
|
||||
203
tests/test_plex.py
Normal file
203
tests/test_plex.py
Normal file
@@ -0,0 +1,203 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
import dateutil.parser
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_plex_get_companions_data():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.plex.get_companions_data()
|
||||
assert res.status_code == 200
|
||||
assert res.response_bodies is not None
|
||||
assert res.response_bodies == [
|
||||
operations.ResponseBody(
|
||||
identifier="tv.plex.sonos",
|
||||
base_url="https://sonos.plex.tv",
|
||||
title="Sonos",
|
||||
link_url="https://sonos.plex.tv/link",
|
||||
provides="client,player",
|
||||
token="<value>",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def test_plex_get_user_friends():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.plex.get_user_friends()
|
||||
assert res.status_code == 200
|
||||
assert res.friends is not None
|
||||
assert res.friends == [
|
||||
operations.Friend(
|
||||
email="username@email.com",
|
||||
friendly_name="exampleUser",
|
||||
home=True,
|
||||
id=0,
|
||||
restricted=False,
|
||||
shared_servers=[
|
||||
operations.SharedServers(),
|
||||
],
|
||||
shared_sources=[
|
||||
operations.SharedSources(),
|
||||
],
|
||||
status=operations.Status.ACCEPTED,
|
||||
thumb="https://plex.tv/users/7d1916e0d8f6e76b/avatar?c=1694481578",
|
||||
title="username123",
|
||||
username="username123",
|
||||
uuid="7d1916e0d8f6e76b",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def test_plex_get_geo_data():
|
||||
s = PlexAPI()
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.plex.get_geo_data()
|
||||
assert res.status_code == 200
|
||||
assert res.geo_data is not None
|
||||
assert res.geo_data == operations.GetGeoDataGeoData(
|
||||
code="VI",
|
||||
continent_code="NA",
|
||||
country="United States Virgin Islands",
|
||||
city="Amsterdam",
|
||||
european_union_member=True,
|
||||
time_zone="America/St_Thomas",
|
||||
postal_code="802",
|
||||
in_privacy_restricted_country=True,
|
||||
in_privacy_restricted_region=True,
|
||||
subdivisions="Saint Thomas",
|
||||
coordinates="18.3381, -64.8941",
|
||||
)
|
||||
|
||||
|
||||
def test_plex_get_home_data():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.plex.get_home_data()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetHomeDataResponseBody(
|
||||
id=1841489,
|
||||
name="Blindkitty38's home",
|
||||
guest_user_id=58815432,
|
||||
guest_user_uuid="f3df4e01bfca0787",
|
||||
)
|
||||
|
||||
|
||||
def test_plex_get_server_resources():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.plex.get_server_resources(
|
||||
include_https=operations.IncludeHTTPS.ENABLE,
|
||||
include_relay=operations.IncludeRelay.ENABLE,
|
||||
include_i_pv6=operations.IncludeIPv6.ENABLE,
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.plex_devices is not None
|
||||
assert res.plex_devices == [
|
||||
operations.PlexDevice(
|
||||
name="<value>",
|
||||
product="Recycled Plastic Mouse",
|
||||
product_version="<value>",
|
||||
platform="<value>",
|
||||
platform_version="<value>",
|
||||
device="Desktop",
|
||||
client_identifier="<value>",
|
||||
created_at=dateutil.parser.isoparse("2019-06-24T11:38:02Z"),
|
||||
last_seen_at=dateutil.parser.isoparse("2019-06-24T11:38:02Z"),
|
||||
provides="<value>",
|
||||
owner_id=645894,
|
||||
source_title="<value>",
|
||||
public_address="<value>",
|
||||
access_token="<value>",
|
||||
owned=False,
|
||||
home=False,
|
||||
synced=False,
|
||||
relay=False,
|
||||
presence=False,
|
||||
https_required=False,
|
||||
public_address_matches=False,
|
||||
dns_rebinding_protection=False,
|
||||
nat_loopback_supported=False,
|
||||
connections=[
|
||||
operations.Connections(
|
||||
protocol=operations.Protocol.HTTP,
|
||||
address="9937 Mante Via",
|
||||
port=4655,
|
||||
uri="https://ajar-sonnet.net/",
|
||||
local=False,
|
||||
relay=False,
|
||||
i_pv6=False,
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def test_plex_get_pin_():
|
||||
s = PlexAPI()
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.plex.get_pin(request={})
|
||||
assert res.status_code == 201
|
||||
assert res.auth_pin_container is not None
|
||||
assert res.auth_pin_container == operations.GetPinAuthPinContainer(
|
||||
id=308667304,
|
||||
code="7RQZ",
|
||||
product="0",
|
||||
trusted=False,
|
||||
qr="https://plex.tv/api/v2/pins/qr/7RQZ",
|
||||
client_identifier="string",
|
||||
location=operations.GeoData(
|
||||
code="VI",
|
||||
continent_code="NA",
|
||||
country="United States Virgin Islands",
|
||||
city="Amsterdam",
|
||||
european_union_member=True,
|
||||
time_zone="America/St_Thomas",
|
||||
postal_code="802",
|
||||
in_privacy_restricted_country=True,
|
||||
in_privacy_restricted_region=True,
|
||||
subdivisions="Saint Thomas",
|
||||
coordinates="18.3381, -64.8941",
|
||||
),
|
||||
expires_in=876,
|
||||
created_at=dateutil.parser.isoparse("2024-07-16T17:03:05Z"),
|
||||
expires_at=dateutil.parser.isoparse("2024-07-16T17:18:05Z"),
|
||||
auth_token=None,
|
||||
new_registration=None,
|
||||
)
|
||||
|
||||
|
||||
def test_plex_get_token_by_pin_id_():
|
||||
s = PlexAPI()
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.plex.get_token_by_pin_id(
|
||||
request={
|
||||
"pin_id": 408895,
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
141
tests/test_search.py
Normal file
141
tests/test_search.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
import dateutil.parser
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_search_perform_search():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.search.perform_search(query="dylan", limit=5)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_search_perform_voice_search():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.search.perform_voice_search(query="dead+poop", limit=5)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_search_get_search_results():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.search.get_search_results(query="110")
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSearchResultsResponseBody(
|
||||
media_container=operations.GetSearchResultsMediaContainer(
|
||||
size=26,
|
||||
identifier="com.plexapp.plugins.library",
|
||||
media_tag_prefix="/system/bundle/media/flags/",
|
||||
media_tag_version=1680021154,
|
||||
metadata=[
|
||||
operations.GetSearchResultsMetadata(
|
||||
library_section_id=1,
|
||||
library_section_title="Movies",
|
||||
library_section_uuid="322a231a-b7f7-49f5-920f-14c61199cd30",
|
||||
source_title="Hera",
|
||||
rating_key=10398,
|
||||
key="/library/metadata/10398",
|
||||
guid="plex://movie/5d7768284de0ee001fcc8f52",
|
||||
studio="Paramount",
|
||||
type="movie",
|
||||
title="Mission: Impossible",
|
||||
content_rating="PG-13",
|
||||
summary="When Ethan Hunt the leader of a crack espionage team whose perilous operation has gone awry with no explanation discovers that a mole has penetrated the CIA he's surprised to learn that he's the No. 1 suspect. To clear his name Hunt now must ferret out the real double agent and in the process even the score.",
|
||||
rating=6.6,
|
||||
audience_rating=7.1,
|
||||
year=1996,
|
||||
tagline="Expect the impossible.",
|
||||
thumb="/library/metadata/10398/thumb/1679505055",
|
||||
art="/library/metadata/10398/art/1679505055",
|
||||
duration=6612628,
|
||||
originally_available_at=dateutil.parser.isoparse(
|
||||
"1996-05-22T00:00:00Z"
|
||||
),
|
||||
added_at=1589234571,
|
||||
updated_at=1679505055,
|
||||
audience_rating_image="rottentomatoes://image.rating.upright",
|
||||
chapter_source="media",
|
||||
primary_extra_key="/library/metadata/10501",
|
||||
rating_image="rottentomatoes://image.rating.ripe",
|
||||
media=[
|
||||
operations.GetSearchResultsMedia(
|
||||
id=26610,
|
||||
duration=6612628,
|
||||
bitrate=4751,
|
||||
width=1916,
|
||||
height=796,
|
||||
aspect_ratio=2.35,
|
||||
audio_channels=6,
|
||||
audio_codec="aac",
|
||||
video_codec="hevc",
|
||||
video_resolution=1080,
|
||||
container="mkv",
|
||||
video_frame_rate="24p",
|
||||
audio_profile="lc",
|
||||
video_profile="main 10",
|
||||
part=[
|
||||
operations.GetSearchResultsPart(
|
||||
id=26610,
|
||||
key="/library/parts/26610/1589234571/file.mkv",
|
||||
duration=6612628,
|
||||
file="/movies/Mission Impossible (1996)/Mission Impossible (1996) Bluray-1080p.mkv",
|
||||
size=3926903851,
|
||||
audio_profile="lc",
|
||||
container="mkv",
|
||||
video_profile="main 10",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
genre=[
|
||||
operations.GetSearchResultsGenre(
|
||||
tag="Action",
|
||||
),
|
||||
],
|
||||
director=[
|
||||
operations.GetSearchResultsDirector(
|
||||
tag="Brian De Palma",
|
||||
),
|
||||
],
|
||||
writer=[
|
||||
operations.GetSearchResultsWriter(
|
||||
tag="David Koepp",
|
||||
),
|
||||
],
|
||||
country=[
|
||||
operations.GetSearchResultsCountry(
|
||||
tag="United States of America",
|
||||
),
|
||||
],
|
||||
role=[
|
||||
operations.GetSearchResultsRole(
|
||||
tag="Tom Cruise",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
provider=[
|
||||
operations.Provider(
|
||||
key="/system/search",
|
||||
title="Local Network",
|
||||
type="mixed",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
261
tests/test_server.py
Normal file
261
tests/test_server.py
Normal file
@@ -0,0 +1,261 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_server_get_server_capabilities():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_server_capabilities()
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_server_get_server_preferences():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_server_preferences()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetServerPreferencesResponseBody(
|
||||
media_container=operations.GetServerPreferencesMediaContainer(
|
||||
size=161,
|
||||
setting=[
|
||||
operations.Setting(
|
||||
id="EnableDatabaseTrace",
|
||||
label="",
|
||||
summary="",
|
||||
type="bool",
|
||||
default=False,
|
||||
value=False,
|
||||
hidden=True,
|
||||
advanced=False,
|
||||
group="",
|
||||
enum_values="1:admin only|2:everyone",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_server_get_available_clients():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_available_clients()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetAvailableClientsResponseBody(
|
||||
media_container=operations.GetAvailableClientsMediaContainer(
|
||||
size=1,
|
||||
server=[
|
||||
operations.Server(
|
||||
name="iPad",
|
||||
host="10.10.10.102",
|
||||
address="10.10.10.102",
|
||||
port=32500,
|
||||
machine_identifier="A2E901F8-E016-43A7-ADFB-EF8CA8A4AC05",
|
||||
version="8.17",
|
||||
protocol="plex",
|
||||
product="Plex for iOS",
|
||||
device_class="tablet",
|
||||
protocol_version=2,
|
||||
protocol_capabilities="playback,playqueues,timeline,provider-playback",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_server_get_devices():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_devices()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetDevicesResponseBody(
|
||||
media_container=operations.GetDevicesMediaContainer(
|
||||
size=151,
|
||||
identifier="com.plexapp.system.devices",
|
||||
device=[
|
||||
operations.Device(
|
||||
id=1,
|
||||
name="iPhone",
|
||||
platform="iOS",
|
||||
created_at=1654131230,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_server_get_server_identity():
|
||||
s = PlexAPI()
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_server_identity()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetServerIdentityResponseBody(
|
||||
media_container=operations.GetServerIdentityMediaContainer(
|
||||
size=0,
|
||||
machine_identifier="96f2fe7a78c9dc1f16a16bedbe90f98149be16b4",
|
||||
version="1.31.3.6868-28fc46b27",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_server_get_my_plex_account():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_my_plex_account()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetMyPlexAccountResponseBody(
|
||||
my_plex=operations.MyPlex(
|
||||
auth_token="Z5v-PrNASDFpsaCi3CPK7",
|
||||
username="example.email@mail.com",
|
||||
mapping_state="mapped",
|
||||
sign_in_state="ok",
|
||||
public_address="140.20.68.140",
|
||||
public_port=32400,
|
||||
private_address="10.10.10.47",
|
||||
private_port=32400,
|
||||
subscription_features="federated-auth,hardware_transcoding,home,hwtranscode,item_clusters,kevin-bacon,livetv,loudness,lyrics,music-analysis,music_videos,pass,photo_autotags,photos-v5,photosV6-edit,photosV6-tv-albums,premium_music_metadata,radio,server-manager,session_bandwidth_restrictions,session_kick,shared-radio,sync,trailers,tuner-sharing,type-first,unsupportedtuners,webhooks",
|
||||
subscription_state="Active",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_server_get_resized_photo():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_resized_photo(
|
||||
request={
|
||||
"width": 110,
|
||||
"height": 165,
|
||||
"opacity": 100,
|
||||
"blur": 0,
|
||||
"min_size": operations.MinSize.ONE,
|
||||
"upscale": operations.Upscale.ONE,
|
||||
"url": "/library/metadata/49564/thumb/1654258204",
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_server_get_media_providers():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_media_providers(x_plex_token="CV5xoxjTpFKUzBTShsaf")
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetMediaProvidersResponseBody(
|
||||
media_container=operations.GetMediaProvidersMediaContainer(
|
||||
media_provider=[
|
||||
operations.MediaProvider(
|
||||
feature=[
|
||||
operations.Feature(
|
||||
type="<value>",
|
||||
flavor="global",
|
||||
scrobble_key="/:/scrobble/new",
|
||||
unscrobble_key="/:/unscrobble/new",
|
||||
action=[
|
||||
operations.Action(
|
||||
id="addToContinueWatching",
|
||||
key="/actions/addToContinueWatching",
|
||||
),
|
||||
],
|
||||
),
|
||||
operations.Feature(
|
||||
type="<value>",
|
||||
flavor="global",
|
||||
scrobble_key="/:/scrobble/new",
|
||||
unscrobble_key="/:/unscrobble/new",
|
||||
action=[
|
||||
operations.Action(
|
||||
id="addToContinueWatching",
|
||||
key="/actions/addToContinueWatching",
|
||||
),
|
||||
operations.Action(
|
||||
id="addToContinueWatching",
|
||||
key="/actions/addToContinueWatching",
|
||||
),
|
||||
],
|
||||
),
|
||||
operations.Feature(
|
||||
type="<value>",
|
||||
flavor="global",
|
||||
scrobble_key="/:/scrobble/new",
|
||||
unscrobble_key="/:/unscrobble/new",
|
||||
action=[
|
||||
operations.Action(
|
||||
id="addToContinueWatching",
|
||||
key="/actions/addToContinueWatching",
|
||||
),
|
||||
operations.Action(
|
||||
id="addToContinueWatching",
|
||||
key="/actions/addToContinueWatching",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_server_get_server_list():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.server.get_server_list()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetServerListResponseBody(
|
||||
media_container=operations.GetServerListMediaContainer(
|
||||
size=1,
|
||||
server=[
|
||||
operations.GetServerListServer(
|
||||
name="Hera",
|
||||
host="10.10.10.47",
|
||||
address="10.10.10.47",
|
||||
port=32400,
|
||||
machine_identifier="96f2fe7a78c9dc1f16a16bedbe90f98149be16b4",
|
||||
version="1.31.3.6868-28fc46b27",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
454
tests/test_sessions.py
Normal file
454
tests/test_sessions.py
Normal file
@@ -0,0 +1,454 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
import dateutil.parser
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_sessions_get_sessions():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_sessions()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSessionsResponseBody(
|
||||
media_container=operations.GetSessionsMediaContainer(
|
||||
size=1,
|
||||
metadata=[
|
||||
operations.GetSessionsMetadata(
|
||||
added_at=1705543312,
|
||||
art="/library/metadata/39904/art/1705310687",
|
||||
duration=186240,
|
||||
grandparent_art="/library/metadata/39904/art/1705310687",
|
||||
grandparent_guid="plex://artist/5d07bbfd403c6402904a6480",
|
||||
grandparent_key="/library/metadata/39904",
|
||||
grandparent_rating_key="39904",
|
||||
grandparent_thumb="/library/metadata/39904/thumb/1705310687",
|
||||
grandparent_title="Green Day",
|
||||
guid="plex://track/6535834f71f22f36f71a8e8f",
|
||||
index=1,
|
||||
key="/library/metadata/67085",
|
||||
library_section_id="3",
|
||||
library_section_key="/library/sections/3",
|
||||
library_section_title="Music",
|
||||
music_analysis_version="1",
|
||||
parent_guid="plex://album/65394d6d472b8ab03ef47f12",
|
||||
parent_index=1,
|
||||
parent_key="/library/metadata/67084",
|
||||
parent_rating_key="67084",
|
||||
parent_studio="Reprise Records",
|
||||
parent_thumb="/library/metadata/67084/thumb/1705543314",
|
||||
parent_title="Saviors",
|
||||
parent_year=2024,
|
||||
rating_count=45885,
|
||||
rating_key="67085",
|
||||
session_key="203",
|
||||
thumb="/library/metadata/67084/thumb/1705543314",
|
||||
title="The American Dream Is Killing Me",
|
||||
title_sort="American Dream Is Killing Me",
|
||||
type="track",
|
||||
updated_at=1705543314,
|
||||
view_offset=1000,
|
||||
media=[
|
||||
operations.GetSessionsMedia(
|
||||
audio_channels=2,
|
||||
audio_codec="flac",
|
||||
bitrate=1014,
|
||||
container="flac",
|
||||
duration=186240,
|
||||
id="130355",
|
||||
selected=True,
|
||||
part=[
|
||||
operations.GetSessionsPart(
|
||||
container="flac",
|
||||
duration=186240,
|
||||
file="/music/Green Day/Saviors (2024)/Green Day - Saviors - 01 - The American Dream Is Killing Me.flac",
|
||||
has_thumbnail="1",
|
||||
id="130625",
|
||||
key="/library/parts/130625/1705543268/file.flac",
|
||||
size=23644000,
|
||||
decision="directplay",
|
||||
selected=True,
|
||||
stream=[
|
||||
operations.GetSessionsStream(
|
||||
album_gain="-12.94",
|
||||
album_peak="1.000000",
|
||||
album_range="4.751014",
|
||||
audio_channel_layout="stereo",
|
||||
bit_depth=16,
|
||||
bitrate=1014,
|
||||
channels=2,
|
||||
codec="flac",
|
||||
display_title="FLAC (Stereo)",
|
||||
extended_display_title="FLAC (Stereo)",
|
||||
gain="-12.94",
|
||||
id="352487",
|
||||
index=0,
|
||||
loudness="-5.94",
|
||||
lra="1.74",
|
||||
peak="1.000000",
|
||||
sampling_rate=44100,
|
||||
selected=True,
|
||||
stream_type=2,
|
||||
location="direct",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
user=operations.GetSessionsUser(
|
||||
id="1",
|
||||
thumb="https://plex.tv/users/844780fc6f8a26b5/avatar?c=1705853661",
|
||||
title="Blindkitty38",
|
||||
),
|
||||
player=operations.Player(
|
||||
address="10.10.10.171",
|
||||
machine_identifier="3tsdzir85m2onc3qyr255aq1",
|
||||
model="standalone",
|
||||
platform="windows",
|
||||
platform_version="10.0.22621",
|
||||
product="Plex for Windows",
|
||||
profile="Plex Desktop",
|
||||
remote_public_address="68.248.140.20",
|
||||
state="playing",
|
||||
title="DESKTOP-BL80MTD",
|
||||
version="1.85.0.4071-21128b56",
|
||||
local=True,
|
||||
relayed=False,
|
||||
secure=True,
|
||||
user_id=1,
|
||||
),
|
||||
session=operations.Session(
|
||||
id="93h7e00ncblxncqw9lkfaoxi",
|
||||
bandwidth=1050,
|
||||
location="lan",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_get_session_history_viewed_at_descending():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_session_history(
|
||||
sort="viewedAt:desc", account_id=1, filter_={}, library_section_id=12
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSessionHistoryResponseBody(
|
||||
media_container=operations.GetSessionHistoryMediaContainer(
|
||||
size=10855,
|
||||
metadata=[
|
||||
operations.GetSessionHistoryMetadata(
|
||||
history_key="/status/sessions/history/1",
|
||||
key="/library/metadata/32171",
|
||||
rating_key="32171",
|
||||
library_section_id="2",
|
||||
parent_key="/library/metadata/32170",
|
||||
grandparent_key="/library/metadata/32132",
|
||||
title="The Noise That Blue Makes",
|
||||
grandparent_title="Taskmaster",
|
||||
type="episode",
|
||||
thumb="/library/metadata/32171/thumb/-1",
|
||||
parent_thumb="/library/metadata/32170/thumb/1654134301",
|
||||
grandparent_thumb="/library/metadata/32132/thumb/1703933346",
|
||||
grandparent_art="/library/metadata/32132/art/1703933346",
|
||||
index=1,
|
||||
parent_index=13,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2022-04-14T00:00:00Z"
|
||||
).date(),
|
||||
viewed_at=1654139223,
|
||||
account_id=1,
|
||||
device_id=5,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_get_session_history_viewed_at_ascending():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_session_history(
|
||||
sort="viewedAt:asc", account_id=1, filter_={}, library_section_id=12
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSessionHistoryResponseBody(
|
||||
media_container=operations.GetSessionHistoryMediaContainer(
|
||||
size=10855,
|
||||
metadata=[
|
||||
operations.GetSessionHistoryMetadata(
|
||||
history_key="/status/sessions/history/1",
|
||||
key="/library/metadata/32171",
|
||||
rating_key="32171",
|
||||
library_section_id="2",
|
||||
parent_key="/library/metadata/32170",
|
||||
grandparent_key="/library/metadata/32132",
|
||||
title="The Noise That Blue Makes",
|
||||
grandparent_title="Taskmaster",
|
||||
type="episode",
|
||||
thumb="/library/metadata/32171/thumb/-1",
|
||||
parent_thumb="/library/metadata/32170/thumb/1654134301",
|
||||
grandparent_thumb="/library/metadata/32132/thumb/1703933346",
|
||||
grandparent_art="/library/metadata/32132/art/1703933346",
|
||||
index=1,
|
||||
parent_index=13,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2022-04-14T00:00:00Z"
|
||||
).date(),
|
||||
viewed_at=1654139223,
|
||||
account_id=1,
|
||||
device_id=5,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_get_session_history_rating_descending():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_session_history(
|
||||
sort="rating:desc", account_id=1, filter_={}, library_section_id=12
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSessionHistoryResponseBody(
|
||||
media_container=operations.GetSessionHistoryMediaContainer(
|
||||
size=10855,
|
||||
metadata=[
|
||||
operations.GetSessionHistoryMetadata(
|
||||
history_key="/status/sessions/history/1",
|
||||
key="/library/metadata/32171",
|
||||
rating_key="32171",
|
||||
library_section_id="2",
|
||||
parent_key="/library/metadata/32170",
|
||||
grandparent_key="/library/metadata/32132",
|
||||
title="The Noise That Blue Makes",
|
||||
grandparent_title="Taskmaster",
|
||||
type="episode",
|
||||
thumb="/library/metadata/32171/thumb/-1",
|
||||
parent_thumb="/library/metadata/32170/thumb/1654134301",
|
||||
grandparent_thumb="/library/metadata/32132/thumb/1703933346",
|
||||
grandparent_art="/library/metadata/32132/art/1703933346",
|
||||
index=1,
|
||||
parent_index=13,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2022-04-14T00:00:00Z"
|
||||
).date(),
|
||||
viewed_at=1654139223,
|
||||
account_id=1,
|
||||
device_id=5,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_get_session_history_rating_ascending():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_session_history(
|
||||
sort="rating:asc", account_id=1, filter_={}, library_section_id=12
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSessionHistoryResponseBody(
|
||||
media_container=operations.GetSessionHistoryMediaContainer(
|
||||
size=10855,
|
||||
metadata=[
|
||||
operations.GetSessionHistoryMetadata(
|
||||
history_key="/status/sessions/history/1",
|
||||
key="/library/metadata/32171",
|
||||
rating_key="32171",
|
||||
library_section_id="2",
|
||||
parent_key="/library/metadata/32170",
|
||||
grandparent_key="/library/metadata/32132",
|
||||
title="The Noise That Blue Makes",
|
||||
grandparent_title="Taskmaster",
|
||||
type="episode",
|
||||
thumb="/library/metadata/32171/thumb/-1",
|
||||
parent_thumb="/library/metadata/32170/thumb/1654134301",
|
||||
grandparent_thumb="/library/metadata/32132/thumb/1703933346",
|
||||
grandparent_art="/library/metadata/32132/art/1703933346",
|
||||
index=1,
|
||||
parent_index=13,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2022-04-14T00:00:00Z"
|
||||
).date(),
|
||||
viewed_at=1654139223,
|
||||
account_id=1,
|
||||
device_id=5,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_get_session_history_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_session_history(
|
||||
sort="viewedAt:desc", account_id=1, filter_={}, library_section_id=12
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSessionHistoryResponseBody(
|
||||
media_container=operations.GetSessionHistoryMediaContainer(
|
||||
size=10855,
|
||||
metadata=[
|
||||
operations.GetSessionHistoryMetadata(
|
||||
history_key="/status/sessions/history/1",
|
||||
key="/library/metadata/32171",
|
||||
rating_key="32171",
|
||||
library_section_id="2",
|
||||
parent_key="/library/metadata/32170",
|
||||
grandparent_key="/library/metadata/32132",
|
||||
title="The Noise That Blue Makes",
|
||||
grandparent_title="Taskmaster",
|
||||
type="episode",
|
||||
thumb="/library/metadata/32171/thumb/-1",
|
||||
parent_thumb="/library/metadata/32170/thumb/1654134301",
|
||||
grandparent_thumb="/library/metadata/32132/thumb/1703933346",
|
||||
grandparent_art="/library/metadata/32132/art/1703933346",
|
||||
index=1,
|
||||
parent_index=13,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2022-04-14T00:00:00Z"
|
||||
).date(),
|
||||
viewed_at=1654139223,
|
||||
account_id=1,
|
||||
device_id=5,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_get_session_history_viewed_at():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_session_history(
|
||||
account_id=1, filter_={}, library_section_id=12
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetSessionHistoryResponseBody(
|
||||
media_container=operations.GetSessionHistoryMediaContainer(
|
||||
size=10855,
|
||||
metadata=[
|
||||
operations.GetSessionHistoryMetadata(
|
||||
history_key="/status/sessions/history/1",
|
||||
key="/library/metadata/32171",
|
||||
rating_key="32171",
|
||||
library_section_id="2",
|
||||
parent_key="/library/metadata/32170",
|
||||
grandparent_key="/library/metadata/32132",
|
||||
title="The Noise That Blue Makes",
|
||||
grandparent_title="Taskmaster",
|
||||
type="episode",
|
||||
thumb="/library/metadata/32171/thumb/-1",
|
||||
parent_thumb="/library/metadata/32170/thumb/1654134301",
|
||||
grandparent_thumb="/library/metadata/32132/thumb/1703933346",
|
||||
grandparent_art="/library/metadata/32132/art/1703933346",
|
||||
index=1,
|
||||
parent_index=13,
|
||||
originally_available_at=dateutil.parser.parse(
|
||||
"2022-04-14T00:00:00Z"
|
||||
).date(),
|
||||
viewed_at=1654139223,
|
||||
account_id=1,
|
||||
device_id=5,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_get_transcode_sessions():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.get_transcode_sessions()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetTranscodeSessionsResponseBody(
|
||||
media_container=operations.GetTranscodeSessionsMediaContainer(
|
||||
size=1,
|
||||
transcode_session=[
|
||||
operations.TranscodeSession(
|
||||
key="vv3i2q2lax92qlzul1hbd4bx",
|
||||
throttled=False,
|
||||
complete=False,
|
||||
progress=1.7999999523162842,
|
||||
size=-22,
|
||||
speed=25.100000381469727,
|
||||
error=False,
|
||||
duration=1445695,
|
||||
remaining=53,
|
||||
context="streaming",
|
||||
source_video_codec="h264",
|
||||
source_audio_codec="aac",
|
||||
video_decision="transcode",
|
||||
audio_decision="transcode",
|
||||
subtitle_decision="burn",
|
||||
protocol="http",
|
||||
container="mkv",
|
||||
video_codec="h264",
|
||||
audio_codec="opus",
|
||||
audio_channels=1,
|
||||
transcode_hw_requested=True,
|
||||
time_stamp=1705895805.4919229,
|
||||
max_offset_available=29.53,
|
||||
min_offset_available=3.003000020980835,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_sessions_stop_transcode_session():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.sessions.stop_transcode_session(session_key="zz7llzqlx8w9vnrsbnwhbmep")
|
||||
assert res.status_code == 204
|
||||
128
tests/test_statistics.py
Normal file
128
tests/test_statistics.py
Normal file
@@ -0,0 +1,128 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_statistics_get_statistics_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.statistics.get_statistics(timespan=4)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetStatisticsResponseBody(
|
||||
media_container=operations.GetStatisticsMediaContainer(
|
||||
size=5497,
|
||||
device=[
|
||||
operations.GetStatisticsDevice(
|
||||
id=208,
|
||||
name="Roku Express",
|
||||
platform="Roku",
|
||||
client_identifier="793095d235660625108ef785cc7646e9",
|
||||
created_at=1706470556,
|
||||
),
|
||||
],
|
||||
account=[
|
||||
operations.Account(
|
||||
id=238960586,
|
||||
key="/accounts/238960586",
|
||||
name="Diane",
|
||||
default_audio_language="en",
|
||||
auto_select_audio=True,
|
||||
default_subtitle_language="en",
|
||||
subtitle_mode=1,
|
||||
thumb="https://plex.tv/users/50d83634246da1de/avatar?c=1707110967",
|
||||
),
|
||||
],
|
||||
statistics_media=[
|
||||
operations.StatisticsMedia(
|
||||
account_id=1,
|
||||
device_id=13,
|
||||
timespan=4,
|
||||
at=1707141600,
|
||||
metadata_type=4,
|
||||
count=1,
|
||||
duration=1555,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_statistics_get_resources_statistics_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.statistics.get_resources_statistics(timespan=4)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetResourcesStatisticsResponseBody(
|
||||
media_container=operations.GetResourcesStatisticsMediaContainer(
|
||||
size=5497,
|
||||
statistics_resources=[
|
||||
operations.StatisticsResources(
|
||||
timespan=6,
|
||||
at=1718384427,
|
||||
host_cpu_utilization=1.276,
|
||||
process_cpu_utilization=0.025,
|
||||
host_memory_utilization=17.026,
|
||||
process_memory_utilization=0.493,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_statistics_get_bandwidth_statistics_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.statistics.get_bandwidth_statistics(timespan=4)
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetBandwidthStatisticsResponseBody(
|
||||
media_container=operations.GetBandwidthStatisticsMediaContainer(
|
||||
size=5497,
|
||||
device=[
|
||||
operations.GetBandwidthStatisticsDevice(
|
||||
id=208,
|
||||
name="Roku Express",
|
||||
platform="Roku",
|
||||
client_identifier="793095d235660625108ef785cc7646e9",
|
||||
created_at=1706470556,
|
||||
),
|
||||
],
|
||||
account=[
|
||||
operations.GetBandwidthStatisticsAccount(
|
||||
id=238960586,
|
||||
key="/accounts/238960586",
|
||||
name="Diane",
|
||||
default_audio_language="en",
|
||||
auto_select_audio=True,
|
||||
default_subtitle_language="en",
|
||||
subtitle_mode=1,
|
||||
thumb="https://plex.tv/users/50d83634246da1de/avatar?c=1707110967",
|
||||
),
|
||||
],
|
||||
statistics_bandwidth=[
|
||||
operations.StatisticsBandwidth(
|
||||
account_id=238960586,
|
||||
device_id=208,
|
||||
timespan=6,
|
||||
at=1718387650,
|
||||
lan=True,
|
||||
bytes=22,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
74
tests/test_updater.py
Normal file
74
tests/test_updater.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_updater_get_update_status():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.updater.get_update_status()
|
||||
assert res.status_code == 200
|
||||
assert res.object is not None
|
||||
assert res.object == operations.GetUpdateStatusResponseBody(
|
||||
media_container=operations.GetUpdateStatusMediaContainer(
|
||||
size=1,
|
||||
can_install=False,
|
||||
checked_at=1705801232,
|
||||
download_url="https://plex.tv/downloads/latest/5?channel=8&build=linux-x86_64&distro=redhat&X-Plex-Token=xxxxxxxxxxxxxxxxxxxx",
|
||||
status=0,
|
||||
release=[
|
||||
operations.Release(
|
||||
key="https://plex.tv/updater/releases/5136",
|
||||
version="1.40.0.7775-456fbaf97",
|
||||
added="(PLEASE NOTE) This version makes changes to the database which will make it compatible only with server versions 1.31.2 or higher (released March 14). You will not be able to use your database on Plex Media Server versions lower than this after this update. Please also be patient when updating to this version if you have a very large database and allow the upgrade process to finish.\n"
|
||||
+ "(Collections) Items added to a collection from the item context menu will now lock the collection field on the items (#12793)\n"
|
||||
+ "(Music) Store track genres and add filtering options (#14653)\n"
|
||||
+ "(Music) Support ID3v2.4 null-separated tags for genres and release type (#14653)\n"
|
||||
+ "(View History) No longer create a view history entry for items marked as played (#10888)\n"
|
||||
+ "(Web) Updated to 4.118.0",
|
||||
fixed="(Agents) Changing a 'Other Videos' type library to the modern movie agent would fail (#14483)\n"
|
||||
+ "(Agents) It is possible that agents are not initialised during startup on rare occasions (#14654)\n"
|
||||
+ "(Agents) Remove the legacy OpenSubtitles agent which is no longer supported upstream (#14667)\n"
|
||||
+ "(Collection) Server could become unresponsive when collection membership changes (#14612)\n"
|
||||
+ "(DVR) Previously watched recordings could be deleted without being watched again (#13779)\n"
|
||||
+ "(Libraries) When performing fix match on items from certain music libraries the language would default to Arabic (#14501)\n"
|
||||
+ "(Library) The Content Rating not equal to None filter does not work (#14620)\n"
|
||||
+ "(Search) Album search results could contain all the album's tracks too (#14486)\n"
|
||||
+ "(Subtitles) In some circumstances, sidecar subtitles can show up for media when they're no longer available (#14674)\n"
|
||||
+ "(Transcoder) HW encoding would fail on devices with no rate control (#14222)\n"
|
||||
+ "(Transcoder) Software transcoding on Ubuntu could cause unexpected behavior (#14605)",
|
||||
download_url="https://plex.tv/downloads/latest/5?channel=8&build=linux-x86_64&distro=redhat&X-Plex-Token=xxxxxxxxxxxxxxxxxxxx",
|
||||
state="notify",
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_updater_check_for_updates_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.updater.check_for_updates(download=operations.Download.ONE)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_updater_apply_updates_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.updater.apply_updates(
|
||||
tonight=operations.Tonight.ONE, skip=operations.Skip.ONE
|
||||
)
|
||||
assert res.status_code == 200
|
||||
58
tests/test_video.py
Normal file
58
tests/test_video.py
Normal file
@@ -0,0 +1,58 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_video_get_timeline_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.video.get_timeline(
|
||||
request={
|
||||
"rating_key": 23409,
|
||||
"key": "/library/metadata/23409",
|
||||
"state": operations.State.PLAYING,
|
||||
"has_mde": 1,
|
||||
"time": 2000,
|
||||
"duration": 10000,
|
||||
"context": "home:hub.continueWatching",
|
||||
"play_queue_item_id": 1,
|
||||
"play_back_time": 2000,
|
||||
"row": 1,
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_video_start_universal_transcode_():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.video.start_universal_transcode(
|
||||
request={
|
||||
"has_mde": 1,
|
||||
"path": "/library/metadata/23409",
|
||||
"media_index": 0,
|
||||
"part_index": 0,
|
||||
"protocol": "hls",
|
||||
"fast_seek": 0,
|
||||
"direct_play": 0,
|
||||
"direct_stream": 0,
|
||||
"subtitle_size": 100,
|
||||
"subtites": "burn",
|
||||
"audio_boost": 100,
|
||||
"location": "lan",
|
||||
"media_buffer_size": 102400,
|
||||
"session": "zvcage8b7rkioqcm8f4uns4c",
|
||||
"add_debug_overlay": 0,
|
||||
"auto_adjust_quality": 0,
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
22
tests/test_watchlist.py
Normal file
22
tests/test_watchlist.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
||||
|
||||
from plex_api_client import PlexAPI
|
||||
from plex_api_client.models import operations
|
||||
|
||||
|
||||
def test_watchlist_get_watch_list():
|
||||
s = PlexAPI(
|
||||
access_token="<YOUR_API_KEY_HERE>",
|
||||
)
|
||||
|
||||
assert s is not None
|
||||
|
||||
res = s.watchlist.get_watch_list(
|
||||
request={
|
||||
"filter_": operations.Filter.AVAILABLE,
|
||||
"x_plex_container_start": 0,
|
||||
"x_plex_container_size": 50,
|
||||
"x_plex_token": "CV5xoxjTpFKUzBTShsaf",
|
||||
}
|
||||
)
|
||||
assert res.status_code == 200
|
||||
Reference in New Issue
Block a user