getanyapi 0.82.0__tar.gz → 0.83.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 (108) hide show
  1. {getanyapi-0.82.0 → getanyapi-0.83.0}/PKG-INFO +1 -1
  2. {getanyapi-0.82.0 → getanyapi-0.83.0}/pyproject.toml +1 -1
  3. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/__init__.py +1 -1
  4. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/appstore.py +65 -2
  5. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/tiktok.py +61 -2
  6. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/twitter.py +55 -0
  7. {getanyapi-0.82.0 → getanyapi-0.83.0}/.gitignore +0 -0
  8. {getanyapi-0.82.0 → getanyapi-0.83.0}/README.md +0 -0
  9. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/_account.py +0 -0
  10. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/_async_client.py +0 -0
  11. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/_client.py +0 -0
  12. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/_errors.py +0 -0
  13. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/_idempotency.py +0 -0
  14. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/_pagination.py +0 -0
  15. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/_transport.py +0 -0
  16. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/discovery_types.py +0 -0
  17. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/__init__.py +0 -0
  18. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/ahrefs.py +0 -0
  19. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/airbnb.py +0 -0
  20. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/alibaba.py +0 -0
  21. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/amazon.py +0 -0
  22. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/apollo.py +0 -0
  23. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/bluesky.py +0 -0
  24. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/booking.py +0 -0
  25. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/capterra.py +0 -0
  26. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/chatgpt.py +0 -0
  27. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/coinmarketcap.py +0 -0
  28. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/company.py +0 -0
  29. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/company_enrichment.py +0 -0
  30. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/company_identify.py +0 -0
  31. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/company_search.py +0 -0
  32. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/congress.py +0 -0
  33. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/contact_enrichment.py +0 -0
  34. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/douyin.py +0 -0
  35. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/ebay.py +0 -0
  36. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/email.py +0 -0
  37. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/email_finding.py +0 -0
  38. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/email_verification.py +0 -0
  39. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/facebook.py +0 -0
  40. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/fiverr.py +0 -0
  41. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/g2.py +0 -0
  42. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/gemini.py +0 -0
  43. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/github.py +0 -0
  44. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/glassdoor.py +0 -0
  45. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/google.py +0 -0
  46. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/google_ads.py +0 -0
  47. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/google_finance.py +0 -0
  48. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/google_shopping.py +0 -0
  49. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/hackernews.py +0 -0
  50. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/indeed.py +0 -0
  51. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/instagram.py +0 -0
  52. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/job_search.py +0 -0
  53. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/linkedin.py +0 -0
  54. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/maps.py +0 -0
  55. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/mobile_phone.py +0 -0
  56. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/naver.py +0 -0
  57. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/nextdoor.py +0 -0
  58. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/people_search.py +0 -0
  59. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/perplexity.py +0 -0
  60. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/person.py +0 -0
  61. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/person_enrichment.py +0 -0
  62. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/pexels.py +0 -0
  63. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/pinterest.py +0 -0
  64. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/playstore.py +0 -0
  65. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/polymarket.py +0 -0
  66. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/property_records.py +0 -0
  67. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/realtor.py +0 -0
  68. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/reddit.py +0 -0
  69. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/redfin.py +0 -0
  70. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/rednote.py +0 -0
  71. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/sec.py +0 -0
  72. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/semrush.py +0 -0
  73. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/seo.py +0 -0
  74. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/similarweb.py +0 -0
  75. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/snapchat.py +0 -0
  76. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/social.py +0 -0
  77. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/spotify.py +0 -0
  78. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/substack.py +0 -0
  79. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/technographics.py +0 -0
  80. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/threads.py +0 -0
  81. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/tiktok_shop.py +0 -0
  82. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/tripadvisor.py +0 -0
  83. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/trustpilot.py +0 -0
  84. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/truthsocial.py +0 -0
  85. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/unsplash.py +0 -0
  86. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/upwork.py +0 -0
  87. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/walmart.py +0 -0
  88. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/web.py +0 -0
  89. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/weibo.py +0 -0
  90. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/yahoo_finance.py +0 -0
  91. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/yelp.py +0 -0
  92. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/youtube.py +0 -0
  93. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/zhihu.py +0 -0
  94. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/platforms/zillow.py +0 -0
  95. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/py.typed +0 -0
  96. {getanyapi-0.82.0 → getanyapi-0.83.0}/src/getanyapi/types.py +0 -0
  97. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/conftest.py +0 -0
  98. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_account.py +0 -0
  99. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_client.py +0 -0
  100. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_durable_requests.py +0 -0
  101. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_envelope.py +0 -0
  102. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_errors.py +0 -0
  103. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_fixture_roundtrip.py +0 -0
  104. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_fixture_sweep.py +0 -0
  105. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_not_found_reason.py +0 -0
  106. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_pagination.py +0 -0
  107. {getanyapi-0.82.0 → getanyapi-0.83.0}/tests/test_transport.py +0 -0
  108. {getanyapi-0.82.0 → getanyapi-0.83.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: getanyapi
3
- Version: 0.82.0
3
+ Version: 0.83.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.82.0"
7
+ version = "0.83.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"
@@ -55,7 +55,7 @@ from .types import (
55
55
  unwrap,
56
56
  )
57
57
 
58
- __version__ = "0.82.0"
58
+ __version__ = "0.83.0"
59
59
 
60
60
  __all__ = [
61
61
  # clients + top-level functions
@@ -9,6 +9,12 @@ from pydantic import BaseModel, ConfigDict, Field
9
9
  from typing_extensions import NotRequired, Required, TypedDict, Unpack
10
10
 
11
11
  from ..types import RequestOptions, RunResult
12
+ from .._pagination import (
13
+ AsyncPaginator,
14
+ Paginator,
15
+ apaginate,
16
+ paginate,
17
+ )
12
18
 
13
19
  if TYPE_CHECKING:
14
20
  from .._async_client import AsyncAnyAPI
@@ -24,22 +30,33 @@ class AppstoreReviewsInput(TypedDict, total=False):
24
30
  """Numeric App Store app ID, the digits at the end of the app's store URL without the 'id' prefix (e.g. 310633997)."""
25
31
  country: NotRequired[str]
26
32
  """Two-letter App Store storefront country code to read reviews from. Default: us."""
33
+ cursor: NotRequired[str]
34
+ """Opaque pagination cursor from a previous response's nextCursor. Omit for the first page; pass it to fetch the next page of reviews."""
27
35
  ignoreSources: NotRequired[list[str]]
28
36
  """Optional. Source ids to skip for this request, taken from this endpoint's `lanes[].source.id`. The cheapest remaining source serves and the price is that of the dearest remaining source. An id that does not serve this endpoint, or that is also in `source`, is rejected as invalid input with no charge; skipping every source is rejected the same way."""
29
37
  limit: NotRequired[int]
30
38
  """Maximum number of results to return (1-100, default 100). Range: 1 to 100."""
31
39
  preferLatencyUnderMs: NotRequired[int]
32
40
  """Optional; omit it and routing is unchanged, with the cheapest source serving. Prefer sources whose typical response time (median over the trailing 30 days, as published on this endpoint's lane health) is under this many milliseconds; among those, the cheapest serves. This can raise your price: when the cheapest source misses the target, a faster and dearer one serves, and you are quoted and charged its price. If no source is that fast the request is still served, by whichever source offers the best speed for its price - it is never refused for being slow. Sources we have not timed are tried last. This is a preference, not a guarantee: the median describes past requests and is not a ceiling on this one, and it excludes any wait this request itself asks for. On a paginated walk it applies to the first page only: later pages stay with the source that page chose, at the price it was quoted. Minimum: 1."""
33
- requireFields: NotRequired[list[Literal["appId", "helpfulVotes", "url", "version"]]]
34
- """Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `helpfulVotes` or `version`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a review that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge."""
41
+ requireFields: NotRequired[
42
+ list[Literal["appId", "helpfulVotes", "nextCursor", "url", "version"]]
43
+ ]
44
+ """Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `helpfulVotes` or `version`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a review that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge. On a paginated walk it applies to the first page only; later pages stay with the source that page chose, at the price it was quoted."""
35
45
  source: NotRequired[list[str]]
36
46
  """Optional. Source ids to prefer, in order, taken from this endpoint's `lanes[].source.id` in /catalog or /apis. Omit it and the cheapest source serves, with automatic failover. Listed sources are tried first in the order given, then the others, unless `allowFallbacks` is false. A single source with `allowFallbacks` false is served only by that source at its price, quoted and charged exactly, with no failover. The price is that of the dearest source that may serve. An id that does not serve this endpoint is rejected as invalid input with no charge; a listed source that is not serving right now is refused with no charge, so omit `source` to be served by another. On a paginated walk, later pages must include the source that served page one, or omit `source`."""
37
47
 
38
48
 
39
49
  class AppstoreReviewsData(BaseModel):
50
+ model_config = ConfigDict(populate_by_name=True)
51
+
40
52
  items: list[AppstoreReviewsItem] = Field(
41
53
  description="Review records: star rating, review title and text, reviewer nickname, app version, and review date. Populated whenever the provider has data for the entity."
42
54
  )
55
+ next_cursor: str | None = Field(
56
+ default=None,
57
+ alias="nextCursor",
58
+ description="Opaque cursor for the next page of reviews, or null when there are no more. Pass it back as cursor to continue.",
59
+ )
43
60
 
44
61
 
45
62
  class AppstoreReviewsItem(BaseModel):
@@ -111,6 +128,29 @@ class AppstoreNamespace:
111
128
  )
112
129
  return RunResult[AppstoreReviewsData].model_validate(raw)
113
130
 
131
+ def iter_reviews(
132
+ self,
133
+ *,
134
+ options: RequestOptions | None = None,
135
+ **input: Unpack[AppstoreReviewsInput],
136
+ ) -> Paginator[AppstoreReviewsItem, AppstoreReviewsData]:
137
+ """Iterate App Store Reviews results, following pagination cursors.
138
+
139
+ Yields validated `AppstoreReviewsItem` items from the `items` field of
140
+ each page. Use `.pages()` on the returned paginator to walk whole
141
+ `RunResult` pages.
142
+ """
143
+ return paginate(
144
+ self._client,
145
+ "appstore.reviews",
146
+ dict(input),
147
+ "items",
148
+ item_model=AppstoreReviewsItem,
149
+ data_model=AppstoreReviewsData,
150
+ bare=False,
151
+ options=options,
152
+ )
153
+
114
154
 
115
155
  class AsyncAppstoreNamespace:
116
156
  """Typed methods for this platform. Attached lazily to the client."""
@@ -138,3 +178,26 @@ class AsyncAppstoreNamespace:
138
178
  "appstore.reviews", dict(input), options
139
179
  )
