getanyapi 0.7.0__tar.gz → 0.8.0__tar.gz

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.
Files changed (83) hide show
  1. {getanyapi-0.7.0 → getanyapi-0.8.0}/PKG-INFO +1 -1
  2. {getanyapi-0.7.0 → getanyapi-0.8.0}/pyproject.toml +1 -1
  3. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/__init__.py +1 -1
  4. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/twitter.py +168 -19
  5. {getanyapi-0.7.0 → getanyapi-0.8.0}/.gitignore +0 -0
  6. {getanyapi-0.7.0 → getanyapi-0.8.0}/README.md +0 -0
  7. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/_account.py +0 -0
  8. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/_async_client.py +0 -0
  9. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/_client.py +0 -0
  10. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/_errors.py +0 -0
  11. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/_pagination.py +0 -0
  12. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/_transport.py +0 -0
  13. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/__init__.py +0 -0
  14. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/ahrefs.py +0 -0
  15. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/airbnb.py +0 -0
  16. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/alibaba.py +0 -0
  17. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/amazon.py +0 -0
  18. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/apollo.py +0 -0
  19. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/appstore.py +0 -0
  20. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/bluesky.py +0 -0
  21. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/booking.py +0 -0
  22. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/coinmarketcap.py +0 -0
  23. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/congress.py +0 -0
  24. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/dexscreener.py +0 -0
  25. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/douyin.py +0 -0
  26. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/ebay.py +0 -0
  27. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/email.py +0 -0
  28. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/facebook.py +0 -0
  29. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/fiverr.py +0 -0
  30. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/github.py +0 -0
  31. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/glassdoor.py +0 -0
  32. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/google.py +0 -0
  33. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/google_ads.py +0 -0
  34. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/google_finance.py +0 -0
  35. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/google_shopping.py +0 -0
  36. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/hackernews.py +0 -0
  37. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/indeed.py +0 -0
  38. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/instagram.py +0 -0
  39. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/linkedin.py +0 -0
  40. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/maps.py +0 -0
  41. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/pandaexpress.py +0 -0
  42. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/person.py +0 -0
  43. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/pinterest.py +0 -0
  44. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/playstore.py +0 -0
  45. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/polymarket.py +0 -0
  46. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/realtor.py +0 -0
  47. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/reddit.py +0 -0
  48. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/redfin.py +0 -0
  49. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/rednote.py +0 -0
  50. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/sec.py +0 -0
  51. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/semrush.py +0 -0
  52. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/seo.py +0 -0
  53. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/snapchat.py +0 -0
  54. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/social.py +0 -0
  55. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/spotify.py +0 -0
  56. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/substack.py +0 -0
  57. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/threads.py +0 -0
  58. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/tiktok.py +0 -0
  59. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/tiktok_shop.py +0 -0
  60. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/tripadvisor.py +0 -0
  61. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/trustpilot.py +0 -0
  62. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/truthsocial.py +0 -0
  63. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/upwork.py +0 -0
  64. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/walmart.py +0 -0
  65. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/web.py +0 -0
  66. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/weibo.py +0 -0
  67. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/whatsapp.py +0 -0
  68. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/yahoo_finance.py +0 -0
  69. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/yelp.py +0 -0
  70. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/youtube.py +0 -0
  71. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/zhihu.py +0 -0
  72. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/platforms/zillow.py +0 -0
  73. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/py.typed +0 -0
  74. {getanyapi-0.7.0 → getanyapi-0.8.0}/src/getanyapi/types.py +0 -0
  75. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/conftest.py +0 -0
  76. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_account.py +0 -0
  77. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_client.py +0 -0
  78. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_envelope.py +0 -0
  79. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_errors.py +0 -0
  80. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_fixture_roundtrip.py +0 -0
  81. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_fixture_sweep.py +0 -0
  82. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_pagination.py +0 -0
  83. {getanyapi-0.7.0 → getanyapi-0.8.0}/tests/test_transport.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: getanyapi
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: Official typed Python SDK for AnyAPI: any API, one wallet, USD, no subscriptions.
5
5
  Project-URL: Homepage, https://getanyapi.com
6
6
  Project-URL: Documentation, https://getanyapi.com/docs
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "getanyapi"
7
- version = "0.7.0"
7
+ version = "0.8.0"
8
8
  description = "Official typed Python SDK for AnyAPI: any API, one wallet, USD, no subscriptions."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -49,7 +49,7 @@ from .types import (
49
49
  unwrap,
50
50
  )
