universal-mcp-applications 0.1.30rc1__py3-none-any.whl → 0.1.36rc1__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.
- universal_mcp/applications/ahrefs/app.py +52 -198
- universal_mcp/applications/airtable/app.py +23 -122
- universal_mcp/applications/apollo/app.py +111 -464
- universal_mcp/applications/asana/app.py +417 -1567
- universal_mcp/applications/aws_s3/app.py +33 -100
- universal_mcp/applications/bill/app.py +546 -1957
- universal_mcp/applications/box/app.py +1068 -3981
- universal_mcp/applications/braze/app.py +364 -1430
- universal_mcp/applications/browser_use/app.py +2 -8
- universal_mcp/applications/cal_com_v2/app.py +207 -625
- universal_mcp/applications/calendly/app.py +61 -200
- universal_mcp/applications/canva/app.py +45 -110
- universal_mcp/applications/clickup/app.py +207 -674
- universal_mcp/applications/coda/app.py +146 -426
- universal_mcp/applications/confluence/app.py +310 -1098
- universal_mcp/applications/contentful/app.py +36 -151
- universal_mcp/applications/crustdata/app.py +28 -107
- universal_mcp/applications/dialpad/app.py +283 -756
- universal_mcp/applications/digitalocean/app.py +1766 -5777
- universal_mcp/applications/domain_checker/app.py +3 -54
- universal_mcp/applications/e2b/app.py +14 -64
- universal_mcp/applications/elevenlabs/app.py +9 -47
- universal_mcp/applications/exa/app.py +6 -17
- universal_mcp/applications/falai/app.py +23 -100
- universal_mcp/applications/figma/app.py +53 -137
- universal_mcp/applications/file_system/app.py +2 -13
- universal_mcp/applications/firecrawl/app.py +51 -152
- universal_mcp/applications/fireflies/app.py +59 -281
- universal_mcp/applications/fpl/app.py +91 -528
- universal_mcp/applications/fpl/utils/fixtures.py +15 -49
- universal_mcp/applications/fpl/utils/helper.py +25 -89
- universal_mcp/applications/fpl/utils/league_utils.py +20 -64
- universal_mcp/applications/ghost_content/app.py +52 -161
- universal_mcp/applications/github/app.py +19 -56
- universal_mcp/applications/gong/app.py +88 -248
- universal_mcp/applications/google_calendar/app.py +16 -68
- universal_mcp/applications/google_docs/app.py +88 -188
- universal_mcp/applications/google_drive/app.py +140 -462
- universal_mcp/applications/google_gemini/app.py +12 -64
- universal_mcp/applications/google_mail/app.py +28 -157
- universal_mcp/applications/google_searchconsole/app.py +15 -48
- universal_mcp/applications/google_sheet/app.py +101 -578
- universal_mcp/applications/google_sheet/helper.py +10 -37
- universal_mcp/applications/hashnode/app.py +57 -269
- universal_mcp/applications/heygen/app.py +44 -122
- universal_mcp/applications/http_tools/app.py +10 -32
- universal_mcp/applications/hubspot/api_segments/crm_api.py +460 -1573
- universal_mcp/applications/hubspot/api_segments/marketing_api.py +74 -262
- universal_mcp/applications/hubspot/app.py +23 -87
- universal_mcp/applications/jira/app.py +2071 -7986
- universal_mcp/applications/klaviyo/app.py +494 -1376
- universal_mcp/applications/linkedin/README.md +23 -4
- universal_mcp/applications/linkedin/app.py +392 -212
- universal_mcp/applications/mailchimp/app.py +450 -1605
- universal_mcp/applications/markitdown/app.py +8 -20
- universal_mcp/applications/miro/app.py +217 -699
- universal_mcp/applications/ms_teams/app.py +64 -186
- universal_mcp/applications/neon/app.py +86 -192
- universal_mcp/applications/notion/app.py +21 -36
- universal_mcp/applications/onedrive/app.py +14 -36
- universal_mcp/applications/openai/app.py +42 -165
- universal_mcp/applications/outlook/app.py +16 -76
- universal_mcp/applications/perplexity/app.py +4 -19
- universal_mcp/applications/pipedrive/app.py +832 -3142
- universal_mcp/applications/posthog/app.py +163 -432
- universal_mcp/applications/reddit/app.py +40 -139
- universal_mcp/applications/resend/app.py +41 -107
- universal_mcp/applications/retell/app.py +14 -41
- universal_mcp/applications/rocketlane/app.py +221 -934
- universal_mcp/applications/scraper/README.md +7 -4
- universal_mcp/applications/scraper/app.py +280 -93
- universal_mcp/applications/semanticscholar/app.py +22 -64
- universal_mcp/applications/semrush/app.py +43 -77
- universal_mcp/applications/sendgrid/app.py +512 -1262
- universal_mcp/applications/sentry/app.py +271 -906
- universal_mcp/applications/serpapi/app.py +40 -143
- universal_mcp/applications/sharepoint/app.py +15 -37
- universal_mcp/applications/shopify/app.py +1551 -4287
- universal_mcp/applications/shortcut/app.py +155 -417
- universal_mcp/applications/slack/app.py +50 -101
- universal_mcp/applications/spotify/app.py +126 -325
- universal_mcp/applications/supabase/app.py +104 -213
- universal_mcp/applications/tavily/app.py +1 -1
- universal_mcp/applications/trello/app.py +693 -2656
- universal_mcp/applications/twilio/app.py +14 -50
- universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
- universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
- universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
- universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
- universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
- universal_mcp/applications/whatsapp/app.py +35 -186
- universal_mcp/applications/whatsapp/audio.py +2 -6
- universal_mcp/applications/whatsapp/whatsapp.py +17 -51
- universal_mcp/applications/whatsapp_business/app.py +70 -283
- universal_mcp/applications/wrike/app.py +45 -118
- universal_mcp/applications/yahoo_finance/app.py +19 -65
- universal_mcp/applications/youtube/app.py +75 -261
- universal_mcp/applications/zenquotes/app.py +2 -2
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/METADATA +2 -2
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/RECORD +105 -106
- universal_mcp/applications/scraper/scraper_testers.py +0 -17
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/WHEEL +0 -0
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from typing import Any
|
|
2
|
-
|
|
3
2
|
from universal_mcp.applications.application import APIApplication
|
|
4
3
|
from universal_mcp.integrations import Integration
|
|
5
4
|
|
|
@@ -15,13 +14,9 @@ class NotionApp(APIApplication):
|
|
|
15
14
|
credentials = self.integration.get_credentials()
|
|
16
15
|
if "headers" in credentials:
|
|
17
16
|
return credentials["headers"]
|
|
18
|
-
return {
|
|
19
|
-
"Authorization": f"Bearer {credentials['access_token']}",
|
|
20
|
-
"Accept": "application/json",
|
|
21
|
-
"Notion-Version": "2022-06-28",
|
|
22
|
-
}
|
|
17
|
+
return {"Authorization": f"Bearer {credentials['access_token']}", "Accept": "application/json", "Notion-Version": "2022-06-28"}
|
|
23
18
|
|
|
24
|
-
def retrieve_a_user(self, id, request_body=None) -> dict[str, Any]:
|
|
19
|
+
async def retrieve_a_user(self, id, request_body=None) -> dict[str, Any]:
|
|
25
20
|
"""
|
|
26
21
|
Retrieves a user's details from the server using their unique identifier.
|
|
27
22
|
|
|
@@ -47,9 +42,7 @@ class NotionApp(APIApplication):
|
|
|
47
42
|
response.raise_for_status()
|
|
48
43
|
return response.json()
|
|
49
44
|
|
|
50
|
-
def list_all_users(
|
|
51
|
-
self,
|
|
52
|
-
) -> dict[str, Any]:
|
|
45
|
+
async def list_all_users(self) -> dict[str, Any]:
|
|
53
46
|
"""
|
|
54
47
|
Retrieves a complete list of users from the API endpoint.
|
|
55
48
|
|
|
@@ -72,9 +65,7 @@ class NotionApp(APIApplication):
|
|
|
72
65
|
response.raise_for_status()
|
|
73
66
|
return response.json()
|
|
74
67
|
|
|
75
|
-
def retrieve_your_token_sbot_user(
|
|
76
|
-
self,
|
|
77
|
-
) -> dict[str, Any]:
|
|
68
|
+
async def retrieve_your_token_sbot_user(self) -> dict[str, Any]:
|
|
78
69
|
"""
|
|
79
70
|
Retrieves the current user's authentication token information from the SBOT service.
|
|
80
71
|
|
|
@@ -94,7 +85,7 @@ class NotionApp(APIApplication):
|
|
|
94
85
|
response.raise_for_status()
|
|
95
86
|
return response.json()
|
|
96
87
|
|
|
97
|
-
def retrieve_a_database(self, id) -> dict[str, Any]:
|
|
88
|
+
async def retrieve_a_database(self, id) -> dict[str, Any]:
|
|
98
89
|
"""
|
|
99
90
|
Retrieves detailed information about a specific database using its unique identifier.
|
|
100
91
|
|
|
@@ -119,7 +110,7 @@ class NotionApp(APIApplication):
|
|
|
119
110
|
response.raise_for_status()
|
|
120
111
|
return response.json()
|
|
121
112
|
|
|
122
|
-
def update_a_database(self, id, request_body=None) -> dict[str, Any]:
|
|
113
|
+
async def update_a_database(self, id, request_body=None) -> dict[str, Any]:
|
|
123
114
|
"""
|
|
124
115
|
Updates a database entry with the specified ID using a PATCH request.
|
|
125
116
|
|
|
@@ -145,7 +136,7 @@ class NotionApp(APIApplication):
|
|
|
145
136
|
response.raise_for_status()
|
|
146
137
|
return response.json()
|
|
147
138
|
|
|
148
|
-
def query_a_database(self, id, request_body=None) -> dict[str, Any]:
|
|
139
|
+
async def query_a_database(self, id, request_body=None) -> dict[str, Any]:
|
|
149
140
|
"""
|
|
150
141
|
Executes a database query operation using a specified database ID and optional request parameters
|
|
151
142
|
|
|
@@ -171,7 +162,7 @@ class NotionApp(APIApplication):
|
|
|
171
162
|
response.raise_for_status()
|
|
172
163
|
return response.json()
|
|
173
164
|
|
|
174
|
-
def create_a_database(self, request_body=None) -> dict[str, Any]:
|
|
165
|
+
async def create_a_database(self, request_body=None) -> dict[str, Any]:
|
|
175
166
|
"""
|
|
176
167
|
Creates a new database on the server by sending a POST request to the database endpoint.
|
|
177
168
|
|
|
@@ -195,7 +186,7 @@ class NotionApp(APIApplication):
|
|
|
195
186
|
response.raise_for_status()
|
|
196
187
|
return response.json()
|
|
197
188
|
|
|
198
|
-
def create_a_page(self, request_body=None) -> dict[str, Any]:
|
|
189
|
+
async def create_a_page(self, request_body=None) -> dict[str, Any]:
|
|
199
190
|
"""
|
|
200
191
|
Creates a new page by sending a POST request to the API endpoint.
|
|
201
192
|
|
|
@@ -218,7 +209,7 @@ class NotionApp(APIApplication):
|
|
|
218
209
|
response.raise_for_status()
|
|
219
210
|
return response.json()
|
|
220
211
|
|
|
221
|
-
def retrieve_a_page(self, id) -> dict[str, Any]:
|
|
212
|
+
async def retrieve_a_page(self, id) -> dict[str, Any]:
|
|
222
213
|
"""
|
|
223
214
|
Retrieves a specific page's data from a remote server using its unique identifier.
|
|
224
215
|
|
|
@@ -243,7 +234,7 @@ class NotionApp(APIApplication):
|
|
|
243
234
|
response.raise_for_status()
|
|
244
235
|
return response.json()
|
|
245
236
|
|
|
246
|
-
def update_page_properties(self, id, request_body=None) -> dict[str, Any]:
|
|
237
|
+
async def update_page_properties(self, id, request_body=None) -> dict[str, Any]:
|
|
247
238
|
"""
|
|
248
239
|
Updates the properties of a page with the specified ID using the provided request body.
|
|
249
240
|
|
|
@@ -270,7 +261,7 @@ class NotionApp(APIApplication):
|
|
|
270
261
|
response.raise_for_status()
|
|
271
262
|
return response.json()
|
|
272
263
|
|
|
273
|
-
def retrieve_a_page_property_item(self, page_id, property_id) -> dict[str, Any]:
|
|
264
|
+
async def retrieve_a_page_property_item(self, page_id, property_id) -> dict[str, Any]:
|
|
274
265
|
"""
|
|
275
266
|
Retrieves a specific property item from a Notion page using the page ID and property ID.
|
|
276
267
|
|
|
@@ -298,7 +289,7 @@ class NotionApp(APIApplication):
|
|
|
298
289
|
response.raise_for_status()
|
|
299
290
|
return response.json()
|
|
300
291
|
|
|
301
|
-
def retrieve_block_children(self, id, page_size=None) -> dict[str, Any]:
|
|
292
|
+
async def retrieve_block_children(self, id, page_size=None) -> dict[str, Any]:
|
|
302
293
|
"""
|
|
303
294
|
Retrieves all child blocks for a specified parent block using its ID via the API.
|
|
304
295
|
|
|
@@ -324,7 +315,7 @@ class NotionApp(APIApplication):
|
|
|
324
315
|
response.raise_for_status()
|
|
325
316
|
return response.json()
|
|
326
317
|
|
|
327
|
-
def append_block_children(self, id, request_body=None) -> dict[str, Any]:
|
|
318
|
+
async def append_block_children(self, id, request_body=None) -> dict[str, Any]:
|
|
328
319
|
"""
|
|
329
320
|
Appends child elements to a specified block and returns the updated block data.
|
|
330
321
|
|
|
@@ -350,7 +341,7 @@ class NotionApp(APIApplication):
|
|
|
350
341
|
response.raise_for_status()
|
|
351
342
|
return response.json()
|
|
352
343
|
|
|
353
|
-
def retrieve_a_block(self, id) -> dict[str, Any]:
|
|
344
|
+
async def retrieve_a_block(self, id) -> dict[str, Any]:
|
|
354
345
|
"""
|
|
355
346
|
Retrieves a specific block of data from the API using its unique identifier.
|
|
356
347
|
|
|
@@ -375,7 +366,7 @@ class NotionApp(APIApplication):
|
|
|
375
366
|
response.raise_for_status()
|
|
376
367
|
return response.json()
|
|
377
368
|
|
|
378
|
-
def delete_a_block(self, id) -> dict[str, Any]:
|
|
369
|
+
async def delete_a_block(self, id) -> dict[str, Any]:
|
|
379
370
|
"""
|
|
380
371
|
Deletes a specified block by its ID and returns the server response.
|
|
381
372
|
|
|
@@ -400,7 +391,7 @@ class NotionApp(APIApplication):
|
|
|
400
391
|
response.raise_for_status()
|
|
401
392
|
return response.json()
|
|
402
393
|
|
|
403
|
-
def update_a_block(self, id, request_body=None) -> dict[str, Any]:
|
|
394
|
+
async def update_a_block(self, id, request_body=None) -> dict[str, Any]:
|
|
404
395
|
"""
|
|
405
396
|
Updates a specific block resource via a PATCH request to the API endpoint
|
|
406
397
|
|
|
@@ -426,7 +417,7 @@ class NotionApp(APIApplication):
|
|
|
426
417
|
response.raise_for_status()
|
|
427
418
|
return response.json()
|
|
428
419
|
|
|
429
|
-
def search(self, request_body=None) -> dict[str, Any]:
|
|
420
|
+
async def search(self, request_body=None) -> dict[str, Any]:
|
|
430
421
|
"""
|
|
431
422
|
Executes a search operation by sending a POST request to the search endpoint and returns the results
|
|
432
423
|
|
|
@@ -449,9 +440,7 @@ class NotionApp(APIApplication):
|
|
|
449
440
|
response.raise_for_status()
|
|
450
441
|
return response.json()
|
|
451
442
|
|
|
452
|
-
def retrieve_comments(
|
|
453
|
-
self, block_id=None, page_size=None, request_body=None
|
|
454
|
-
) -> dict[str, Any]:
|
|
443
|
+
async def retrieve_comments(self, block_id=None, page_size=None, request_body=None) -> dict[str, Any]:
|
|
455
444
|
"""
|
|
456
445
|
Retrieves comments from a remote server with optional block filtering and pagination support.
|
|
457
446
|
|
|
@@ -471,16 +460,12 @@ class NotionApp(APIApplication):
|
|
|
471
460
|
retrieve, fetch, comments, api, pagination, http
|
|
472
461
|
"""
|
|
473
462
|
url = f"{self.base_url}/v1/comments"
|
|
474
|
-
query_params = {
|
|
475
|
-
k: v
|
|
476
|
-
for k, v in [("block_id", block_id), ("page_size", page_size)]
|
|
477
|
-
if v is not None
|
|
478
|
-
}
|
|
463
|
+
query_params = {k: v for k, v in [("block_id", block_id), ("page_size", page_size)] if v is not None}
|
|
479
464
|
response = self._get(url, params=query_params)
|
|
480
465
|
response.raise_for_status()
|
|
481
466
|
return response.json()
|
|
482
467
|
|
|
483
|
-
def add_comment_to_page(self, request_body=None) -> dict[str, Any]:
|
|
468
|
+
async def add_comment_to_page(self, request_body=None) -> dict[str, Any]:
|
|
484
469
|
"""
|
|
485
470
|
Adds a comment to a page by making an HTTP POST request to the comments endpoint.
|
|
486
471
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import os
|
|
3
3
|
from typing import Any
|
|
4
|
-
|
|
5
4
|
from loguru import logger
|
|
6
5
|
from universal_mcp.applications.application import APIApplication
|
|
7
6
|
from universal_mcp.integrations import Integration
|
|
@@ -17,7 +16,7 @@ class OnedriveApp(APIApplication):
|
|
|
17
16
|
super().__init__(name="onedrive", integration=integration, **kwargs)
|
|
18
17
|
self.base_url = "https://graph.microsoft.com/v1.0"
|
|
19
18
|
|
|
20
|
-
def get_my_profile(self) -> dict[str, Any]:
|
|
19
|
+
async def get_my_profile(self) -> dict[str, Any]:
|
|
21
20
|
"""
|
|
22
21
|
Fetches the profile for the currently authenticated user, specifically retrieving their ID and user principal name. This function confirms user identity, distinguishing it from `get_drive_info`, which returns details about the OneDrive storage space (e.g., quota) rather than the user's personal profile.
|
|
23
22
|
|
|
@@ -35,7 +34,7 @@ class OnedriveApp(APIApplication):
|
|
|
35
34
|
response = self._get(url, params=query_params)
|
|
36
35
|
return self._handle_response(response)
|
|
37
36
|
|
|
38
|
-
def get_drive_info(self) -> dict[str, Any]:
|
|
37
|
+
async def get_drive_info(self) -> dict[str, Any]:
|
|
39
38
|
"""
|
|
40
39
|
Fetches high-level information about the user's entire OneDrive. It returns drive-wide details like the owner and storage quota, differing from `get_item_metadata` which describes a specific item, and `get_my_profile` which retrieves general user account information.
|
|
41
40
|
|
|
@@ -63,7 +62,7 @@ class OnedriveApp(APIApplication):
|
|
|
63
62
|
response = self._get(url)
|
|
64
63
|
return self._handle_response(response)
|
|
65
64
|
|
|
66
|
-
def search_files(self, query: str) -> dict[str, Any]:
|
|
65
|
+
async def search_files(self, query: str) -> dict[str, Any]:
|
|
67
66
|
"""
|
|
68
67
|
Searches the user's entire OneDrive for files and folders matching a specified text query. This function performs a comprehensive search from the drive's root, distinguishing it from `list_files` or `list_folders` which only browse the contents of a single directory.
|
|
69
68
|
|
|
@@ -78,12 +77,11 @@ class OnedriveApp(APIApplication):
|
|
|
78
77
|
"""
|
|
79
78
|
if not query:
|
|
80
79
|
raise ValueError("Search query cannot be empty.")
|
|
81
|
-
|
|
82
80
|
url = f"{self.base_url}/me/drive/root/search(q='{query}')"
|
|
83
81
|
response = self._get(url)
|
|
84
82
|
return self._handle_response(response)
|
|
85
83
|
|
|
86
|
-
def get_item_metadata(self, item_id: str) -> dict[str, Any]:
|
|
84
|
+
async def get_item_metadata(self, item_id: str) -> dict[str, Any]:
|
|
87
85
|
"""
|
|
88
86
|
Fetches detailed metadata for a specific file or folder using its unique ID. It returns properties like name, size, and type. Unlike `get_document_content`, it doesn't retrieve the file's actual content, focusing solely on the item's attributes for quick inspection without a full download.
|
|
89
87
|
|
|
@@ -98,12 +96,11 @@ class OnedriveApp(APIApplication):
|
|
|
98
96
|
"""
|
|
99
97
|
if not item_id:
|
|
100
98
|
raise ValueError("Missing required parameter 'item_id'.")
|
|
101
|
-
|
|
102
99
|
url = f"{self.base_url}/me/drive/items/{item_id}"
|
|
103
100
|
response = self._get(url)
|
|
104
101
|
return self._handle_response(response)
|
|
105
102
|
|
|
106
|
-
def create_folder(self, name: str, parent_id: str = "root") -> dict[str, Any]:
|
|
103
|
+
async def create_folder(self, name: str, parent_id: str = "root") -> dict[str, Any]:
|
|
107
104
|
"""
|
|
108
105
|
Creates a new folder with a specified name within a parent directory, which defaults to the root. Returns metadata for the new folder. Unlike `create_folder_and_list`, this function only creates the folder and returns its specific metadata, not the parent directory's contents.
|
|
109
106
|
|
|
@@ -119,13 +116,12 @@ class OnedriveApp(APIApplication):
|
|
|
119
116
|
"""
|
|
120
117
|
if not name:
|
|
121
118
|
raise ValueError("Folder name cannot be empty.")
|
|
122
|
-
|
|
123
119
|
url = f"{self.base_url}/me/drive/items/{parent_id}/children"
|
|
124
120
|
data = {"name": name, "folder": {}, "@microsoft.graph.conflictBehavior": "rename"}
|
|
125
121
|
response = self._post(url, data=data)
|
|
126
122
|
return self._handle_response(response)
|
|
127
123
|
|
|
128
|
-
def delete_item(self, item_id: str) -> dict[str, Any]:
|
|
124
|
+
async def delete_item(self, item_id: str) -> dict[str, Any]:
|
|
129
125
|
"""
|
|
130
126
|
Permanently deletes a specified file or folder from OneDrive using its unique item ID. This versatile function can remove any type of drive item, distinguished from functions that only list or create specific types. A successful deletion returns an empty response, confirming the item's removal.
|
|
131
127
|
|
|
@@ -140,12 +136,11 @@ class OnedriveApp(APIApplication):
|
|
|
140
136
|
"""
|
|
141
137
|
if not item_id:
|
|
142
138
|
raise ValueError("Missing required parameter 'item_id'.")
|
|
143
|
-
|
|
144
139
|
url = f"{self.base_url}/me/drive/items/{item_id}"
|
|
145
140
|
response = self._delete(url)
|
|
146
141
|
return self._handle_response(response)
|
|
147
142
|
|
|
148
|
-
def download_file(self, item_id: str) -> dict[str, Any]:
|
|
143
|
+
async def download_file(self, item_id: str) -> dict[str, Any]:
|
|
149
144
|
"""
|
|
150
145
|
Retrieves a temporary, pre-authenticated download URL for a specific file using its item ID. This function provides a link for subsequent download, differing from `get_document_content` which directly fetches the file's raw content. The URL is returned within a dictionary.
|
|
151
146
|
|
|
@@ -160,7 +155,6 @@ class OnedriveApp(APIApplication):
|
|
|
160
155
|
"""
|
|
161
156
|
if not item_id:
|
|
162
157
|
raise ValueError("Missing required parameter 'item_id'.")
|
|
163
|
-
|
|
164
158
|
url = f"{self.base_url}/me/drive/items/{item_id}"
|
|
165
159
|
response = self._get(url)
|
|
166
160
|
metadata = self._handle_response(response)
|
|
@@ -169,7 +163,7 @@ class OnedriveApp(APIApplication):
|
|
|
169
163
|
raise ValueError("Could not retrieve download URL for the item.")
|
|
170
164
|
return {"download_url": download_url}
|
|
171
165
|
|
|
172
|
-
def upload_file(self, file_path: str, parent_id: str = "root", file_name: str | None = None) -> dict[str, Any]:
|
|
166
|
+
async def upload_file(self, file_path: str, parent_id: str = "root", file_name: str | None = None) -> dict[str, Any]:
|
|
173
167
|
"""
|
|
174
168
|
Uploads a local binary file (under 4MB) from a given path to a specified OneDrive folder. Unlike `upload_text_file`, which uploads string content, this function reads from the filesystem. The destination filename can be customized, and it returns the new file's metadata upon completion.
|
|
175
169
|
|
|
@@ -186,17 +180,15 @@ class OnedriveApp(APIApplication):
|
|
|
186
180
|
"""
|
|
187
181
|
if not os.path.exists(file_path):
|
|
188
182
|
raise FileNotFoundError(f"The file was not found at path: {file_path}")
|
|
189
|
-
|
|
190
183
|
if not file_name:
|
|
191
184
|
file_name = os.path.basename(file_path)
|
|
192
|
-
|
|
193
185
|
url = f"{self.base_url}/me/drive/items/{parent_id}:/{file_name}:/content"
|
|
194
186
|
with open(file_path, "rb") as f:
|
|
195
187
|
data = f.read()
|
|
196
188
|
response = self._put(url, data=data, content_type="application/octet-stream")
|
|
197
189
|
return self._handle_response(response)
|
|
198
190
|
|
|
199
|
-
def list_folders(self, item_id: str = "root") -> dict[str, Any]:
|
|
191
|
+
async def list_folders(self, item_id: str = "root") -> dict[str, Any]:
|
|
200
192
|
"""
|
|
201
193
|
Retrieves a list of only the folders within a specified parent directory in OneDrive. Unlike `_list_drive_items` which returns all items, this function filters the results to exclude files. Defaults to the root directory if no parent `item_id` is provided.
|
|
202
194
|
|
|
@@ -213,7 +205,7 @@ class OnedriveApp(APIApplication):
|
|
|
213
205
|
folders = [item for item in all_items.get("value", []) if "folder" in item]
|
|
214
206
|
return {"value": folders}
|
|
215
207
|
|
|
216
|
-
def list_files(self, item_id: str = "root") -> dict[str, Any]:
|
|
208
|
+
async def list_files(self, item_id: str = "root") -> dict[str, Any]:
|
|
217
209
|
"""
|
|
218
210
|
Retrieves a list of files within a specified OneDrive folder, defaulting to the root. Unlike `_list_drive_items` which fetches all items, this function filters the results to exclusively return items identified as files, excluding any subdirectories.
|
|
219
211
|
|
|
@@ -230,7 +222,7 @@ class OnedriveApp(APIApplication):
|
|
|
230
222
|
files = [item for item in all_items.get("value", []) if "file" in item]
|
|
231
223
|
return {"value": files}
|
|
232
224
|
|
|
233
|
-
def create_folder_and_list(self, name: str, parent_id: str = "root") -> dict[str, Any]:
|
|
225
|
+
async def create_folder_and_list(self, name: str, parent_id: str = "root") -> dict[str, Any]:
|
|
234
226
|
"""
|
|
235
227
|
Performs a composite action: creates a new folder, then lists all items (files and folders) within that parent directory. This confirms creation by returning the parent's updated contents, distinct from `create_folder` which only returns the new folder's metadata.
|
|
236
228
|
|
|
@@ -247,7 +239,7 @@ class OnedriveApp(APIApplication):
|
|
|
247
239
|
self.create_folder(name=name, parent_id=parent_id)
|
|
248
240
|
return self._list_drive_items(item_id=parent_id)
|
|
249
241
|
|
|
250
|
-
def upload_text_file(self, content: str, parent_id: str = "root", file_name: str = "new_file.txt") -> dict[str, Any]:
|
|
242
|
+
async def upload_text_file(self, content: str, parent_id: str = "root", file_name: str = "new_file.txt") -> dict[str, Any]:
|
|
251
243
|
"""
|
|
252
244
|
Creates and uploads a new file to OneDrive directly from a string of text content. Unlike `upload_file`, which requires a local file path, this function is specifically for creating a text file from in-memory string data, with a customizable name and destination folder.
|
|
253
245
|
|
|
@@ -264,13 +256,12 @@ class OnedriveApp(APIApplication):
|
|
|
264
256
|
"""
|
|
265
257
|
if not file_name:
|
|
266
258
|
raise ValueError("File name cannot be empty.")
|
|
267
|
-
|
|
268
259
|
url = f"{self.base_url}/me/drive/items/{parent_id}:/{file_name}:/content"
|
|
269
260
|
data = content.encode("utf-8")
|
|
270
261
|
response = self._put(url, data=data, content_type="text/plain")
|
|
271
262
|
return self._handle_response(response)
|
|
272
263
|
|
|
273
|
-
def get_document_content(self, item_id: str) -> dict[str, Any]:
|
|
264
|
+
async def get_document_content(self, item_id: str) -> dict[str, Any]:
|
|
274
265
|
"""
|
|
275
266
|
Retrieves the content of a specific file by its item ID and returns it directly as base64-encoded data. This function is distinct from `download_file`, which only provides a temporary URL for the content, and from `get_item_metadata`, which returns file attributes without the content itself. The function fetches the content by following the file's pre-authenticated download URL.
|
|
276
267
|
|
|
@@ -289,36 +280,23 @@ class OnedriveApp(APIApplication):
|
|
|
289
280
|
"""
|
|
290
281
|
if not item_id:
|
|
291
282
|
raise ValueError("Missing required parameter 'item_id'.")
|
|
292
|
-
|
|
293
283
|
metadata = self.get_item_metadata(item_id=item_id)
|
|
294
284
|
file_metadata = metadata.get("file")
|
|
295
285
|
if not file_metadata:
|
|
296
286
|
raise ValueError(f"Item with ID '{item_id}' is not a file.")
|
|
297
|
-
|
|
298
287
|
file_mime_type = file_metadata.get("mimeType", "application/octet-stream")
|
|
299
288
|
file_name = metadata.get("name")
|
|
300
|
-
|
|
301
289
|
download_url = metadata.get("@microsoft.graph.downloadUrl")
|
|
302
290
|
if not download_url:
|
|
303
291
|
logger.error(f"Could not find @microsoft.graph.downloadUrl in metadata for item {item_id}")
|
|
304
292
|
raise ValueError("Could not retrieve download URL for the item.")
|
|
305
|
-
|
|
306
293
|
response = self._get(download_url)
|
|
307
|
-
|
|
308
294
|
response.raise_for_status()
|
|
309
|
-
|
|
310
295
|
content = response.content
|
|
311
|
-
|
|
312
296
|
attachment_type = file_mime_type.split("/")[0] if "/" in file_mime_type else "file"
|
|
313
297
|
if attachment_type not in ["image", "audio", "video", "text"]:
|
|
314
298
|
attachment_type = "file"
|
|
315
|
-
|
|
316
|
-
return {
|
|
317
|
-
"type": attachment_type,
|
|
318
|
-
"data": content,
|
|
319
|
-
"mime_type": file_mime_type,
|
|
320
|
-
"file_name": file_name,
|
|
321
|
-
}
|
|
299
|
+
return {"type": attachment_type, "data": content, "mime_type": file_mime_type, "file_name": file_name}
|
|
322
300
|
|
|
323
301
|
def list_tools(self):
|
|
324
302
|
return [
|