universal-mcp-applications 0.1.22__py3-none-any.whl → 0.1.39rc8__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 +92 -238
- universal_mcp/applications/airtable/app.py +23 -122
- universal_mcp/applications/apollo/app.py +122 -475
- universal_mcp/applications/asana/app.py +605 -1755
- universal_mcp/applications/aws_s3/app.py +36 -103
- universal_mcp/applications/bill/app.py +644 -2055
- universal_mcp/applications/box/app.py +1246 -4159
- universal_mcp/applications/braze/app.py +410 -1476
- universal_mcp/applications/browser_use/README.md +15 -1
- universal_mcp/applications/browser_use/__init__.py +1 -0
- universal_mcp/applications/browser_use/app.py +94 -37
- universal_mcp/applications/cal_com_v2/app.py +207 -625
- universal_mcp/applications/calendly/app.py +103 -242
- universal_mcp/applications/canva/app.py +75 -140
- universal_mcp/applications/clickup/app.py +331 -798
- universal_mcp/applications/coda/app.py +240 -520
- universal_mcp/applications/confluence/app.py +497 -1285
- universal_mcp/applications/contentful/app.py +36 -151
- universal_mcp/applications/crustdata/app.py +42 -121
- universal_mcp/applications/dialpad/app.py +451 -924
- universal_mcp/applications/digitalocean/app.py +2071 -6082
- 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/README.md +8 -4
- universal_mcp/applications/exa/app.py +408 -186
- universal_mcp/applications/falai/app.py +24 -101
- universal_mcp/applications/figma/app.py +91 -175
- universal_mcp/applications/file_system/app.py +2 -13
- universal_mcp/applications/firecrawl/app.py +186 -163
- universal_mcp/applications/fireflies/app.py +59 -281
- universal_mcp/applications/fpl/app.py +92 -529
- 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 +66 -175
- universal_mcp/applications/github/app.py +28 -65
- universal_mcp/applications/gong/app.py +140 -300
- universal_mcp/applications/google_calendar/app.py +26 -78
- universal_mcp/applications/google_docs/app.py +324 -354
- universal_mcp/applications/google_drive/app.py +194 -793
- universal_mcp/applications/google_gemini/app.py +29 -64
- universal_mcp/applications/google_mail/README.md +1 -0
- universal_mcp/applications/google_mail/app.py +93 -214
- universal_mcp/applications/google_searchconsole/app.py +25 -58
- universal_mcp/applications/google_sheet/app.py +174 -623
- universal_mcp/applications/google_sheet/helper.py +26 -53
- universal_mcp/applications/hashnode/app.py +57 -269
- universal_mcp/applications/heygen/app.py +77 -155
- universal_mcp/applications/http_tools/app.py +10 -32
- universal_mcp/applications/hubspot/README.md +1 -1
- universal_mcp/applications/hubspot/app.py +7508 -99
- universal_mcp/applications/jira/app.py +2419 -8334
- universal_mcp/applications/klaviyo/app.py +737 -1619
- universal_mcp/applications/linkedin/README.md +23 -4
- universal_mcp/applications/linkedin/app.py +861 -155
- universal_mcp/applications/mailchimp/app.py +696 -1851
- universal_mcp/applications/markitdown/app.py +8 -20
- universal_mcp/applications/miro/app.py +333 -815
- universal_mcp/applications/ms_teams/app.py +85 -207
- universal_mcp/applications/neon/app.py +144 -250
- universal_mcp/applications/notion/app.py +36 -51
- universal_mcp/applications/onedrive/README.md +24 -0
- universal_mcp/applications/onedrive/__init__.py +1 -0
- universal_mcp/applications/onedrive/app.py +316 -0
- universal_mcp/applications/openai/app.py +42 -165
- universal_mcp/applications/outlook/README.md +22 -9
- universal_mcp/applications/outlook/app.py +606 -262
- universal_mcp/applications/perplexity/README.md +2 -1
- universal_mcp/applications/perplexity/app.py +162 -20
- universal_mcp/applications/pipedrive/app.py +1021 -3331
- universal_mcp/applications/posthog/app.py +272 -541
- universal_mcp/applications/reddit/app.py +88 -204
- universal_mcp/applications/resend/app.py +41 -107
- universal_mcp/applications/retell/app.py +23 -50
- universal_mcp/applications/rocketlane/app.py +250 -963
- universal_mcp/applications/scraper/README.md +7 -4
- universal_mcp/applications/scraper/app.py +245 -283
- universal_mcp/applications/semanticscholar/app.py +36 -78
- universal_mcp/applications/semrush/app.py +43 -77
- universal_mcp/applications/sendgrid/app.py +826 -1576
- universal_mcp/applications/sentry/app.py +444 -1079
- universal_mcp/applications/serpapi/app.py +40 -143
- universal_mcp/applications/sharepoint/README.md +16 -14
- universal_mcp/applications/sharepoint/app.py +245 -154
- universal_mcp/applications/shopify/app.py +1743 -4479
- universal_mcp/applications/shortcut/app.py +272 -534
- universal_mcp/applications/slack/app.py +58 -109
- universal_mcp/applications/spotify/app.py +206 -405
- universal_mcp/applications/supabase/app.py +174 -283
- universal_mcp/applications/tavily/app.py +2 -2
- universal_mcp/applications/trello/app.py +853 -2816
- 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 +86 -299
- universal_mcp/applications/wrike/app.py +80 -153
- universal_mcp/applications/yahoo_finance/app.py +19 -65
- universal_mcp/applications/youtube/app.py +120 -306
- universal_mcp/applications/zenquotes/app.py +4 -4
- {universal_mcp_applications-0.1.22.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/METADATA +4 -2
- {universal_mcp_applications-0.1.22.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/RECORD +113 -117
- {universal_mcp_applications-0.1.22.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/WHEEL +1 -1
- universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
- universal_mcp/applications/hubspot/api_segments/api_segment_base.py +0 -54
- universal_mcp/applications/hubspot/api_segments/crm_api.py +0 -7337
- universal_mcp/applications/hubspot/api_segments/marketing_api.py +0 -1467
- universal_mcp/applications/unipile/README.md +0 -28
- universal_mcp/applications/unipile/__init__.py +0 -1
- universal_mcp/applications/unipile/app.py +0 -1077
- {universal_mcp_applications-0.1.22.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/licenses/LICENSE +0 -0
|
@@ -8,7 +8,7 @@ class HashnodeApp(GraphQLApplication):
|
|
|
8
8
|
super().__init__(name="hashnode", base_url="https://gql.hashnode.com", **kwargs)
|
|
9
9
|
self.integration = integration
|
|
10
10
|
|
|
11
|
-
def publish_post(
|
|
11
|
+
async def publish_post(
|
|
12
12
|
self,
|
|
13
13
|
publication_id: str,
|
|
14
14
|
title: str,
|
|
@@ -38,42 +38,22 @@ class HashnodeApp(GraphQLApplication):
|
|
|
38
38
|
Tags:
|
|
39
39
|
publish, post, hashnode, api, important
|
|
40
40
|
"""
|
|
41
|
-
publish_post_mutation = gql(
|
|
42
|
-
mutation PublishPost($input: PublishPostInput!) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
url
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
""")
|
|
50
|
-
|
|
51
|
-
variables = {
|
|
52
|
-
"input": {
|
|
53
|
-
"publicationId": publication_id,
|
|
54
|
-
"title": title,
|
|
55
|
-
"contentMarkdown": content,
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
41
|
+
publish_post_mutation = gql(
|
|
42
|
+
"\n mutation PublishPost($input: PublishPostInput!) {\n publishPost(input: $input) {\n post {\n url\n }\n }\n }\n "
|
|
43
|
+
)
|
|
44
|
+
variables = {"input": {"publicationId": publication_id, "title": title, "contentMarkdown": content}}
|
|
59
45
|
if tags:
|
|
60
|
-
variables["input"]["tags"] = [
|
|
61
|
-
{"name": tag, "slug": tag.replace(" ", "-").lower()} for tag in tags
|
|
62
|
-
]
|
|
63
|
-
|
|
46
|
+
variables["input"]["tags"] = [{"name": tag, "slug": tag.replace(" ", "-").lower()} for tag in tags]
|
|
64
47
|
if slug:
|
|
65
48
|
variables["input"]["slug"] = slug
|
|
66
|
-
|
|
67
49
|
if subtitle:
|
|
68
50
|
variables["input"]["subtitle"] = subtitle
|
|
69
|
-
|
|
70
51
|
if cover_image:
|
|
71
52
|
variables["input"]["coverImageOptions"] = {"coverImageURL": cover_image}
|
|
72
|
-
|
|
73
53
|
result = self.mutate(publish_post_mutation, variables)
|
|
74
54
|
return result["publishPost"]["post"]["url"]
|
|
75
55
|
|
|
76
|
-
def create_draft(
|
|
56
|
+
async def create_draft(
|
|
77
57
|
self,
|
|
78
58
|
publication_id: str,
|
|
79
59
|
title: str,
|
|
@@ -104,39 +84,22 @@ class HashnodeApp(GraphQLApplication):
|
|
|
104
84
|
Tags:
|
|
105
85
|
create, draft, post, hashnode, api, important
|
|
106
86
|
"""
|
|
107
|
-
create_draft_mutation = gql(
|
|
108
|
-
mutation CreateDraft($input: CreateDraftInput!) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
id
|
|
112
|
-
slug
|
|
113
|
-
title
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
""")
|
|
118
|
-
variables = {
|
|
119
|
-
"input": {
|
|
120
|
-
"publicationId": publication_id,
|
|
121
|
-
"title": title,
|
|
122
|
-
"contentMarkdown": content,
|
|
123
|
-
}
|
|
124
|
-
}
|
|
87
|
+
create_draft_mutation = gql(
|
|
88
|
+
"\n mutation CreateDraft($input: CreateDraftInput!) {\n createDraft(input: $input) {\n draft {\n id\n slug\n title\n }\n }\n }\n "
|
|
89
|
+
)
|
|
90
|
+
variables = {"input": {"publicationId": publication_id, "title": title, "contentMarkdown": content}}
|
|
125
91
|
if tags:
|
|
126
|
-
variables["input"]["tags"] = [
|
|
127
|
-
{"name": tag, "slug": tag.replace(" ", "-").lower()} for tag in tags
|
|
128
|
-
]
|
|
92
|
+
variables["input"]["tags"] = [{"name": tag, "slug": tag.replace(" ", "-").lower()} for tag in tags]
|
|
129
93
|
if slug:
|
|
130
94
|
variables["input"]["slug"] = slug
|
|
131
95
|
if subtitle:
|
|
132
96
|
variables["input"]["subtitle"] = subtitle
|
|
133
97
|
if cover_image:
|
|
134
98
|
variables["input"]["coverImageOptions"] = {"coverImageURL": cover_image}
|
|
135
|
-
|
|
136
99
|
result = self.mutate(create_draft_mutation, variables)
|
|
137
100
|
return result["createDraft"]["draft"]
|
|
138
101
|
|
|
139
|
-
def publish_draft(self, post_id: str) -> str:
|
|
102
|
+
async def publish_draft(self, post_id: str) -> str:
|
|
140
103
|
"""
|
|
141
104
|
Publishes a draft post.
|
|
142
105
|
|
|
@@ -152,20 +115,14 @@ class HashnodeApp(GraphQLApplication):
|
|
|
152
115
|
Tags:
|
|
153
116
|
publish, draft, post, hashnode, api, important
|
|
154
117
|
"""
|
|
155
|
-
publish_draft_mutation = gql(
|
|
156
|
-
mutation PublishDraft($input: PublishDraftInput!) {
|
|
157
|
-
|
|
158
|
-
post {
|
|
159
|
-
url
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
""")
|
|
118
|
+
publish_draft_mutation = gql(
|
|
119
|
+
"\n mutation PublishDraft($input: PublishDraftInput!) {\n publishDraft(input: $input) {\n post {\n url\n }\n }\n }\n "
|
|
120
|
+
)
|
|
164
121
|
variables = {"input": {"draftId": post_id}}
|
|
165
122
|
result = self.mutate(publish_draft_mutation, variables)
|
|
166
123
|
return result["publishDraft"]["post"]["url"]
|
|
167
124
|
|
|
168
|
-
def get_me(self) -> dict:
|
|
125
|
+
async def get_me(self) -> dict:
|
|
169
126
|
"""
|
|
170
127
|
Fetches details about the authenticated user.
|
|
171
128
|
|
|
@@ -178,58 +135,16 @@ class HashnodeApp(GraphQLApplication):
|
|
|
178
135
|
Tags:
|
|
179
136
|
get, me, hashnode, api, query, important
|
|
180
137
|
"""
|
|
181
|
-
get_me_query = gql(
|
|
182
|
-
query Me {
|
|
183
|
-
|
|
184
|
-
id
|
|
185
|
-
username
|
|
186
|
-
name
|
|
187
|
-
bio {
|
|
188
|
-
markdown
|
|
189
|
-
html
|
|
190
|
-
text
|
|
191
|
-
}
|
|
192
|
-
profilePicture
|
|
193
|
-
socialMediaLinks {
|
|
194
|
-
website
|
|
195
|
-
github
|
|
196
|
-
twitter
|
|
197
|
-
instagram
|
|
198
|
-
facebook
|
|
199
|
-
stackoverflow
|
|
200
|
-
linkedin
|
|
201
|
-
youtube
|
|
202
|
-
bluesky
|
|
203
|
-
}
|
|
204
|
-
emailNotificationPreferences {
|
|
205
|
-
weeklyNewsletterEmails
|
|
206
|
-
activityNotifications
|
|
207
|
-
generalAnnouncements
|
|
208
|
-
monthlyBlogStats
|
|
209
|
-
newFollowersWeekly
|
|
210
|
-
}
|
|
211
|
-
followersCount
|
|
212
|
-
followingsCount
|
|
213
|
-
tagline
|
|
214
|
-
dateJoined
|
|
215
|
-
location
|
|
216
|
-
availableFor
|
|
217
|
-
email
|
|
218
|
-
unverifiedEmail
|
|
219
|
-
role
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
""")
|
|
223
|
-
|
|
138
|
+
get_me_query = gql(
|
|
139
|
+
"\n query Me {\n me {\n id\n username\n name\n bio {\n markdown\n html\n text\n }\n profilePicture\n socialMediaLinks {\n website\n github\n twitter\n instagram\n facebook\n stackoverflow\n linkedin\n youtube\n bluesky\n }\n emailNotificationPreferences {\n weeklyNewsletterEmails\n activityNotifications\n generalAnnouncements\n monthlyBlogStats\n newFollowersWeekly\n }\n followersCount\n followingsCount\n tagline\n dateJoined\n location\n availableFor\n email\n unverifiedEmail\n role\n }\n }\n "
|
|
140
|
+
)
|
|
224
141
|
result = self.query(get_me_query)
|
|
225
|
-
|
|
226
|
-
# It's good practice to check if 'me' exists in the result
|
|
227
142
|
if "me" in result:
|
|
228
143
|
return result.get("me")
|
|
229
144
|
else:
|
|
230
145
|
raise Exception("Failed to retrieve 'me' data from Hashnode API response.")
|
|
231
146
|
|
|
232
|
-
def get_publication(self, host: str = None, publication_id: str = None) -> dict:
|
|
147
|
+
async def get_publication(self, host: str = None, publication_id: str = None) -> dict:
|
|
233
148
|
"""
|
|
234
149
|
Fetches details about a publication by host or ID. Only one of host or publication_id should be provided.
|
|
235
150
|
|
|
@@ -247,40 +162,18 @@ class HashnodeApp(GraphQLApplication):
|
|
|
247
162
|
Tags:
|
|
248
163
|
get, publication, hashnode, api, query, important
|
|
249
164
|
"""
|
|
250
|
-
if not host and not publication_id:
|
|
165
|
+
if not host and (not publication_id):
|
|
251
166
|
raise ValueError("Either host or publication_id must be provided.")
|
|
252
|
-
|
|
253
|
-
query_string = """
|
|
254
|
-
query Publication($host: String, $id: ObjectId) {
|
|
255
|
-
publication(host: $host, id: $id) {
|
|
256
|
-
id
|
|
257
|
-
title
|
|
258
|
-
url
|
|
259
|
-
isTeam
|
|
260
|
-
posts(first: 5) {
|
|
261
|
-
edges {
|
|
262
|
-
node {
|
|
263
|
-
id
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
"""
|
|
167
|
+
query_string = "\n query Publication($host: String, $id: ObjectId) {\n publication(host: $host, id: $id) {\n id\n title\n url\n isTeam\n posts(first: 5) {\n edges {\n node {\n id\n }\n }\n }\n }\n }\n "
|
|
270
168
|
get_publication_query = gql(query_string)
|
|
271
|
-
|
|
272
|
-
# Construct variables such that only one of host or id is included
|
|
273
169
|
if host:
|
|
274
170
|
variables = {"host": host}
|
|
275
171
|
else:
|
|
276
172
|
variables = {"id": publication_id}
|
|
277
|
-
|
|
278
173
|
result = self.query(get_publication_query, variables)
|
|
279
174
|
return result.get("publication")
|
|
280
175
|
|
|
281
|
-
def list_posts(
|
|
282
|
-
self, publication_id: str, first: int = 10, after: str = None
|
|
283
|
-
) -> dict:
|
|
176
|
+
async def list_posts(self, publication_id: str, first: int = 10, after: str = None) -> dict:
|
|
284
177
|
"""
|
|
285
178
|
Lists posts from a publication.
|
|
286
179
|
|
|
@@ -298,36 +191,16 @@ class HashnodeApp(GraphQLApplication):
|
|
|
298
191
|
Tags:
|
|
299
192
|
list, posts, hashnode, api, query, important
|
|
300
193
|
"""
|
|
301
|
-
list_posts_query = gql(
|
|
302
|
-
query Publication($id: ObjectId!, $first: Int!, $after: String) {
|
|
303
|
-
|
|
304
|
-
posts(first: $first, after: $after) {
|
|
305
|
-
edges {
|
|
306
|
-
node {
|
|
307
|
-
id
|
|
308
|
-
title
|
|
309
|
-
slug
|
|
310
|
-
url
|
|
311
|
-
}
|
|
312
|
-
cursor
|
|
313
|
-
}
|
|
314
|
-
pageInfo {
|
|
315
|
-
endCursor
|
|
316
|
-
hasNextPage
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
""")
|
|
194
|
+
list_posts_query = gql(
|
|
195
|
+
"\n query Publication($id: ObjectId!, $first: Int!, $after: String) {\n publication(id: $id) {\n posts(first: $first, after: $after) {\n edges {\n node {\n id\n title\n slug\n url\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n "
|
|
196
|
+
)
|
|
322
197
|
variables = {"id": publication_id, "first": first}
|
|
323
198
|
if after:
|
|
324
199
|
variables["after"] = after
|
|
325
200
|
result = self.query(list_posts_query, variables)
|
|
326
201
|
return result.get("publication", {}).get("posts")
|
|
327
202
|
|
|
328
|
-
def get_post(
|
|
329
|
-
self, post_id: str = None, slug: str = None, hostname: str = None
|
|
330
|
-
) -> dict:
|
|
203
|
+
async def get_post(self, post_id: str = None, slug: str = None, hostname: str = None) -> dict:
|
|
331
204
|
"""
|
|
332
205
|
Fetches details of a single post by ID, or by slug and hostname.
|
|
333
206
|
|
|
@@ -346,45 +219,21 @@ class HashnodeApp(GraphQLApplication):
|
|
|
346
219
|
Tags:
|
|
347
220
|
get, post, hashnode, api, query, important
|
|
348
221
|
"""
|
|
349
|
-
if not post_id and not (slug and hostname):
|
|
350
|
-
raise ValueError(
|
|
351
|
-
|
|
352
|
-
)
|
|
353
|
-
|
|
354
|
-
get_post_query = gql("""
|
|
355
|
-
query Post($id: ID, $slug: String, $hostname: String) {
|
|
356
|
-
post(id: $id, slug: $slug, hostname: $hostname) {
|
|
357
|
-
id
|
|
358
|
-
slug
|
|
359
|
-
previousSlugs
|
|
360
|
-
title
|
|
361
|
-
subtitle
|
|
362
|
-
author {
|
|
363
|
-
id
|
|
364
|
-
username
|
|
365
|
-
name
|
|
366
|
-
}
|
|
367
|
-
comments(first: 5) {
|
|
368
|
-
edges {
|
|
369
|
-
node {
|
|
370
|
-
id
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
""")
|
|
222
|
+
if not post_id and (not (slug and hostname)):
|
|
223
|
+
raise ValueError("Either post_id or both slug and hostname must be provided.")
|
|
224
|
+
get_post_query = gql(
|
|
225
|
+
"\n query Post($id: ID, $slug: String, $hostname: String) {\n post(id: $id, slug: $slug, hostname: $hostname) {\n id\n slug\n previousSlugs\n title\n subtitle\n \t\t\tauthor {\n id\n username\n name\n }\n comments(first: 5) {\n edges {\n node {\n id\n }\n }\n }\n }\n }\n "
|
|
226
|
+
)
|
|
377
227
|
variables = {}
|
|
378
228
|
if post_id:
|
|
379
229
|
variables["id"] = post_id
|
|
380
230
|
else:
|
|
381
231
|
variables["slug"] = slug
|
|
382
232
|
variables["hostname"] = hostname
|
|
383
|
-
|
|
384
233
|
result = self.query(get_post_query, variables)
|
|
385
234
|
return result.get("post")
|
|
386
235
|
|
|
387
|
-
def modify_post(
|
|
236
|
+
async def modify_post(
|
|
388
237
|
self,
|
|
389
238
|
post_id: str,
|
|
390
239
|
title: str = None,
|
|
@@ -415,41 +264,26 @@ class HashnodeApp(GraphQLApplication):
|
|
|
415
264
|
Tags:
|
|
416
265
|
modify, post, hashnode, api, important
|
|
417
266
|
"""
|
|
418
|
-
update_post_mutation = gql(
|
|
419
|
-
mutation UpdatePost($input: UpdatePostInput!) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
url
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
""")
|
|
427
|
-
|
|
428
|
-
variables = {
|
|
429
|
-
"input": {
|
|
430
|
-
"id": post_id,
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
267
|
+
update_post_mutation = gql(
|
|
268
|
+
"\n mutation UpdatePost($input: UpdatePostInput!) {\n updatePost(input: $input) {\n post {\n url\n }\n }\n }\n "
|
|
269
|
+
)
|
|
270
|
+
variables = {"input": {"id": post_id}}
|
|
434
271
|
if title:
|
|
435
272
|
variables["input"]["title"] = title
|
|
436
273
|
if content:
|
|
437
274
|
variables["input"]["contentMarkdown"] = content
|
|
438
275
|
if tags:
|
|
439
|
-
variables["input"]["tags"] = [
|
|
440
|
-
{"name": tag, "slug": tag.replace(" ", "-").lower()} for tag in tags
|
|
441
|
-
]
|
|
276
|
+
variables["input"]["tags"] = [{"name": tag, "slug": tag.replace(" ", "-").lower()} for tag in tags]
|
|
442
277
|
if slug:
|
|
443
278
|
variables["input"]["slug"] = slug
|
|
444
279
|
if subtitle:
|
|
445
280
|
variables["input"]["subtitle"] = subtitle
|
|
446
281
|
if cover_image:
|
|
447
282
|
variables["input"]["coverImageOptions"] = {"coverImageURL": cover_image}
|
|
448
|
-
|
|
449
283
|
result = self.mutate(update_post_mutation, variables)
|
|
450
284
|
return result["updatePost"]["post"]["url"]
|
|
451
285
|
|
|
452
|
-
def delete_post(self, post_id: str) -> str:
|
|
286
|
+
async def delete_post(self, post_id: str) -> str:
|
|
453
287
|
"""
|
|
454
288
|
Deletes a post using the GraphQL API.
|
|
455
289
|
|
|
@@ -465,24 +299,14 @@ class HashnodeApp(GraphQLApplication):
|
|
|
465
299
|
Tags:
|
|
466
300
|
delete, post, hashnode, api
|
|
467
301
|
"""
|
|
468
|
-
delete_post_mutation = gql(
|
|
469
|
-
mutation RemovePost($input: RemovePostInput!) {
|
|
470
|
-
|
|
471
|
-
post {
|
|
472
|
-
id
|
|
473
|
-
slug
|
|
474
|
-
previousSlugs
|
|
475
|
-
title
|
|
476
|
-
subtitle
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
""")
|
|
302
|
+
delete_post_mutation = gql(
|
|
303
|
+
"\n mutation RemovePost($input: RemovePostInput!) {\n removePost(input: $input) {\n post {\n id\n slug\n previousSlugs\n title\n subtitle\n }\n }\n }\n "
|
|
304
|
+
)
|
|
481
305
|
variables = {"input": {"id": post_id}}
|
|
482
306
|
result = self.mutate(delete_post_mutation, variables)
|
|
483
307
|
return result.get("removePost", {}).get("post", "Post deleted successfully")
|
|
484
308
|
|
|
485
|
-
def add_comment(self, post_id: str, content: str) -> dict:
|
|
309
|
+
async def add_comment(self, post_id: str, content: str) -> dict:
|
|
486
310
|
"""
|
|
487
311
|
Adds a comment to a post using the GraphQL API.
|
|
488
312
|
|
|
@@ -499,32 +323,14 @@ class HashnodeApp(GraphQLApplication):
|
|
|
499
323
|
Tags:
|
|
500
324
|
add, comment, post, hashnode, api, important
|
|
501
325
|
"""
|
|
502
|
-
add_comment_mutation = gql(
|
|
503
|
-
mutation AddComment($input: AddCommentInput!) {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
id
|
|
507
|
-
content {
|
|
508
|
-
markdown
|
|
509
|
-
}
|
|
510
|
-
author {
|
|
511
|
-
id
|
|
512
|
-
username
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
""")
|
|
518
|
-
variables = {
|
|
519
|
-
"input": {
|
|
520
|
-
"postId": post_id,
|
|
521
|
-
"contentMarkdown": content,
|
|
522
|
-
}
|
|
523
|
-
}
|
|
326
|
+
add_comment_mutation = gql(
|
|
327
|
+
"\n mutation AddComment($input: AddCommentInput!) {\n addComment(input: $input) {\n comment {\n id\n content {\n markdown\n }\n author {\n id\n username\n }\n }\n }\n }\n "
|
|
328
|
+
)
|
|
329
|
+
variables = {"input": {"postId": post_id, "contentMarkdown": content}}
|
|
524
330
|
result = self.mutate(add_comment_mutation, variables)
|
|
525
331
|
return result.get("addComment", {}).get("comment")
|
|
526
332
|
|
|
527
|
-
def delete_comment(self, comment_id: str) -> str:
|
|
333
|
+
async def delete_comment(self, comment_id: str) -> str:
|
|
528
334
|
"""
|
|
529
335
|
Deletes a comment using the GraphQL API.
|
|
530
336
|
|
|
@@ -540,22 +346,14 @@ class HashnodeApp(GraphQLApplication):
|
|
|
540
346
|
Tags:
|
|
541
347
|
delete, comment, hashnode, api
|
|
542
348
|
"""
|
|
543
|
-
delete_comment_mutation = gql(
|
|
544
|
-
mutation RemoveComment($input: RemoveCommentInput!) {
|
|
545
|
-
|
|
546
|
-
comment {
|
|
547
|
-
id
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
""")
|
|
349
|
+
delete_comment_mutation = gql(
|
|
350
|
+
"\n mutation RemoveComment($input: RemoveCommentInput!) {\n removeComment(input: $input) {\n comment {\n id\n }\n }\n }\n "
|
|
351
|
+
)
|
|
552
352
|
variables = {"input": {"id": comment_id}}
|
|
553
353
|
result = self.mutate(delete_comment_mutation, variables)
|
|
554
|
-
return result.get("removeComment", {}).get(
|
|
555
|
-
"comment", "Comment deleted successfully"
|
|
556
|
-
)
|
|
354
|
+
return result.get("removeComment", {}).get("comment", "Comment deleted successfully")
|
|
557
355
|
|
|
558
|
-
def get_user(self, username: str) -> dict:
|
|
356
|
+
async def get_user(self, username: str) -> dict:
|
|
559
357
|
"""
|
|
560
358
|
Fetches details about a user by username.
|
|
561
359
|
|
|
@@ -571,19 +369,9 @@ class HashnodeApp(GraphQLApplication):
|
|
|
571
369
|
Tags:
|
|
572
370
|
get, user, hashnode, api, query
|
|
573
371
|
"""
|
|
574
|
-
get_user_query = gql(
|
|
575
|
-
query User($username: String!) {
|
|
576
|
-
|
|
577
|
-
id
|
|
578
|
-
username
|
|
579
|
-
name
|
|
580
|
-
tagline
|
|
581
|
-
profilePicture
|
|
582
|
-
followersCount
|
|
583
|
-
followingsCount
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
""")
|
|
372
|
+
get_user_query = gql(
|
|
373
|
+
"\n query User($username: String!) {\n user(username: $username) {\n id\n username\n name\n tagline\n profilePicture\n followersCount\n followingsCount\n }\n }\n "
|
|
374
|
+
)
|
|
587
375
|
variables = {"username": username}
|
|
588
376
|
result = self.query(get_user_query, variables)
|
|
589
377
|
return result.get("user")
|