51
51
 
52
- __version__ = "0.7.0"
52
+ __version__ = "0.8.0"
53
53
 
54
54
  __all__ = [
55
55
  # clients + top-level functions
@@ -108,17 +108,26 @@ class TwitterTweetTranscriptInput(TypedDict, total=False):
108
108
  """Tweet URL of the video to transcribe (e.g. https://x.com/TheoVon/status/1916982720317821050)."""
109
109
 
110
110
 
111
+ class TwitterUserPostsInput(TypedDict, total=False):
112
+ """Input for X / Twitter User Posts."""
113
+
114
+ cursor: NotRequired[str]
115
+ """Opaque pagination cursor from a previous response's nextCursor. Omit for the first page."""
116
+ handle: Required[str]
117
+ """Twitter/X handle without the leading @."""
118
+
119
+
111
120
  class TwitterUserTweetsInput(TypedDict, total=False):
112
- """Input for Twitter User Tweets."""
121
+ """Input for X / Twitter User Tweets and Replies."""
113
122
 
114
123
  cursor: NotRequired[str]
115
- """Opaque pagination cursor from a previous response's nextCursor. Omit for the first page; pass it to fetch the next page of tweets."""
124
+ """Reserved for cursor-capable lanes. The current bulk lane returns nextCursor as null, so omit this field."""
116
125
  handle: Required[str]
117
126
  """Twitter/X handle without the leading @."""
118
127
  limit: NotRequired[int]
119
- """Per-page maximum number of tweets to return (1-1000), newest first. A provider may return a smaller native page of approximately 20; follow nextCursor for more. With requireSinglePage true, up to this many are returned in one (pricier) call. Range: 1 to 1000. Default: 20."""
128
+ """Maximum number of authored tweets and replies to return in the current bulk call (1-1000). The provider may return fewer results. Range: 1 to 1000. Default: 20."""
120
129
  requireSinglePage: NotRequired[bool]
121
- """Set true to get up to limit tweets in a single response instead of cheap pages, served by a bulk provider at a higher price."""
130
+ """Compatibility flag for requiring one response. The current lane already returns up to limit results in one bulk call, whether this is omitted or true."""
122
131
 
123
132
 
124
133
  class TwitterCommunityData(BaseModel):
@@ -408,13 +417,61 @@ class TwitterTweetTranscriptData(BaseModel):
408
417
  transcript: str
409
418
 
410
419
 
420
+ class TwitterUserPostsData(BaseModel):
421
+ model_config = ConfigDict(populate_by_name=True)
422
+
423
+ next_cursor: str = Field(
424
+ alias="nextCursor",
425
+ description="Opaque cursor for the next native Posts-tab page, or null when no more pages are available.",
426
+ )
427
+ tweets: list[TwitterUserPostsTweet] = Field(
428
+ description="Posts in profile order. A pinned post may appear before otherwise reverse-chronological results. Populated whenever the provider has data for the entity."
429
+ )
430
+
431
+
432
+ class TwitterUserPostsTweet(BaseModel):
433
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
434
+
435
+ bookmarks: int = Field(description="Number of bookmarks.")
436
+ created_utc: float = Field(
437
+ alias="createdUtc",
438
+ description="UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. Populated whenever the provider has data for the entity.",
439
+ )
440
+ id: str = Field(
441
+ description="The post's numeric tweet ID, represented as a string. Populated whenever the provider has data for the entity."
442
+ )
443
+ is_pinned: bool = Field(
444
+ alias="isPinned",
445
+ description="Whether X marks the post as pinned on the profile.",
446
+ )
447
+ is_reply: bool | None = Field(
448
+ default=None,
449
+ alias="isReply",
450
+ description="Whether X marks the record as a reply. Certified Posts-tab captures use this for self-thread continuations.",
451
+ )
452
+ lang: str | None = Field(
453
+ default=None, description="Language code reported for the post, when available."
454
+ )
455
+ likes: int = Field(description="Number of likes.")
456
+ quotes: int | None = Field(default=None, description="Number of quote posts.")
457
+ replies: int = Field(description="Number of replies.")
458
+ retweets: int = Field(description="Number of reposts or retweets.")
459
+ text: str = Field(
460
+ description="The post text. Empty for media-only posts. Populated whenever the provider has data for the entity."
461
+ )
462
+ url: str = Field(
463
+ description="Canonical x.com URL of the post. Populated whenever the provider has data for the entity."
464
+ )
465
+ views: int = Field(description="Number of views.")
466
+
467
+
411
468
  class TwitterUserTweetsData(BaseModel):
412
469
  model_config = ConfigDict(populate_by_name=True)
413
470
 
414
471
  next_cursor: str | None = Field(
415
472
  default=None,
416
473
  alias="nextCursor",
417
- description="Opaque cursor for the next page of tweets, or null when this lane has no more. Pass it back as cursor to continue.",
474
+ description="Reserved pagination cursor. The current bulk lane returns null; cursor-capable lanes may return an opaque continuation value in the future.",
418
475
  )
419
476
  tweets: list[TwitterUserTweetsTweet] = Field(
420
477
  description="Populated whenever the provider has data for the entity."
@@ -720,20 +777,66 @@ class TwitterNamespace:
720
777
  )
721
778
  return RunResult[TwitterTweetTranscriptData].model_validate(raw)
722
779
 
780
+ def user_posts(
781
+ self,
782
+ *,
783
+ options: RequestOptions | None = None,
784
+ **input: Unpack[TwitterUserPostsInput],
785
+ ) -> RunResult[TwitterUserPostsData]:
786
+ """X / Twitter User Posts
787
+
788
+ Get an X (Twitter) account's profile Posts-tab timeline by handle. Results
789
+ follow profile order: a pinned post may appear first, followed by otherwise
790
+ reverse-chronological authored posts, reposts, quotes, and self-thread
791
+ continuations.
792
+
793
+ Price: $0.00075 per request.
794
+
795
+ Example:
796
+ res = client.twitter.user_posts(handle="levelsio")
797
+ """
798
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
799
+ "twitter.user_posts", dict(input), options
800
+ )
801
+ return RunResult[TwitterUserPostsData].model_validate(raw)
802
+
803
+ def iter_user_posts(
804
+ self,
805
+ *,
806
+ options: RequestOptions | None = None,
807
+ **input: Unpack[TwitterUserPostsInput],
808
+ ) -> Paginator[TwitterUserPostsTweet, TwitterUserPostsData]:
809
+ """Iterate X / Twitter User Posts results, following pagination cursors.
810
+
811
+ Yields validated `TwitterUserPostsTweet` items from the `tweets` field of
812
+ each page. Use `.pages()` on the returned paginator to walk whole
813
+ `RunResult` pages.
814
+ """
815
+ return paginate(
816
+ self._client,
817
+ "twitter.user_posts",
818
+ dict(input),
819
+ "tweets",
820
+ item_model=TwitterUserPostsTweet,
821
+ data_model=TwitterUserPostsData,
822
+ bare=False,
823
+ options=options,
824
+ )
825
+
723
826
  def user_tweets(
724
827
  self,
725
828
  *,
726
829
  options: RequestOptions | None = None,
727
830
  **input: Unpack[TwitterUserTweetsInput],
728
831
  ) -> RunResult[TwitterUserTweetsData]:
