universal-mcp 0.1.8rc2__py3-none-any.whl → 0.1.8rc4__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 (53) hide show
  1. universal_mcp/__init__.py +0 -2
  2. universal_mcp/analytics.py +75 -0
  3. universal_mcp/applications/ahrefs/README.md +76 -0
  4. universal_mcp/applications/ahrefs/__init__.py +0 -0
  5. universal_mcp/applications/ahrefs/app.py +2291 -0
  6. universal_mcp/applications/application.py +94 -5
  7. universal_mcp/applications/calendly/app.py +412 -171
  8. universal_mcp/applications/coda/README.md +133 -0
  9. universal_mcp/applications/coda/__init__.py +0 -0
  10. universal_mcp/applications/coda/app.py +3671 -0
  11. universal_mcp/applications/e2b/app.py +8 -35
  12. universal_mcp/applications/figma/README.md +74 -0
  13. universal_mcp/applications/figma/__init__.py +0 -0
  14. universal_mcp/applications/figma/app.py +1261 -0
  15. universal_mcp/applications/firecrawl/app.py +3 -33
  16. universal_mcp/applications/github/app.py +41 -42
  17. universal_mcp/applications/google_calendar/app.py +20 -31
  18. universal_mcp/applications/google_docs/app.py +21 -46
  19. universal_mcp/applications/google_drive/app.py +53 -76
  20. universal_mcp/applications/google_mail/app.py +40 -56
  21. universal_mcp/applications/google_sheet/app.py +43 -68
  22. universal_mcp/applications/markitdown/app.py +4 -4
  23. universal_mcp/applications/notion/app.py +93 -83
  24. universal_mcp/applications/perplexity/app.py +4 -38
  25. universal_mcp/applications/reddit/app.py +32 -32
  26. universal_mcp/applications/resend/app.py +4 -22
  27. universal_mcp/applications/serpapi/app.py +6 -32
  28. universal_mcp/applications/tavily/app.py +4 -24
  29. universal_mcp/applications/wrike/app.py +565 -237
  30. universal_mcp/applications/youtube/app.py +625 -183
  31. universal_mcp/applications/zenquotes/app.py +3 -3
  32. universal_mcp/exceptions.py +1 -0
  33. universal_mcp/integrations/__init__.py +11 -2
  34. universal_mcp/integrations/agentr.py +27 -4
  35. universal_mcp/integrations/integration.py +14 -6
  36. universal_mcp/logger.py +3 -56
  37. universal_mcp/servers/__init__.py +2 -1
  38. universal_mcp/servers/server.py +73 -77
  39. universal_mcp/stores/store.py +5 -3
  40. universal_mcp/tools/__init__.py +1 -1
  41. universal_mcp/tools/adapters.py +4 -1
  42. universal_mcp/tools/func_metadata.py +5 -6
  43. universal_mcp/tools/tools.py +108 -51
  44. universal_mcp/utils/docgen.py +121 -69
  45. universal_mcp/utils/docstring_parser.py +44 -21
  46. universal_mcp/utils/dump_app_tools.py +33 -23
  47. universal_mcp/utils/installation.py +199 -8
  48. universal_mcp/utils/openapi.py +121 -47
  49. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc4.dist-info}/METADATA +2 -2
  50. universal_mcp-0.1.8rc4.dist-info/RECORD +81 -0
  51. universal_mcp-0.1.8rc2.dist-info/RECORD +0 -71
  52. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc4.dist-info}/WHEEL +0 -0
  53. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc4.dist-info}/entry_points.txt +0 -0
@@ -1,9 +1,6 @@
1
1
  from typing import Any
2
2
 
3
- from loguru import logger
4
-
5
3
  from universal_mcp.applications import APIApplication
6
- from universal_mcp.exceptions import NotAuthorizedError
7
4
  from universal_mcp.integrations import Integration
8
5
 
9
6
 
@@ -11,36 +8,30 @@ class YoutubeApp(APIApplication):
11
8
  def __init__(self, integration: Integration = None, **kwargs) -> None:
12
9
  """
13
10
  Initializes an instance of a YouTube application integration.
14
-
11
+
15
12
  Args:
16
13
  integration: An optional Integration object to be used with the YouTube application integration.
17
14
  kwargs: Additional keyword arguments to be passed to the parent class initializer.
18
-
15
+
19
16
  Returns:
20
17
  None
21
18
  """
22
- super().__init__(name='youtube', integration=integration, **kwargs)
19
+ super().__init__(name="youtube", integration=integration, **kwargs)
23
20
  self.base_url = "https://www.googleapis.com/youtube/v3"
24
21
 
25
- def _get_headers(self):
26
- if not self.integration:
27
- raise ValueError("Integration not configured for YoutubeApp")
28
- credentials = self.integration.get_credentials()
29
- if not credentials:
30
- logger.warning("No Google credentials found via integration.")
31
- action = self.integration.authorize()
32
- raise NotAuthorizedError(action)
33
- if "headers" in credentials:
34
- return credentials["headers"]
35
- return {
36
- "Authorization": f"Bearer {credentials['access_token']}",
37
- "Content-Type": "application/json",
38
- }
39
-
40
- def get_jobs_job_reports(self, jobId, createdAfter=None, onBehalfOfContentOwner=None, pageSize=None, pageToken=None, startTimeAtOrAfter=None, startTimeBefore=None) -> Any:
22
+ def get_jobs_job_reports(
23
+ self,
24
+ jobId,
25
+ createdAfter=None,
26
+ onBehalfOfContentOwner=None,
27
+ pageSize=None,
28
+ pageToken=None,
29
+ startTimeAtOrAfter=None,
30
+ startTimeBefore=None,
31
+ ) -> Any:
41
32
  """
42
33
  Retrieves job reports for a specific job based on provided filters and parameters.
43
-
34
+
44
35
  Args:
45
36
  self: The instance of the class on which the method is being called.
46
37
  jobId: The unique identifier for the job whose reports are to be retrieved.
@@ -50,28 +41,41 @@ class YoutubeApp(APIApplication):
50
41
  pageToken: Optional; a token identifying the page of results to return.
51
42
  startTimeAtOrAfter: Optional; filter to include only reports starting at or after this date-time (ISO 8601 format).
52
43
  startTimeBefore: Optional; filter to include only reports with a start time before this date-time (ISO 8601 format).
53
-
44
+
54
45
  Returns:
55
46
  A JSON object containing the job reports matching the provided criteria.
56
47
  """
57
48
  if jobId is None:
58
49
  raise ValueError("Missing required parameter 'jobId'")
59
50
  url = f"{self.base_url}/v1/jobs/{jobId}/reports"
60
- query_params = {k: v for k, v in [('createdAfter', createdAfter), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('pageSize', pageSize), ('pageToken', pageToken), ('startTimeAtOrAfter', startTimeAtOrAfter), ('startTimeBefore', startTimeBefore)] if v is not None}
51
+ query_params = {
52
+ k: v
53
+ for k, v in [
54
+ ("createdAfter", createdAfter),
55
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
56
+ ("pageSize", pageSize),
57
+ ("pageToken", pageToken),
58
+ ("startTimeAtOrAfter", startTimeAtOrAfter),
59
+ ("startTimeBefore", startTimeBefore),
60
+ ]
61
+ if v is not None
62
+ }
61
63
  response = self._get(url, params=query_params)
62
64
  response.raise_for_status()
63
65
  return response.json()
64
66
 
65
- def get_jobs_job_reports_report(self, jobId, reportId, onBehalfOfContentOwner=None) -> Any:
67
+ def get_jobs_job_reports_report(
68
+ self, jobId, reportId, onBehalfOfContentOwner=None
69
+ ) -> Any:
66
70
  """
67
71
  Retrieves a report for a specified job using the jobId and reportId.
68
-
72
+
69
73
  Args:
70
74
  self: The instance of the class on which this method is called.
71
75
  jobId: The unique identifier for the job associated with the report.
72
76
  reportId: The unique identifier for the report to retrieve.
73
77
  onBehalfOfContentOwner: Optional; if specified, the request is performed on behalf of the content owner associated with this parameter.
74
-
78
+
75
79
  Returns:
76
80
  A JSON object containing the details of the requested report.
77
81
  """
@@ -80,7 +84,11 @@ class YoutubeApp(APIApplication):
80
84
  if reportId is None:
81
85
  raise ValueError("Missing required parameter 'reportId'")
82
86
  url = f"{self.base_url}/v1/jobs/{jobId}/reports/{reportId}"
