plex-api-client 0.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. plex_api/__init__.py +4 -0
  2. plex_api/_hooks/__init__.py +5 -0
  3. plex_api/_hooks/registration.py +13 -0
  4. plex_api/_hooks/sdkhooks.py +57 -0
  5. plex_api/_hooks/types.py +74 -0
  6. plex_api/activities.py +151 -0
  7. plex_api/authentication.py +146 -0
  8. plex_api/butler.py +333 -0
  9. plex_api/hubs.py +158 -0
  10. plex_api/library.py +808 -0
  11. plex_api/log.py +225 -0
  12. plex_api/media.py +210 -0
  13. plex_api/models/__init__.py +4 -0
  14. plex_api/models/components/__init__.py +5 -0
  15. plex_api/models/components/security.py +11 -0
  16. plex_api/models/errors/__init__.py +63 -0
  17. plex_api/models/errors/addplaylistcontents.py +32 -0
  18. plex_api/models/errors/applyupdates.py +32 -0
  19. plex_api/models/errors/cancelserveractivities.py +32 -0
  20. plex_api/models/errors/checkforupdates.py +32 -0
  21. plex_api/models/errors/clearplaylistcontents.py +32 -0
  22. plex_api/models/errors/createplaylist.py +32 -0
  23. plex_api/models/errors/deletelibrary.py +32 -0
  24. plex_api/models/errors/deleteplaylist.py +32 -0
  25. plex_api/models/errors/enablepapertrail.py +32 -0
  26. plex_api/models/errors/getavailableclients.py +32 -0
  27. plex_api/models/errors/getbutlertasks.py +32 -0
  28. plex_api/models/errors/getdevices.py +32 -0
  29. plex_api/models/errors/getfilehash.py +32 -0
  30. plex_api/models/errors/getglobalhubs.py +32 -0
  31. plex_api/models/errors/getlibraries.py +32 -0
  32. plex_api/models/errors/getlibrary.py +32 -0
  33. plex_api/models/errors/getlibraryhubs.py +32 -0
  34. plex_api/models/errors/getmetadata.py +32 -0
  35. plex_api/models/errors/getmetadatachildren.py +32 -0
  36. plex_api/models/errors/getmyplexaccount.py +32 -0
  37. plex_api/models/errors/getondeck.py +32 -0
  38. plex_api/models/errors/getpin.py +32 -0
  39. plex_api/models/errors/getplaylist.py +32 -0
  40. plex_api/models/errors/getplaylistcontents.py +32 -0
  41. plex_api/models/errors/getplaylists.py +32 -0
  42. plex_api/models/errors/getrecentlyadded.py +32 -0
  43. plex_api/models/errors/getresizedphoto.py +32 -0
  44. plex_api/models/errors/getsearchresults.py +32 -0
  45. plex_api/models/errors/getserveractivities.py +32 -0
  46. plex_api/models/errors/getservercapabilities.py +32 -0
  47. plex_api/models/errors/getserveridentity.py +32 -0
  48. plex_api/models/errors/getserverlist.py +32 -0
  49. plex_api/models/errors/getserverpreferences.py +32 -0
  50. plex_api/models/errors/getsessionhistory.py +32 -0
  51. plex_api/models/errors/getsessions.py +32 -0
  52. plex_api/models/errors/getsourceconnectioninformation.py +32 -0
  53. plex_api/models/errors/getstatistics.py +32 -0
  54. plex_api/models/errors/gettimeline.py +32 -0
  55. plex_api/models/errors/gettoken.py +32 -0
  56. plex_api/models/errors/gettranscodesessions.py +32 -0
  57. plex_api/models/errors/gettransienttoken.py +32 -0
  58. plex_api/models/errors/getupdatestatus.py +32 -0
  59. plex_api/models/errors/logline.py +32 -0
  60. plex_api/models/errors/logmultiline.py +32 -0
  61. plex_api/models/errors/markplayed.py +32 -0
  62. plex_api/models/errors/markunplayed.py +32 -0
  63. plex_api/models/errors/performsearch.py +32 -0
  64. plex_api/models/errors/performvoicesearch.py +32 -0
  65. plex_api/models/errors/refreshlibrary.py +32 -0
  66. plex_api/models/errors/sdkerror.py +24 -0
  67. plex_api/models/errors/startalltasks.py +32 -0
  68. plex_api/models/errors/starttask.py +32 -0
  69. plex_api/models/errors/startuniversaltranscode.py +32 -0
  70. plex_api/models/errors/stopalltasks.py +32 -0
  71. plex_api/models/errors/stoptask.py +32 -0
  72. plex_api/models/errors/stoptranscodesession.py +32 -0
  73. plex_api/models/errors/updateplaylist.py +32 -0
  74. plex_api/models/errors/updateplayprogress.py +32 -0
  75. plex_api/models/errors/uploadplaylist.py +32 -0
  76. plex_api/models/operations/__init__.py +64 -0
  77. plex_api/models/operations/addplaylistcontents.py +74 -0
  78. plex_api/models/operations/applyupdates.py +39 -0
  79. plex_api/models/operations/cancelserveractivities.py +25 -0
  80. plex_api/models/operations/checkforupdates.py +32 -0
  81. plex_api/models/operations/clearplaylistcontents.py +25 -0
  82. plex_api/models/operations/createplaylist.py +91 -0
  83. plex_api/models/operations/deletelibrary.py +25 -0
  84. plex_api/models/operations/deleteplaylist.py +25 -0
  85. plex_api/models/operations/enablepapertrail.py +17 -0
  86. plex_api/models/operations/getavailableclients.py +58 -0
  87. plex_api/models/operations/getbutlertasks.py +52 -0
  88. plex_api/models/operations/getdevices.py +53 -0
  89. plex_api/models/operations/getfilehash.py +28 -0
  90. plex_api/models/operations/getglobalhubs.py +100 -0
  91. plex_api/models/operations/getlibraries.py +79 -0
  92. plex_api/models/operations/getlibrary.py +153 -0
  93. plex_api/models/operations/getlibraryhubs.py +205 -0
  94. plex_api/models/operations/getlibraryitems.py +227 -0
  95. plex_api/models/operations/getmetadata.py +264 -0
  96. plex_api/models/operations/getmetadatachildren.py +115 -0
  97. plex_api/models/operations/getmyplexaccount.py +50 -0
  98. plex_api/models/operations/getondeck.py +166 -0
  99. plex_api/models/operations/getpin.py +86 -0
  100. plex_api/models/operations/getplaylist.py +70 -0
  101. plex_api/models/operations/getplaylistcontents.py +178 -0
  102. plex_api/models/operations/getplaylists.py +85 -0
  103. plex_api/models/operations/getrecentlyadded.py +166 -0
  104. plex_api/models/operations/getresizedphoto.py +48 -0
  105. plex_api/models/operations/getsearchresults.py +182 -0
  106. plex_api/models/operations/getserveractivities.py +63 -0
  107. plex_api/models/operations/getservercapabilities.py +99 -0
  108. plex_api/models/operations/getserveridentity.py +42 -0
  109. plex_api/models/operations/getserverlist.py +53 -0
  110. plex_api/models/operations/getserverpreferences.py +57 -0
  111. plex_api/models/operations/getsessionhistory.py +67 -0
  112. plex_api/models/operations/getsessions.py +185 -0
  113. plex_api/models/operations/getsourceconnectioninformation.py +25 -0
  114. plex_api/models/operations/getstatistics.py +93 -0
  115. plex_api/models/operations/gettimeline.py +50 -0
  116. plex_api/models/operations/gettoken.py +35 -0
  117. plex_api/models/operations/gettranscodesessions.py +71 -0
  118. plex_api/models/operations/gettransienttoken.py +36 -0
  119. plex_api/models/operations/getupdatestatus.py +57 -0
  120. plex_api/models/operations/logline.py +50 -0
  121. plex_api/models/operations/logmultiline.py +17 -0
  122. plex_api/models/operations/markplayed.py +25 -0
  123. plex_api/models/operations/markunplayed.py +25 -0
  124. plex_api/models/operations/performsearch.py +30 -0
  125. plex_api/models/operations/performvoicesearch.py +30 -0
  126. plex_api/models/operations/refreshlibrary.py +25 -0
  127. plex_api/models/operations/searchlibrary.py +96 -0
  128. plex_api/models/operations/startalltasks.py +17 -0
  129. plex_api/models/operations/starttask.py +43 -0
  130. plex_api/models/operations/startuniversaltranscode.py +56 -0
  131. plex_api/models/operations/stopalltasks.py +17 -0
  132. plex_api/models/operations/stoptask.py +43 -0
  133. plex_api/models/operations/stoptranscodesession.py +25 -0
  134. plex_api/models/operations/updateplaylist.py +30 -0
  135. plex_api/models/operations/updateplayprogress.py +29 -0
  136. plex_api/models/operations/uploadplaylist.py +47 -0
  137. plex_api/playlists.py +629 -0
  138. plex_api/plex.py +154 -0
  139. plex_api/sdk.py +180 -0
  140. plex_api/sdkconfiguration.py +52 -0
  141. plex_api/search.py +232 -0
  142. plex_api/server.py +525 -0
  143. plex_api/sessions.py +272 -0
  144. plex_api/statistics.py +86 -0
  145. plex_api/updater.py +212 -0
  146. plex_api/utils/__init__.py +4 -0
  147. plex_api/utils/retries.py +120 -0
  148. plex_api/utils/utils.py +898 -0
  149. plex_api/video.py +136 -0
  150. plex_api_client-0.6.1.dist-info/LICENSE.md +21 -0
  151. plex_api_client-0.6.1.dist-info/METADATA +397 -0
  152. plex_api_client-0.6.1.dist-info/RECORD +154 -0
  153. plex_api_client-0.6.1.dist-info/WHEEL +5 -0
  154. plex_api_client-0.6.1.dist-info/top_level.txt +1 -0