140
180
  return RunResult[AppstoreReviewsData].model_validate(raw)
181
+
182
+ def iter_reviews(
183
+ self,
184
+ *,
185
+ options: RequestOptions | None = None,
186
+ **input: Unpack[AppstoreReviewsInput],
187
+ ) -> AsyncPaginator[AppstoreReviewsItem, AppstoreReviewsData]:
188
+ """Iterate App Store Reviews results, following pagination cursors.
189
+
190
+ Yields validated `AppstoreReviewsItem` items from the `items` field of
191
+ each page. Use `.pages()` on the returned paginator to walk whole
192
+ `RunResult` pages.
193
+ """
194
+ return apaginate(
195
+ self._client,
196
+ "appstore.reviews",
197
+ dict(input),
198
+ "items",
199
+ item_model=AppstoreReviewsItem,
200
+ data_model=AppstoreReviewsData,
201
+ bare=False,
202
+ options=options,
203
+ )
@@ -165,6 +165,8 @@ class TiktokHashtagVideosInput(TypedDict, total=False):
165
165
 
166
166
  allowFallbacks: NotRequired[bool]
167
167
  """Optional, default true. When false, only the sources listed in `source` may serve; the request is refused with no charge if none of them can. When true, the listed sources are tried first and any other source may serve after them, at the normal price. Default: true."""
