universal-mcp-applications 0.1.30__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 +9 -2
- 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 +216 -102
- 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.30.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/METADATA +2 -2
- {universal_mcp_applications-0.1.30.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/RECORD +105 -105
- {universal_mcp_applications-0.1.30.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/WHEEL +0 -0
- {universal_mcp_applications-0.1.30.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
from collections.abc import Callable
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
from typing import Any
|
|
4
|
-
|
|
5
4
|
from loguru import logger
|
|
6
5
|
|
|
7
6
|
try:
|
|
8
7
|
from twilio.rest import Client as TwilioClient
|
|
9
8
|
except ImportError:
|
|
10
9
|
TwilioClient = None
|
|
11
|
-
logger.error(
|
|
12
|
-
"Twilio SDK is not installed. Please install 'twilio' to use TwilioApp."
|
|
13
|
-
)
|
|
14
|
-
|
|
10
|
+
logger.error("Twilio SDK is not installed. Please install 'twilio' to use TwilioApp.")
|
|
15
11
|
from universal_mcp.applications.application import APIApplication
|
|
16
12
|
from universal_mcp.exceptions import NotAuthorizedError, ToolError
|
|
17
13
|
from universal_mcp.integrations import Integration
|
|
@@ -29,9 +25,7 @@ class TwilioApp(APIApplication):
|
|
|
29
25
|
self._account_sid: str | None = None
|
|
30
26
|
self._auth_token: str | None = None
|
|
31
27
|
if TwilioClient is None:
|
|
32
|
-
logger.warning(
|
|
33
|
-
"Twilio SDK is not available. Twilio tools will not function."
|
|
34
|
-
)
|
|
28
|
+
logger.warning("Twilio SDK is not available. Twilio tools will not function.")
|
|
35
29
|
|
|
36
30
|
@property
|
|
37
31
|
def account_sid(self) -> str:
|
|
@@ -45,16 +39,9 @@ class TwilioApp(APIApplication):
|
|
|
45
39
|
credentials = self.integration.get_credentials()
|
|
46
40
|
except Exception as e:
|
|
47
41
|
raise NotAuthorizedError(f"Failed to get Twilio credentials: {e}")
|
|
48
|
-
|
|
49
|
-
sid = (
|
|
50
|
-
credentials.get("account_sid")
|
|
51
|
-
or credentials.get("ACCOUNT_SID")
|
|
52
|
-
or credentials.get("TWILIO_ACCOUNT_SID")
|
|
53
|
-
)
|
|
42
|
+
sid = credentials.get("account_sid") or credentials.get("ACCOUNT_SID") or credentials.get("TWILIO_ACCOUNT_SID")
|
|
54
43
|
if not sid:
|
|
55
|
-
raise NotAuthorizedError(
|
|
56
|
-
"Twilio Account SID is missing. Please set it in the integration."
|
|
57
|
-
)
|
|
44
|
+
raise NotAuthorizedError("Twilio Account SID is missing. Please set it in the integration.")
|
|
58
45
|
self._account_sid = sid
|
|
59
46
|
return self._account_sid
|
|
60
47
|
|
|
@@ -70,16 +57,9 @@ class TwilioApp(APIApplication):
|
|
|
70
57
|
credentials = self.integration.get_credentials()
|
|
71
58
|
except Exception as e:
|
|
72
59
|
raise NotAuthorizedError(f"Failed to get Twilio credentials: {e}")
|
|
73
|
-
|
|
74
|
-
token = (
|
|
75
|
-
credentials.get("auth_token")
|
|
76
|
-
or credentials.get("AUTH_TOKEN")
|
|
77
|
-
or credentials.get("TWILIO_AUTH_TOKEN")
|
|
78
|
-
)
|
|
60
|
+
token = credentials.get("auth_token") or credentials.get("AUTH_TOKEN") or credentials.get("TWILIO_AUTH_TOKEN")
|
|
79
61
|
if not token:
|
|
80
|
-
raise NotAuthorizedError(
|
|
81
|
-
"Twilio Auth Token is missing. Please set it in the integration."
|
|
82
|
-
)
|
|
62
|
+
raise NotAuthorizedError("Twilio Auth Token is missing. Please set it in the integration.")
|
|
83
63
|
self._auth_token = token
|
|
84
64
|
return self._auth_token
|
|
85
65
|
|
|
@@ -94,7 +74,7 @@ class TwilioApp(APIApplication):
|
|
|
94
74
|
self._twilio_client = TwilioClient(self.account_sid, self.auth_token)
|
|
95
75
|
return self._twilio_client
|
|
96
76
|
|
|
97
|
-
def create_message(self, from_: str, to: str, body: str) -> dict[str, Any]:
|
|
77
|
+
async def create_message(self, from_: str, to: str, body: str) -> dict[str, Any]:
|
|
98
78
|
"""
|
|
99
79
|
Sends a new SMS or MMS message using Twilio.
|
|
100
80
|
|
|
@@ -114,12 +94,7 @@ class TwilioApp(APIApplication):
|
|
|
114
94
|
create, message, sms, mms, send, twilio, api, important
|
|
115
95
|
"""
|
|
116
96
|
try:
|
|
117
|
-
message = self.twilio_client.messages.create(
|
|
118
|
-
from_=from_,
|
|
119
|
-
to=to,
|
|
120
|
-
body=body,
|
|
121
|
-
)
|
|
122
|
-
# Convert the Twilio MessageInstance to a dict
|
|
97
|
+
message = self.twilio_client.messages.create(from_=from_, to=to, body=body)
|
|
123
98
|
return {
|
|
124
99
|
"sid": message.sid,
|
|
125
100
|
"status": message.status,
|
|
@@ -137,7 +112,7 @@ class TwilioApp(APIApplication):
|
|
|
137
112
|
raise NotAuthorizedError(f"Twilio authentication failed: {e}")
|
|
138
113
|
raise ToolError(f"Failed to send message: {e}")
|
|
139
114
|
|
|
140
|
-
def fetch_message(self, message_sid: str) -> dict[str, Any]:
|
|
115
|
+
async def fetch_message(self, message_sid: str) -> dict[str, Any]:
|
|
141
116
|
"""
|
|
142
117
|
Fetches the details of a specific message by its SID.
|
|
143
118
|
|
|
@@ -173,11 +148,8 @@ class TwilioApp(APIApplication):
|
|
|
173
148
|
raise NotAuthorizedError(f"Twilio authentication failed: {e}")
|
|
174
149
|
raise ToolError(f"Failed to fetch message: {e}")
|
|
175
150
|
|
|
176
|
-
def list_messages(
|
|
177
|
-
self,
|
|
178
|
-
limit: int = 20,
|
|
179
|
-
date_sent_before: datetime | None = None,
|
|
180
|
-
date_sent_after: datetime | None = None,
|
|
151
|
+
async def list_messages(
|
|
152
|
+
self, limit: int = 20, date_sent_before: datetime | None = None, date_sent_after: datetime | None = None
|
|
181
153
|
) -> list[dict[str, Any]]:
|
|
182
154
|
"""
|
|
183
155
|
Lists messages from your Twilio account, optionally filtered by date.
|
|
@@ -198,14 +170,11 @@ class TwilioApp(APIApplication):
|
|
|
198
170
|
list, message, sms, mms, read, twilio, api, important
|
|
199
171
|
"""
|
|
200
172
|
try:
|
|
201
|
-
params = {
|
|
202
|
-
"limit": limit,
|
|
203
|
-
}
|
|
173
|
+
params = {"limit": limit}
|
|
204
174
|
if date_sent_before:
|
|
205
175
|
params["date_sent_before"] = date_sent_before
|
|
206
176
|
if date_sent_after:
|
|
207
177
|
params["date_sent_after"] = date_sent_after
|
|
208
|
-
|
|
209
178
|
messages = self.twilio_client.messages.list(**params)
|
|
210
179
|
result = []
|
|
211
180
|
for msg in messages:
|
|
@@ -229,7 +198,7 @@ class TwilioApp(APIApplication):
|
|
|
229
198
|
raise NotAuthorizedError(f"Twilio authentication failed: {e}")
|
|
230
199
|
raise ToolError(f"Failed to list messages: {e}")
|
|
231
200
|
|
|
232
|
-
def delete_message(self, message_sid: str) -> bool:
|
|
201
|
+
async def delete_message(self, message_sid: str) -> bool:
|
|
233
202
|
"""
|
|
234
203
|
Deletes a specific message from your Twilio account.
|
|
235
204
|
|
|
@@ -261,9 +230,4 @@ class TwilioApp(APIApplication):
|
|
|
261
230
|
Returns:
|
|
262
231
|
A list of callable tool methods.
|
|
263
232
|
"""
|
|
264
|
-
return [
|
|
265
|
-
self.create_message,
|
|
266
|
-
self.fetch_message,
|
|
267
|
-
self.list_messages,
|
|
268
|
-
self.delete_message,
|
|
269
|
-
]
|
|
233
|
+
return [self.create_message, self.fetch_message, self.list_messages, self.delete_message]
|
|
@@ -7,9 +7,7 @@ class ComplianceApi(APISegmentBase):
|
|
|
7
7
|
def __init__(self, main_app_client: Any):
|
|
8
8
|
super().__init__(main_app_client)
|
|
9
9
|
|
|
10
|
-
def list_batch_compliance_jobs(
|
|
11
|
-
self, type, status=None, compliance_job_fields=None
|
|
12
|
-
) -> dict[str, Any]:
|
|
10
|
+
def list_batch_compliance_jobs(self, type, status=None, compliance_job_fields=None) -> dict[str, Any]:
|
|
13
11
|
"""
|
|
14
12
|
Retrieves a list of compliance jobs, requiring a job `type` ('tweets' or 'users') and allowing optional filtering by `status`. This function fetches multiple jobs, distinguishing it from `get_batch_compliance_job` which retrieves a single job by its unique ID.
|
|
15
13
|
|
|
@@ -42,9 +40,7 @@ class ComplianceApi(APISegmentBase):
|
|
|
42
40
|
response.raise_for_status()
|
|
43
41
|
return response.json()
|
|
44
42
|
|
|
45
|
-
def create_batch_compliance_job(
|
|
46
|
-
self, type, name=None, resumable=None
|
|
47
|
-
) -> dict[str, Any]:
|
|
43
|
+
def create_batch_compliance_job(self, type, name=None, resumable=None) -> dict[str, Any]:
|
|
48
44
|
"""
|
|
49
45
|
Creates a new batch compliance job for a specified type ('tweets' or 'users'). A custom name can be provided, and resumable uploads can be enabled. This initiates the job creation process, differing from functions that list or retrieve existing jobs.
|
|
50
46
|
|
|
@@ -65,9 +61,7 @@ class ComplianceApi(APISegmentBase):
|
|
|
65
61
|
"""
|
|
66
62
|
request_body_data = None
|
|
67
63
|
request_body_data = {"name": name, "resumable": resumable, "type": type}
|
|
68
|
-
request_body_data = {
|
|
69
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
70
|
-
}
|
|
64
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
71
65
|
url = f"{self.main_app_client.base_url}/2/compliance/jobs"
|
|
72
66
|
query_params = {}
|
|
73
67
|
response = self._post(
|
|
@@ -100,11 +94,7 @@ class ComplianceApi(APISegmentBase):
|
|
|
100
94
|
if id is None:
|
|
101
95
|
raise ValueError("Missing required parameter 'id'.")
|
|
102
96
|
url = f"{self.main_app_client.base_url}/2/compliance/jobs/{id}"
|
|
103
|
-
query_params = {
|
|
104
|
-
k: v
|
|
105
|
-
for k, v in [("compliance_job.fields", compliance_job_fields)]
|
|
106
|
-
if v is not None
|
|
107
|
-
}
|
|
97
|
+
query_params = {k: v for k, v in [("compliance_job.fields", compliance_job_fields)] if v is not None}
|
|
108
98
|
response = self._get(url, params=query_params)
|
|
109
99
|
response.raise_for_status()
|
|
110
100
|
return response.json()
|
|
@@ -7,9 +7,7 @@ class DmConversationsApi(APISegmentBase):
|
|
|
7
7
|
def __init__(self, main_app_client: Any):
|
|
8
8
|
super().__init__(main_app_client)
|
|
9
9
|
|
|
10
|
-
def create_dm_conversation(
|
|
11
|
-
self, conversation_type=None, message=None, participant_ids=None
|
|
12
|
-
) -> dict[str, Any]:
|
|
10
|
+
def create_dm_conversation(self, conversation_type=None, message=None, participant_ids=None) -> dict[str, Any]:
|
|
13
11
|
"""
|
|
14
12
|
Creates a new group Direct Message conversation with specified participants and sends an initial message. This function specifically handles the creation of new multi-participant conversations, distinct from other methods in this class that add messages to existing one-to-one or group DMs.
|
|
15
13
|
|
|
@@ -34,9 +32,7 @@ class DmConversationsApi(APISegmentBase):
|
|
|
34
32
|
"message": message,
|
|
35
33
|
"participant_ids": participant_ids,
|
|
36
34
|
}
|
|
37
|
-
request_body_data = {
|
|
38
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
39
|
-
}
|
|
35
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
40
36
|
url = f"{self.main_app_client.base_url}/2/dm_conversations"
|
|
41
37
|
query_params = {}
|
|
42
38
|
response = self._post(
|
|
@@ -105,9 +101,7 @@ class DmConversationsApi(APISegmentBase):
|
|
|
105
101
|
response.raise_for_status()
|
|
106
102
|
return response.json()
|
|
107
103
|
|
|
108
|
-
def send_dm_by_participant_id(
|
|
109
|
-
self, participant_id, attachments=None, text=None
|
|
110
|
-
) -> dict[str, Any]:
|
|
104
|
+
def send_dm_by_participant_id(self, participant_id, attachments=None, text=None) -> dict[str, Any]:
|
|
111
105
|
"""
|
|
112
106
|
Sends a direct message to a user specified by their participant ID. It creates a new one-on-one conversation or appends the message to an existing one. Unlike other functions, this method identifies the conversation using the participant's ID rather than a pre-existing conversation ID.
|
|
113
107
|
|
|
@@ -130,9 +124,7 @@ class DmConversationsApi(APISegmentBase):
|
|
|
130
124
|
raise ValueError("Missing required parameter 'participant_id'.")
|
|
131
125
|
request_body_data = None
|
|
132
126
|
request_body_data = {"attachments": attachments, "text": text}
|
|
133
|
-
request_body_data = {
|
|
134
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
135
|
-
}
|
|
127
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
136
128
|
url = f"{self.main_app_client.base_url}/2/dm_conversations/with/{participant_id}/messages"
|
|
137
129
|
query_params = {}
|
|
138
130
|
response = self._post(
|
|
@@ -144,9 +136,7 @@ class DmConversationsApi(APISegmentBase):
|
|
|
144
136
|
response.raise_for_status()
|
|
145
137
|
return response.json()
|
|
146
138
|
|
|
147
|
-
def add_message_to_dm_conversation(
|
|
148
|
-
self, dm_conversation_id, attachments=None, text=None
|
|
149
|
-
) -> dict[str, Any]:
|
|
139
|
+
def add_message_to_dm_conversation(self, dm_conversation_id, attachments=None, text=None) -> dict[str, Any]:
|
|
150
140
|
"""
|
|
151
141
|
Sends a new message with optional text and attachments to an existing Direct Message conversation. The target conversation is specified by its `dm_conversation_id`, distinguishing it from functions that create new conversations or send one-to-one messages using a participant ID.
|
|
152
142
|
|
|
@@ -169,9 +159,7 @@ class DmConversationsApi(APISegmentBase):
|
|
|
169
159
|
raise ValueError("Missing required parameter 'dm_conversation_id'.")
|
|
170
160
|
request_body_data = None
|
|
171
161
|
request_body_data = {"attachments": attachments, "text": text}
|
|
172
|
-
request_body_data = {
|
|
173
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
174
|
-
}
|
|
162
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
175
163
|
url = f"{self.main_app_client.base_url}/2/dm_conversations/{dm_conversation_id}/messages"
|
|
176
164
|
query_params = {}
|
|
177
165
|
response = self._post(
|
|
@@ -7,9 +7,7 @@ class LikesApi(APISegmentBase):
|
|
|
7
7
|
def __init__(self, main_app_client: Any):
|
|
8
8
|
super().__init__(main_app_client)
|
|
9
9
|
|
|
10
|
-
def get_likes_compliance_stream(
|
|
11
|
-
self, backfill_minutes=None, start_time=None, end_time=None
|
|
12
|
-
) -> Any:
|
|
10
|
+
def get_likes_compliance_stream(self, backfill_minutes=None, start_time=None, end_time=None) -> Any:
|
|
13
11
|
"""
|
|
14
12
|
Streams compliance-related data for 'like' events, such as un-likes, with optional time and backfill filters. This endpoint is for compliance monitoring, differing from the firehose and sample streams which provide real-time like creation events.
|
|
15
13
|
|
|
@@ -32,9 +32,7 @@ class ListsApi(APISegmentBase):
|
|
|
32
32
|
"name": name,
|
|
33
33
|
"private": private,
|
|
34
34
|
}
|
|
35
|
-
request_body_data = {
|
|
36
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
37
|
-
}
|
|
35
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
38
36
|
url = f"{self.main_app_client.base_url}/2/lists"
|
|
39
37
|
query_params = {}
|
|
40
38
|
response = self._post(
|
|
@@ -71,9 +69,7 @@ class ListsApi(APISegmentBase):
|
|
|
71
69
|
response.raise_for_status()
|
|
72
70
|
return response.json()
|
|
73
71
|
|
|
74
|
-
def get_list_by_id(
|
|
75
|
-
self, id, list_fields=None, expansions=None, user_fields=None
|
|
76
|
-
) -> dict[str, Any]:
|
|
72
|
+
def get_list_by_id(self, id, list_fields=None, expansions=None, user_fields=None) -> dict[str, Any]:
|
|
77
73
|
"""
|
|
78
74
|
Retrieves detailed information for a specific list by its ID. This function allows for response customization by specifying which list and user fields to return and supports expansions to include related objects like the owner's user data.
|
|
79
75
|
|
|
@@ -109,9 +105,7 @@ class ListsApi(APISegmentBase):
|
|
|
109
105
|
response.raise_for_status()
|
|
110
106
|
return response.json()
|
|
111
107
|
|
|
112
|
-
def update_list(
|
|
113
|
-
self, id, description=None, name=None, private=None
|
|
114
|
-
) -> dict[str, Any]:
|
|
108
|
+
def update_list(self, id, description=None, name=None, private=None) -> dict[str, Any]:
|
|
115
109
|
"""
|
|
116
110
|
Modifies an existing Twitter list identified by its unique ID. This function updates the list's name, description, or privacy status by sending a PUT request to the API and returns the updated list data upon success.
|
|
117
111
|
|
|
@@ -139,9 +133,7 @@ class ListsApi(APISegmentBase):
|
|
|
139
133
|
"name": name,
|
|
140
134
|
"private": private,
|
|
141
135
|
}
|
|
142
|
-
request_body_data = {
|
|
143
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
144
|
-
}
|
|
136
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
145
137
|
url = f"{self.main_app_client.base_url}/2/lists/{id}"
|
|
146
138
|
query_params = {}
|
|
147
139
|
response = self._put(
|
|
@@ -271,9 +263,7 @@ class ListsApi(APISegmentBase):
|
|
|
271
263
|
raise ValueError("Missing required parameter 'id'.")
|
|
272
264
|
request_body_data = None
|
|
273
265
|
request_body_data = {"user_id": user_id}
|
|
274
|
-
request_body_data = {
|
|
275
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
276
|
-
}
|
|
266
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
277
267
|
url = f"{self.main_app_client.base_url}/2/lists/{id}/members"
|
|
278
268
|
query_params = {}
|
|
279
269
|
response = self._post(
|
|
@@ -28,9 +28,7 @@ class TrendsApi(APISegmentBase):
|
|
|
28
28
|
if woeid is None:
|
|
29
29
|
raise ValueError("Missing required parameter 'woeid'.")
|
|
30
30
|
url = f"{self.main_app_client.base_url}/2/trends/by/woeid/{woeid}"
|
|
31
|
-
query_params = {
|
|
32
|
-
k: v for k, v in [("trend.fields", trend_fields)] if v is not None
|
|
33
|
-
}
|
|
31
|
+
query_params = {k: v for k, v in [("trend.fields", trend_fields)] if v is not None}
|
|
34
32
|
response = self._get(url, params=query_params)
|
|
35
33
|
response.raise_for_status()
|
|
36
34
|
return response.json()
|
|
@@ -111,9 +111,7 @@ class TweetsApi(APISegmentBase):
|
|
|
111
111
|
"reply_settings": reply_settings,
|
|
112
112
|
"text": text,
|
|
113
113
|
}
|
|
114
|
-
request_body_data = {
|
|
115
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
116
|
-
}
|
|
114
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
117
115
|
url = f"{self.main_app_client.base_url}/2/tweets"
|
|
118
116
|
query_params = {}
|
|
119
117
|
response = self._post(
|
|
@@ -125,9 +123,7 @@ class TweetsApi(APISegmentBase):
|
|
|
125
123
|
response.raise_for_status()
|
|
126
124
|
return response.json()
|
|
127
125
|
|
|
128
|
-
def get_tweets_compliance_stream(
|
|
129
|
-
self, partition, backfill_minutes=None, start_time=None, end_time=None
|
|
130
|
-
) -> Any:
|
|
126
|
+
def get_tweets_compliance_stream(self, partition, backfill_minutes=None, start_time=None, end_time=None) -> Any:
|
|
131
127
|
"""
|
|
132
128
|
Streams real-time compliance events for tweets, such as deletions and user updates, from a specified partition. Unlike other stream functions that return tweet content, this provides metadata about content and user status changes, supporting optional time-based filtering and backfilling.
|
|
133
129
|
|
|
@@ -569,9 +565,7 @@ class TweetsApi(APISegmentBase):
|
|
|
569
565
|
response.raise_for_status()
|
|
570
566
|
return response.json()
|
|
571
567
|
|
|
572
|
-
def stream_labeled_tweets(
|
|
573
|
-
self, backfill_minutes=None, start_time=None, end_time=None
|
|
574
|
-
) -> Any:
|
|
568
|
+
def stream_labeled_tweets(self, backfill_minutes=None, start_time=None, end_time=None) -> Any:
|
|
575
569
|
"""
|
|
576
570
|
Streams real-time Tweet objects labeled for compliance reasons, such as withheld content. Unlike `get_tweets_compliance_stream`, which provides events, this returns the actual tweets. Supports filtering by a time window and backfilling missed data upon reconnection.
|
|
577
571
|
|
|
@@ -917,9 +911,7 @@ class TweetsApi(APISegmentBase):
|
|
|
917
911
|
response.raise_for_status()
|
|
918
912
|
return response.json()
|
|
919
913
|
|
|
920
|
-
def get_filtered_stream_rules(
|
|
921
|
-
self, ids=None, max_results=None, pagination_token=None
|
|
922
|
-
) -> dict[str, Any]:
|
|
914
|
+
def get_filtered_stream_rules(self, ids=None, max_results=None, pagination_token=None) -> dict[str, Any]:
|
|
923
915
|
"""
|
|
924
916
|
Retrieves the active filtering rules for a Twitter API v2 filtered stream. It can fetch all rules or a subset specified by rule IDs, with support for pagination to manage large rule sets, complementing the `add_or_delete_rules` and `search_stream` functions.
|
|
925
917
|
|
|
@@ -952,9 +944,7 @@ class TweetsApi(APISegmentBase):
|
|
|
952
944
|
response.raise_for_status()
|
|
953
945
|
return response.json()
|
|
954
946
|
|
|
955
|
-
def update_stream_rules(
|
|
956
|
-
self, dry_run=None, delete_all=None, add=None, delete=None
|
|
957
|
-
) -> dict[str, Any]:
|
|
947
|
+
def update_stream_rules(self, dry_run=None, delete_all=None, add=None, delete=None) -> dict[str, Any]:
|
|
958
948
|
"""
|
|
959
949
|
Adds or removes filtering rules for a tweet stream. Supports a dry-run mode to validate rule syntax without application and an option to delete all existing rules. This function directly modifies the active rule set used by the `search_stream` function.
|
|
960
950
|
|
|
@@ -976,15 +966,9 @@ class TweetsApi(APISegmentBase):
|
|
|
976
966
|
"""
|
|
977
967
|
request_body_data = None
|
|
978
968
|
request_body_data = {"add": add, "delete": delete}
|
|
979
|
-
request_body_data = {
|
|
980
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
981
|
-
}
|
|
969
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
982
970
|
url = f"{self.main_app_client.base_url}/2/tweets/search/stream/rules"
|
|
983
|
-
query_params = {
|
|
984
|
-
k: v
|
|
985
|
-
for k, v in [("dry_run", dry_run), ("delete_all", delete_all)]
|
|
986
|
-
if v is not None
|
|
987
|
-
}
|
|
971
|
+
query_params = {k: v for k, v in [("dry_run", dry_run), ("delete_all", delete_all)] if v is not None}
|
|
988
972
|
response = self._post(
|
|
989
973
|
url,
|
|
990
974
|
data=request_body_data,
|
|
@@ -1012,11 +996,7 @@ class TweetsApi(APISegmentBase):
|
|
|
1012
996
|
General
|
|
1013
997
|
"""
|
|
1014
998
|
url = f"{self.main_app_client.base_url}/2/tweets/search/stream/rules/counts"
|
|
1015
|
-
query_params = {
|
|
1016
|
-
k: v
|
|
1017
|
-
for k, v in [("rules_count.fields", rules_count_fields)]
|
|
1018
|
-
if v is not None
|
|
1019
|
-
}
|
|
999
|
+
query_params = {k: v for k, v in [("rules_count.fields", rules_count_fields)] if v is not None}
|
|
1020
1000
|
response = self._get(url, params=query_params)
|
|
1021
1001
|
response.raise_for_status()
|
|
1022
1002
|
return response.json()
|
|
@@ -1332,9 +1312,7 @@ class TweetsApi(APISegmentBase):
|
|
|
1332
1312
|
raise ValueError("Missing required parameter 'tweet_id'.")
|
|
1333
1313
|
request_body_data = None
|
|
1334
1314
|
request_body_data = {"hidden": hidden}
|
|
1335
|
-
request_body_data = {
|
|
1336
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
1337
|
-
}
|
|
1315
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
1338
1316
|
url = f"{self.main_app_client.base_url}/2/tweets/{tweet_id}/hidden"
|
|
1339
1317
|
query_params = {}
|
|
1340
1318
|
response = self._put(
|
|
@@ -26,11 +26,7 @@ class UsageApi(APISegmentBase):
|
|
|
26
26
|
Usage
|
|
27
27
|
"""
|
|
28
28
|
url = f"{self.main_app_client.base_url}/2/usage/tweets"
|
|
29
|
-
query_params = {
|
|
30
|
-
k: v
|
|
31
|
-
for k, v in [("days", days), ("usage.fields", usage_fields)]
|
|
32
|
-
if v is not None
|
|
33
|
-
}
|
|
29
|
+
query_params = {k: v for k, v in [("days", days), ("usage.fields", usage_fields)] if v is not None}
|
|
34
30
|
response = self._get(url, params=query_params)
|
|
35
31
|
response.raise_for_status()
|
|
36
32
|
return response.json()
|
|
@@ -7,9 +7,7 @@ class UsersApi(APISegmentBase):
|
|
|
7
7
|
def __init__(self, main_app_client: Any):
|
|
8
8
|
super().__init__(main_app_client)
|
|
9
9
|
|
|
10
|
-
def get_users_by_ids(
|
|
11
|
-
self, ids, user_fields=None, expansions=None, tweet_fields=None
|
|
12
|
-
) -> dict[str, Any]:
|
|
10
|
+
def get_users_by_ids(self, ids, user_fields=None, expansions=None, tweet_fields=None) -> dict[str, Any]:
|
|
13
11
|
"""
|
|
14
12
|
Retrieves detailed information for multiple users in a single API request, specified by a list of their unique IDs. Unlike `find_user_by_id`, which fetches a single user, this function performs a bulk lookup and allows for response customization with optional fields and expansions.
|
|
15
13
|
|
|
@@ -44,9 +42,7 @@ class UsersApi(APISegmentBase):
|
|
|
44
42
|
response.raise_for_status()
|
|
45
43
|
return response.json()
|
|
46
44
|
|
|
47
|
-
def get_users_by_usernames(
|
|
48
|
-
self, usernames, user_fields=None, expansions=None, tweet_fields=None
|
|
49
|
-
) -> dict[str, Any]:
|
|
45
|
+
def get_users_by_usernames(self, usernames, user_fields=None, expansions=None, tweet_fields=None) -> dict[str, Any]:
|
|
50
46
|
"""
|
|
51
47
|
Fetches public data for a batch of users specified by their usernames. This function supports retrieving multiple users in a single request, unlike `find_user_by_username`. It allows for data customization through optional fields and expansions.
|
|
52
48
|
|
|
@@ -81,9 +77,7 @@ class UsersApi(APISegmentBase):
|
|
|
81
77
|
response.raise_for_status()
|
|
82
78
|
return response.json()
|
|
83
79
|
|
|
84
|
-
def find_user_by_username(
|
|
85
|
-
self, username, user_fields=None, expansions=None, tweet_fields=None
|
|
86
|
-
) -> dict[str, Any]:
|
|
80
|
+
def find_user_by_username(self, username, user_fields=None, expansions=None, tweet_fields=None) -> dict[str, Any]:
|
|
87
81
|
"""
|
|
88
82
|
Retrieves detailed information for a single user specified by their username, with options to include additional user, tweet, and expansion fields. This differs from `find_users_by_username`, which fetches data for multiple users in a single request.
|
|
89
83
|
|
|
@@ -119,9 +113,7 @@ class UsersApi(APISegmentBase):
|
|
|
119
113
|
response.raise_for_status()
|
|
120
114
|
return response.json()
|
|
121
115
|
|
|
122
|
-
def get_users_compliance_stream(
|
|
123
|
-
self, partition, backfill_minutes=None, start_time=None, end_time=None
|
|
124
|
-
) -> Any:
|
|
116
|
+
def get_users_compliance_stream(self, partition, backfill_minutes=None, start_time=None, end_time=None) -> Any:
|
|
125
117
|
"""
|
|
126
118
|
Streams real-time user compliance events, such as account deletions or suspensions, from a specified data partition. Allows for backfilling missed data after a disconnection and filtering the event stream by a specific time range for targeted data retrieval.
|
|
127
119
|
|
|
@@ -156,9 +148,7 @@ class UsersApi(APISegmentBase):
|
|
|
156
148
|
response.raise_for_status()
|
|
157
149
|
return response.json()
|
|
158
150
|
|
|
159
|
-
def get_authenticated_user(
|
|
160
|
-
self, user_fields=None, expansions=None, tweet_fields=None
|
|
161
|
-
) -> dict[str, Any]:
|
|
151
|
+
def get_authenticated_user(self, user_fields=None, expansions=None, tweet_fields=None) -> dict[str, Any]:
|
|
162
152
|
"""
|
|
163
153
|
Retrieves detailed information about the authenticated user making the request. Optional parameters allow for customizing the returned user and tweet data fields and including expanded objects. This differs from other 'find' functions as it requires no ID or username.
|
|
164
154
|
|
|
@@ -238,9 +228,7 @@ class UsersApi(APISegmentBase):
|
|
|
238
228
|
response.raise_for_status()
|
|
239
229
|
return response.json()
|
|
240
230
|
|
|
241
|
-
def find_user_by_id(
|
|
242
|
-
self, id, user_fields=None, expansions=None, tweet_fields=None
|
|
243
|
-
) -> dict[str, Any]:
|
|
231
|
+
def find_user_by_id(self, id, user_fields=None, expansions=None, tweet_fields=None) -> dict[str, Any]:
|
|
244
232
|
"""
|
|
245
233
|
Retrieves detailed information for a single user specified by their unique ID. This function allows for response customization using optional fields and expansions. It differs from `find_users_by_id`, which fetches data for multiple users in a single request.
|
|
246
234
|
|
|
@@ -403,9 +391,7 @@ class UsersApi(APISegmentBase):
|
|
|
403
391
|
raise ValueError("Missing required parameter 'id'.")
|
|
404
392
|
request_body_data = None
|
|
405
393
|
request_body_data = {"tweet_id": tweet_id}
|
|
406
|
-
request_body_data = {
|
|
407
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
408
|
-
}
|
|
394
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
409
395
|
url = f"{self.main_app_client.base_url}/2/users/{id}/bookmarks"
|
|
410
396
|
query_params = {}
|
|
411
397
|
response = self._post(
|
|
@@ -515,9 +501,7 @@ class UsersApi(APISegmentBase):
|
|
|
515
501
|
raise ValueError("Missing required parameter 'id'.")
|
|
516
502
|
request_body_data = None
|
|
517
503
|
request_body_data = {"list_id": list_id}
|
|
518
|
-
request_body_data = {
|
|
519
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
520
|
-
}
|
|
504
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
521
505
|
url = f"{self.main_app_client.base_url}/2/users/{id}/followed_lists"
|
|
522
506
|
query_params = {}
|
|
523
507
|
response = self._post(
|
|
@@ -675,9 +659,7 @@ class UsersApi(APISegmentBase):
|
|
|
675
659
|
raise ValueError("Missing required parameter 'id'.")
|
|
676
660
|
request_body_data = None
|
|
677
661
|
request_body_data = {"target_user_id": target_user_id}
|
|
678
|
-
request_body_data = {
|
|
679
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
680
|
-
}
|
|
662
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
681
663
|
url = f"{self.main_app_client.base_url}/2/users/{id}/following"
|
|
682
664
|
query_params = {}
|
|
683
665
|
response = self._post(
|
|
@@ -768,9 +750,7 @@ class UsersApi(APISegmentBase):
|
|
|
768
750
|
raise ValueError("Missing required parameter 'id'.")
|
|
769
751
|
request_body_data = None
|
|
770
752
|
request_body_data = {"tweet_id": tweet_id}
|
|
771
|
-
request_body_data = {
|
|
772
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
773
|
-
}
|
|
753
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
774
754
|
url = f"{self.main_app_client.base_url}/2/users/{id}/likes"
|
|
775
755
|
query_params = {}
|
|
776
756
|
response = self._post(
|
|
@@ -997,9 +977,7 @@ class UsersApi(APISegmentBase):
|
|
|
997
977
|
raise ValueError("Missing required parameter 'id'.")
|
|
998
978
|
request_body_data = None
|
|
999
979
|
request_body_data = {"target_user_id": target_user_id}
|
|
1000
|
-
request_body_data = {
|
|
1001
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
1002
|
-
}
|
|
980
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
1003
981
|
url = f"{self.main_app_client.base_url}/2/users/{id}/muting"
|
|
1004
982
|
query_params = {}
|
|
1005
983
|
response = self._post(
|
|
@@ -1059,9 +1037,7 @@ class UsersApi(APISegmentBase):
|
|
|
1059
1037
|
response.raise_for_status()
|
|
1060
1038
|
return response.json()
|
|
1061
1039
|
|
|
1062
|
-
def get_user_pinned_lists(
|
|
1063
|
-
self, id, list_fields=None, expansions=None, user_fields=None
|
|
1064
|
-
) -> dict[str, Any]:
|
|
1040
|
+
def get_user_pinned_lists(self, id, list_fields=None, expansions=None, user_fields=None) -> dict[str, Any]:
|
|
1065
1041
|
"""
|
|
1066
1042
|
Retrieves the collection of lists pinned by a specific user, identified by their ID. Optional parameters allow for customizing the returned list and user data fields, and including expansions. This is distinct from fetching lists a user follows or owns.
|
|
1067
1043
|
|
|
@@ -1119,9 +1095,7 @@ class UsersApi(APISegmentBase):
|
|
|
1119
1095
|
raise ValueError("Missing required parameter 'id'.")
|
|
1120
1096
|
request_body_data = None
|
|
1121
1097
|
request_body_data = {"list_id": list_id}
|
|
1122
|
-
request_body_data = {
|
|
1123
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
1124
|
-
}
|
|
1098
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
1125
1099
|
url = f"{self.main_app_client.base_url}/2/users/{id}/pinned_lists"
|
|
1126
1100
|
query_params = {}
|
|
1127
1101
|
response = self._post(
|
|
@@ -1183,9 +1157,7 @@ class UsersApi(APISegmentBase):
|
|
|
1183
1157
|
raise ValueError("Missing required parameter 'id'.")
|
|
1184
1158
|
request_body_data = None
|
|
1185
1159
|
request_body_data = {"tweet_id": tweet_id}
|
|
1186
|
-
request_body_data = {
|
|
1187
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
1188
|
-
}
|
|
1160
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
1189
1161
|
url = f"{self.main_app_client.base_url}/2/users/{id}/retweets"
|
|
1190
1162
|
query_params = {}
|
|
1191
1163
|
response = self._post(
|