universal-mcp-applications 0.1.33__py3-none-any.whl → 0.1.39rc16__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.

Potentially problematic release.


This version of universal-mcp-applications might be problematic. Click here for more details.

Files changed (119) hide show
  1. universal_mcp/applications/BEST_PRACTICES.md +1 -1
  2. universal_mcp/applications/ahrefs/app.py +92 -238
  3. universal_mcp/applications/airtable/app.py +36 -135
  4. universal_mcp/applications/apollo/app.py +124 -477
  5. universal_mcp/applications/asana/app.py +605 -1755
  6. universal_mcp/applications/aws_s3/app.py +63 -119
  7. universal_mcp/applications/bill/app.py +644 -2055
  8. universal_mcp/applications/box/app.py +1246 -4159
  9. universal_mcp/applications/braze/app.py +410 -1476
  10. universal_mcp/applications/browser_use/README.md +15 -1
  11. universal_mcp/applications/browser_use/__init__.py +1 -0
  12. universal_mcp/applications/browser_use/app.py +91 -26
  13. universal_mcp/applications/cal_com_v2/app.py +207 -625
  14. universal_mcp/applications/calendly/app.py +103 -242
  15. universal_mcp/applications/canva/app.py +75 -140
  16. universal_mcp/applications/clickup/app.py +331 -798
  17. universal_mcp/applications/coda/app.py +240 -520
  18. universal_mcp/applications/confluence/app.py +497 -1285
  19. universal_mcp/applications/contentful/app.py +40 -155
  20. universal_mcp/applications/crustdata/app.py +44 -123
  21. universal_mcp/applications/dialpad/app.py +451 -924
  22. universal_mcp/applications/digitalocean/app.py +2071 -6082
  23. universal_mcp/applications/domain_checker/app.py +3 -54
  24. universal_mcp/applications/e2b/app.py +17 -68
  25. universal_mcp/applications/elevenlabs/README.md +27 -3
  26. universal_mcp/applications/elevenlabs/app.py +741 -74
  27. universal_mcp/applications/exa/README.md +8 -4
  28. universal_mcp/applications/exa/app.py +415 -186
  29. universal_mcp/applications/falai/README.md +5 -7
  30. universal_mcp/applications/falai/app.py +156 -232
  31. universal_mcp/applications/figma/app.py +91 -175
  32. universal_mcp/applications/file_system/app.py +2 -13
  33. universal_mcp/applications/firecrawl/app.py +198 -176
  34. universal_mcp/applications/fireflies/app.py +59 -281
  35. universal_mcp/applications/fpl/app.py +92 -529
  36. universal_mcp/applications/fpl/utils/fixtures.py +15 -49
  37. universal_mcp/applications/fpl/utils/helper.py +25 -89
  38. universal_mcp/applications/fpl/utils/league_utils.py +20 -64
  39. universal_mcp/applications/ghost_content/app.py +70 -179
  40. universal_mcp/applications/github/app.py +30 -67
  41. universal_mcp/applications/gong/app.py +142 -302
  42. universal_mcp/applications/google_calendar/app.py +26 -78
  43. universal_mcp/applications/google_docs/README.md +15 -14
  44. universal_mcp/applications/google_docs/app.py +103 -206
  45. universal_mcp/applications/google_drive/app.py +194 -793
  46. universal_mcp/applications/google_gemini/app.py +68 -59
  47. universal_mcp/applications/google_mail/README.md +1 -0
  48. universal_mcp/applications/google_mail/app.py +93 -214
  49. universal_mcp/applications/google_searchconsole/app.py +25 -58
  50. universal_mcp/applications/google_sheet/README.md +2 -1
  51. universal_mcp/applications/google_sheet/app.py +226 -624
  52. universal_mcp/applications/google_sheet/helper.py +26 -53
  53. universal_mcp/applications/hashnode/app.py +57 -269
  54. universal_mcp/applications/heygen/README.md +10 -32
  55. universal_mcp/applications/heygen/app.py +339 -811
  56. universal_mcp/applications/http_tools/app.py +10 -32
  57. universal_mcp/applications/hubspot/README.md +1 -1
  58. universal_mcp/applications/hubspot/app.py +7508 -99
  59. universal_mcp/applications/jira/app.py +2419 -8334
  60. universal_mcp/applications/klaviyo/app.py +739 -1621
  61. universal_mcp/applications/linkedin/README.md +18 -1
  62. universal_mcp/applications/linkedin/app.py +729 -251
  63. universal_mcp/applications/mailchimp/app.py +696 -1851
  64. universal_mcp/applications/markitdown/app.py +8 -20
  65. universal_mcp/applications/miro/app.py +333 -815
  66. universal_mcp/applications/ms_teams/app.py +420 -1407
  67. universal_mcp/applications/neon/app.py +144 -250
  68. universal_mcp/applications/notion/app.py +38 -53
  69. universal_mcp/applications/onedrive/app.py +26 -48
  70. universal_mcp/applications/openai/app.py +43 -166
  71. universal_mcp/applications/outlook/README.md +22 -9
  72. universal_mcp/applications/outlook/app.py +403 -141
  73. universal_mcp/applications/perplexity/README.md +2 -1
  74. universal_mcp/applications/perplexity/app.py +161 -20
  75. universal_mcp/applications/pipedrive/app.py +1021 -3331
  76. universal_mcp/applications/posthog/app.py +272 -541
  77. universal_mcp/applications/reddit/app.py +65 -164
  78. universal_mcp/applications/resend/app.py +72 -139
  79. universal_mcp/applications/retell/app.py +23 -50
  80. universal_mcp/applications/rocketlane/app.py +252 -965
  81. universal_mcp/applications/scraper/app.py +114 -142
  82. universal_mcp/applications/semanticscholar/app.py +36 -78
  83. universal_mcp/applications/semrush/app.py +44 -78
  84. universal_mcp/applications/sendgrid/app.py +826 -1576
  85. universal_mcp/applications/sentry/app.py +444 -1079
  86. universal_mcp/applications/serpapi/app.py +44 -146
  87. universal_mcp/applications/sharepoint/app.py +27 -49
  88. universal_mcp/applications/shopify/app.py +1748 -4486
  89. universal_mcp/applications/shortcut/app.py +275 -536
  90. universal_mcp/applications/slack/app.py +43 -125
  91. universal_mcp/applications/spotify/app.py +206 -405
  92. universal_mcp/applications/supabase/app.py +174 -283
  93. universal_mcp/applications/tavily/app.py +2 -2
  94. universal_mcp/applications/trello/app.py +853 -2816
  95. universal_mcp/applications/twilio/app.py +27 -62
  96. universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
  97. universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
  98. universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
  99. universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
  100. universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
  101. universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
  102. universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
  103. universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
  104. universal_mcp/applications/whatsapp/app.py +35 -186
  105. universal_mcp/applications/whatsapp/audio.py +2 -6
  106. universal_mcp/applications/whatsapp/whatsapp.py +17 -51
  107. universal_mcp/applications/whatsapp_business/app.py +86 -299
  108. universal_mcp/applications/wrike/app.py +80 -153
  109. universal_mcp/applications/yahoo_finance/app.py +19 -65
  110. universal_mcp/applications/youtube/app.py +120 -306
  111. universal_mcp/applications/zenquotes/app.py +3 -3
  112. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/METADATA +4 -2
  113. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/RECORD +115 -119
  114. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/WHEEL +1 -1
  115. universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
  116. universal_mcp/applications/hubspot/api_segments/api_segment_base.py +0 -54
  117. universal_mcp/applications/hubspot/api_segments/crm_api.py +0 -7337
  118. universal_mcp/applications/hubspot/api_segments/marketing_api.py +0 -1467
  119. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,5 @@