83
- query_params = {k: v for k, v in [('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
87
+ query_params = {
88
+ k: v
89
+ for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)]
90
+ if v is not None
91
+ }
84
92
  response = self._get(url, params=query_params)
85
93
  response.raise_for_status()
86
94
  return response.json()
@@ -88,37 +96,56 @@ class YoutubeApp(APIApplication):
88
96
  def delete_jobs_job(self, jobId, onBehalfOfContentOwner=None) -> Any:
89
97
  """
90
98
  Deletes a job with the specified job ID, optionally acting on behalf of a content owner.
91
-
99
+
92
100
  Args:
93
101
  jobId: The unique identifier of the job to be deleted. Must not be None.
94
102
  onBehalfOfContentOwner: Optional. The ID of the content owner on whose behalf the request is made.
95
-
103
+
96
104
  Returns:
97
105
  Returns the JSON response of the delete operation as a Python dictionary.
98
106
  """
99
107
  if jobId is None:
100
108
  raise ValueError("Missing required parameter 'jobId'")
101
109
  url = f"{self.base_url}/v1/jobs/{jobId}"
102
- query_params = {k: v for k, v in [('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
110
+ query_params = {
111
+ k: v
112
+ for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)]
113
+ if v is not None
114
+ }
103
115
  response = self._delete(url, params=query_params)
104
116
  response.raise_for_status()
105
117
  return response.json()
106
118
 
107
- def get_jobs(self, includeSystemManaged=None, onBehalfOfContentOwner=None, pageSize=None, pageToken=None) -> Any:
119
+ def get_jobs(
120
+ self,
121
+ includeSystemManaged=None,
122
+ onBehalfOfContentOwner=None,
123
+ pageSize=None,
124
+ pageToken=None,
125
+ ) -> Any:
108
126
  """
109
127
  Retrieves a list of jobs from the server, optionally filtering by specified query parameters.
110
-
128
+
111
129
  Args:
112
130
  includeSystemManaged: Optional; a boolean indicating whether to include system managed jobs in the result.
113
131
  onBehalfOfContentOwner: Optional; a string representing the content owner on behalf of which the request is made.
114
132
  pageSize: Optional; an integer specifying the number of jobs to return per page.
115
133
  pageToken: Optional; a string representing the token to specify the start of the page for paginated results.
116
-
134
+
117
135
  Returns:
118
136
  A JSON-decoded response containing the list of jobs and related metadata.
119
137
  """
120
138
  url = f"{self.base_url}/v1/jobs"
121
- query_params = {k: v for k, v in [('includeSystemManaged', includeSystemManaged), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('pageSize', pageSize), ('pageToken', pageToken)] if v is not None}
139
+ query_params = {
140
+ k: v
141
+ for k, v in [
142
+ ("includeSystemManaged", includeSystemManaged),
143
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
144
+ ("pageSize", pageSize),
145
+ ("pageToken", pageToken),
146
+ ]
147
+ if v is not None
148
+ }
122
149
  response = self._get(url, params=query_params)
123
150
  response.raise_for_status()
124
151
  return response.json()
@@ -126,10 +153,10 @@ class YoutubeApp(APIApplication):
126
153
  def get_media_resource_name(self, resourceName) -> Any:
127
154
  """
128
155
  Retrieves a media resource by name and returns its JSON representation.
129
-
156
+
130
157
  Args:
131
158
  resourceName: The name of the media resource to be retrieved. Cannot be None.
132
-
159
+
133
160
  Returns:
134
161
  The JSON representation of the media resource.
135
162
  """
@@ -141,61 +168,97 @@ class YoutubeApp(APIApplication):
141
168
  response.raise_for_status()
142
169
  return response.json()
143
170
 
144
- def get_reporttypes(self, includeSystemManaged=None, onBehalfOfContentOwner=None, pageSize=None, pageToken=None) -> Any:
171
+ def get_reporttypes(
172
+ self,
173
+ includeSystemManaged=None,
174
+ onBehalfOfContentOwner=None,
175
+ pageSize=None,
176
+ pageToken=None,
177
+ ) -> Any:
145
178
  """
146
179
  Retrieves a list of report types from the API with optional filtering and pagination.
147
-
180
+
148
181
  Args:
149
182
  includeSystemManaged: Optional; a boolean flag indicating if system-managed report types should be included.
150
183
  onBehalfOfContentOwner: Optional; a string that specifies the content owner for whom the user is acting on behalf of.
151
184
  pageSize: Optional; an integer that defines the number of results to return per page.
152
185
  pageToken: Optional; a string token that indicates a specific page of results to retrieve.
153
-
186
+
154
187
  Returns:
155
188
  A JSON object containing the list of report types available from the API.
156
189
  """
157
190
  url = f"{self.base_url}/v1/reportTypes"
158
- query_params = {k: v for k, v in [('includeSystemManaged', includeSystemManaged), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('pageSize', pageSize), ('pageToken', pageToken)] if v is not None}
191
+ query_params = {
192
+ k: v
193
+ for k, v in [
194
+ ("includeSystemManaged", includeSystemManaged),
195
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
196
+ ("pageSize", pageSize),
197
+ ("pageToken", pageToken),
198
+ ]
199
+ if v is not None
200
+ }
159
201
  response = self._get(url, params=query_params)
160
202
  response.raise_for_status()
161
203
  return response.json()
162
204
 
163
- def delete_captions(self, id=None, onBehalfOf=None, onBehalfOfContentOwner=None) -> Any:
205
+ def delete_captions(
206
+ self, id=None, onBehalfOf=None, onBehalfOfContentOwner=None
207
+ ) -> Any:
164
208
  """
165
209
  Deletes captions from a specified resource.
166
-
210
+
167
211
  Args:
168
212
  id: Optional; the unique identifier for the caption resource to delete.
169
213
  onBehalfOf: Optional; a parameter to identify the user for whom the request is made.
170
214
  onBehalfOfContentOwner: Optional; a parameter to specify the content owner for whom the request is made.
171
-
215
+
172
216
  Returns:
173
217
  Returns the response JSON object after deleting the caption resource.
174
218
  """
175
219
  url = f"{self.base_url}/captions"
176
- query_params = {k: v for k, v in [('id', id), ('onBehalfOf', onBehalfOf), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
220
+ query_params = {
221
+ k: v
222
+ for k, v in [
223
+ ("id", id),
224
+ ("onBehalfOf", onBehalfOf),
225
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
226
+ ]
227
+ if v is not None
228
+ }
177
229
  response = self._delete(url, params=query_params)
178
230
  response.raise_for_status()
179
231
  return response.json()
180
232
 
181
- def get_captions(self, id, onBehalfOf=None, onBehalfOfContentOwner=None, tfmt=None, tlang=None) -> Any:
233
+ def get_captions(
234
+ self, id, onBehalfOf=None, onBehalfOfContentOwner=None, tfmt=None, tlang=None
235
+ ) -> Any:
182
236
  """
183
237
  Retrieves captions for a specified video by its ID, optionally allowing additional query customizations.
184
-
238
+
185
239
  Args:
186
240
  id: The unique identifier for the video whose captions are to be retrieved. This parameter is mandatory.
187
241
  onBehalfOf: The ID of the user on whose behalf the request is made. Defaults to None.
188
242
  onBehalfOfContentOwner: The ID of the content owner on whose behalf the request is made. Defaults to None.
189
243
  tfmt: The format of the caption track, such as 'srt' or 'ttml'. Defaults to None.
190
244
  tlang: The language of the caption track, specified as a language code. Defaults to None.
191
-
245
+
192
246
  Returns:
193
247
  A JSON object containing the captions data for the specified video.
194
248
  """
195
249
  if id is None:
196
250
  raise ValueError("Missing required parameter 'id'")
197
251
  url = f"{self.base_url}/captions/{id}"
198
- query_params = {k: v for k, v in [('onBehalfOf', onBehalfOf), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('tfmt', tfmt), ('tlang', tlang)] if v is not None}
252
+ query_params = {
253
+ k: v
254
+ for k, v in [
255
+ ("onBehalfOf", onBehalfOf),
256
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
257
+ ("tfmt", tfmt),
258
+ ("tlang", tlang),
259
+ ]
260
+ if v is not None
261
+ }
199
262
  response = self._get(url, params=query_params)
200
263
  response.raise_for_status()
201
264
  return response.json()
@@ -203,15 +266,15 @@ class YoutubeApp(APIApplication):
203
266
  def delete_comments(self, id=None) -> Any:
204
267
  """
205
268
  Deletes a comment or comments from the server based on the specified ID.
206
-
269
+
207
270
  Args:
208
271
  id: Optional ID of the comment to be deleted. If not provided, and based on implementation, all comments may be deleted.
209
-
272
+
210
273
  Returns:
211
274
  The JSON response from the server after attempting to delete the comment(s).
212
275
  """
213
276
  url = f"{self.base_url}/comments"
214
- query_params = {k: v for k, v in [('id', id)] if v is not None}
277
+ query_params = {k: v for k, v in [("id", id)] if v is not None}
215
278
  response = self._delete(url, params=query_params)
216
279
  response.raise_for_status()
217
280
  return response.json()
@@ -219,79 +282,125 @@ class YoutubeApp(APIApplication):
219
282
  def add_comments_mark_as_spam(self, id=None) -> Any:
220
283
  """
221
284
  Marks a comment as spam by sending a POST request to the specified API endpoint.
222
-
285
+
223
286
  Args:
224
287
  id: Optional; the unique identifier of the comment to be marked as spam. If not provided, no specific comment ID is included in the request parameters.
225
-
288
+
226
289
  Returns:
227
290
  The JSON response from the API containing the result of the mark-as-spam operation.
228
291
  """
229
292
  url = f"{self.base_url}/comments/markAsSpam"
230
- query_params = {k: v for k, v in [('id', id)] if v is not None}
293
+ query_params = {k: v for k, v in [("id", id)] if v is not None}
231
294
  response = self._post(url, data={}, params=query_params)
232
295
  response.raise_for_status()
233
296
  return response.json()
234
297
 
235
- def add_comments_set_moderation_status(self, banAuthor=None, id=None, moderationStatus=None) -> Any:
298
+ def add_comments_set_moderation_status(
299
+ self, banAuthor=None, id=None, moderationStatus=None
300
+ ) -> Any:
236
301
  """
237
302
  Sets the moderation status for a comment and optionally bans the author.
238
-
303
+
239
304
  Args:
240
305
  banAuthor: Optional; a boolean indicating whether to ban the author of the comment.
241
306
  id: Optional; a string representing the unique identifier of the comment to be moderated.
242
307
  moderationStatus: Optional; a string specifying the desired moderation status for the comment, such as 'approved', 'rejected', etc.
243
-
308
+
244
309
  Returns:
245
310
  A JSON object containing the response from the server after attempting to set the moderation status for the specified comment.
246
311
  """
247
312
  url = f"{self.base_url}/comments/setModerationStatus"
248
- query_params = {k: v for k, v in [('banAuthor', banAuthor), ('id', id), ('moderationStatus', moderationStatus)] if v is not None}
313
+ query_params = {
314
+ k: v
315
+ for k, v in [
316
+ ("banAuthor", banAuthor),
317
+ ("id", id),
318
+ ("moderationStatus", moderationStatus),
319
+ ]
320
+ if v is not None
321
+ }
249
322
  response = self._post(url, data={}, params=query_params)
250
323
  response.raise_for_status()
251
324
  return response.json()
252
325
 
253
- def delete_live_broadcasts(self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None) -> Any:
326
+ def delete_live_broadcasts(
327
+ self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None
328
+ ) -> Any:
254
329
  """
255
330
  Deletes live broadcasts from a platform using specified query parameters.
256
-
331
+
257
332
  Args:
258
333
  id: Optional; The unique identifier for the live broadcast to delete.
259
334
  onBehalfOfContentOwner: Optional; The content owner on whose behalf the API request is being made.
260
335
  onBehalfOfContentOwnerChannel: Optional; The channel ID associated with the content owner.
261
-
336
+
262
337
  Returns:
263
338
  A JSON object containing the server's response to the delete request.
264
339
  """
265
340
  url = f"{self.base_url}/liveBroadcasts"
266
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('onBehalfOfContentOwnerChannel', onBehalfOfContentOwnerChannel)] if v is not None}
341
+ query_params = {
342
+ k: v
343
+ for k, v in [
344
+ ("id", id),
345
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
346
+ ("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel),
347
+ ]
348
+ if v is not None
349
+ }
267
350
  response = self._delete(url, params=query_params)
268
351
  response.raise_for_status()
269
352
  return response.json()
270
353
 
271
- def add_live_broadcasts_bind(self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None, part=None, streamId=None) -> Any:
354
+ def add_live_broadcasts_bind(
355
+ self,
356
+ id=None,
357
+ onBehalfOfContentOwner=None,
358
+ onBehalfOfContentOwnerChannel=None,
359
+ part=None,
360
+ streamId=None,
361
+ ) -> Any:
272
362
  """
273
363
  Binds a live broadcast to a stream on YouTube, using specified parameters to authenticate and identify the broadcast and stream.
274
-
364
+
275
365
  Args:
276
366
  id: Optional; str. The id of the live broadcast to bind.
277
367
  onBehalfOfContentOwner: Optional; str. The YouTube CMS content owner on behalf of whom the operation is performed.
278
368
  onBehalfOfContentOwnerChannel: Optional; str. The YouTube channel ID for which the live broadcast is operated, on behalf of a content owner.
279
369
  part: Optional; str. The part parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include.
280
370
  streamId: Optional; str. The id of the stream to which the live broadcast is to be bound.
281
-
371
+
282
372
  Returns:
283
373
  The JSON response object from the YouTube API after attempting to bind the live broadcast to the stream.
284
374
  """
285
375
  url = f"{self.base_url}/liveBroadcasts/bind"
286
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('onBehalfOfContentOwnerChannel', onBehalfOfContentOwnerChannel), ('part', part), ('streamId', streamId)] if v is not None}
376
+ query_params = {
377
+ k: v
378
+ for k, v in [
379
+ ("id", id),
380
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
381
+ ("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel),
382
+ ("part", part),
383
+ ("streamId", streamId),
384
+ ]
385
+ if v is not None
386
+ }
287
387
  response = self._post(url, data={}, params=query_params)
288
388
  response.raise_for_status()
289
389
  return response.json()
290
390
 
291
- def add_live_broadcasts_control(self, displaySlate=None, id=None, offsetTimeMs=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None, part=None, walltime=None) -> Any:
391
+ def add_live_broadcasts_control(
392
+ self,
393
+ displaySlate=None,
394
+ id=None,
395
+ offsetTimeMs=None,
396
+ onBehalfOfContentOwner=None,
397
+ onBehalfOfContentOwnerChannel=None,
398
+ part=None,
399
+ walltime=None,
400
+ ) -> Any:
292
401
  """
293
402
  Controls a live broadcast by sending a POST request with specified parameters.
294
-
403
+
295
404
  Args:
296
405
  displaySlate: Optional; Specifies whether or not to show a slate during the broadcast.
297
406
  id: Optional; The ID of the live broadcast to control.
@@ -300,32 +409,61 @@ class YoutubeApp(APIApplication):
300
409
  onBehalfOfContentOwnerChannel: Optional; The channel owned by the content owner.
301
410
  part: Optional; Specifies a comma-separated list of one or more broadcasts resource properties.
302
411
  walltime: Optional; An RFC 3339 timestamp that represents the time at which the action takes place.
303
-
412
+
304
413
  Returns:
305
414
  The JSON response from the server after controlling the live broadcast.
306
415
  """
307
416
  url = f"{self.base_url}/liveBroadcasts/control"
308
- query_params = {k: v for k, v in [('displaySlate', displaySlate), ('id', id), ('offsetTimeMs', offsetTimeMs), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('onBehalfOfContentOwnerChannel', onBehalfOfContentOwnerChannel), ('part', part), ('walltime', walltime)] if v is not None}
417
+ query_params = {
418
+ k: v
419
+ for k, v in [
420
+ ("displaySlate", displaySlate),
421
+ ("id", id),
422
+ ("offsetTimeMs", offsetTimeMs),
423
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
424
+ ("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel),
425
+ ("part", part),
426
+ ("walltime", walltime),
427
+ ]
428
+ if v is not None
429
+ }
309
430
  response = self._post(url, data={}, params=query_params)
310
431
  response.raise_for_status()
311
432
  return response.json()
312
433
 
313
- def add_live_broadcasts_transition(self, broadcastStatus=None, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None, part=None) -> Any:
434
+ def add_live_broadcasts_transition(
435
+ self,
436
+ broadcastStatus=None,
437
+ id=None,
438
+ onBehalfOfContentOwner=None,
439
+ onBehalfOfContentOwnerChannel=None,
440
+ part=None,
441
+ ) -> Any:
314
442
  """
315
443
  Transitions a live broadcast to a specified status for a given broadcast ID.
316
-
444
+
317
445
  Args:
318
446
  broadcastStatus: Optional; The status to which the live broadcast should be transitioned.
319
447
  id: Optional; The unique identifier of the broadcast that needs to be transitioned.
320
448
  onBehalfOfContentOwner: Optional; The YouTube content owner on whose behalf the API request is being made.
321
449
  onBehalfOfContentOwnerChannel: Optional; The YouTube channel ID of the channel associated with the specified content owner.
322
450
  part: Optional; A comma-separated list of one or more liveBroadcast resource properties that the API response will include.
323
-
451
+
324
452
  Returns:
325
453
  The JSON response from the API containing the details of the transitioned live broadcast.
326
454
  """
327
455
  url = f"{self.base_url}/liveBroadcasts/transition"
328
- query_params = {k: v for k, v in [('broadcastStatus', broadcastStatus), ('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('onBehalfOfContentOwnerChannel', onBehalfOfContentOwnerChannel), ('part', part)] if v is not None}
456
+ query_params = {
457
+ k: v
458
+ for k, v in [
459
+ ("broadcastStatus", broadcastStatus),
460
+ ("id", id),
461
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
462
+ ("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel),
463
+ ("part", part),
464
+ ]
465
+ if v is not None
466
+ }
329
467
  response = self._post(url, data={}, params=query_params)
330
468
  response.raise_for_status()
331
469
  return response.json()
@@ -333,15 +471,15 @@ class YoutubeApp(APIApplication):
333
471
  def delete_live_chat_bans(self, id=None) -> Any:
334
472
  """
335
473
  Deletes a live chat ban identified by the given ID from the server.
336
-
474
+
337
475
  Args:
338
476
  id: Optional; The unique identifier of the live chat ban to be deleted. If None, no specific ban is targeted.
339
-
477
+
340
478
  Returns:
341
479
  The JSON response from the server after the delete operation, which may include details of the deletion.
342
480
  """
343
481
  url = f"{self.base_url}/liveChat/bans"
344
- query_params = {k: v for k, v in [('id', id)] if v is not None}
482
+ query_params = {k: v for k, v in [("id", id)] if v is not None}
345
483
  response = self._delete(url, params=query_params)
346
484
  response.raise_for_status()
347
485
  return response.json()
@@ -349,15 +487,15 @@ class YoutubeApp(APIApplication):
349
487
  def delete_live_chat_messages(self, id=None) -> Any:
350
488
  """
351
489
  Deletes live chat messages based on the specified message ID.
352
-
490
+
353
491
  Args:
354
492
  id: Optional; The identifier of the specific live chat message to be deleted. If not provided, it defaults to None.
355
-
493
+
356
494
  Returns:
357
495
  A JSON object containing the server's response to the deletion request. It includes details about the operation's success or failure.
358
496
  """
359
497
  url = f"{self.base_url}/liveChat/messages"
360
- query_params = {k: v for k, v in [('id', id)] if v is not None}
498
+ query_params = {k: v for k, v in [("id", id)] if v is not None}
361
499
  response = self._delete(url, params=query_params)
362
500
  response.raise_for_status()
363
501
  return response.json()
@@ -365,15 +503,15 @@ class YoutubeApp(APIApplication):
365
503
  def delete_live_chat_moderators(self, id=None) -> Any:
366
504
  """
367
505
  Deletes a live chat moderator by ID.
368
-
506
+
369
507
  Args:
370
508
  id: The ID of the live chat moderator to delete. If None, no moderator is deleted.
371
-
509
+
372
510
  Returns:
373
511
  The JSON response from the server after attempting to delete the moderator.
374
512
  """
375
513
  url = f"{self.base_url}/liveChat/moderators"
376
- query_params = {k: v for k, v in [('id', id)] if v is not None}
514
+ query_params = {k: v for k, v in [("id", id)] if v is not None}
377
515
  response = self._delete(url, params=query_params)
378
516
  response.raise_for_status()
379
517
  return response.json()
@@ -381,16 +519,20 @@ class YoutubeApp(APIApplication):
381
519
  def delete_videos(self, id=None, onBehalfOfContentOwner=None) -> Any:
382
520
  """
383
521
  Deletes videos based on specified criteria from a video platform.
384
-
522
+
385
523
  Args:
386
524
  id: Optional; A string representing the unique identifier of the video to be deleted. If not provided, no video ID will be specified for deletion.
387
525
  onBehalfOfContentOwner: Optional; A string representing the content owner on whose behalf the operation is being performed. If omitted, the operation is performed on behalf of the authenticated user.
388
-
526
+
389
527
  Returns:
390
528
  Returns a JSON object containing the response from the API after attempting to delete the video(s), including any relevant status or error information.
391
529
  """
392
530
  url = f"{self.base_url}/videos"
393
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
531
+ query_params = {
532
+ k: v
533
+ for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
534
+ if v is not None
535
+ }
394
536
  response = self._delete(url, params=query_params)
395
537
  response.raise_for_status()
396
538
  return response.json()
@@ -398,16 +540,20 @@ class YoutubeApp(APIApplication):
398
540
  def get_videos_get_rating(self, id=None, onBehalfOfContentOwner=None) -> Any:
399
541
  """
400
542
  Retrieves the rating of a video using video ID and optional content owner specification.
401
-
543
+
402
544
  Args:
403
545
  id: Optional; The ID of the video for which the rating is to be retrieved. If None, no specific video ID is used in the request.
404
546
  onBehalfOfContentOwner: Optional; Identifies the content owner for whom the request is being made. Used for API requests made on behalf of a content owner.
405
-
547
+
406
548
  Returns:
407
549
  A JSON object containing the video rating information returned by the API.
408
550
  """
409
551
  url = f"{self.base_url}/videos/getRating"
410
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
552
+ query_params = {
553
+ k: v
554
+ for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
555
+ if v is not None
556
+ }
411
557
  response = self._get(url, params=query_params)
412
558
  response.raise_for_status()
413
559
  return response.json()
@@ -415,16 +561,18 @@ class YoutubeApp(APIApplication):
415
561
  def add_videos_rate(self, id=None, rating=None) -> Any:
416
562
  """
417
563
  Submit a rating for a video on the server using the provided video ID and rating value.
418
-
564
+
419
565
  Args:
420
566
  id: Optional; The unique identifier of the video to rate. If None, the video ID is not included in the request.
421
567
  rating: Optional; The rating value to assign to the video. If None, the rating is not included in the request.
422
-
568
+
423
569
  Returns:
424
570
  The JSON response from the server after submitting the rating.
425
571
  """
426
572
  url = f"{self.base_url}/videos/rate"
427
- query_params = {k: v for k, v in [('id', id), ('rating', rating)] if v is not None}
573
+ query_params = {
574
+ k: v for k, v in [("id", id), ("rating", rating)] if v is not None
575
+ }
428
576
  response = self._post(url, data={}, params=query_params)
429
577
  response.raise_for_status()
430
578
  return response.json()
@@ -432,16 +580,20 @@ class YoutubeApp(APIApplication):
432
580
  def add_videos_report_abuse(self, onBehalfOfContentOwner=None) -> Any:
433
581
  """
434
582
  Sends a report to YouTube indicating a video's potential abuse.
435
-
583
+
436
584
  Args:
437
585
  self: The instance of the class containing this method.
438
586
  onBehalfOfContentOwner: Optional; The YouTube content owner on whose behalf the abuse report is being sent.
439
-
587
+
440
588
  Returns:
441
589
  The JSON response from the YouTube API after reporting the abuse.
442
590
  """
443
591
  url = f"{self.base_url}/videos/reportAbuse"
444
- query_params = {k: v for k, v in [('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
592
+ query_params = {
593
+ k: v
594
+ for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)]
595
+ if v is not None
596
+ }
445
597
  response = self._post(url, data={}, params=query_params)
446
598
  response.raise_for_status()
447
599
  return response.json()
@@ -449,16 +601,23 @@ class YoutubeApp(APIApplication):
449
601
  def add_watermarks_set(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
450
602
  """
451
603
  Sets watermarks on a specified YouTube channel using optional content owner credentials.
452
-
604
+
453
605
  Args:
454
606
  channelId: Optional; The ID of the YouTube channel on which to set the watermark.
455
607
  onBehalfOfContentOwner: Optional; The content owner's ID that the request is made on behalf of, allowing authenticated channel actions.
456
-
608
+
457
609
  Returns:
458
610
  The JSON response from the API call, which includes details about the watermark setting operation.
459
611
  """
460
612
  url = f"{self.base_url}/watermarks/set"
461
- query_params = {k: v for k, v in [('channelId', channelId), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
613
+ query_params = {
614
+ k: v
615
+ for k, v in [
616
+ ("channelId", channelId),
617
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
618
+ ]
619
+ if v is not None
620
+ }
462
621
  response = self._post(url, data={}, params=query_params)
463
622
  response.raise_for_status()
464
623
  return response.json()
@@ -466,24 +625,42 @@ class YoutubeApp(APIApplication):
466
625
  def add_watermarks_unset(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
467
626
  """
468
627
  Removes watermarks from a YouTube channel specified by channel ID.
469
-
628
+
470
629
  Args:
471
630
  channelId: Optional; The unique identifier of the YouTube channel from which to remove watermarks.
472
631
  onBehalfOfContentOwner: Optional; The content owner that the request is on behalf of, used by YouTube content partners.
473
-
632
+
474
633
  Returns:
475
634
  The JSON response from the YouTube API after attempting to remove the watermarks.
476
635
  """
477
636
  url = f"{self.base_url}/watermarks/unset"
478
- query_params = {k: v for k, v in [('channelId', channelId), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
637
+ query_params = {
638
+ k: v
639
+ for k, v in [
640
+ ("channelId", channelId),
641
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
642
+ ]
643
+ if v is not None
644
+ }
479
645
  response = self._post(url, data={}, params=query_params)
480
646
  response.raise_for_status()
481
647
  return response.json()
482
648
 
483
- def get_activities(self, channelId=None, home=None, maxResults=None, mine=None, pageToken=None, part=None, publishedAfter=None, publishedBefore=None, regionCode=None) -> Any:
649
+ def get_activities(
650
+ self,
651
+ channelId=None,
652
+ home=None,
653
+ maxResults=None,
654
+ mine=None,
655
+ pageToken=None,
656
+ part=None,
657
+ publishedAfter=None,
658
+ publishedBefore=None,
659
+ regionCode=None,
660
+ ) -> Any:
484
661
  """
485
662
  Get YouTube channel activities.
486
-
663
+
487
664
  Args:
488
665
  channelId: Channel ID
489
666
  home: User's feed
@@ -494,29 +671,52 @@ class YoutubeApp(APIApplication):
494
671
  publishedAfter: After date
495
672
  publishedBefore: Before date
496
673
  regionCode: Region code
497
-
674
+
498
675
  Returns:
499
676
  JSON with activities
500
677
  """
501
678
  url = f"{self.base_url}/activities"
502
- query_params = {k: v for k, v in [('channelId', channelId), ('home', home), ('maxResults', maxResults), ('mine', mine), ('pageToken', pageToken), ('part', part), ('publishedAfter', publishedAfter), ('publishedBefore', publishedBefore), ('regionCode', regionCode)] if v is not None}
679
+ query_params = {
680
+ k: v
681
+ for k, v in [
682
+ ("channelId", channelId),
683
+ ("home", home),
684
+ ("maxResults", maxResults),
685
+ ("mine", mine),
686
+ ("pageToken", pageToken),
687
+ ("part", part),
688
+ ("publishedAfter", publishedAfter),
689
+ ("publishedBefore", publishedBefore),
690
+ ("regionCode", regionCode),
691
+ ]
692
+ if v is not None
693
+ }
503
694
  response = self._get(url, params=query_params)
504
695
  response.raise_for_status()
505
696
  return response.json()
506
697
 
507
- def add_channel_banners_insert(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
698
+ def add_channel_banners_insert(
699
+ self, channelId=None, onBehalfOfContentOwner=None
700
+ ) -> Any:
508
701
  """
509
702
  Inserts a new channel banner for a specified YouTube channel using YouTube Data API.
510
-
703
+
511
704
  Args:
512
705
  channelId: Optional; A string representing the unique identifier of the YouTube channel for which the banner is being inserted.
513
706
  onBehalfOfContentOwner: Optional; A string indicating that the request is on behalf of an authenticated content owner and specifies the content owner's external ID.
514
-
707
+
515
708
  Returns:
516
709
  A JSON object containing the response from the YouTube Data API with details about the newly inserted channel banner.
517
710
  """
518
711
  url = f"{self.base_url}/channelBanners/insert"
519
- query_params = {k: v for k, v in [('channelId', channelId), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
712
+ query_params = {
713
+ k: v
714
+ for k, v in [
715
+ ("channelId", channelId),
716
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
717
+ ]
718
+ if v is not None
719
+ }
520
720
  response = self._post(url, data={}, params=query_params)
521
721
  response.raise_for_status()
522
722
  return response.json()
@@ -524,24 +724,41 @@ class YoutubeApp(APIApplication):
524
724
  def delete_channel_sections(self, id=None, onBehalfOfContentOwner=None) -> Any:
525
725
  """
526
726
  Deletes channel sections from a platform specified by the base URL.
527
-
727
+
528
728
  Args:
529
729
  id: Optional; A string representing the unique identifier of the channel section to be deleted.
530
730
  onBehalfOfContentOwner: Optional; A string indicating that the request is being made on behalf of the content owner specified by this parameter.
531
-
731
+
532
732
  Returns:
533
733
  Returns a JSON-decoded response object from the server after attempting to delete the specified channel section.
534
734
  """
535
735
  url = f"{self.base_url}/channelSections"
536
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
736
+ query_params = {
737
+ k: v
738
+ for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
739
+ if v is not None
740
+ }
537
741
  response = self._delete(url, params=query_params)
538
742
  response.raise_for_status()
539
743
  return response.json()
540
744
 
541
- def get_channels(self, categoryId=None, forUsername=None, hl=None, id=None, managedByMe=None, maxResults=None, mine=None, mySubscribers=None, onBehalfOfContentOwner=None, pageToken=None, part=None) -> Any:
745
+ def get_channels(
746
+ self,
747
+ categoryId=None,
748
+ forUsername=None,
749
+ hl=None,
750
+ id=None,
751
+ managedByMe=None,
752
+ maxResults=None,
753
+ mine=None,
754
+ mySubscribers=None,
755
+ onBehalfOfContentOwner=None,
756
+ pageToken=None,
757
+ part=None,
758
+ ) -> Any:
542
759
  """
543
760
  Get YouTube channels.
544
-
761
+
545
762
  Args:
546
763
  categoryId: Category ID
547
764
  forUsername: Username
@@ -554,23 +771,52 @@ class YoutubeApp(APIApplication):
554
771
  onBehalfOfContentOwner: Owner ID
555
772
  pageToken: Page token
556
773
  part: Response parts
557
-
774
+
558
775
  Returns:
559
776
  JSON with channels
560
777
  """
561
778
  url = f"{self.base_url}/channels"
562
- query_params = {k: v for k, v in [('categoryId', categoryId), ('forUsername', forUsername), ('hl', hl), ('id', id), ('managedByMe', managedByMe), ('maxResults', maxResults), ('mine', mine), ('mySubscribers', mySubscribers), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('pageToken', pageToken), ('part', part)] if v is not None}
779
+ query_params = {
780
+ k: v
781
+ for k, v in [
782
+ ("categoryId", categoryId),
783
+ ("forUsername", forUsername),
784
+ ("hl", hl),
785
+ ("id", id),
786
+ ("managedByMe", managedByMe),
787
+ ("maxResults", maxResults),
788
+ ("mine", mine),
789
+ ("mySubscribers", mySubscribers),
790
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
791
+ ("pageToken", pageToken),
792
+ ("part", part),
793
+ ]
794
+ if v is not None
795
+ }
563
796
  response = self._get(url, params=query_params)
564
797
  response.raise_for_status()
565
798
  return response.json()
566
799
 
567
- def get_comment_threads(self, allThreadsRelatedToChannelId=None, channelId=None, id=None, maxResults=None, moderationStatus=None, order=None, pageToken=None, part=None, searchTerms=None, textFormat=None, videoId=None) -> Any:
800
+ def get_comment_threads(
801
+ self,
802
+ allThreadsRelatedToChannelId=None,
803
+ channelId=None,
804
+ id=None,
805
+ maxResults=None,
806
+ moderationStatus=None,
807
+ order=None,
808
+ pageToken=None,
809
+ part=None,
810
+ searchTerms=None,
811
+ textFormat=None,
812
+ videoId=None,
813
+ ) -> Any:
568
814
  """
569
815
  Get YouTube comment threads.
570
-
816
+
571
817
  Args:
572
818
  allThreadsRelatedToChannelId: Threads for channel
573
- channelId: Channel ID
819
+ channelId: Channel ID
574
820
  id: Comment thread IDs
575
821
  maxResults: Results limit
576
822
  moderationStatus: Moderation status
@@ -580,31 +826,58 @@ class YoutubeApp(APIApplication):
580
826
  searchTerms: Search terms
581
827
  textFormat: Text format
582
828
  videoId: Video ID
583
-
829
+
584
830
  Returns:
585
831
  JSON with comment threads
586
832
  """
587
833
  url = f"{self.base_url}/commentThreads"
588
- query_params = {k: v for k, v in [('allThreadsRelatedToChannelId', allThreadsRelatedToChannelId), ('channelId', channelId), ('id', id), ('maxResults', maxResults), ('moderationStatus', moderationStatus), ('order', order), ('pageToken', pageToken), ('part', part), ('searchTerms', searchTerms), ('textFormat', textFormat), ('videoId', videoId)] if v is not None}
834
+ query_params = {
835
+ k: v
836
+ for k, v in [
837
+ ("allThreadsRelatedToChannelId", allThreadsRelatedToChannelId),
838
+ ("channelId", channelId),
839
+ ("id", id),
840
+ ("maxResults", maxResults),
841
+ ("moderationStatus", moderationStatus),
842
+ ("order", order),
843
+ ("pageToken", pageToken),
844
+ ("part", part),
845
+ ("searchTerms", searchTerms),
846
+ ("textFormat", textFormat),
847
+ ("videoId", videoId),
848
+ ]
849
+ if v is not None
850
+ }
589
851
  response = self._get(url, params=query_params)
590
852
  response.raise_for_status()
591
853
  return response.json()
592
854
 
593
- def get_fanfundingevents(self, hl=None, maxResults=None, pageToken=None, part=None) -> Any:
855
+ def get_fanfundingevents(
856
+ self, hl=None, maxResults=None, pageToken=None, part=None
857
+ ) -> Any:
594
858
  """
595
859
  Retrieves fan funding events based on specified filter criteria.
596
-
860
+
597
861
  Args:
598
862
  hl: Optional; a string representing the language for text values. If not specified, the default language will be used.
599
863
  maxResults: Optional; an integer specifying the maximum number of results to return. If not specified, a server-determined default will be used.
600
864
  pageToken: Optional; a string token to retrieve a specific page in a paginated set of results. Useful for navigating through large sets of data.
601
865
  part: Optional; a comma-separated list of one or more 'fanFundingEvent' resource properties that the API response will include.
602
-
866
+
603
867
  Returns:
604
868
  The function returns the JSON-decoded response of the fan funding events data retrieved from the API.
605
869
  """
606
870
  url = f"{self.base_url}/fanFundingEvents"
607
- query_params = {k: v for k, v in [('hl', hl), ('maxResults', maxResults), ('pageToken', pageToken), ('part', part)] if v is not None}
871
+ query_params = {
872
+ k: v
873
+ for k, v in [
874
+ ("hl", hl),
875
+ ("maxResults", maxResults),
876
+ ("pageToken", pageToken),
877
+ ("part", part),
878
+ ]
879
+ if v is not None
880
+ }
608
881
  response = self._get(url, params=query_params)
609
882
  response.raise_for_status()
610
883
  return response.json()
@@ -612,18 +885,27 @@ class YoutubeApp(APIApplication):
612
885
  def get_guecategories(self, hl=None, id=None, part=None, regionCode=None) -> Any:
613
886
  """
614
887
  Fetches guide categories from a remote service based on specified parameters.
615
-
888
+
616
889
  Args:
617
890
  hl: Optional; a string that specifies the language localization.
618
891
  id: Optional; a string representing the ID of the guide category.
619
892
  part: Optional; a string indicating which parts of the guide category resource to return.
620
893
  regionCode: Optional; a string that denotes the region of interest.
621
-
894
+
622
895
  Returns:
623
896
  A dictionary containing the JSON response representing guide categories from the service.
624
897
  """
625
898
  url = f"{self.base_url}/guideCategories"
626
- query_params = {k: v for k, v in [('hl', hl), ('id', id), ('part', part), ('regionCode', regionCode)] if v is not None}
899
+ query_params = {
900
+ k: v
901
+ for k, v in [
902
+ ("hl", hl),
903
+ ("id", id),
904
+ ("part", part),
905
+ ("regionCode", regionCode),
906
+ ]
907
+ if v is not None
908
+ }
627
909
  response = self._get(url, params=query_params)
628
910
  response.raise_for_status()
629
911
  return response.json()
@@ -631,16 +913,16 @@ class YoutubeApp(APIApplication):
631
913
  def get_languages(self, hl=None, part=None) -> Any:
632
914
  """
633
915
  Fetches a list of supported languages from the internationalization API.
634
-
916
+
635
917
  Args:
636
918
  hl: Optional; The language code to localize the language names, e.g., 'en' for English.
637
919
  part: Optional; The part parameter specifies a comma-separated list of one or more i18nLanguage resource properties that the API response will include.
638
-
920
+
639
921
  Returns:
640
922
  A JSON object containing the API response with the list of supported languages.
641
923
  """
642
924
  url = f"{self.base_url}/i18nLanguages"
643
- query_params = {k: v for k, v in [('hl', hl), ('part', part)] if v is not None}
925
+ query_params = {k: v for k, v in [("hl", hl), ("part", part)] if v is not None}
644
926
  response = self._get(url, params=query_params)
645
927
  response.raise_for_status()
646
928
  return response.json()
@@ -648,34 +930,44 @@ class YoutubeApp(APIApplication):
648
930
  def get_regions(self, hl=None, part=None) -> Any:
649
931
  """
650
932
  Retrieves a list of i18n regions from a specified API endpoint.
651
-
933
+
652
934
  Args:
653
935
  hl: Optional; a string representing the language code for which the regions are requested.
654
936
  part: Optional; a string specifying a comma-separated list of one or more i18nRegion resource parts to include in the API response.
655
-
937
+
656
938
  Returns:
657
939
  The JSON response from the API containing the list of i18n regions.
658
940
  """
659
941
  url = f"{self.base_url}/i18nRegions"
660
- query_params = {k: v for k, v in [('hl', hl), ('part', part)] if v is not None}
942
+ query_params = {k: v for k, v in [("hl", hl), ("part", part)] if v is not None}
661
943
  response = self._get(url, params=query_params)
662
944
  response.raise_for_status()
663
945
  return response.json()
664
946
 
665
- def delete_livestreams(self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None) -> Any:
947
+ def delete_livestreams(
948
+ self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None
949
+ ) -> Any:
666
950
  """
667
951
  Deletes a livestream resource from the YouTube Data API using optional filtering parameters.
668
-
952
+
669
953
  Args:
670
954
  id: Optional; A comma-separated list of YouTube livestream IDs that identify the resources to be deleted.
671
955
  onBehalfOfContentOwner: Optional; YouTube content owner who is channel owner of the livestream and makes this API call.
672
956
  onBehalfOfContentOwnerChannel: Optional; The YouTube channel ID on behalf of which the API call is being made.
673
-
957
+
674
958
  Returns:
675
959
  A JSON object containing the API's response to the delete request.
676
960
  """
677
961
  url = f"{self.base_url}/liveStreams"
678
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('onBehalfOfContentOwnerChannel', onBehalfOfContentOwnerChannel)] if v is not None}
962
+ query_params = {
963
+ k: v
964
+ for k, v in [
965
+ ("id", id),
966
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
967
+ ("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel),
968
+ ]
969
+ if v is not None
970
+ }
679
971
  response = self._delete(url, params=query_params)
680
972
  response.raise_for_status()
681
973
  return response.json()
@@ -683,16 +975,20 @@ class YoutubeApp(APIApplication):
683
975
  def delete_play_list_items(self, id=None, onBehalfOfContentOwner=None) -> Any:
684
976
  """
685
977
  Deletes playlist items identified by the given id or on behalf of the specified content owner.
686
-
978
+
687
979
  Args:
688
980
  id: Optional; The ID of the playlist item to be deleted.
689
981
  onBehalfOfContentOwner: Optional; The content owner on whose behalf the playlist item is being deleted.
690
-
982
+
691
983
  Returns:
692
984
  The JSON response from the server indicating the result of the deletion operation.
693
985
  """
694
986
  url = f"{self.base_url}/playlistItems"
695
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
987
+ query_params = {
988
+ k: v
989
+ for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
990
+ if v is not None
991
+ }
696
992
  response = self._delete(url, params=query_params)
697
993
  response.raise_for_status()
698
994
  return response.json()
@@ -700,24 +996,61 @@ class YoutubeApp(APIApplication):
700
996
  def delete_playlists(self, id=None, onBehalfOfContentOwner=None) -> Any:
701
997
  """
702
998
  Deletes playlists based on specified criteria.
703
-
999
+
704
1000
  Args:
705
1001
  id: Optional; A string representing the ID of the playlist to delete. Default is None.
706
1002
  onBehalfOfContentOwner: Optional; A string representing the content owner in whose behalf the operation is being performed. Default is None.
707
-
1003
+
708
1004
  Returns:
709
1005
  The JSON response from the server as a result of the delete operation.
710
1006
  """
711
1007
  url = f"{self.base_url}/playlists"
712
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
1008
+ query_params = {
1009
+ k: v
1010
+ for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
1011
+ if v is not None
1012
+ }
713
1013
  response = self._delete(url, params=query_params)
714
1014
  response.raise_for_status()
715
1015
  return response.json()
716
1016
 
717
- def get_search(self, channelId=None, channelType=None, eventType=None, forContentOwner=None, forDeveloper=None, forMine=None, location=None, locationRadius=None, maxResults=None, onBehalfOfContentOwner=None, order=None, pageToken=None, part=None, publishedAfter=None, publishedBefore=None, q=None, regionCode=None, relatedToVideoId=None, relevanceLanguage=None, safeSearch=None, topicId=None, type=None, videoCaption=None, videoCategoryId=None, videoDefinition=None, videoDimension=None, videoDuration=None, videoEmbeddable=None, videoLicense=None, videoSyndicated=None, videoType=None) -> Any:
1017
+ def get_search(
1018
+ self,
1019
+ channelId=None,
1020
+ channelType=None,
1021
+ eventType=None,
1022
+ forContentOwner=None,
1023
+ forDeveloper=None,
1024
+ forMine=None,
1025
+ location=None,
1026
+ locationRadius=None,
1027
+ maxResults=None,
1028
+ onBehalfOfContentOwner=None,
1029
+ order=None,
1030
+ pageToken=None,
1031
+ part=None,
1032
+ publishedAfter=None,
1033
+ publishedBefore=None,
1034
+ q=None,
1035
+ regionCode=None,
1036
+ relatedToVideoId=None,
1037
+ relevanceLanguage=None,
1038
+ safeSearch=None,
1039
+ topicId=None,
1040
+ type=None,
1041
+ videoCaption=None,
1042
+ videoCategoryId=None,
1043
+ videoDefinition=None,
1044
+ videoDimension=None,
1045
+ videoDuration=None,
1046
+ videoEmbeddable=None,
1047
+ videoLicense=None,
1048
+ videoSyndicated=None,
1049
+ videoType=None,
1050
+ ) -> Any:
718
1051
  """
719
1052
  Search YouTube Data API with filters.
720
-
1053
+
721
1054
  Args:
722
1055
  channelId: Channel filter
723
1056
  channelType: Channel type
@@ -750,31 +1083,78 @@ class YoutubeApp(APIApplication):
750
1083
  videoLicense: License
751
1084
  videoSyndicated: Syndicated
752
1085
  videoType: Video type
753
-
1086
+
754
1087
  Returns:
755
1088
  JSON with search results
756
1089
  """
757
1090
  url = f"{self.base_url}/search"
758
- query_params = {k: v for k, v in [('channelId', channelId), ('channelType', channelType), ('eventType', eventType), ('forContentOwner', forContentOwner), ('forDeveloper', forDeveloper), ('forMine', forMine), ('location', location), ('locationRadius', locationRadius), ('maxResults', maxResults), ('onBehalfOfContentOwner', onBehalfOfContentOwner), ('order', order), ('pageToken', pageToken), ('part', part), ('publishedAfter', publishedAfter), ('publishedBefore', publishedBefore), ('q', q), ('regionCode', regionCode), ('relatedToVideoId', relatedToVideoId), ('relevanceLanguage', relevanceLanguage), ('safeSearch', safeSearch), ('topicId', topicId), ('type', type), ('videoCaption', videoCaption), ('videoCategoryId', videoCategoryId), ('videoDefinition', videoDefinition), ('videoDimension', videoDimension), ('videoDuration', videoDuration), ('videoEmbeddable', videoEmbeddable), ('videoLicense', videoLicense), ('videoSyndicated', videoSyndicated), ('videoType', videoType)] if v is not None}
1091
+ query_params = {
1092
+ k: v
1093
+ for k, v in [
1094
+ ("channelId", channelId),
1095
+ ("channelType", channelType),
1096
+ ("eventType", eventType),
1097
+ ("forContentOwner", forContentOwner),
1098
+ ("forDeveloper", forDeveloper),
1099
+ ("forMine", forMine),
1100
+ ("location", location),
1101
+ ("locationRadius", locationRadius),
1102
+ ("maxResults", maxResults),
1103
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
1104
+ ("order", order),
1105
+ ("pageToken", pageToken),
1106
+ ("part", part),
1107
+ ("publishedAfter", publishedAfter),
1108
+ ("publishedBefore", publishedBefore),
1109
+ ("q", q),
1110
+ ("regionCode", regionCode),
1111
+ ("relatedToVideoId", relatedToVideoId),
1112
+ ("relevanceLanguage", relevanceLanguage),
1113
+ ("safeSearch", safeSearch),
1114
+ ("topicId", topicId),
1115
+ ("type", type),
1116
+ ("videoCaption", videoCaption),
1117
+ ("videoCategoryId", videoCategoryId),
1118
+ ("videoDefinition", videoDefinition),
1119
+ ("videoDimension", videoDimension),
1120
+ ("videoDuration", videoDuration),
1121
+ ("videoEmbeddable", videoEmbeddable),
1122
+ ("videoLicense", videoLicense),
1123
+ ("videoSyndicated", videoSyndicated),
1124
+ ("videoType", videoType),
1125
+ ]
1126
+ if v is not None
1127
+ }
759
1128
  response = self._get(url, params=query_params)
760
1129
  response.raise_for_status()
761
1130
  return response.json()
762
1131
 
763
- def get_sponsors(self, filter=None, maxResults=None, pageToken=None, part=None) -> Any:
1132
+ def get_sponsors(
1133
+ self, filter=None, maxResults=None, pageToken=None, part=None
1134
+ ) -> Any:
764
1135
  """
765
1136
  Fetches a list of sponsors from a server, applying optional filtering and pagination.
766
-
1137
+
767
1138
  Args:
768
1139
  filter: Optional; A string containing filtering criteria for the sponsors.
769
1140
  maxResults: Optional; An integer limiting the number of sponsors returned.
770
1141
  pageToken: Optional; A token string used to retrieve a specific page of results.
771
1142
  part: Optional; A string specifying which parts of the sponsor details to fetch.
772
-
1143
+
773
1144
  Returns:
774
1145
  The JSON response containing the list of sponsors, potentially filtered and paginated, as returned by the server.
775
1146
  """
776
1147
  url = f"{self.base_url}/sponsors"
777
- query_params = {k: v for k, v in [('filter', filter), ('maxResults', maxResults), ('pageToken', pageToken), ('part', part)] if v is not None}
1148
+ query_params = {
1149
+ k: v
1150
+ for k, v in [
1151
+ ("filter", filter),
1152
+ ("maxResults", maxResults),
1153
+ ("pageToken", pageToken),
1154
+ ("part", part),
1155
+ ]
1156
+ if v is not None
1157
+ }
778
1158
  response = self._get(url, params=query_params)
779
1159
  response.raise_for_status()
780
1160
  return response.json()
@@ -782,34 +1162,45 @@ class YoutubeApp(APIApplication):
782
1162
  def delete_subscriptions(self, id=None) -> Any:
783
1163
  """
784
1164
  Deletes subscriptions by sending a DELETE request to the API.
785
-
1165
+
786
1166
  Args:
787
1167
  id: Optional; An identifier for a specific subscription to delete. If None, deletes all subscriptions.
788
-
1168
+
789
1169
  Returns:
790
1170
  The JSON response from the API after attempting to delete the subscription(s).
791
1171
  """
792
1172
  url = f"{self.base_url}/subscriptions"
793
- query_params = {k: v for k, v in [('id', id)] if v is not None}
1173
+ query_params = {k: v for k, v in [("id", id)] if v is not None}
794
1174
  response = self._delete(url, params=query_params)
795
1175
  response.raise_for_status()
796
1176
  return response.json()
797
1177
 
798
- def get_superchatevents(self, hl=None, maxResults=None, pageToken=None, part=None) -> Any:
1178
+ def get_superchatevents(
1179
+ self, hl=None, maxResults=None, pageToken=None, part=None
1180
+ ) -> Any:
799
1181
  """
800
1182
  Fetches a list of super chat events from the YouTube API with optional filtering parameters.
801
-
1183
+
802
1184
  Args:
803
1185
  hl: Optional; the language code to select localized resource information.
804
1186
  maxResults: Optional; the maximum number of items that should be returned in the result set.
805
1187
  pageToken: Optional; the token to identify a specific page in the result set.
806
1188
  part: Optional; the parameter specifying which super chat event resource parts to include in the response.
807
-
1189
+
808
1190
  Returns:
809
1191
  A JSON object containing the super chat events data returned by the YouTube API.
810
1192
  """
811
1193
  url = f"{self.base_url}/superChatEvents"
812
- query_params = {k: v for k, v in [('hl', hl), ('maxResults', maxResults), ('pageToken', pageToken), ('part', part)] if v is not None}
1194
+ query_params = {
1195
+ k: v
1196
+ for k, v in [
1197
+ ("hl", hl),
1198
+ ("maxResults", maxResults),
1199
+ ("pageToken", pageToken),
1200
+ ("part", part),
1201
+ ]
1202
+ if v is not None
1203
+ }
813
1204
  response = self._get(url, params=query_params)
814
1205
  response.raise_for_status()
815
1206
  return response.json()
@@ -817,16 +1208,23 @@ class YoutubeApp(APIApplication):
817
1208
  def add_thumbnails_set(self, onBehalfOfContentOwner=None, videoId=None) -> Any:
818
1209
  """
819
1210
  Sets a thumbnail for a specified video on behalf of a content owner using the YouTube API.
820
-
1211
+
821
1212
  Args:
822
1213
  onBehalfOfContentOwner: Optional; str. The YouTube content owner ID on whose behalf the request is being made.
823
1214
  videoId: Optional; str. The ID of the video for which the thumbnails are being set.
824
-
1215
+
825
1216
  Returns:
826
1217
  dict. The response from the YouTube API as a JSON object, containing details of the updated video thumbnail.
827
1218
  """
828
1219
  url = f"{self.base_url}/thumbnails/set"
829
- query_params = {k: v for k, v in [('onBehalfOfContentOwner', onBehalfOfContentOwner), ('videoId', videoId)] if v is not None}
1220
+ query_params = {
1221
+ k: v
1222
+ for k, v in [
1223
+ ("onBehalfOfContentOwner", onBehalfOfContentOwner),
1224
+ ("videoId", videoId),
1225
+ ]
1226
+ if v is not None
1227
+ }
830
1228
  response = self._post(url, data={}, params=query_params)
831
1229
  response.raise_for_status()
832
1230
  return response.json()
@@ -834,16 +1232,16 @@ class YoutubeApp(APIApplication):
834
1232
  def get_video_abuse_report_reasons(self, hl=None, part=None) -> Any:
835
1233
  """
836
1234
  Fetches a list of video abuse report reasons with optional localization and response filtering.
837
-
1235
+
838
1236
  Args:
839
1237
  hl: An optional parameter specifying the language for localizing the response. This is typically a BCP-47 language code, such as 'en' or 'fr'.
840
1238
  part: An optional parameter specifying which parts of the abuse report reasons to include in the response. This could specify fields like 'id' or 'snippet'.
841
-
1239
+
842
1240
  Returns:
843
1241
  The function returns a JSON object containing the list of video abuse report reasons, or filtered parts of it, if specified.
844
1242
  """
845
1243
  url = f"{self.base_url}/videoAbuseReportReasons"
846
- query_params = {k: v for k, v in [('hl', hl), ('part', part)] if v is not None}
1244
+ query_params = {k: v for k, v in [("hl", hl), ("part", part)] if v is not None}
847
1245
  response = self._get(url, params=query_params)
848
1246
  response.raise_for_status()
849
1247
  return response.json()
@@ -851,18 +1249,27 @@ class YoutubeApp(APIApplication):
851
1249
  def get_veocategories(self, hl=None, id=None, part=None, regionCode=None) -> Any:
852
1250
  """
853
1251
  Fetches video categories from an external API using specified query parameters.
854
-
1252
+
855
1253
  Args:
856
1254
  hl: Optional; the language code for localized video category names, e.g., 'en'.
857
1255
  id: Optional; a comma-separated list of video category IDs to filter the results.
858
1256
  part: Optional; a list of properties to include in the response, e.g., 'snippet'.
859
1257
  regionCode: Optional; an ISO 3166-1 alpha-2 country code to filter the categories for a specific region.
860
-
1258
+
861
1259
  Returns:
862
1260
  The JSON response from the API containing video category information.
863
1261
  """
864
1262
  url = f"{self.base_url}/videoCategories"
865
- query_params = {k: v for k, v in [('hl', hl), ('id', id), ('part', part), ('regionCode', regionCode)] if v is not None}
1263
+ query_params = {
1264
+ k: v
1265
+ for k, v in [
1266
+ ("hl", hl),
1267
+ ("id", id),
1268
+ ("part", part),
1269
+ ("regionCode", regionCode),
1270
+ ]
1271
+ if v is not None
1272
+ }
866
1273
  response = self._get(url, params=query_params)
867
1274
  response.raise_for_status()
868
1275
  return response.json()
@@ -870,16 +1277,20 @@ class YoutubeApp(APIApplication):
870
1277
  def delete_groupitems(self, id=None, onBehalfOfContentOwner=None) -> Any:
871
1278
  """
872
1279
  Deletes group items based on specified parameters.
873
-
1280
+
874
1281
  Args:
875
1282
  id: Optional; A string that identifies the group item to be deleted. If not provided, all group items may be affected depending on other parameters.
876
1283
  onBehalfOfContentOwner: Optional; A string representing the content owner on whose behalf the request is being made. This is typically used for partners or channels managed by the content owner.
877
-
1284
+
878
1285
  Returns:
879
1286
  A JSON object containing the response from the deletion request, which includes the results of the delete operation.
880
1287
  """
881
1288
  url = f"{self.base_url}/groupItems"
882
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
1289
+ query_params = {
1290
+ k: v
1291
+ for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
1292
+ if v is not None
1293
+ }
883
1294
  response = self._delete(url, params=query_params)
884
1295
  response.raise_for_status()
885
1296
  return response.json()
@@ -887,24 +1298,40 @@ class YoutubeApp(APIApplication):
887
1298
  def delete_groups(self, id=None, onBehalfOfContentOwner=None) -> Any:
888
1299
  """
889
1300
  Deletes groups specified by their ID, optionally on behalf of a content owner.
890
-
1301
+
891
1302
  Args:
892
1303
  id: Optional; The unique identifier for the group to be deleted. If not provided, no specific group ID will be targeted.
893
1304
  onBehalfOfContentOwner: Optional; The content owner that the group deletion is being performed on behalf of.
894
-
1305
+
895
1306
  Returns:
896
1307
  A JSON-decoded response from the server indicating the success or failure of the delete operation.
897
1308
  """
898
1309
  url = f"{self.base_url}/groups"
899
- query_params = {k: v for k, v in [('id', id), ('onBehalfOfContentOwner', onBehalfOfContentOwner)] if v is not None}
1310
+ query_params = {
1311
+ k: v
1312
+ for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
1313
+ if v is not None
1314
+ }
900
1315
  response = self._delete(url, params=query_params)
901
1316
  response.raise_for_status()
902
1317
  return response.json()
903
1318
 
904
- def get_reports(self, currency=None, dimensions=None, end=None, filters=None, ids=None, include=None, max=None, metrics=None, sort=None, start=None) -> Any:
1319
+ def get_reports(
1320
+ self,
1321
+ currency=None,
1322
+ dimensions=None,
1323
+ end=None,
1324
+ filters=None,
1325
+ ids=None,
1326
+ include=None,
1327
+ max=None,
1328
+ metrics=None,
1329
+ sort=None,
1330
+ start=None,
1331
+ ) -> Any:
905
1332
  """
906
1333
  Fetches and returns report data based on specified filtering and sorting criteria.
907
-
1334
+
908
1335
  Args:
909
1336
  currency: Optional; Specifies the currency format for the report.
910
1337
  dimensions: Optional; List of dimensions to include in the report.
@@ -916,12 +1343,27 @@ class YoutubeApp(APIApplication):
916
1343
  metrics: Optional; List of metrics to include in the report.
917
1344
  sort: Optional; Order by which to sort the report results.
918
1345
  start: Optional; Start date for the report data range.
919
-
1346
+
920
1347
  Returns:
921
1348
  The response containing the report data in JSON format.
922
1349
  """
923
1350
  url = f"{self.base_url}/reports"
924
- query_params = {k: v for k, v in [('currency', currency), ('dimensions', dimensions), ('end', end), ('filters', filters), ('ids', ids), ('include', include), ('max', max), ('metrics', metrics), ('sort', sort), ('start', start)] if v is not None}
1351
+ query_params = {
1352
+ k: v
1353
+ for k, v in [
1354
+ ("currency", currency),
1355
+ ("dimensions", dimensions),
1356
+ ("end", end),
1357
+ ("filters", filters),
1358
+ ("ids", ids),
1359
+ ("include", include),
1360
+ ("max", max),
1361
+ ("metrics", metrics),
1362
+ ("sort", sort),
1363
+ ("start", start),
1364
+ ]
1365
+ if v is not None
1366
+ }
925
1367
  response = self._get(url, params=query_params)
926
1368
  response.raise_for_status()
927
1369
  return response.json()
@@ -929,10 +1371,10 @@ class YoutubeApp(APIApplication):
929
1371
  def list_tools(self):
930
1372
  """
931
1373
  Returns a list of tool methods available in the class instance.
932
-
1374
+
933
1375
  Args:
934
1376
  None: This function does not accept any parameters.
935
-
1377
+
936
1378
  Returns:
937
1379
  list: A list containing references to various tool methods associated with job reports, media resources, comments, broadcasts, videos, activities, channels, etc.
938
1380
  """
@@ -982,5 +1424,5 @@ class YoutubeApp(APIApplication):
982
1424
  self.get_veocategories,
983
1425
  self.delete_groupitems,
984
1426
  self.delete_groups,
985
- self.get_reports
1427
+ self.get_reports,
986
1428
  ]