729
- """Twitter User Tweets
832
+ """X / Twitter User Tweets and Replies
730
833
 
731
- Get an X (Twitter) account's latest tweets by handle, newest first
732
- (reverse-chronological, replies included), with engagement, views, language,
733
- and cursor pagination. Limit is a per-page maximum; native pages contain
734
- approximately 20 tweets unless requireSinglePage selects a bulk lane.
834
+ Get up to the requested limit of tweets and replies authored by an X
835
+ (Twitter) account in one bulk call, with engagement, views, and language.
836
+ The current lane returns nextCursor as null; cursor is reserved for future
837
+ cursor-capable lanes.
735
838
 
736
- Price: $0.00075 per request.
839
+ Price: $0 per request plus $0.0002 per result (maximum $0.2).
737
840
 
738
841
  Example:
739
842
  res = client.twitter.user_tweets(handle="levelsio", limit=20)
@@ -749,7 +852,7 @@ class TwitterNamespace:
749
852
  options: RequestOptions | None = None,
750
853
  **input: Unpack[TwitterUserTweetsInput],
751
854
  ) -> Paginator[TwitterUserTweetsTweet, TwitterUserTweetsData]:
752
- """Iterate Twitter User Tweets results, following pagination cursors.
855
+ """Iterate X / Twitter User Tweets and Replies results, following pagination cursors.
753
856
 