1
1
  import os
2
2
  from typing import Any
3
-
4
3
  from universal_mcp.applications.application import APIApplication
5
4
  from universal_mcp.integrations import Integration
6
5
  from youtube_transcript_api import YouTubeTranscriptApi
@@ -22,7 +21,7 @@ class YoutubeApp(APIApplication):
22
21
  super().__init__(name="youtube", integration=integration, **kwargs)
23
22
  self.base_url = "https://www.googleapis.com/youtube/v3"
24
23
 
25
- def list_job_reports(
24
+ async def list_job_reports(
26
25
  self,
27
26
  jobId,
28
27
  createdAfter=None,
@@ -68,11 +67,11 @@ class YoutubeApp(APIApplication):
68
67
  ]
69
68
  if v is not None
70
69
  }
71
- response = self._get(url, params=query_params)
70
+ response = await self._aget(url, params=query_params)
72
71
  response.raise_for_status()
73
72
  return response.json()
74
73
 
75
- def get_job_report(self, jobId, reportId, onBehalfOfContentOwner=None) -> Any:
74
+ async def get_job_report(self, jobId, reportId, onBehalfOfContentOwner=None) -> Any:
76
75
  """
77
76
  Fetches a single, specific report identified by its `reportId` from within a given `jobId`. This retrieves an individual record, distinguishing it from `get_jobs_job_reports`, which returns a list of reports for a job. The request can be made on behalf of a content owner.
78
77
 
@@ -96,16 +95,12 @@ class YoutubeApp(APIApplication):
96
95
  if reportId is None:
97
96
  raise ValueError("Missing required parameter 'reportId'")
98
97
  url = f"{self.base_url}/v1/jobs/{jobId}/reports/{reportId}"
99
- query_params = {
100
- k: v
101
- for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)]
102
- if v is not None
103
- }
104
- response = self._get(url, params=query_params)
98
+ query_params = {k: v for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
99
+ response = await self._aget(url, params=query_params)
105
100
  response.raise_for_status()
106
101
  return response.json()
107
102
 
108
- def delete_job(self, jobId, onBehalfOfContentOwner=None) -> Any:
103
+ async def delete_job(self, jobId, onBehalfOfContentOwner=None) -> Any:
109
104
  """
110
105
  Deletes a specific job resource using its unique `jobId`, optionally on behalf of a content owner. This action permanently removes the job itself, differentiating it from functions that only retrieve or manage job reports.
111
106
 
@@ -126,22 +121,12 @@ class YoutubeApp(APIApplication):
126
121
  if jobId is None:
127
122
  raise ValueError("Missing required parameter 'jobId'")
128
123
  url = f"{self.base_url}/v1/jobs/{jobId}"