168
+ cursor: NotRequired[str]
169
+ """Opaque pagination cursor from a previous response's nextCursor. Omit for the first page; pass it to fetch the next page of videos."""
168
170
  hashtag: Required[str]
169
171
  """TikTok hashtag to fetch videos for, without the # prefix (e.g. booktok)."""
170
172
  ignoreSources: NotRequired[list[str]]
@@ -174,9 +176,13 @@ class TiktokHashtagVideosInput(TypedDict, total=False):
174
176
  preferLatencyUnderMs: NotRequired[int]
175
177
  """Optional; omit it and routing is unchanged, with the cheapest source serving. Prefer sources whose typical response time (median over the trailing 30 days, as published on this endpoint's lane health) is under this many milliseconds; among those, the cheapest serves. This can raise your price: when the cheapest source misses the target, a faster and dearer one serves, and you are quoted and charged its price. If no source is that fast the request is still served, by whichever source offers the best speed for its price - it is never refused for being slow. Sources we have not timed are tried last. This is a preference, not a guarantee: the median describes past requests and is not a ceiling on this one, and it excludes any wait this request itself asks for. On a paginated walk it applies to the first page only: later pages stay with the source that page chose, at the price it was quoted. Minimum: 1."""
176
178
  requireFields: NotRequired[
177
- list[Literal["commentCount", "likeCount", "playCount", "shareCount"]]
179
+ list[
180
+ Literal[
181
+ "commentCount", "likeCount", "nextCursor", "playCount", "shareCount"
182
+ ]
183
+ ]
178
184
  ]