754
857
  Yields validated `TwitterUserTweetsTweet` items from the `tweets` field of
755
858
  each page. Use `.pages()` on the returned paginator to walk whole
@@ -1039,20 +1142,66 @@ class AsyncTwitterNamespace:
1039
1142
  )
1040
1143
  return RunResult[TwitterTweetTranscriptData].model_validate(raw)
1041
1144
 
1145
+ async def user_posts(
1146
+ self,
1147
+ *,
1148
+ options: RequestOptions | None = None,
1149
+ **input: Unpack[TwitterUserPostsInput],
1150
+ ) -> RunResult[TwitterUserPostsData]:
1151
+ """X / Twitter User Posts
1152
+
1153
+ Get an X (Twitter) account's profile Posts-tab timeline by handle. Results
1154
+ follow profile order: a pinned post may appear first, followed by otherwise
1155
+ reverse-chronological authored posts, reposts, quotes, and self-thread
1156
+ continuations.
1157
+
1158
+ Price: $0.00075 per request.
1159
+
1160
+ Example:
1161
+ res = client.twitter.user_posts(handle="levelsio")
1162
+ """
1163
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
1164
+ "twitter.user_posts", dict(input), options
1165
+ )
1166
+ return RunResult[TwitterUserPostsData].model_validate(raw)
1167
+
1168
+ def iter_user_posts(
1169
+ self,
1170
+ *,
1171
+ options: RequestOptions | None = None,
1172
+ **input: Unpack[TwitterUserPostsInput],
1173
+ ) -> AsyncPaginator[TwitterUserPostsTweet, TwitterUserPostsData]:
1174
+ """Iterate X / Twitter User Posts results, following pagination cursors.
1175
+
1176
+ Yields validated `TwitterUserPostsTweet` items from the `tweets` field of
1177
+ each page. Use `.pages()` on the returned paginator to walk whole
1178
+ `RunResult` pages.
1179
+ """
1180
+ return apaginate(
1181
+ self._client,
1182
+ "twitter.user_posts",
1183
+ dict(input),
1184
+ "tweets",
1185
+ item_model=TwitterUserPostsTweet,
1186
+ data_model=TwitterUserPostsData,
1187
+ bare=False,
1188
+ options=options,
1189
+ )
1190
+
1042
1191
  async def user_tweets(
1043
1192
  self,
1044
1193
  *,
1045
1194
  options: RequestOptions | None = None,
1046
1195
  **input: Unpack[TwitterUserTweetsInput],
1047
1196
  ) -> RunResult[TwitterUserTweetsData]:
1048
- """Twitter User Tweets
1197
+ """X / Twitter User Tweets and Replies
1049
1198
 
1050
- Get an X (Twitter) account's latest tweets by handle, newest first
1051
- (reverse-chronological, replies included), with engagement, views, language,
1052
- and cursor pagination. Limit is a per-page maximum; native pages contain
1053
- approximately 20 tweets unless requireSinglePage selects a bulk lane.
1199
+ Get up to the requested limit of tweets and replies authored by an X
1200
+ (Twitter) account in one bulk call, with engagement, views, and language.
1201
+ The current lane returns nextCursor as null; cursor is reserved for future
1202
+ cursor-capable lanes.
1054
1203
 
1055
- Price: $0.00075 per request.
1204
+ Price: $0 per request plus $0.0002 per result (maximum $0.2).
1056
1205
 
1057
1206
  Example:
1058
1207
  res = client.twitter.user_tweets(handle="levelsio", limit=20)
@@ -1068,7 +1217,7 @@ class AsyncTwitterNamespace:
1068
1217
  options: RequestOptions | None = None,
1069
1218
  **input: Unpack[TwitterUserTweetsInput],
1070
1219
  ) -> AsyncPaginator[TwitterUserTweetsTweet, TwitterUserTweetsData]:
1071
- """Iterate Twitter User Tweets results, following pagination cursors.
1220
+ """Iterate X / Twitter User Tweets and Replies results, following pagination cursors.
1072
1221
 
1073
1222
  Yields validated `TwitterUserTweetsTweet` items from the `tweets` field of
1074
1223
  each page. Use `.pages()` on the returned paginator to walk whole
File without changes
File without changes
File without changes