129
- query_params = {
130
- k: v
131
- for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)]
132
- if v is not None
133
- }
134
- response = self._delete(url, params=query_params)
124
+ query_params = {k: v for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
125
+ response = await self._adelete(url, params=query_params)
135
126
  response.raise_for_status()
136
127
  return response.json()
137
128
 
138
- def list_jobs(
139
- self,
140
- includeSystemManaged=None,
141
- onBehalfOfContentOwner=None,
142
- pageSize=None,
143
- pageToken=None,
144
- ) -> Any:
129
+ async def list_jobs(self, includeSystemManaged=None, onBehalfOfContentOwner=None, pageSize=None, pageToken=None) -> Any:
145
130
  """
146
131
  Retrieves a paginated list of asynchronous jobs from the YouTube Reporting API. Supports filtering by content owner and including system-managed jobs. This function lists multiple jobs, distinct from `get_jobs_job_reports` which retrieves reports for a single job.
147
132
 
@@ -171,11 +156,11 @@ class YoutubeApp(APIApplication):
171
156
  ]
172
157
  if v is not None
173
158
  }
174
- response = self._get(url, params=query_params)
159
+ response = await self._aget(url, params=query_params)
175
160
  response.raise_for_status()
176
161
  return response.json()
177
162
 
178
- def download_report_media(self, resourceName) -> Any:
163
+ async def download_report_media(self, resourceName) -> Any:
179
164
  """
180
165
  Downloads the content of a bulk data report from the YouTube Reporting API by its unique `resourceName`. This function retrieves the actual media file generated by a reporting job, distinct from functions that only fetch report metadata.
181
166
 
@@ -196,17 +181,11 @@ class YoutubeApp(APIApplication):
196
181
  raise ValueError("Missing required parameter 'resourceName'")
197
182
  url = f"{self.base_url}/v1/media/{resourceName}"
198
183
  query_params = {}
199
- response = self._get(url, params=query_params)
184
+ response = await self._aget(url, params=query_params)
200
185
  response.raise_for_status()
201
186
  return response.json()
202
187
 
203
- def get_reporttypes(
204
- self,
205
- includeSystemManaged=None,
206
- onBehalfOfContentOwner=None,
207
- pageSize=None,
208
- pageToken=None,
209
- ) -> Any:
188
+ async def get_reporttypes(self, includeSystemManaged=None, onBehalfOfContentOwner=None, pageSize=None, pageToken=None) -> Any:
210
189
  """
211
190
  Retrieves a list of available report types from the YouTube Reporting API, supporting pagination and filtering. This function returns metadata about what kinds of reports can be generated, distinct from functions like `get_reports` that fetch actual report content.
212
191
 
@@ -236,13 +215,11 @@ class YoutubeApp(APIApplication):
236
215
  ]
237
216
  if v is not None
238
217
  }
239
- response = self._get(url, params=query_params)
218
+ response = await self._aget(url, params=query_params)
240
219
  response.raise_for_status()
241
220
  return response.json()
242
221
 
243
- def delete_captions(
244
- self, id=None, onBehalfOf=None, onBehalfOfContentOwner=None
245
- ) -> Any:
222
+ async def delete_captions(self, id=None, onBehalfOf=None, onBehalfOfContentOwner=None) -> Any:
246
223
  """
247
224
  Deletes a specific YouTube caption resource using its unique ID, with optional delegation for content owners. This management function removes the entire caption track, unlike `get_captions` which only retrieves the transcript text for a given video ID.
248
225
 
@@ -262,19 +239,13 @@ class YoutubeApp(APIApplication):
262
239
  """
263
240
  url = f"{self.base_url}/captions"
264
241
  query_params = {
265
- k: v
266
- for k, v in [
267
- ("id", id),
268
- ("onBehalfOf", onBehalfOf),
269
- ("onBehalfOfContentOwner", onBehalfOfContentOwner),
270
- ]
271
- if v is not None
242
+ k: v for k, v in [("id", id), ("onBehalfOf", onBehalfOf), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None
272
243
  }
273
- response = self._delete(url, params=query_params)
244
+ response = await self._adelete(url, params=query_params)
274
245
  response.raise_for_status()
275
246
  return response.json()
276
247
 
277
- def get_transcript_text(self, video_id: str) -> str:
248
+ async def get_transcript_text(self, video_id: str) -> str:
278
249
  """
279
250
  Fetches the full text transcript for a YouTube video using its ID. Unlike other methods using the official API, this function utilizes the `youtube-transcript-api` library to extract and concatenate all caption snippets into a single, timestamp-free string of the video's spoken content.
280
251
 
@@ -293,36 +264,22 @@ class YoutubeApp(APIApplication):
293
264
  """
294
265
  if video_id is None:
295
266
  raise ValueError("Missing required parameter 'video_id'")
296
-
297
267
  try:
298
268
  proxy_username = os.getenv("PROXY_USERNAME")
299
269
  proxy_password = os.getenv("PROXY_PASSWORD")
300
270
  proxy_port = int(os.getenv("PROXY_PORT", 80))
301
-
302
271
  if not proxy_username or not proxy_password:
303
- raise ValueError(
304
- "PROXY_USERNAME and PROXY_PASSWORD must be set when using proxy"
305
- )
272
+ raise ValueError("PROXY_USERNAME and PROXY_PASSWORD must be set when using proxy")
306
273
  api = YouTubeTranscriptApi(
307
- proxy_config=WebshareProxyConfig(
308
- proxy_username=proxy_username,
309
- proxy_password=proxy_password,
310
- proxy_port=proxy_port,
311
- ),
274
+ proxy_config=WebshareProxyConfig(proxy_username=proxy_username, proxy_password=proxy_password, proxy_port=proxy_port)
312
275
  )
313
276
  transcript = api.fetch(video_id)
314
-
315
- transcript_text = " ".join(
316
- [snippet.text for snippet in transcript.snippets]
317
- )
318
-
277
+ transcript_text = " ".join([snippet.text for snippet in transcript.snippets])
319
278
  return transcript_text
320
279
  except Exception as e:
321
- raise Exception(
322
- f"Failed to retrieve transcript for video {video_id}: {str(e)}"
323
- )
280
+ raise Exception(f"Failed to retrieve transcript for video {video_id}: {str(e)}")
324
281
 
325
- def delete_comments(self, id=None) -> Any:
282
+ async def delete_comments(self, id=None) -> Any:
326
283
  """
327
284
  Permanently removes a specific comment identified by its unique ID via a DELETE request. Unlike moderation functions like `add_comments_mark_as_spam`, which only alter a comment's state, this action is irreversible and deletes the resource. An `id` is required to specify the target comment.
328
285
 
@@ -340,10 +297,10 @@ class YoutubeApp(APIApplication):
340
297
  """
341
298
  url = f"{self.base_url}/comments"
342
299
  query_params = {k: v for k, v in [("id", id)] if v is not None}
343
- response = self._delete(url, params=query_params)
300
+ response = await self._adelete(url, params=query_params)
344
301
  return self._handle_response(response)
345
302
 
346
- def mark_comment_as_spam(self, id=None) -> Any:
303
+ async def mark_comment_as_spam(self, id=None) -> Any:
347
304
  """
348
305
  Marks a specified YouTube comment as spam via a POST request to the API. This moderation action is distinct from deleting comments (`delete_comments`) or setting other statuses like 'approved' or 'rejected' (`add_comments_set_moderation_status`).
349
306
 
@@ -361,13 +318,11 @@ class YoutubeApp(APIApplication):
361
318
  """
362
319
  url = f"{self.base_url}/comments/markAsSpam"
363
320
  query_params = {k: v for k, v in [("id", id)] if v is not None}
364
- response = self._post(url, data={}, params=query_params)
321
+ response = await self._apost(url, data={}, params=query_params)
365
322
  response.raise_for_status()
366
323
  return response.json()
367
324
 
368
- def set_comment_moderation_status(
369
- self, banAuthor=None, id=None, moderationStatus=None
370
- ) -> Any:
325
+ async def set_comment_moderation_status(self, banAuthor=None, id=None, moderationStatus=None) -> Any:
371
326
  """
372
327
  Sets the moderation status (e.g., 'approved', 'rejected') for specified comments and can optionally ban the author. Unlike `add_comments_mark_as_spam`, this function allows for various moderation states, providing more granular control over comment management.
373
328
 
@@ -386,22 +341,12 @@ class YoutubeApp(APIApplication):
386
341
  moderation, comments, management, api-client, status-update, ban-author
387
342
  """
388
343
  url = f"{self.base_url}/comments/setModerationStatus"
389
- query_params = {
390
- k: v
391
- for k, v in [
392
- ("banAuthor", banAuthor),
393
- ("id", id),
394
- ("moderationStatus", moderationStatus),
395
- ]
396
- if v is not None
397
- }
398
- response = self._post(url, data={}, params=query_params)
344
+ query_params = {k: v for k, v in [("banAuthor", banAuthor), ("id", id), ("moderationStatus", moderationStatus)] if v is not None}
345
+ response = await self._apost(url, data={}, params=query_params)
399
346
  response.raise_for_status()
400
347
  return response.json()
401
348
 
402
- def delete_live_broadcasts(
403
- self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None
404
- ) -> Any:
349
+ async def delete_live_broadcasts(self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None) -> Any:
405
350
  """
406
351
  Deletes a YouTube live broadcast event by its unique ID via the API. This request can be made on behalf of a content owner or channel. It targets the `/liveBroadcasts` endpoint, distinguishing it from `delete_livestreams` which manages the actual content stream.
407
352
 
@@ -429,17 +374,12 @@ class YoutubeApp(APIApplication):
429
374
  ]