179
- """Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `playCount`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a video that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge. A source that returns only a rounded or shortened value for a field does not count as returning it."""
185
+ """Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `playCount`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a video that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge. A source that returns only a rounded or shortened value for a field does not count as returning it. On a paginated walk it applies to the first page only; later pages stay with the source that page chose, at the price it was quoted."""
180
186
  source: NotRequired[list[str]]
181
187
  """Optional. Source ids to prefer, in order, taken from this endpoint's `lanes[].source.id` in /catalog or /apis. Omit it and the cheapest source serves, with automatic failover. Listed sources are tried first in the order given, then the others, unless `allowFallbacks` is false. A single source with `allowFallbacks` false is served only by that source at its price, quoted and charged exactly, with no failover. The price is that of the dearest source that may serve. An id that does not serve this endpoint is rejected as invalid input with no charge; a listed source that is not serving right now is refused with no charge, so omit `source` to be served by another. On a paginated walk, later pages must include the source that served page one, or omit `source`."""
182
188
 
@@ -1052,9 +1058,16 @@ class TiktokFollowingFollowing(BaseModel):
1052
1058
 
1053
1059
 
1054
1060
  class TiktokHashtagVideosData(BaseModel):
1061
+ model_config = ConfigDict(populate_by_name=True)
1062
+
1055
1063
  items: list[TiktokHashtagVideosItem] = Field(
1056
1064
  description="Recent TikTok video records for the hashtag. Populated whenever the provider has data for the entity."
1057
1065
  )
1066
+ next_cursor: str | None = Field(
1067
+ default=None,
1068
+ alias="nextCursor",
1069
+ description="Opaque cursor for the next page of videos, or null when there are no more. Pass it back as cursor to continue.",
1070
+ )
1058
1071
 
1059
1072
 
1060
1073
  class TiktokHashtagVideosItem(BaseModel):
@@ -2863,6 +2876,29 @@ class TiktokNamespace:
2863
2876
  )
2864
2877
  return RunResult[TiktokHashtagVideosData].model_validate(raw)
2865
2878
 