plex_api/log.py ADDED
@@ -0,0 +1,225 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ import requests as requests_http
4
+ from .sdkconfiguration import SDKConfiguration
5
+ from plex_api import utils
6
+ from plex_api._hooks import AfterErrorContext, AfterSuccessContext, BeforeRequestContext, HookContext
7
+ from plex_api.models import errors, operations
8
+
9
+ class Log:
10
+ r"""Submit logs to the Log Handler for Plex Media Server"""
11
+ sdk_configuration: SDKConfiguration
12
+
13
+ def __init__(self, sdk_config: SDKConfiguration) -> None:
14
+ self.sdk_configuration = sdk_config
15
+
16
+
17
+
18
+ def log_line(self, level: operations.Level, message: str, source: str) -> operations.LogLineResponse:
19
+ r"""Logging a single line message.
20
+ This endpoint will write a single-line log message, including a level and source to the main Plex Media Server log.
21
+ """
22
+ hook_ctx = HookContext(operation_id='logLine', oauth2_scopes=[], security_source=self.sdk_configuration.security)
23
+ request = operations.LogLineRequest(
24
+ level=level,
25
+ message=message,
26
+ source=source,
27
+ )
28
+
29
+ base_url = utils.template_url(*self.sdk_configuration.get_server_details())
30
+
31
+ url = base_url + '/log'
32
+
33
+ if callable(self.sdk_configuration.security):
34
+ headers, query_params = utils.get_security(self.sdk_configuration.security())
35
+ else:
36
+ headers, query_params = utils.get_security(self.sdk_configuration.security)
37
+
38
+ query_params = { **utils.get_query_params(operations.LogLineRequest, request, self.sdk_configuration.globals), **query_params }
39
+ headers['Accept'] = 'application/json'
40
+ headers['user-agent'] = self.sdk_configuration.user_agent
41
+ client = self.sdk_configuration.client
42
+
43
+ try:
44
+ req = client.prepare_request(requests_http.Request('GET', url, params=query_params, headers=headers))
45
+ req = self.sdk_configuration.get_hooks().before_request(BeforeRequestContext(hook_ctx), req)
46
+ http_res = client.send(req)
47
+ except Exception as e:
48
+ _, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), None, e)
49
+ if e is not None:
50
+ raise e
51
+
52
+ if utils.match_status_codes(['400','401','4XX','5XX'], http_res.status_code):
53
+ result, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), http_res, None)
54
+ if e is not None:
55
+ raise e
56
+ if result is not None:
57
+ http_res = result
58
+ else:
59
+ http_res = self.sdk_configuration.get_hooks().after_success(AfterSuccessContext(hook_ctx), http_res)
60
+
61
+
62
+
63
+ res = operations.LogLineResponse(status_code=http_res.status_code, content_type=http_res.headers.get('Content-Type') or '', raw_response=http_res)
64
+
65
+ if http_res.status_code == 200:
66
+ pass
67
+ elif http_res.status_code == 400 or http_res.status_code >= 400 and http_res.status_code < 500 or http_res.status_code >= 500 and http_res.status_code < 600:
68
+ raise errors.SDKError('API error occurred', http_res.status_code, http_res.text, http_res)
69
+ elif http_res.status_code == 401:
70
+ if utils.match_content_type(http_res.headers.get('Content-Type') or '', 'application/json'):
71
+ out = utils.unmarshal_json(http_res.text, errors.LogLineResponseBody)
72
+ out.raw_response = http_res
73
+ raise out
74
+ else:
75
+ content_type = http_res.headers.get('Content-Type')
76
+ raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
77
+ else:
78
+ raise errors.SDKError('unknown status code received', http_res.status_code, http_res.text, http_res)
79
+
80
+ return res
81
+
82
+
83
+
84
+ def log_multi_line(self, request: str) -> operations.LogMultiLineResponse:
85
+ r"""Logging a multi-line message
86
+ This endpoint allows for the batch addition of log entries to the main Plex Media Server log.
87
+ It accepts a text/plain request body, where each line represents a distinct log entry.
88
+ Each log entry consists of URL-encoded key-value pairs, specifying log attributes such as 'level', 'message', and 'source'.
89
+
90
+ Log entries are separated by a newline character (`\n`).
91
+ Each entry's parameters should be URL-encoded to ensure accurate parsing and handling of special characters.
92
+ This method is efficient for logging multiple entries in a single API call, reducing the overhead of multiple individual requests.
93
+
94
+ The 'level' parameter specifies the log entry's severity or importance, with the following integer values:
95
+ - `0`: Error - Critical issues that require immediate attention.
96
+ - `1`: Warning - Important events that are not critical but may indicate potential issues.
97
+ - `2`: Info - General informational messages about system operation.
98
+ - `3`: Debug - Detailed information useful for debugging purposes.
99
+ - `4`: Verbose - Highly detailed diagnostic information for in-depth analysis.
100
+
101
+ The 'message' parameter contains the log text, and 'source' identifies the log message's origin (e.g., an application name or module).
102
+
103
+ Example of a single log entry format:
104
+ `level=4&message=Sample%20log%20entry&source=applicationName`
105
+
106
+ Ensure each parameter is properly URL-encoded to avoid interpretation issues.
107
+ """
108
+ hook_ctx = HookContext(operation_id='logMultiLine', oauth2_scopes=[], security_source=self.sdk_configuration.security)
109
+ base_url = utils.template_url(*self.sdk_configuration.get_server_details())
110
+
111
+ url = base_url + '/log'
112
+
113
+ if callable(self.sdk_configuration.security):
114
+ headers, query_params = utils.get_security(self.sdk_configuration.security())
115
+ else:
116
+ headers, query_params = utils.get_security(self.sdk_configuration.security)
117
+
118
+ req_content_type, data, form = utils.serialize_request_body(request, str, "request", False, False, 'string')
119
+ if req_content_type is not None and req_content_type not in ('multipart/form-data', 'multipart/mixed'):
120
+ headers['content-type'] = req_content_type
121
+ if data is None and form is None:
122
+ raise Exception('request body is required')
123
+ headers['Accept'] = 'application/json'
124
+ headers['user-agent'] = self.sdk_configuration.user_agent
125
+ client = self.sdk_configuration.client
126
+
127
+ try:
128
+ req = client.prepare_request(requests_http.Request('POST', url, params=query_params, data=data, files=form, headers=headers))
129
+ req = self.sdk_configuration.get_hooks().before_request(BeforeRequestContext(hook_ctx), req)
130
+ http_res = client.send(req)
131
+ except Exception as e:
132
+ _, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), None, e)
133
+ if e is not None:
134
+ raise e
135
+
136
+ if utils.match_status_codes(['400','401','4XX','5XX'], http_res.status_code):
137
+ result, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), http_res, None)
138
+ if e is not None:
139
+ raise e
140
+ if result is not None:
141
+ http_res = result
142
+ else:
143
+ http_res = self.sdk_configuration.get_hooks().after_success(AfterSuccessContext(hook_ctx), http_res)
144
+
145
+
146
+
147
+ res = operations.LogMultiLineResponse(status_code=http_res.status_code, content_type=http_res.headers.get('Content-Type') or '', raw_response=http_res)
148
+
149
+ if http_res.status_code == 200:
150
+ pass
151
+ elif http_res.status_code == 400 or http_res.status_code >= 400 and http_res.status_code < 500 or http_res.status_code >= 500 and http_res.status_code < 600:
152
+ raise errors.SDKError('API error occurred', http_res.status_code, http_res.text, http_res)
153
+ elif http_res.status_code == 401:
154
+ if utils.match_content_type(http_res.headers.get('Content-Type') or '', 'application/json'):
155
+ out = utils.unmarshal_json(http_res.text, errors.LogMultiLineResponseBody)
156
+ out.raw_response = http_res
157
+ raise out
158
+ else:
159
+ content_type = http_res.headers.get('Content-Type')
160
+ raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
161
+ else:
162
+ raise errors.SDKError('unknown status code received', http_res.status_code, http_res.text, http_res)
163
+
164
+ return res
165
+
166
+
167
+
168
+ def enable_paper_trail(self) -> operations.EnablePaperTrailResponse:
169
+ r"""Enabling Papertrail
170
+ This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time.
171
+ """
172
+ hook_ctx = HookContext(operation_id='enablePaperTrail', oauth2_scopes=[], security_source=self.sdk_configuration.security)
173
+ base_url = utils.template_url(*self.sdk_configuration.get_server_details())
174
+
175
+ url = base_url + '/log/networked'
176
+
177
+ if callable(self.sdk_configuration.security):
178
+ headers, query_params = utils.get_security(self.sdk_configuration.security())
179
+ else:
180
+ headers, query_params = utils.get_security(self.sdk_configuration.security)
181
+
182
+ headers['Accept'] = 'application/json'
183
+ headers['user-agent'] = self.sdk_configuration.user_agent
184
+ client = self.sdk_configuration.client
185
+
186
+ try:
187
+ req = client.prepare_request(requests_http.Request('GET', url, params=query_params, headers=headers))
188
+ req = self.sdk_configuration.get_hooks().before_request(BeforeRequestContext(hook_ctx), req)
189
+ http_res = client.send(req)
190
+ except Exception as e:
191
+ _, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), None, e)
192
+ if e is not None:
193
+ raise e
194
+
195
+ if utils.match_status_codes(['400','401','403','4XX','5XX'], http_res.status_code):
196
+ result, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), http_res, None)
197
+ if e is not None:
198
+ raise e
199
+ if result is not None:
200
+ http_res = result
201
+ else:
202
+ http_res = self.sdk_configuration.get_hooks().after_success(AfterSuccessContext(hook_ctx), http_res)
203
+
204
+
205
+
206
+ res = operations.EnablePaperTrailResponse(status_code=http_res.status_code, content_type=http_res.headers.get('Content-Type') or '', raw_response=http_res)
207
+
208
+ if http_res.status_code == 200:
209
+ pass
210
+ elif http_res.status_code == 400 or http_res.status_code == 403 or http_res.status_code >= 400 and http_res.status_code < 500 or http_res.status_code >= 500 and http_res.status_code < 600:
211
+ raise errors.SDKError('API error occurred', http_res.status_code, http_res.text, http_res)
212
+ elif http_res.status_code == 401:
213
+ if utils.match_content_type(http_res.headers.get('Content-Type') or '', 'application/json'):
214
+ out = utils.unmarshal_json(http_res.text, errors.EnablePaperTrailResponseBody)
215
+ out.raw_response = http_res
216
+ raise out
217
+ else:
218
+ content_type = http_res.headers.get('Content-Type')
219
+ raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
220
+ else:
221
+ raise errors.SDKError('unknown status code received', http_res.status_code, http_res.text, http_res)
222
+
223
+ return res
224
+
225
+
plex_api/media.py ADDED
@@ -0,0 +1,210 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ import requests as requests_http
4
+ from .sdkconfiguration import SDKConfiguration
5
+ from plex_api import utils
6
+ from plex_api._hooks import AfterErrorContext, AfterSuccessContext, BeforeRequestContext, HookContext
7
+ from plex_api.models import errors, operations
8
+
9
+ class Media:
10
+ r"""API Calls interacting with Plex Media Server Media"""
11
+ sdk_configuration: SDKConfiguration
12
+
13
+ def __init__(self, sdk_config: SDKConfiguration) -> None:
14
+ self.sdk_configuration = sdk_config
15
+
16
+
17
+
18
+ def mark_played(self, key: float) -> operations.MarkPlayedResponse:
19
+ r"""Mark Media Played
20
+ This will mark the provided media key as Played.
21
+ """
22
+ hook_ctx = HookContext(operation_id='markPlayed', oauth2_scopes=[], security_source=self.sdk_configuration.security)
23
+ request = operations.MarkPlayedRequest(
24
+ key=key,
25
+ )
26
+
27
+ base_url = utils.template_url(*self.sdk_configuration.get_server_details())
28
+
29
+ url = base_url + '/:/scrobble'
30
+
31
+ if callable(self.sdk_configuration.security):
32
+ headers, query_params = utils.get_security(self.sdk_configuration.security())
33
+ else:
34
+ headers, query_params = utils.get_security(self.sdk_configuration.security)
35
+
36
+ query_params = { **utils.get_query_params(operations.MarkPlayedRequest, request, self.sdk_configuration.globals), **query_params }
37
+ headers['Accept'] = 'application/json'
38
+ headers['user-agent'] = self.sdk_configuration.user_agent
39
+ client = self.sdk_configuration.client
40
+
41
+ try:
42
+ req = client.prepare_request(requests_http.Request('GET', url, params=query_params, headers=headers))
43
+ req = self.sdk_configuration.get_hooks().before_request(BeforeRequestContext(hook_ctx), req)
44
+ http_res = client.send(req)
45
+ except Exception as e:
46
+ _, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), None, e)
47
+ if e is not None:
48
+ raise e
49
+
50
+ if utils.match_status_codes(['400','401','4XX','5XX'], http_res.status_code):
51
+ result, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), http_res, None)
52
+ if e is not None:
53
+ raise e
54
+ if result is not None:
55
+ http_res = result
56
+ else:
57
+ http_res = self.sdk_configuration.get_hooks().after_success(AfterSuccessContext(hook_ctx), http_res)
58
+
59
+
60
+
61
+ res = operations.MarkPlayedResponse(status_code=http_res.status_code, content_type=http_res.headers.get('Content-Type') or '', raw_response=http_res)
62
+
63
+ if http_res.status_code == 200:
64
+ pass
65
+ elif http_res.status_code == 400 or http_res.status_code >= 400 and http_res.status_code < 500 or http_res.status_code >= 500 and http_res.status_code < 600:
66
+ raise errors.SDKError('API error occurred', http_res.status_code, http_res.text, http_res)
67
+ elif http_res.status_code == 401:
68
+ if utils.match_content_type(http_res.headers.get('Content-Type') or '', 'application/json'):
69
+ out = utils.unmarshal_json(http_res.text, errors.MarkPlayedResponseBody)
70
+ out.raw_response = http_res
71
+ raise out
72
+ else:
73
+ content_type = http_res.headers.get('Content-Type')
74
+ raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
75
+ else:
76
+ raise errors.SDKError('unknown status code received', http_res.status_code, http_res.text, http_res)
77
+
78
+ return res
79
+
80
+
81
+
82
+ def mark_unplayed(self, key: float) -> operations.MarkUnplayedResponse:
83
+ r"""Mark Media Unplayed
84
+ This will mark the provided media key as Unplayed.
85
+ """
86
+ hook_ctx = HookContext(operation_id='markUnplayed', oauth2_scopes=[], security_source=self.sdk_configuration.security)
87
+ request = operations.MarkUnplayedRequest(
88
+ key=key,
89
+ )
90
+
91
+ base_url = utils.template_url(*self.sdk_configuration.get_server_details())
92
+
93
+ url = base_url + '/:/unscrobble'
94
+
95
+ if callable(self.sdk_configuration.security):
96
+ headers, query_params = utils.get_security(self.sdk_configuration.security())
97
+ else:
98
+ headers, query_params = utils.get_security(self.sdk_configuration.security)
99
+
100
+ query_params = { **utils.get_query_params(operations.MarkUnplayedRequest, request, self.sdk_configuration.globals), **query_params }
101
+ headers['Accept'] = 'application/json'
102
+ headers['user-agent'] = self.sdk_configuration.user_agent
103
+ client = self.sdk_configuration.client
104
+
105
+ try:
106
+ req = client.prepare_request(requests_http.Request('GET', url, params=query_params, headers=headers))
107
+ req = self.sdk_configuration.get_hooks().before_request(BeforeRequestContext(hook_ctx), req)
108
+ http_res = client.send(req)
109
+ except Exception as e:
110
+ _, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), None, e)
111
+ if e is not None:
112
+ raise e
113
+
114
+ if utils.match_status_codes(['400','401','4XX','5XX'], http_res.status_code):
115
+ result, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), http_res, None)
116
+ if e is not None:
117
+ raise e
118
+ if result is not None:
119
+ http_res = result
120
+ else:
121
+ http_res = self.sdk_configuration.get_hooks().after_success(AfterSuccessContext(hook_ctx), http_res)
122
+
123
+
124
+
125
+ res = operations.MarkUnplayedResponse(status_code=http_res.status_code, content_type=http_res.headers.get('Content-Type') or '', raw_response=http_res)
126
+
127
+ if http_res.status_code == 200:
128
+ pass
129
+ elif http_res.status_code == 400 or http_res.status_code >= 400 and http_res.status_code < 500 or http_res.status_code >= 500 and http_res.status_code < 600:
130
+ raise errors.SDKError('API error occurred', http_res.status_code, http_res.text, http_res)
131
+ elif http_res.status_code == 401:
132
+ if utils.match_content_type(http_res.headers.get('Content-Type') or '', 'application/json'):
133
+ out = utils.unmarshal_json(http_res.text, errors.MarkUnplayedResponseBody)
134
+ out.raw_response = http_res
135
+ raise out
136
+ else:
137
+ content_type = http_res.headers.get('Content-Type')
138
+ raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
139
+ else:
140
+ raise errors.SDKError('unknown status code received', http_res.status_code, http_res.text, http_res)
141
+
142
+ return res
143
+
144
+
145
+
146
+ def update_play_progress(self, key: str, time: float, state: str) -> operations.UpdatePlayProgressResponse:
147
+ r"""Update Media Play Progress
148
+ This API command can be used to update the play progress of a media item.
149
+ """
150
+ hook_ctx = HookContext(operation_id='updatePlayProgress', oauth2_scopes=[], security_source=self.sdk_configuration.security)
151
+ request = operations.UpdatePlayProgressRequest(
152
+ key=key,
153
+ time=time,
154
+ state=state,
155
+ )
156
+
157
+ base_url = utils.template_url(*self.sdk_configuration.get_server_details())
158
+
159
+ url = base_url + '/:/progress'
160
+
161
+ if callable(self.sdk_configuration.security):
162
+ headers, query_params = utils.get_security(self.sdk_configuration.security())
163
+ else:
164
+ headers, query_params = utils.get_security(self.sdk_configuration.security)
165
+
166
+ query_params = { **utils.get_query_params(operations.UpdatePlayProgressRequest, request, self.sdk_configuration.globals), **query_params }
167
+ headers['Accept'] = 'application/json'
168
+ headers['user-agent'] = self.sdk_configuration.user_agent
169
+ client = self.sdk_configuration.client
170
+
171
+ try:
172
+ req = client.prepare_request(requests_http.Request('POST', url, params=query_params, headers=headers))
173
+ req = self.sdk_configuration.get_hooks().before_request(BeforeRequestContext(hook_ctx), req)
174
+ http_res = client.send(req)
175
+ except Exception as e:
176
+ _, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), None, e)
177
+ if e is not None:
178
+ raise e
179
+
180
+ if utils.match_status_codes(['400','401','4XX','5XX'], http_res.status_code):
181
+ result, e = self.sdk_configuration.get_hooks().after_error(AfterErrorContext(hook_ctx), http_res, None)
182
+ if e is not None:
183
+ raise e
184
+ if result is not None:
185
+ http_res = result
186
+ else:
187
+ http_res = self.sdk_configuration.get_hooks().after_success(AfterSuccessContext(hook_ctx), http_res)
188
+
189
+
190
+
191
+ res = operations.UpdatePlayProgressResponse(status_code=http_res.status_code, content_type=http_res.headers.get('Content-Type') or '', raw_response=http_res)
192
+
193
+ if http_res.status_code == 200:
194
+ pass
195
+ elif http_res.status_code == 400 or http_res.status_code >= 400 and http_res.status_code < 500 or http_res.status_code >= 500 and http_res.status_code < 600:
196
+ raise errors.SDKError('API error occurred', http_res.status_code, http_res.text, http_res)
197
+ elif http_res.status_code == 401:
198
+ if utils.match_content_type(http_res.headers.get('Content-Type') or '', 'application/json'):
199
+ out = utils.unmarshal_json(http_res.text, errors.UpdatePlayProgressResponseBody)
200
+ out.raw_response = http_res
201
+ raise out
202
+ else:
203
+ content_type = http_res.headers.get('Content-Type')
204
+ raise errors.SDKError(f'unknown content-type received: {content_type}', http_res.status_code, http_res.text, http_res)
205
+ else:
206
+ raise errors.SDKError('unknown status code received', http_res.status_code, http_res.text, http_res)
207
+
208
+ return res
209
+
210
+
@@ -0,0 +1,4 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+
4
+ # package
@@ -0,0 +1,5 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ from .security import *
4
+
5
+ __all__ = ["Security"]
@@ -0,0 +1,11 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ import dataclasses
5
+
6
+
7
+ @dataclasses.dataclass
8
+ class Security:
9
+ access_token: str = dataclasses.field(metadata={'security': { 'scheme': True, 'type': 'apiKey', 'sub_type': 'header', 'field_name': 'X-Plex-Token' }})
10
+
11
+
@@ -0,0 +1,63 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ from .addplaylistcontents import *
4
+ from .applyupdates import *
5
+ from .cancelserveractivities import *
6
+ from .checkforupdates import *
7
+ from .clearplaylistcontents import *
8
+ from .createplaylist import *
9
+ from .deletelibrary import *
10
+ from .deleteplaylist import *
11
+ from .enablepapertrail import *
12
+ from .getavailableclients import *
13
+ from .getbutlertasks import *
14
+ from .getdevices import *
15
+ from .getfilehash import *
16
+ from .getglobalhubs import *
17
+ from .getlibraries import *
18
+ from .getlibrary import *
19
+ from .getlibraryhubs import *
20
+ from .getmetadata import *
21
+ from .getmetadatachildren import *
22
+ from .getmyplexaccount import *
23
+ from .getondeck import *
24
+ from .getpin import *
25
+ from .getplaylist import *
26
+ from .getplaylistcontents import *
27
+ from .getplaylists import *
28
+ from .getrecentlyadded import *
29
+ from .getresizedphoto import *
30
+ from .getsearchresults import *
31
+ from .getserveractivities import *
32
+ from .getservercapabilities import *
33
+ from .getserveridentity import *
34
+ from .getserverlist import *
35
+ from .getserverpreferences import *
36
+ from .getsessionhistory import *
37
+ from .getsessions import *
38
+ from .getsourceconnectioninformation import *
39
+ from .getstatistics import *
40
+ from .gettimeline import *
41
+ from .gettoken import *
42
+ from .gettranscodesessions import *
43
+ from .gettransienttoken import *
44
+ from .getupdatestatus import *
45
+ from .logline import *
46
+ from .logmultiline import *
47
+ from .markplayed import *
48
+ from .markunplayed import *
49
+ from .performsearch import *
50
+ from .performvoicesearch import *
51
+ from .refreshlibrary import *
52
+ from .sdkerror import *
53
+ from .startalltasks import *
54
+ from .starttask import *
55
+ from .startuniversaltranscode import *
56
+ from .stopalltasks import *
57
+ from .stoptask import *
58
+ from .stoptranscodesession import *
59
+ from .updateplaylist import *
60
+ from .updateplayprogress import *
61
+ from .uploadplaylist import *
62
+
63
+ __all__ = ["AddPlaylistContentsErrors","AddPlaylistContentsResponseBody","ApplyUpdatesErrors","ApplyUpdatesResponseBody","CancelServerActivitiesErrors","CancelServerActivitiesResponseBody","CheckForUpdatesErrors","CheckForUpdatesResponseBody","ClearPlaylistContentsErrors","ClearPlaylistContentsResponseBody","CreatePlaylistErrors","CreatePlaylistResponseBody","DeleteLibraryErrors","DeleteLibraryResponseBody","DeletePlaylistErrors","DeletePlaylistResponseBody","EnablePaperTrailErrors","EnablePaperTrailResponseBody","Errors","GetAvailableClientsErrors","GetAvailableClientsResponseBody","GetButlerTasksErrors","GetButlerTasksResponseBody","GetDevicesErrors","GetDevicesResponseBody","GetFileHashErrors","GetFileHashResponseBody","GetGlobalHubsErrors","GetGlobalHubsResponseBody","GetLibrariesErrors","GetLibrariesResponseBody","GetLibraryErrors","GetLibraryHubsErrors","GetLibraryHubsResponseBody","GetLibraryResponseBody","GetMetadataChildrenErrors","GetMetadataChildrenResponseBody","GetMetadataErrors","GetMetadataResponseBody","GetMyPlexAccountErrors","GetMyPlexAccountResponseBody","GetOnDeckErrors","GetOnDeckResponseBody","GetPinErrors","GetPinResponseBody","GetPlaylistContentsErrors","GetPlaylistContentsResponseBody","GetPlaylistErrors","GetPlaylistResponseBody","GetPlaylistsErrors","GetPlaylistsResponseBody","GetRecentlyAddedErrors","GetRecentlyAddedResponseBody","GetResizedPhotoErrors","GetResizedPhotoResponseBody","GetSearchResultsErrors","GetSearchResultsResponseBody","GetServerActivitiesErrors","GetServerActivitiesResponseBody","GetServerCapabilitiesResponseBody","GetServerIdentityErrors","GetServerIdentityResponseBody","GetServerListErrors","GetServerListResponseBody","GetServerPreferencesErrors","GetServerPreferencesResponseBody","GetSessionHistoryErrors","GetSessionHistoryResponseBody","GetSessionsErrors","GetSessionsResponseBody","GetSourceConnectionInformationErrors","GetSourceConnectionInformationResponseBody","GetStatisticsErrors","GetStatisticsResponseBody","GetTimelineErrors","GetTimelineResponseBody","GetTokenErrors","GetTokenResponseBody","GetTranscodeSessionsErrors","GetTranscodeSessionsResponseBody","GetTransientTokenErrors","GetTransientTokenResponseBody","GetUpdateStatusErrors","GetUpdateStatusResponseBody","LogLineErrors","LogLineResponseBody","LogMultiLineErrors","LogMultiLineResponseBody","MarkPlayedErrors","MarkPlayedResponseBody","MarkUnplayedErrors","MarkUnplayedResponseBody","PerformSearchErrors","PerformSearchResponseBody","PerformVoiceSearchErrors","PerformVoiceSearchResponseBody","RefreshLibraryErrors","RefreshLibraryResponseBody","SDKError","StartAllTasksErrors","StartAllTasksResponseBody","StartTaskErrors","StartTaskResponseBody","StartUniversalTranscodeErrors","StartUniversalTranscodeResponseBody","StopAllTasksErrors","StopAllTasksResponseBody","StopTaskErrors","StopTaskResponseBody","StopTranscodeSessionErrors","StopTranscodeSessionResponseBody","UpdatePlayProgressErrors","UpdatePlayProgressResponseBody","UpdatePlaylistErrors","UpdatePlaylistResponseBody","UploadPlaylistErrors","UploadPlaylistResponseBody"]
@@ -0,0 +1,32 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ import dataclasses
5
+ import requests as requests_http
6
+ from dataclasses_json import Undefined, dataclass_json
7
+ from plex_api import utils
8
+ from typing import List, Optional
9
+
10
+
11
+ @dataclass_json(undefined=Undefined.EXCLUDE)
12
+ @dataclasses.dataclass
13
+ class AddPlaylistContentsErrors:
14
+ code: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('code'), 'exclude': lambda f: f is None }})
15
+ message: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('message'), 'exclude': lambda f: f is None }})
16
+ status: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status'), 'exclude': lambda f: f is None }})
17
+
18
+
19
+
20
+
21
+ @dataclass_json(undefined=Undefined.EXCLUDE)
22
+
23
+ @dataclasses.dataclass
24
+ class AddPlaylistContentsResponseBody(Exception):
25
+ r"""Unauthorized - Returned if the X-Plex-Token is missing from the header or query."""
26
+ errors: Optional[List[AddPlaylistContentsErrors]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('errors'), 'exclude': lambda f: f is None }})
27
+ raw_response: Optional[requests_http.Response] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'exclude': lambda f: True }})
28
+ r"""Raw HTTP response; suitable for custom response parsing"""
29
+
30
+
31
+ def __str__(self) -> str:
32
+ return utils.marshal_json(self, type(self))
@@ -0,0 +1,32 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ import dataclasses
5
+ import requests as requests_http
6
+ from dataclasses_json import Undefined, dataclass_json
7
+ from plex_api import utils
8
+ from typing import List, Optional
9
+
10
+
11
+ @dataclass_json(undefined=Undefined.EXCLUDE)
12
+ @dataclasses.dataclass
13
+ class ApplyUpdatesErrors:
14
+ code: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('code'), 'exclude': lambda f: f is None }})
15
+ message: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('message'), 'exclude': lambda f: f is None }})
16
+ status: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status'), 'exclude': lambda f: f is None }})
17
+
18
+
19
+
20
+
21
+ @dataclass_json(undefined=Undefined.EXCLUDE)
22
+
23
+ @dataclasses.dataclass
24
+ class ApplyUpdatesResponseBody(Exception):
25
+ r"""Unauthorized - Returned if the X-Plex-Token is missing from the header or query."""
26
+ errors: Optional[List[ApplyUpdatesErrors]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('errors'), 'exclude': lambda f: f is None }})
27
+ raw_response: Optional[requests_http.Response] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'exclude': lambda f: True }})
28
+ r"""Raw HTTP response; suitable for custom response parsing"""
29
+
30
+
31
+ def __str__(self) -> str:
32
+ return utils.marshal_json(self, type(self))
@@ -0,0 +1,32 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ import dataclasses
5
+ import requests as requests_http
6
+ from dataclasses_json import Undefined, dataclass_json
7
+ from plex_api import utils
8
+ from typing import List, Optional
9
+
10
+
11
+ @dataclass_json(undefined=Undefined.EXCLUDE)
12
+ @dataclasses.dataclass
13
+ class CancelServerActivitiesErrors:
14
+ code: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('code'), 'exclude': lambda f: f is None }})
15
+ message: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('message'), 'exclude': lambda f: f is None }})
16
+ status: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status'), 'exclude': lambda f: f is None }})
17
+
18
+
19
+
20
+
21
+ @dataclass_json(undefined=Undefined.EXCLUDE)
22
+
23
+ @dataclasses.dataclass
24
+ class CancelServerActivitiesResponseBody(Exception):
25
+ r"""Unauthorized - Returned if the X-Plex-Token is missing from the header or query."""
26
+ errors: Optional[List[CancelServerActivitiesErrors]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('errors'), 'exclude': lambda f: f is None }})
27
+ raw_response: Optional[requests_http.Response] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'exclude': lambda f: True }})
28
+ r"""Raw HTTP response; suitable for custom response parsing"""
29
+
30
+
31
+ def __str__(self) -> str:
32
+ return utils.marshal_json(self, type(self))
@@ -0,0 +1,32 @@
1
+ """Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ import dataclasses
5
+ import requests as requests_http
6
+ from dataclasses_json import Undefined, dataclass_json
7
+ from plex_api import utils
8
+ from typing import List, Optional
9
+
10
+
11
+ @dataclass_json(undefined=Undefined.EXCLUDE)
12
+ @dataclasses.dataclass
13
+ class CheckForUpdatesErrors:
14
+ code: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('code'), 'exclude': lambda f: f is None }})
15
+ message: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('message'), 'exclude': lambda f: f is None }})
16
+ status: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status'), 'exclude': lambda f: f is None }})
17
+
18
+
19
+
20
+
21
+ @dataclass_json(undefined=Undefined.EXCLUDE)
22
+
23
+ @dataclasses.dataclass
24
+ class CheckForUpdatesResponseBody(Exception):
25
+ r"""Unauthorized - Returned if the X-Plex-Token is missing from the header or query."""
26
+ errors: Optional[List[CheckForUpdatesErrors]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('errors'), 'exclude': lambda f: f is None }})
27
+ raw_response: Optional[requests_http.Response] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'exclude': lambda f: True }})
28
+ r"""Raw HTTP response; suitable for custom response parsing"""
29
+
30
+
31
+ def __str__(self) -> str:
32
+ return utils.marshal_json(self, type(self))