430
375
  if v is not None
431
376
  }
432
- response = self._delete(url, params=query_params)
377
+ response = await self._adelete(url, params=query_params)
433
378
  response.raise_for_status()
434
379
  return response.json()
435
380
 
436
- def bind_live_broadcast_to_stream(
437
- self,
438
- id=None,
439
- onBehalfOfContentOwner=None,
440
- onBehalfOfContentOwnerChannel=None,
441
- part=None,
442
- streamId=None,
381
+ async def bind_live_broadcast_to_stream(
382
+ self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None, part=None, streamId=None
443
383
  ) -> Any:
444
384
  """
445
385
  Binds a YouTube live broadcast to a video stream using their respective IDs. This action associates the broadcast's metadata with the content stream, optionally performing the action on behalf of a content owner, facilitating the link between a planned event and its live video feed.
@@ -472,11 +412,11 @@ class YoutubeApp(APIApplication):
472
412
  ]
473
413
  if v is not None
474
414
  }
475
- response = self._post(url, data={}, params=query_params)
415
+ response = await self._apost(url, data={}, params=query_params)
476
416
  response.raise_for_status()
477
417
  return response.json()
478
418
 
479
- def control_live_broadcast(
419
+ async def control_live_broadcast(
480
420
  self,
481
421
  displaySlate=None,
482
422
  id=None,
@@ -521,17 +461,12 @@ class YoutubeApp(APIApplication):
521
461
  ]
522
462
  if v is not None
523
463
  }
524
- response = self._post(url, data={}, params=query_params)
464
+ response = await self._apost(url, data={}, params=query_params)
525
465
  response.raise_for_status()
526
466
  return response.json()
527
467
 
528
- def transition_live_broadcast(
529
- self,
530
- broadcastStatus=None,
531
- id=None,
532
- onBehalfOfContentOwner=None,
533
- onBehalfOfContentOwnerChannel=None,
534
- part=None,
468
+ async def transition_live_broadcast(
469
+ self, broadcastStatus=None, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None, part=None
535
470
  ) -> Any:
536
471
  """
537
472
  Changes a YouTube live broadcast's status (e.g., making it 'live' or 'complete') by posting to the API's transition endpoint. This function alters the broadcast's lifecycle state, distinct from other control actions like binding it to a stream, and returns the API's JSON response.
@@ -564,11 +499,11 @@ class YoutubeApp(APIApplication):
564
499
  ]
565
500
  if v is not None
566
501
  }
567
- response = self._post(url, data={}, params=query_params)
502
+ response = await self._apost(url, data={}, params=query_params)
568
503
  response.raise_for_status()
569
504
  return response.json()
570
505
 
571
- def delete_live_chat_ban(self, id=None) -> Any:
506
+ async def delete_live_chat_ban(self, id=None) -> Any:
572
507
  """
573
508
  Deletes a specific YouTube live chat ban using its unique ID. It sends a DELETE request to the `/liveChat/bans` endpoint to revoke the ban, allowing the user to participate in the chat again.
574
509
 
@@ -586,11 +521,11 @@ class YoutubeApp(APIApplication):
586
521
  """
587
522
  url = f"{self.base_url}/liveChat/bans"
588
523
  query_params = {k: v for k, v in [("id", id)] if v is not None}
589
- response = self._delete(url, params=query_params)
524
+ response = await self._adelete(url, params=query_params)
590
525
  response.raise_for_status()
591
526
  return response.json()
592
527
 
593
- def delete_live_chat_message(self, id=None) -> Any:
528
+ async def delete_live_chat_message(self, id=None) -> Any:
594
529
  """
595
530
  Deletes a specific YouTube live chat message identified by its unique ID. This function targets the `/liveChat/messages` endpoint, distinguishing it from `delete_live_chat_bans` and `delete_live_chat_moderators`, which manage different aspects of a live chat.
596
531
 
@@ -608,11 +543,11 @@ class YoutubeApp(APIApplication):
608
543
  """
609
544
  url = f"{self.base_url}/liveChat/messages"
610
545
  query_params = {k: v for k, v in [("id", id)] if v is not None}
611
- response = self._delete(url, params=query_params)
546
+ response = await self._adelete(url, params=query_params)
612
547
  response.raise_for_status()
613
548
  return response.json()
614
549
 
615
- def delete_live_chat_moderators(self, id=None) -> Any:
550
+ async def delete_live_chat_moderators(self, id=None) -> Any:
616
551
  """
617
552
  Deletes a specific YouTube live chat moderator using their unique ID. This function sends a DELETE request to the `/liveChat/moderators` API endpoint and returns the server's JSON response, confirming the successful removal or detailing errors. The moderator ID is a required parameter for this action.
618
553
 
@@ -630,11 +565,11 @@ class YoutubeApp(APIApplication):
630
565
  """
631
566
  url = f"{self.base_url}/liveChat/moderators"
632
567
  query_params = {k: v for k, v in [("id", id)] if v is not None}
633
- response = self._delete(url, params=query_params)
568
+ response = await self._adelete(url, params=query_params)
634
569
  response.raise_for_status()
635
570
  return response.json()
636
571
 
637
- def delete_videos(self, id=None, onBehalfOfContentOwner=None) -> Any:
572
+ async def delete_videos(self, id=None, onBehalfOfContentOwner=None) -> Any:
638
573
  """
639
574
  Deletes a specified YouTube video using its unique ID. The operation can be performed on behalf of a content owner by sending an HTTP DELETE request to the `/videos` endpoint. It's distinct from other video functions that only modify or retrieve metadata, like rating or abuse reports.
640
575
 
@@ -652,16 +587,12 @@ class YoutubeApp(APIApplication):
652
587
  delete, video-management, api, async_job
653
588
  """
654
589
  url = f"{self.base_url}/videos"