2879
+ def iter_hashtag_videos(
2880
+ self,
2881
+ *,
2882
+ options: RequestOptions | None = None,
2883
+ **input: Unpack[TiktokHashtagVideosInput],
2884
+ ) -> Paginator[TiktokHashtagVideosItem, TiktokHashtagVideosData]:
2885
+ """Iterate TikTok Hashtag Videos results, following pagination cursors.
2886
+
2887
+ Yields validated `TiktokHashtagVideosItem` items from the `items` field of
2888
+ each page. Use `.pages()` on the returned paginator to walk whole
2889
+ `RunResult` pages.
2890
+ """
2891
+ return paginate(
2892
+ self._client,
2893
+ "tiktok.hashtag_videos",
2894
+ dict(input),
2895
+ "items",
2896
+ item_model=TiktokHashtagVideosItem,
2897
+ data_model=TiktokHashtagVideosData,
2898
+ bare=False,
2899
+ options=options,
2900
+ )
2901
+
2866
2902
  def live(
2867
2903
  self, *, options: RequestOptions | None = None, **input: Unpack[TiktokLiveInput]
2868
2904
  ) -> RunResult[TiktokLiveData]:
@@ -3951,6 +3987,29 @@ class AsyncTiktokNamespace:
3951
3987
  )
3952
3988
  return RunResult[TiktokHashtagVideosData].model_validate(raw)
3953
3989
 
3990
+ def iter_hashtag_videos(
3991
+ self,
3992
+ *,
3993
+ options: RequestOptions | None = None,
3994
+ **input: Unpack[TiktokHashtagVideosInput],
3995
+ ) -> AsyncPaginator[TiktokHashtagVideosItem, TiktokHashtagVideosData]:
3996
+ """Iterate TikTok Hashtag Videos results, following pagination cursors.
3997
+
3998
+ Yields validated `TiktokHashtagVideosItem` items from the `items` field of
3999
+ each page. Use `.pages()` on the returned paginator to walk whole
4000
+ `RunResult` pages.
4001
+ """
4002
+ return apaginate(
4003
+ self._client,
4004
+ "tiktok.hashtag_videos",
4005
+ dict(input),
4006
+ "items",
4007
+ item_model=TiktokHashtagVideosItem,
4008
+ data_model=TiktokHashtagVideosData,
4009
+ bare=False,
4010
+ options=options,
4011
+ )
4012
+
3954
4013
  async def live(
3955
4014
  self, *, options: RequestOptions | None = None, **input: Unpack[TiktokLiveInput]
3956
4015
  ) -> RunResult[TiktokLiveData]:
@@ -128,12 +128,16 @@ class TwitterRepliesInput(TypedDict, total=False):
128
128
 
129
129
  allowFallbacks: NotRequired[bool]
130
130
  """Optional, default true. When false, only the sources listed in `source` may serve; the request is refused with no charge if none of them can. When true, the listed sources are tried first and any other source may serve after them, at the normal price. Default: true."""
131
+ cursor: NotRequired[str]
132
+ """Opaque pagination cursor from a previous response's nextCursor. Omit for the first page; pass it to fetch the next page of replies."""
131
133
  ignoreSources: NotRequired[list[str]]
132
134
  """Optional. Source ids to skip for this request, taken from this endpoint's `lanes[].source.id`. The cheapest remaining source serves and the price is that of the dearest remaining source. An id that does not serve this endpoint, or that is also in `source`, is rejected as invalid input with no charge; skipping every source is rejected the same way."""
133
135
  limit: NotRequired[int]
134
136
  """Maximum number of results to return (1-40, default 40). Per-result lanes cost less at lower limits; a backup that bills its native page may cost up to the advertised request price. Range: 1 to 40."""
135
137
  preferLatencyUnderMs: NotRequired[int]
136
138
  """Optional; omit it and routing is unchanged, with the cheapest source serving. Prefer sources whose typical response time (median over the trailing 30 days, as published on this endpoint's lane health) is under this many milliseconds; among those, the cheapest serves. This can raise your price: when the cheapest source misses the target, a faster and dearer one serves, and you are quoted and charged its price. If no source is that fast the request is still served, by whichever source offers the best speed for its price - it is never refused for being slow. Sources we have not timed are tried last. This is a preference, not a guarantee: the median describes past requests and is not a ceiling on this one, and it excludes any wait this request itself asks for. On a paginated walk it applies to the first page only: later pages stay with the source that page chose, at the price it was quoted. Minimum: 1."""
