MCPcopy Create free account
hub / github.com/Freedium-cfd/web / query_post_graphql

Method query_post_graphql

medium-parser/medium_parser/api.py:30–104  ·  view source on GitHub ↗
(self, post_id: str)

Source from the content-addressed store, hash-verified

28 return await self.query_post_graphql(post_id)
29
30 async def query_post_graphql(self, post_id: str):
31 logger.debug(f"Starting request construction for post {post_id}")
32
33 proxy = None
34 if self.proxy_list:
35 proxy = random.choice(self.proxy_list)
36 logger.debug(f"Using proxy: {proxy}")
37
38 headers = {
39 "X-APOLLO-OPERATION-ID": generate_random_sha256_hash(),
40 "X-APOLLO-OPERATION-NAME": "FullPostQuery",
41 "Accept": "multipart/mixed; deferSpec=20220824, application/json, application/json",
42 "Accept-Language": "en-US",
43 "X-Obvious-CID": "android",
44 "X-Xsrf-Token": "1",
45 "X-Client-Date": str(get_unix_ms()),
46 "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1 (compatible; YandexMobileBot/3.0;", # "donkey/4.5.1187420", # <---- There is Medium version
47 "Cache-Control": "public, max-age=-1",
48 "Content-Type": "application/json",
49 "Connection": "Keep-Alive",
50 }
51
52 if self.auth_cookies is not None:
53 headers["Cookie"] = self.auth_cookies
54
55 graphql_data = {
56 "operationName": "FullPostQuery",
57 "variables": {
58 "postId": post_id,
59 "postMeteringOptions": {},
60 },
61"query": "query FullPostQuery($postId: ID!, $postMeteringOptions: PostMeteringOptions) { post(id: $postId) { __typename id ...FullPostData } meterPost(postId: $postId, postMeteringOptions: $postMeteringOptions) { __typename ...MeteringInfoData } } fragment UserFollowData on User { id socialStats { followingCount followerCount } viewerEdge { isFollowing } } fragment NewsletterData on NewsletterV3 { id viewerEdge { id isSubscribed } } fragment UserNewsletterData on User { id newsletterV3 { __typename ...NewsletterData } } fragment ImageMetadataData on ImageMetadata { id originalWidth originalHeight focusPercentX focusPercentY alt } fragment CollectionFollowData on Collection { id subscriberCount viewerEdge { isFollowing } } fragment CollectionNewsletterData on Collection { id newsletterV3 { __typename ...NewsletterData } } fragment BylineData on Post { id readingTime creator { __typename id imageId username name bio tippingLink viewerEdge { isUser } ...UserFollowData ...UserNewsletterData } collection { __typename id name avatar { __typename id ...ImageMetadataData } ...CollectionFollowData ...CollectionNewsletterData } isLocked firstPublishedAt latestPublishedVersion } fragment ResponseCountData on Post { postResponses { count } } fragment InResponseToPost on Post { id title creator { name } clapCount responsesCount isLocked } fragment PostVisibilityData on Post { id collection { viewerEdge { isEditor canEditPosts canEditOwnPosts } } creator { id } isLocked visibility } fragment PostMenuData on Post { id title creator { __typename ...UserFollowData } collection { __typename ...CollectionFollowData } } fragment PostMetaData on Post { __typename id title visibility ...ResponseCountData clapCount viewerEdge { clapCount } detectedLanguage mediumUrl readingTime updatedAt isLocked allowResponses isProxyPost latestPublishedVersion isSeries firstPublishedAt previewImage { id } inResponseToPostResult { __typename ...InResponseToPost } inResponseToMediaResource { mediumQuote { startOffset endOffset paragraphs { text type markups { type start end anchorType } } } } inResponseToEntityType canonicalUrl collection { id slug name shortDescription avatar { __typename id ...ImageMetadataData } viewerEdge { isFollowing isEditor canEditPosts canEditOwnPosts isMuting } } creator { id isFollowing name bio imageId mediumMemberAt twitterScreenName viewerEdge { isBlocking isMuting isUser } } previewContent { subtitle } pinnedByCreatorAt ...PostVisibilityData ...PostMenuData } fragment LinkMetadataList on Post { linkMetadataList { url alts { type url } } } fragment MediaResourceData on MediaResource { id iframeSrc thumbnailUrl iframeHeight iframeWidth title } fragment IframeData on Iframe { iframeHeight iframeWidth mediaResource { __typename ...MediaResourceData } } fragment MarkupData on Markup { name type start end href title rel type anchorType userId creatorIds } fragment CatalogSummaryData on Catalog { id name description type visibility predefined responsesLocked creator { id name username imageId bio viewerEdge { isUser } } createdAt version itemsLastInsertedAt postItemsCount } fragment CatalogPreviewData on Catalog { __typename ...CatalogSummaryData id itemsConnection(pagingOptions: { limit: 10 } ) { items { entity { __typename ... on Post { id previewImage { id } } } } paging { count } } } fragment MixtapeMetadataData on MixtapeMetadata { mediaResourceId href thumbnailImageId mediaResource { mediumCatalog { __typename ...CatalogPreviewData } } } fragment ParagraphData on Paragraph { id name href text iframe { __typename ...IframeData } layout markups { __typename ...MarkupData } metadata { __typename ...ImageMetadataData } mixtapeMetadata { __typename ...MixtapeMetadataData } type hasDropCap dropCapImage { __typename ...ImageMetadataData } codeBlockMetadata { lang mode } } fragment QuoteData on Quote { id postId userId startOffset endOffset paragraphs { __typename id ...ParagraphData } quoteType } fragment HighlightsData on Post { id highlights { __typename ...QuoteData } } fragment PostFooterCountData on Post { __typename id clapCount viewerEdge { clapCount } ...ResponseCountData responsesLocked mediumUrl title collection { id viewerEdge { isMuting isFollowing } } creator { id viewerEdge { isMuting isFollowing } } } fragment TagNoViewerEdgeData on Tag { id normalizedTagSlug displayTitle followerCount postCount } fragment VideoMetadataData on VideoMetadata { videoId previewImageId originalWidth originalHeight } fragment SectionData on Section { name startIndex textLayout imageLayout videoLayout backgroundImage { __typename ...ImageMetadataData } backgroundVideo { __typename ...VideoMetadataData } } fragment PostBodyData on RichText { sections { __typename ...SectionData } paragraphs { __typename id ...ParagraphData } } fragment FullPostData on Post { __typename ...BylineData ...PostMetaData ...LinkMetadataList ...HighlightsData ...PostFooterCountData tags { __typename id ...TagNoViewerEdgeData } content(postMeteringOptions: $postMeteringOptions) { bodyModel { __typename ...PostBodyData } validatedShareKey } } fragment MeteringInfoData on MeteringInfo { maxUnlockCount unlocksRemaining postIds }",
62 }
63
64 response_data = None
65 exception = None
66
67 logger.debug("Request started...")
68
69 try:
70 async with AsyncSession() as session:
71 response = await session.post(
72 "https://medium.com/_/graphql",
73 headers=headers,
74 json=graphql_data,
75 proxies={"http": proxy, "https": proxy} if proxy else None,
76 timeout=self.timeout,
77 impersonate=self.impersonate,
78 http_version="v3"
79 )
80
81 if response.status_code != 200:
82 logger.error(
83 f"Failed to fetch post by ID {post_id} with status code: {response.status_code}, response: {response.text}"
84 )
85 return None
86
87 response_data = response.json()

Callers 1

query_post_by_idMethod · 0.95

Calls 5

get_unix_msFunction · 0.90
errorMethod · 0.80
postMethod · 0.45
jsonMethod · 0.45

Tested by

no test coverage detected