655
- query_params = {
656
- k: v
657
- for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
658
- if v is not None
659
- }
660
- response = self._delete(url, params=query_params)
590
+ query_params = {k: v for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
591
+ response = await self._adelete(url, params=query_params)
661
592
  response.raise_for_status()
662
593
  return response.json()
663
594
 
664
- def get_video_ratings(self, id=None, onBehalfOfContentOwner=None) -> Any:
595
+ async def get_video_ratings(self, id=None, onBehalfOfContentOwner=None) -> Any:
665
596
  """
666
597
  Retrieves the authenticated user's rating (e.g., 'like', 'dislike') for specified videos. This function fetches existing rating data, distinct from `add_videos_rate` which submits a new rating, and can be performed on behalf of a content owner.
667
598
 
@@ -679,16 +610,12 @@ class YoutubeApp(APIApplication):
679
610
  check, video-management
680
611
  """
681
612
  url = f"{self.base_url}/videos/getRating"
682
- query_params = {
683
- k: v
684
- for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
685
- if v is not None
686
- }
687
- response = self._get(url, params=query_params)
613
+ query_params = {k: v for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
614
+ response = await self._aget(url, params=query_params)
688
615
  response.raise_for_status()
689
616
  return response.json()
690
617
 
691
- def rate_video(self, id=None, rating=None) -> Any:
618
+ async def rate_video(self, id=None, rating=None) -> Any:
692
619
  """
693
620
  Submits a rating (e.g., 'like', 'dislike') for a video specified by its unique ID. This function sends a POST request to the YouTube API's `/videos/rate` endpoint and returns the server's JSON response upon successful submission.
694
621
 
@@ -706,14 +633,12 @@ class YoutubeApp(APIApplication):
706
633
  rate, video-management, importance
707
634
  """
708
635
  url = f"{self.base_url}/videos/rate"
709
- query_params = {
710
- k: v for k, v in [("id", id), ("rating", rating)] if v is not None
711
- }
712
- response = self._post(url, data={}, params=query_params)
636
+ query_params = {k: v for k, v in [("id", id), ("rating", rating)] if v is not None}
637
+ response = await self._apost(url, data={}, params=query_params)
713
638
  response.raise_for_status()
714
639
  return response.json()
715
640
 
716
- def report_video_for_abuse(self, onBehalfOfContentOwner=None) -> Any:
641
+ async def report_video_for_abuse(self, onBehalfOfContentOwner=None) -> Any:
717
642
  """
718
643
  Reports a video for abuse via a POST request to the YouTube API. An optional parameter allows a content owner to submit the report on behalf of their account, flagging potentially inappropriate content for review by YouTube.
719
644
 
@@ -730,16 +655,12 @@ class YoutubeApp(APIApplication):
730
655
  report, abuse, video, content, api
731
656
  """
732
657
  url = f"{self.base_url}/videos/reportAbuse"
733
- query_params = {
734
- k: v
735
- for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)]
736
- if v is not None
737
- }
738
- response = self._post(url, data={}, params=query_params)
658
+ query_params = {k: v for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
659
+ response = await self._apost(url, data={}, params=query_params)
739
660
  response.raise_for_status()
740
661
  return response.json()
741
662
 
742
- def set_channel_watermark(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
663
+ async def set_channel_watermark(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
743
664
  """
744
665
  Sets a branding watermark on a specified YouTube channel. The operation targets the channel using its ID and can be executed on behalf of a content owner. This function contrasts with `add_watermarks_unset`, which removes the watermark.
745
666
 
@@ -757,21 +678,12 @@ class YoutubeApp(APIApplication):
757
678
  watermark, youtube, management, channel-config
758
679
  """
759
680
  url = f"{self.base_url}/watermarks/set"
760
- query_params = {
761
- k: v
762
- for k, v in [
763
- ("channelId", channelId),
764
- ("onBehalfOfContentOwner", onBehalfOfContentOwner),
765
- ]
766
- if v is not None
767
- }
768
- response = self._post(url, data={}, params=query_params)
681
+ query_params = {k: v for k, v in [("channelId", channelId), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
682
+ response = await self._apost(url, data={}, params=query_params)
769
683
  response.raise_for_status()
770
684
  return response.json()
771
685
 
772
- def unset_channel_watermark(
773
- self, channelId=None, onBehalfOfContentOwner=None
774
- ) -> Any:
686
+ async def unset_channel_watermark(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
775
687
  """
776
688
  Removes the branding watermark for a specified YouTube channel via an API POST request. This operation, the inverse of `add_watermarks_set`, can be executed on behalf of a content owner to unset the channel's current watermark.
777
689
 
@@ -789,19 +701,12 @@ class YoutubeApp(APIApplication):
789
701
  remove, watermark, youtube
790
702
  """
791
703
  url = f"{self.base_url}/watermarks/unset"
792
- query_params = {
793
- k: v
794
- for k, v in [
795
- ("channelId", channelId),
796
- ("onBehalfOfContentOwner", onBehalfOfContentOwner),
797
- ]
798
- if v is not None
799
- }
800
- response = self._post(url, data={}, params=query_params)
704
+ query_params = {k: v for k, v in [("channelId", channelId), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
705
+ response = await self._apost(url, data={}, params=query_params)
801
706
  response.raise_for_status()
802
707
  return response.json()
803
708
 
804
- def get_activities(
709
+ async def get_activities(
805
710
  self,
806
711
  channelId=None,
807
712
  home=None,
@@ -852,11 +757,11 @@ class YoutubeApp(APIApplication):
852
757
  ]
853
758
  if v is not None
854
759
  }
855
- response = self._get(url, params=query_params)
760
+ response = await self._aget(url, params=query_params)
856
761
  response.raise_for_status()
857
762
  return response.json()
858
763
 
859
- def insert_channel_banner(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
764
+ async def insert_channel_banner(self, channelId=None, onBehalfOfContentOwner=None) -> Any:
860
765
  """
861
766
  Uploads and sets a new banner image for a specified YouTube channel. This function makes a POST request to the `/channelBanners/insert` endpoint, optionally on behalf of a content owner, and returns details of the newly created banner.
862
767
 
@@ -874,19 +779,12 @@ class YoutubeApp(APIApplication):
874
779
  insert, channel, banner, youtube-api, management, async_job
875
780
  """
876
781
  url = f"{self.base_url}/channelBanners/insert"
877
- query_params = {
878
- k: v
879
- for k, v in [
880
- ("channelId", channelId),
881
- ("onBehalfOfContentOwner", onBehalfOfContentOwner),
882
- ]
883
- if v is not None
884
- }
885
- response = self._post(url, data={}, params=query_params)
782
+ query_params = {k: v for k, v in [("channelId", channelId), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
783
+ response = await self._apost(url, data={}, params=query_params)
886
784
  response.raise_for_status()
887
785
  return response.json()
888
786
 
889
- def delete_channel_sections(self, id=None, onBehalfOfContentOwner=None) -> Any:
787
+ async def delete_channel_sections(self, id=None, onBehalfOfContentOwner=None) -> Any:
890
788
  """
891
789
  Deletes a YouTube channel section by its unique ID via an API request. The operation can be performed on behalf of a content owner for delegated management, returning a JSON response upon success or raising an HTTPError for failures like invalid IDs or insufficient permissions.
892
790
 
@@ -904,16 +802,12 @@ class YoutubeApp(APIApplication):
904
802
  delete, channel-section, management
905
803
  """
906
804
  url = f"{self.base_url}/channelSections"
907
- query_params = {
908
- k: v
909
- for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
910
- if v is not None
911
- }
912
- response = self._delete(url, params=query_params)
805
+ query_params = {k: v for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
806
+ response = await self._adelete(url, params=query_params)
913
807
  response.raise_for_status()
914
808
  return response.json()
915
809
 
916
- def list_channels(
810
+ async def list_channels(
917
811
  self,
918
812
  categoryId=None,
919
813
  forUsername=None,
@@ -970,11 +864,11 @@ class YoutubeApp(APIApplication):
970
864
  ]
971
865
  if v is not None
972
866
  }
973
- response = self._get(url, params=query_params)
867
+ response = await self._aget(url, params=query_params)
974
868
  response.raise_for_status()
975
869
  return response.json()
976
870
 
977
- def get_comment_threads(
871
+ async def get_comment_threads(
978
872
  self,
979
873
  allThreadsRelatedToChannelId=None,
980
874
  channelId=None,
@@ -1031,13 +925,11 @@ class YoutubeApp(APIApplication):
1031
925
  ]
1032
926
  if v is not None
1033
927
  }
1034
- response = self._get(url, params=query_params)
928
+ response = await self._aget(url, params=query_params)
1035
929
  response.raise_for_status()
1036
930
  return response.json()
1037
931
 
1038
- def get_fanfundingevents(
1039
- self, hl=None, maxResults=None, pageToken=None, part=None
1040
- ) -> Any:
932
+ async def get_fanfundingevents(self, hl=None, maxResults=None, pageToken=None, part=None) -> Any:
1041
933
  """
1042
934
  Fetches a list of fan funding events from the YouTube API for the authenticated user's channel. Supports pagination, localization, and partial responses to retrieve customized event data like Super Chat or Super Stickers based on specified filter criteria and response parts.
1043
935
 
@@ -1058,20 +950,13 @@ class YoutubeApp(APIApplication):
1058
950
  """
1059
951
  url = f"{self.base_url}/fanFundingEvents"
1060
952
  query_params = {
1061
- k: v
1062
- for k, v in [
1063
- ("hl", hl),
1064
- ("maxResults", maxResults),
1065
- ("pageToken", pageToken),
1066
- ("part", part),
1067
- ]
1068
- if v is not None
953
+ k: v for k, v in [("hl", hl), ("maxResults", maxResults), ("pageToken", pageToken), ("part", part)] if v is not None
1069
954
  }
1070
- response = self._get(url, params=query_params)
955
+ response = await self._aget(url, params=query_params)
1071
956
  response.raise_for_status()
1072
957
  return response.json()
1073
958
 
1074
- def get_guide_categories(self, hl=None, id=None, part=None, regionCode=None) -> Any:
959
+ async def get_guide_categories(self, hl=None, id=None, part=None, regionCode=None) -> Any:
1075
960
  """
1076
961
  Retrieves a list of official YouTube guide categories (e.g., Music, Sports). This function queries the `/guideCategories` endpoint, allowing results to be filtered by ID or region and localized for a specific language. These are distinct from the categories assigned to individual videos.
1077
962
 
@@ -1091,21 +976,12 @@ class YoutubeApp(APIApplication):
1091
976
  get, fetch, guide-categories, api-call
1092
977
  """
1093
978
  url = f"{self.base_url}/guideCategories"
1094
- query_params = {
1095
- k: v
1096
- for k, v in [
1097
- ("hl", hl),
1098
- ("id", id),
1099
- ("part", part),
1100
- ("regionCode", regionCode),
1101
- ]
1102
- if v is not None
1103
- }
1104
- response = self._get(url, params=query_params)
979
+ query_params = {k: v for k, v in [("hl", hl), ("id", id), ("part", part), ("regionCode", regionCode)] if v is not None}
980
+ response = await self._aget(url, params=query_params)
1105
981
  response.raise_for_status()
1106
982
  return response.json()
1107
983
 
1108
- def get_i18n_languages(self, hl=None, part=None) -> Any:
984
+ async def get_i18n_languages(self, hl=None, part=None) -> Any:
1109
985
  """
1110
986
  Retrieves a list of supported internationalization (i18n) languages from the YouTube API's `/i18nLanguages` endpoint. It can optionally localize the language names in the response. This function is distinct from `get_regions`, which fetches supported geographical regions.
1111
987
 
@@ -1124,11 +1000,11 @@ class YoutubeApp(APIApplication):
1124
1000
  """
1125
1001
  url = f"{self.base_url}/i18nLanguages"
1126
1002
  query_params = {k: v for k, v in [("hl", hl), ("part", part)] if v is not None}
1127
- response = self._get(url, params=query_params)
1003
+ response = await self._aget(url, params=query_params)
1128
1004
  response.raise_for_status()
1129
1005
  return response.json()
1130
1006
 
1131
- def get_i18n_regions(self, hl=None, part=None) -> Any:
1007
+ async def get_i18n_regions(self, hl=None, part=None) -> Any:
1132
1008
  """
1133
1009
  Fetches a list of geographic regions supported by the YouTube API for content localization. It can localize region names using the 'hl' parameter. This is distinct from get_languages, which retrieves supported languages, not geographic areas.
1134
1010
 
@@ -1147,13 +1023,11 @@ class YoutubeApp(APIApplication):
1147
1023
  """
1148
1024
  url = f"{self.base_url}/i18nRegions"
1149
1025
  query_params = {k: v for k, v in [("hl", hl), ("part", part)] if v is not None}
1150
- response = self._get(url, params=query_params)
1026
+ response = await self._aget(url, params=query_params)
1151
1027
  response.raise_for_status()
1152
1028
  return response.json()
1153
1029
 
1154
- def delete_livestreams(
1155
- self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None
1156
- ) -> Any:
1030
+ async def delete_livestreams(self, id=None, onBehalfOfContentOwner=None, onBehalfOfContentOwnerChannel=None) -> Any:
1157
1031
  """
1158
1032
  Deletes one or more YouTube livestreams by ID via the `/liveStreams` API endpoint, optionally on behalf of a content owner. This function is distinct from `delete_live_broadcasts`, which targets a different live video resource, and returns the server's JSON response upon successful deletion.
1159
1033
 
@@ -1181,11 +1055,11 @@ class YoutubeApp(APIApplication):
1181
1055
  ]
1182
1056
  if v is not None
1183
1057
  }
1184
- response = self._delete(url, params=query_params)
1058
+ response = await self._adelete(url, params=query_params)
1185
1059
  response.raise_for_status()
1186
1060
  return response.json()
1187
1061
 
1188
- def delete_playlist_items(self, id=None, onBehalfOfContentOwner=None) -> Any:
1062
+ async def delete_playlist_items(self, id=None, onBehalfOfContentOwner=None) -> Any:
1189
1063
  """
1190
1064
  Deletes one or more YouTube playlist items by their unique IDs. The operation can be performed on behalf of a content owner for delegated authorization, sending a DELETE request to the `/playlistItems` endpoint and returning the server's response.
1191
1065
 
@@ -1203,16 +1077,12 @@ class YoutubeApp(APIApplication):
1203
1077
  delete, playlist-items, management
1204
1078
  """
1205
1079
  url = f"{self.base_url}/playlistItems"
1206
- query_params = {
1207
- k: v
1208
- for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
1209
- if v is not None
1210
- }
1211
- response = self._delete(url, params=query_params)
1080
+ query_params = {k: v for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
1081
+ response = await self._adelete(url, params=query_params)
1212
1082
  response.raise_for_status()
1213
1083
  return response.json()
1214
1084
 
1215
- def delete_playlists(self, id=None, onBehalfOfContentOwner=None) -> Any:
1085
+ async def delete_playlists(self, id=None, onBehalfOfContentOwner=None) -> Any:
1216
1086
  """
1217
1087
  Deletes a YouTube playlist by its unique ID via a DELETE request to the API. The operation can be performed on behalf of a specific content owner for delegated management. This function targets the entire playlist, distinct from `delete_play_list_items` which removes individual videos from a playlist.
1218
1088
 
@@ -1230,16 +1100,12 @@ class YoutubeApp(APIApplication):
1230
1100
  delete, playlists, youtube-api, management
1231
1101
  """
1232
1102
  url = f"{self.base_url}/playlists"
1233
- query_params = {
1234
- k: v
1235
- for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
1236
- if v is not None
1237
- }
1238
- response = self._delete(url, params=query_params)
1103
+ query_params = {k: v for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
1104
+ response = await self._adelete(url, params=query_params)
1239
1105
  response.raise_for_status()
1240
1106
  return response.json()
1241
1107
 
1242
- def get_search(
1108
+ async def get_search(
1243
1109
  self,
1244
1110
  channelId=None,
1245
1111
  channelType=None,
@@ -1356,13 +1222,11 @@ class YoutubeApp(APIApplication):
1356
1222
  ]
1357
1223
  if v is not None
1358
1224
  }
1359
- response = self._get(url, params=query_params)
1225
+ response = await self._aget(url, params=query_params)
1360
1226
  response.raise_for_status()
1361
1227
  return response.json()
1362
1228
 
1363
- def list_sponsors(
1364
- self, filter=None, maxResults=None, pageToken=None, part=None
1365
- ) -> Any:
1229
+ async def list_sponsors(self, filter=None, maxResults=None, pageToken=None, part=None) -> Any:
1366
1230
  """
1367
1231
  Retrieves a list of sponsors for the authenticated user's YouTube channel. This function supports filtering, pagination, and specifying which resource parts to include in the response, allowing for flexible and customized data fetching of sponsor information.
1368
1232
 
@@ -1383,20 +1247,13 @@ class YoutubeApp(APIApplication):
1383
1247
  """
1384
1248
  url = f"{self.base_url}/sponsors"
1385
1249
  query_params = {
1386
- k: v
1387
- for k, v in [
1388
- ("filter", filter),
1389
- ("maxResults", maxResults),
1390
- ("pageToken", pageToken),
1391
- ("part", part),
1392
- ]
1393
- if v is not None
1250
+ k: v for k, v in [("filter", filter), ("maxResults", maxResults), ("pageToken", pageToken), ("part", part)] if v is not None
1394
1251
  }
1395
- response = self._get(url, params=query_params)
1252
+ response = await self._aget(url, params=query_params)
1396
1253
  response.raise_for_status()
1397
1254
  return response.json()
1398
1255
 
1399
- def delete_subscriptions(self, id=None) -> Any:
1256
+ async def delete_subscriptions(self, id=None) -> Any:
1400
1257
  """
1401
1258
  Deletes a specific YouTube channel subscription identified by its unique ID. This function sends a DELETE request to the `/subscriptions` API endpoint and returns the server's JSON response, confirming the operation's success or failure.
1402
1259
 
@@ -1414,13 +1271,11 @@ class YoutubeApp(APIApplication):
1414
1271
  """
1415
1272
  url = f"{self.base_url}/subscriptions"
1416
1273
  query_params = {k: v for k, v in [("id", id)] if v is not None}
1417
- response = self._delete(url, params=query_params)
1274
+ response = await self._adelete(url, params=query_params)
1418
1275
  response.raise_for_status()
1419
1276
  return response.json()
1420
1277
 
1421
- def get_super_chat_events(
1422
- self, hl=None, maxResults=None, pageToken=None, part=None
1423
- ) -> Any:
1278
+ async def get_super_chat_events(self, hl=None, maxResults=None, pageToken=None, part=None) -> Any:
1424
1279
  """
1425
1280
  Retrieves a paginated list of Super Chat events from the YouTube Data API. Allows for localization and specifying which resource parts to include in the response. This function is distinct from `get_fanfundingevents`, which fetches a different type of monetary contribution event.
1426
1281
 
@@ -1441,20 +1296,13 @@ class YoutubeApp(APIApplication):
1441
1296
  """
1442
1297
  url = f"{self.base_url}/superChatEvents"
1443
1298
  query_params = {
1444
- k: v
1445
- for k, v in [
1446
- ("hl", hl),
1447
- ("maxResults", maxResults),
1448
- ("pageToken", pageToken),
1449
- ("part", part),
1450
- ]
1451
- if v is not None
1299
+ k: v for k, v in [("hl", hl), ("maxResults", maxResults), ("pageToken", pageToken), ("part", part)] if v is not None
1452
1300
  }
1453
- response = self._get(url, params=query_params)
1301
+ response = await self._aget(url, params=query_params)
1454
1302
  response.raise_for_status()
1455
1303
  return response.json()
1456
1304
 
1457
- def set_video_thumbnail(self, onBehalfOfContentOwner=None, videoId=None) -> Any:
1305
+ async def set_video_thumbnail(self, onBehalfOfContentOwner=None, videoId=None) -> Any:
1458
1306
  """
1459
1307
  Sets a custom thumbnail for a specified YouTube video via a POST request to the `/thumbnails/set` API endpoint. The operation can be performed on behalf of a content owner for delegated management of video assets.
1460
1308
 
@@ -1472,19 +1320,12 @@ class YoutubeApp(APIApplication):
1472
1320
  thumbnail, youtube-api, video-management, async-job
1473
1321
  """
1474
1322
  url = f"{self.base_url}/thumbnails/set"
1475
- query_params = {
1476
- k: v
1477
- for k, v in [
1478
- ("onBehalfOfContentOwner", onBehalfOfContentOwner),
1479
- ("videoId", videoId),
1480
- ]
1481
- if v is not None
1482
- }
1483
- response = self._post(url, data={}, params=query_params)
1323
+ query_params = {k: v for k, v in [("onBehalfOfContentOwner", onBehalfOfContentOwner), ("videoId", videoId)] if v is not None}
1324
+ response = await self._apost(url, data={}, params=query_params)
1484
1325
  response.raise_for_status()
1485
1326
  return response.json()
1486
1327
 
1487
- def get_video_abuse_report_reasons(self, hl=None, part=None) -> Any:
1328
+ async def get_video_abuse_report_reasons(self, hl=None, part=None) -> Any:
1488
1329
  """
1489
1330
  Retrieves a list of valid reasons (e.g., spam, hate speech) for reporting abusive video content. Supports response localization using a language code (`hl`) and allows filtering which parts of the reason resource (e.g., ID, snippet) are returned, providing metadata before submitting a report.
1490
1331
 
@@ -1503,11 +1344,11 @@ class YoutubeApp(APIApplication):
1503
1344
  """
1504
1345
  url = f"{self.base_url}/videoAbuseReportReasons"
1505
1346
  query_params = {k: v for k, v in [("hl", hl), ("part", part)] if v is not None}
1506
- response = self._get(url, params=query_params)
1347
+ response = await self._aget(url, params=query_params)
1507
1348
  response.raise_for_status()
1508
1349
  return response.json()
1509
1350
 
1510
- def get_video_categories(self, hl=None, id=None, part=None, regionCode=None) -> Any:
1351
+ async def get_video_categories(self, hl=None, id=None, part=None, regionCode=None) -> Any:
1511
1352
  """
1512
1353
  Retrieves official YouTube video categories used for classifying uploaded videos, allowing filtering by ID, region, or language. This is distinct from `get_guecategories`, which fetches channel browsing guides, not categories for individual video uploads.
1513
1354
 
@@ -1527,21 +1368,12 @@ class YoutubeApp(APIApplication):
1527
1368
  fetch, video-categories, api-request, json-response
1528
1369
  """
1529
1370
  url = f"{self.base_url}/videoCategories"
1530
- query_params = {
1531
- k: v
1532
- for k, v in [
1533
- ("hl", hl),
1534
- ("id", id),
1535
- ("part", part),
1536
- ("regionCode", regionCode),
1537
- ]
1538
- if v is not None
1539
- }
1540
- response = self._get(url, params=query_params)
1371
+ query_params = {k: v for k, v in [("hl", hl), ("id", id), ("part", part), ("regionCode", regionCode)] if v is not None}
1372
+ response = await self._aget(url, params=query_params)
1541
1373
  response.raise_for_status()
1542
1374
  return response.json()
1543
1375
 
1544
- def delete_group_items(self, id=None, onBehalfOfContentOwner=None) -> Any:
1376
+ async def delete_group_items(self, id=None, onBehalfOfContentOwner=None) -> Any:
1545
1377
  """
1546
1378
  Deletes specified items from a YouTube Analytics group via an API request. An item can be targeted by its unique ID, and the action can be performed on behalf of a content owner. This function is distinct from `delete_groups`, which removes the entire group.
1547
1379
 
@@ -1559,16 +1391,12 @@ class YoutubeApp(APIApplication):
1559
1391
  delete, groupitems, management
1560
1392
  """
1561
1393
  url = f"{self.base_url}/groupItems"
1562
- query_params = {
1563
- k: v
1564
- for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
1565
- if v is not None
1566
- }
1567
- response = self._delete(url, params=query_params)
1394
+ query_params = {k: v for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
1395
+ response = await self._adelete(url, params=query_params)
1568
1396
  response.raise_for_status()
1569
1397
  return response.json()
1570
1398
 
1571
- def delete_groups(self, id=None, onBehalfOfContentOwner=None) -> Any:
1399
+ async def delete_groups(self, id=None, onBehalfOfContentOwner=None) -> Any:
1572
1400
  """
1573
1401
  Deletes a YouTube group by its ID via an API request, optionally on behalf of a content owner. Unlike `delete_groupitems`, which only removes an item from a group, this function deletes the entire group entity.
1574
1402
 
@@ -1586,27 +1414,13 @@ class YoutubeApp(APIApplication):
1586
1414
  delete, management, async_job, api
1587
1415
  """
1588
1416
  url = f"{self.base_url}/groups"
1589
- query_params = {
1590
- k: v
1591
- for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)]
1592
- if v is not None
1593
- }
1594
- response = self._delete(url, params=query_params)
1417
+ query_params = {k: v for k, v in [("id", id), ("onBehalfOfContentOwner", onBehalfOfContentOwner)] if v is not None}
1418
+ response = await self._adelete(url, params=query_params)
1595
1419
  response.raise_for_status()
1596
1420
  return response.json()
1597
1421
 
1598
- def get_analytics_report(
1599
- self,
1600
- currency=None,
1601
- dimensions=None,
1602
- end=None,
1603
- filters=None,
1604
- ids=None,
1605
- include=None,
1606
- max=None,
1607
- metrics=None,
1608
- sort=None,
1609
- start=None,
1422
+ async def get_analytics_report(
1423
+ self, currency=None, dimensions=None, end=None, filters=None, ids=None, include=None, max=None, metrics=None, sort=None, start=None
1610
1424
  ) -> Any:
1611
1425
  """
1612
1426
  Queries the YouTube Analytics API for performance reports, allowing customization via metrics, dimensions, and filters. Unlike `get_jobs_job_reports` which manages bulk report jobs, this function fetches analytical data directly, providing on-demand insights into channel or content performance.
@@ -1649,7 +1463,7 @@ class YoutubeApp(APIApplication):
1649
1463
  ]
1650
1464
  if v is not None
1651
1465
  }
1652
- response = self._get(url, params=query_params)
1466
+ response = await self._aget(url, params=query_params)
1653
1467
  response.raise_for_status()
1654
1468
  return response.json()
1655
1469