139
+ requireFields: NotRequired[list[Literal["nextCursor"]]]
140
+ """Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `nextCursor`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. Naming a combination that no single source returns together is refused as invalid input, with no charge. On a paginated walk it applies to the first page only; later pages stay with the source that page chose, at the price it was quoted."""
137
141
  source: NotRequired[list[str]]
138
142
  """Optional. Source ids to prefer, in order, taken from this endpoint's `lanes[].source.id` in /catalog or /apis. Omit it and the cheapest source serves, with automatic failover. Listed sources are tried first in the order given, then the others, unless `allowFallbacks` is false. A single source with `allowFallbacks` false is served only by that source at its price, quoted and charged exactly, with no failover. The price is that of the dearest source that may serve. An id that does not serve this endpoint is rejected as invalid input with no charge; a listed source that is not serving right now is refused with no charge, so omit `source` to be served by another. On a paginated walk, later pages must include the source that served page one, or omit `source`."""
139
143
  url: Required[str]
@@ -696,6 +700,11 @@ class TwitterRepliesData(BaseModel):
696
700
  items: list[TwitterRepliesItem] = Field(
697
701
  description="Reply records for the requested post. Populated whenever the provider has data for the entity."
698
702
  )
703
+ next_cursor: str | None = Field(
704
+ default=None,
705
+ alias="nextCursor",
706
+ description="Opaque cursor for the next page of replies, or null when there are no more. Pass it back as cursor to continue.",
707
+ )
699
708
 
700
709
 
701
710
  class TwitterRepliesItem(BaseModel):
@@ -1659,6 +1668,29 @@ class TwitterNamespace:
1659
1668
  )
1660
1669
  return RunResult[TwitterRepliesData].model_validate(raw)
1661
1670
 
1671
+ def iter_replies(
1672
+ self,
1673
+ *,
1674
+ options: RequestOptions | None = None,
1675
+ **input: Unpack[TwitterRepliesInput],
1676
+ ) -> Paginator[TwitterRepliesItem, TwitterRepliesData]:
1677
+ """Iterate X / Twitter Post Replies results, following pagination cursors.
1678
+
1679
+ Yields validated `TwitterRepliesItem` items from the `items` field of
1680
+ each page. Use `.pages()` on the returned paginator to walk whole
1681
+ `RunResult` pages.
1682
+ """
1683
+ return paginate(
1684
+ self._client,
1685
+ "twitter.replies",
1686
+ dict(input),
1687
+ "items",
1688
+ item_model=TwitterRepliesItem,
1689
+ data_model=TwitterRepliesData,
1690
+ bare=False,
1691
+ options=options,
1692
+ )
1693
+
1662
1694
  def search(
1663
1695
  self,
1664
1696
  *,
@@ -2174,6 +2206,29 @@ class AsyncTwitterNamespace:
2174
2206
  )
2175
2207
  return RunResult[TwitterRepliesData].model_validate(raw)
2176
2208
 
2209
+ def iter_replies(
2210
+ self,
2211
+ *,
2212
+ options: RequestOptions | None = None,
2213
+ **input: Unpack[TwitterRepliesInput],
2214
+ ) -> AsyncPaginator[TwitterRepliesItem, TwitterRepliesData]:
2215
+ """Iterate X / Twitter Post Replies results, following pagination cursors.
2216
+
2217
+ Yields validated `TwitterRepliesItem` items from the `items` field of
2218
+ each page. Use `.pages()` on the returned paginator to walk whole
2219
+ `RunResult` pages.
2220
+ """
2221
+ return apaginate(
2222
+ self._client,
2223
+ "twitter.replies",
2224
+ dict(input),
2225
+ "items",
2226
+ item_model=TwitterRepliesItem,
2227
+ data_model=TwitterRepliesData,
2228
+ bare=False,
2229
+ options=options,
2230
+ )
2231
+
2177
2232
  async def search(
2178
2233
  self,
2179
2234
  *,
File without changes
File without changes
File without changes
File without changes