getanyapi 0.1.0__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.
Files changed (68) hide show
  1. getanyapi/__init__.py +76 -0
  2. getanyapi/_account.py +132 -0
  3. getanyapi/_async_client.py +215 -0
  4. getanyapi/_client.py +274 -0
  5. getanyapi/_errors.py +115 -0
  6. getanyapi/_pagination.py +295 -0
  7. getanyapi/_transport.py +239 -0
  8. getanyapi/platforms/__init__.py +89 -0
  9. getanyapi/platforms/ahrefs.py +384 -0
  10. getanyapi/platforms/airbnb.py +120 -0
  11. getanyapi/platforms/alibaba.py +95 -0
  12. getanyapi/platforms/amazon.py +442 -0
  13. getanyapi/platforms/appstore.py +95 -0
  14. getanyapi/platforms/bluesky.py +215 -0
  15. getanyapi/platforms/booking.py +128 -0
  16. getanyapi/platforms/coinmarketcap.py +113 -0
  17. getanyapi/platforms/congress.py +106 -0
  18. getanyapi/platforms/dexscreener.py +104 -0
  19. getanyapi/platforms/ebay.py +215 -0
  20. getanyapi/platforms/email.py +166 -0
  21. getanyapi/platforms/facebook.py +2324 -0
  22. getanyapi/platforms/fiverr.py +122 -0
  23. getanyapi/platforms/github.py +954 -0
  24. getanyapi/platforms/glassdoor.py +93 -0
  25. getanyapi/platforms/google.py +232 -0
  26. getanyapi/platforms/google_ads.py +380 -0
  27. getanyapi/platforms/google_finance.py +170 -0
  28. getanyapi/platforms/google_shopping.py +103 -0
  29. getanyapi/platforms/hackernews.py +276 -0
  30. getanyapi/platforms/indeed.py +114 -0
  31. getanyapi/platforms/instagram.py +1868 -0
  32. getanyapi/platforms/linkedin.py +1064 -0
  33. getanyapi/platforms/maps.py +412 -0
  34. getanyapi/platforms/pandaexpress.py +262 -0
  35. getanyapi/platforms/person.py +96 -0
  36. getanyapi/platforms/pinterest.py +96 -0
  37. getanyapi/platforms/playstore.py +99 -0
  38. getanyapi/platforms/polymarket.py +109 -0
  39. getanyapi/platforms/realtor.py +104 -0
  40. getanyapi/platforms/reddit.py +582 -0
  41. getanyapi/platforms/redfin.py +95 -0
  42. getanyapi/platforms/rednote.py +807 -0
  43. getanyapi/platforms/sec.py +118 -0
  44. getanyapi/platforms/semrush.py +358 -0
  45. getanyapi/platforms/snapchat.py +146 -0
  46. getanyapi/platforms/social.py +105 -0
  47. getanyapi/platforms/spotify.py +588 -0
  48. getanyapi/platforms/substack.py +142 -0
  49. getanyapi/platforms/threads.py +358 -0
  50. getanyapi/platforms/tiktok.py +1827 -0
  51. getanyapi/platforms/tiktok_shop.py +536 -0
  52. getanyapi/platforms/tripadvisor.py +180 -0
  53. getanyapi/platforms/trustpilot.py +114 -0
  54. getanyapi/platforms/truthsocial.py +226 -0
  55. getanyapi/platforms/twitter.py +798 -0
  56. getanyapi/platforms/upwork.py +119 -0
  57. getanyapi/platforms/walmart.py +93 -0
  58. getanyapi/platforms/web.py +264 -0
  59. getanyapi/platforms/whatsapp.py +91 -0
  60. getanyapi/platforms/yahoo_finance.py +95 -0
  61. getanyapi/platforms/yelp.py +141 -0
  62. getanyapi/platforms/youtube.py +1452 -0
  63. getanyapi/platforms/zillow.py +218 -0
  64. getanyapi/py.typed +0 -0
  65. getanyapi/types.py +170 -0
  66. getanyapi-0.1.0.dist-info/METADATA +155 -0
  67. getanyapi-0.1.0.dist-info/RECORD +68 -0
  68. getanyapi-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,582 @@
1
+ # Generated - do not edit. Regenerate with: pnpm generate
2
+ """Generated namespace module for the reddit platform."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import Literal, TYPE_CHECKING
7
+
8
+ from pydantic import BaseModel, ConfigDict, Field
9
+ from typing_extensions import NotRequired, Required, TypedDict, Unpack
10
+
11
+ from ..types import BareRunResult, RequestOptions, RunResult
12
+ from .._pagination import (
13
+ AsyncPaginator,
14
+ Paginator,
15
+ apaginate,
16
+ paginate,
17
+ )
18
+
19
+ if TYPE_CHECKING:
20
+ from .._async_client import AsyncAnyAPI
21
+ from .._client import AnyAPI
22
+
23
+
24
+ class RedditPostCommentsInput(TypedDict, total=False):
25
+ """Input for Reddit Post Comments."""
26
+
27
+ cursor: NotRequired[str]
28
+ """Cursor from a previous response for more comments."""
29
+ url: Required[str]
30
+ """Full Reddit post URL."""
31
+
32
+
33
+ class RedditPostTranscriptInput(TypedDict, total=False):
34
+ """Input for Reddit Post Transcript."""
35
+
36
+ language: NotRequired[str]
37
+ """Optional two-letter language code (defaults to en)."""
38
+ url: Required[str]
39
+ """Reddit post URL or direct v.redd.it video URL to transcribe."""
40
+
41
+
42
+ class RedditSearchInput(TypedDict, total=False):
43
+ """Input for Reddit Search."""
44
+
45
+ cursor: NotRequired[str]
46
+ """Opaque pagination cursor from a previous response's nextCursor. Omit for the first page; pass it to fetch the next page of results."""
47
+ query: Required[str]
48
+ """Free-text search across all of Reddit. Reddit's field operators are supported inside the string: subreddit:<name> to scope to one subreddit, author:<user>, title:<text>, selftext:<text>, self:yes|no, nsfw:yes|no, and boolean AND/OR/NOT. To restrict to a single subreddit you can use subreddit:<name> here, or use the reddit.subreddit_posts SKU for a plain subreddit listing."""
49
+ sort: NotRequired[Literal["relevance", "hot", "top", "new", "comments"]]
50
+ """Result sort order."""
51
+ timeframe: NotRequired[Literal["hour", "day", "week", "month", "year", "all"]]
52
+ """Time window for results."""
53
+
54
+
55
+ class RedditSubredditDetailsInput(TypedDict, total=False):
56
+ """Input for Reddit Subreddit Details."""
57
+
58
+ subreddit: Required[str]
59
+ """Subreddit name without the r/ prefix. Case-sensitive (e.g. "AskReddit", not "askreddit")."""
60
+
61
+
62
+ class RedditSubredditPostsInput(TypedDict, total=False):
63
+ """Input for Reddit Subreddit Posts."""
64
+
65
+ after: NotRequired[str]
66
+ """Pagination cursor from a previous response (its `nextCursor`). Fetches the page that follows; omit for the first page."""
67
+ limit: NotRequired[int]
68
+ """Requested number of posts. Note: the upstream returns one page (about 25 posts) per call; values larger than a page are not delivered in a single response. To fetch more, page with the `after` cursor returned as `nextCursor`. Range: 1 to 100. Default: 25."""
69
+ sort: NotRequired[Literal["hot", "new", "top"]]
70
+ """Listing sort order. Default: hot."""
71
+ subreddit: Required[str]
72
+ """Subreddit name without the leading r/ (e.g. "golang")."""
73
+ timeframe: NotRequired[Literal["all", "year", "month", "week", "day", "hour"]]
74
+ """Time window, applied when sort is "top" (e.g. "year" for the year's top posts). Ignored for hot/new. Omit to default to the current day for top."""
75
+
76
+
77
+ class RedditSubredditSearchInput(TypedDict, total=False):
78
+ """Input for Reddit Subreddit Search."""
79
+
80
+ cursor: NotRequired[str]
81
+ """Optional pagination token from a previous response."""
82
+ query: NotRequired[str]
83
+ """Optional search query to match posts (e.g. 'push ups')."""
84
+ sort: NotRequired[str]
85
+ """Optional sort order: relevance, hot, top, new, comments."""
86
+ subreddit: Required[str]
87
+ """Subreddit name without the r/ prefix (e.g. 'Fitness')."""
88
+ timeframe: NotRequired[str]
89
+ """Optional time filter: all, year, month, week, day, hour."""
90
+
91
+
92
+ class RedditPostCommentsData(BaseModel):
93
+ comments: list[RedditPostCommentsComment]
94
+
95
+
96
+ class RedditPostCommentsComment(BaseModel):
97
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
98
+
99
+ author: str = Field(description="Commenter username, without the u/ prefix.")
100
+ body: str = Field(description="Comment text, as Markdown.")
101
+ created_utc: float = Field(
102
+ alias="createdUtc",
103
+ description="Comment creation time as a UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.",
104
+ )
105
+ id: str = Field(description="Reddit comment ID (base-36, without the t1_ prefix).")
106
+ url: str = Field(description="Permalink to the comment on reddit.com.")
107
+
108
+
109
+ class RedditPostTranscriptData(BaseModel):
110
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
111
+
112
+ language: str
113
+ post_id: str = Field(alias="postId")
114
+ transcript: str
115
+ transcript_not_available: bool = Field(alias="transcriptNotAvailable")
116
+
117
+
118
+ class RedditSearchData(BaseModel):
119
+ model_config = ConfigDict(populate_by_name=True)
120
+
121
+ next_cursor: str = Field(
122
+ alias="nextCursor",
123
+ description="Cursor for the next page of results; pass it back as the `cursor` input to fetch the following page. Empty string when there are no more results.",
124
+ )
125
+ posts: list[RedditSearchPost]
126
+
127
+
128
+ class RedditSearchPost(BaseModel):
129
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
130
+
131
+ author: str = Field(description="Author username, without the u/ prefix.")
132
+ created_utc: float = Field(
133
+ alias="createdUtc",
134
+ description="Post creation time as a UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.",
135
+ )
136
+ id: str = Field(description="Reddit post ID (base-36, without the t3_ prefix).")
137
+ num_comments: int = Field(
138
+ alias="numComments", description="Total number of comments on the post."
139
+ )
140
+ permalink: str = Field(
141
+ description='Canonical reddit.com thread path for the post (e.g. "/r/golang/comments/abc123/..."). Differs from url, which is the destination link. Empty if the upstream omits it.'
142
+ )
143
+ score: int = Field(description="Net score (upvotes minus downvotes) at fetch time.")
144
+ subreddit: str = Field(description="Subreddit name, without the r/ prefix.")
145
+ title: str = Field(description="Post title.")
146
+ url: str = Field(
147
+ description="The post's destination link (the external URL for link posts, or the thread URL for self posts)."
148
+ )
149
+
150
+
151
+ class RedditSubredditDetailsData(BaseModel):
152
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
153
+
154
+ advertiser_category: str = Field(alias="advertiserCategory")
155
+ created_at: str = Field(alias="createdAt")
156
+ description: str
157
+ icon_url: str = Field(alias="iconUrl")
158
+ id: str = Field(description='Reddit fullname, e.g. "t5_2qh1i".')
159
+ name: str
160
+ weekly_active_users: int = Field(alias="weeklyActiveUsers")
161
+
162
+
163
+ class RedditSubredditPostsData(BaseModel):
164
+ model_config = ConfigDict(populate_by_name=True)
165
+
166
+ next_cursor: str = Field(
167
+ alias="nextCursor",
168
+ description="Cursor for the next page of results; pass it back as the `after` input to fetch the following page. Empty string when there are no more results.",
169
+ )
170
+ posts: list[RedditSubredditPostsPost]
171
+
172
+
173
+ class RedditSubredditPostsPost(BaseModel):
174
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
175
+
176
+ author: str = Field(description="Author username, without the u/ prefix.")
177
+ created_utc: float = Field(
178
+ alias="createdUtc",
179
+ description="Post creation time as a UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.",
180
+ )
181
+ id: str = Field(description="Reddit post ID (base-36, without the t3_ prefix).")
182
+ num_comments: int = Field(
183
+ alias="numComments", description="Total number of comments on the post."
184
+ )
185
+ permalink: str = Field(
186
+ description='Canonical reddit.com thread path for the post (e.g. "/r/golang/comments/abc123/..."). Differs from url, which is the destination link. Empty if the upstream omits it.'
187
+ )
188
+ score: int = Field(description="Net score (upvotes minus downvotes) at fetch time.")
189
+ subreddit: str = Field(description="Subreddit name, without the r/ prefix.")
190
+ title: str = Field(description="Post title.")
191
+ url: str = Field(
192
+ description="The post's destination link (the external URL for link posts, or the thread URL for self posts)."
193
+ )
194
+
195
+
196
+ class RedditSubredditSearchData(BaseModel):
197
+ model_config = ConfigDict(populate_by_name=True)
198
+
199
+ next_cursor: str = Field(alias="nextCursor")
200
+ posts: list[RedditSubredditSearchPost]
201
+
202
+
203
+ class RedditSubredditSearchPost(BaseModel):
204
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
205
+
206
+ author: str = Field(description="Author username, without the u/ prefix.")
207
+ created_utc: float = Field(
208
+ alias="createdUtc",
209
+ description="Post creation time as a UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.",
210
+ )
211
+ id: str = Field(description="Reddit post ID (base-36, without the t3_ prefix).")
212
+ nsfw: bool = Field(description="Whether the post is marked NSFW (over 18).")
213
+ num_comments: int = Field(
214
+ alias="numComments", description="Total number of comments on the post."
215
+ )
216
+ permalink: str = Field(
217
+ description='Canonical reddit.com thread path for the post (e.g. "/r/golang/comments/abc123/..."). Differs from url, which is the destination link.'
218
+ )
219
+ score: int = Field(description="Net score (upvotes minus downvotes) at fetch time.")
220
+ subreddit: str = Field(description="Subreddit name, without the r/ prefix.")
221
+ title: str = Field(description="Post title.")
222
+ url: str = Field(
223
+ description="The post's destination link (the external URL for link posts, or the thread URL for self posts)."
224
+ )
225
+
226
+
227
+ class RedditNamespace:
228
+ """Typed methods for this platform. Attached lazily to the client."""
229
+
230
+ def __init__(self, client: "AnyAPI") -> None:
231
+ self._client = client
232
+
233
+ def post_comments(
234
+ self,
235
+ *,
236
+ options: RequestOptions | None = None,
237
+ **input: Unpack[RedditPostCommentsInput],
238
+ ) -> BareRunResult[RedditPostCommentsData]:
239
+ """Reddit Post Comments
240
+
241
+ List the top-level comments on a Reddit post by URL (author, body, score,
242
+ timestamp), normalized across providers with transparent failover.
243
+
244
+ Price: $0.002 per request.
245
+
246
+ Example:
247
+ res = client.reddit.post_comments(url="https://www.reddit.com/r/IAmA/comments/z1c9z/i_am_barack_obama_president_of_the_united_states/")
248
+ """
249
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
250
+ "reddit.post_comments", dict(input), options
251
+ )
252
+ return BareRunResult[RedditPostCommentsData].model_validate(raw)
253
+
254
+ def post_transcript(
255
+ self,
256
+ *,
257
+ options: RequestOptions | None = None,
258
+ **input: Unpack[RedditPostTranscriptInput],
259
+ ) -> RunResult[RedditPostTranscriptData]:
260
+ """Reddit Post Transcript
261
+
262
+ Extract the spoken transcript from a Reddit video post by URL, normalized
263
+ across providers with transparent failover.
264
+
265
+ Price: $0.002 per request.
266
+
267
+ Example:
268
+ res = client.reddit.post_transcript(url="https://www.reddit.com/r/youseeingthisshit/comments/1oiu9xm/")
269
+ """
270
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
271
+ "reddit.post_transcript", dict(input), options
272
+ )
273
+ return RunResult[RedditPostTranscriptData].model_validate(raw)
274
+
275
+ def search(
276
+ self,
277
+ *,
278
+ options: RequestOptions | None = None,
279
+ **input: Unpack[RedditSearchInput],
280
+ ) -> BareRunResult[RedditSearchData]:
281
+ """Reddit Search
282
+
283
+ Search Reddit posts across all subreddits by query, normalized across
284
+ providers with transparent failover.
285
+
286
+ Price: $0.001 per request.
287
+
288
+ Example:
289
+ res = client.reddit.search(query="mechanical keyboard")
290
+ """
291
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
292
+ "reddit.search", dict(input), options
293
+ )
294
+ return BareRunResult[RedditSearchData].model_validate(raw)
295
+
296
+ def iter_search(
297
+ self,
298
+ *,
299
+ options: RequestOptions | None = None,
300
+ **input: Unpack[RedditSearchInput],
301
+ ) -> Paginator[RedditSearchPost, RedditSearchData]:
302
+ """Iterate Reddit Search results, following pagination cursors.
303
+
304
+ Yields validated `RedditSearchPost` items from the `posts` field of
305
+ each page. Use `.pages()` on the returned paginator to walk whole
306
+ `BareRunResult` pages.
307
+ """
308
+ return paginate(
309
+ self._client,
310
+ "reddit.search",
311
+ dict(input),
312
+ "posts",
313
+ item_model=RedditSearchPost,
314
+ data_model=RedditSearchData,
315
+ bare=True,
316
+ options=options,
317
+ )
318
+
319
+ def subreddit_details(
320
+ self,
321
+ *,
322
+ options: RequestOptions | None = None,
323
+ **input: Unpack[RedditSubredditDetailsInput],
324
+ ) -> RunResult[RedditSubredditDetailsData]:
325
+ """Reddit Subreddit Details
326
+
327
+ Fetch a subreddit's metadata - weekly active users, description, and
328
+ category - normalized across providers with transparent failover.
329
+
330
+ Price: $0.001 per request.
331
+
332
+ Example:
333
+ res = client.reddit.subreddit_details(subreddit="programming")
334
+ """
335
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
336
+ "reddit.subreddit_details", dict(input), options
337
+ )
338
+ return RunResult[RedditSubredditDetailsData].model_validate(raw)
339
+
340
+ def subreddit_posts(
341
+ self,
342
+ *,
343
+ options: RequestOptions | None = None,
344
+ **input: Unpack[RedditSubredditPostsInput],
345
+ ) -> BareRunResult[RedditSubredditPostsData]:
346
+ """Reddit Subreddit Posts
347
+
348
+ Fetch posts from a subreddit listing (hot, new, or top), normalized across
349
+ providers with transparent failover.
350
+
351
+ Price: $0.002 per request.
352
+
353
+ Example:
354
+ res = client.reddit.subreddit_posts(limit=5, subreddit="programming")
355
+ """
356
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
357
+ "reddit.subreddit_posts", dict(input), options
358
+ )
359
+ return BareRunResult[RedditSubredditPostsData].model_validate(raw)
360
+
361
+ def subreddit_search(
362
+ self,
363
+ *,
364
+ options: RequestOptions | None = None,
365
+ **input: Unpack[RedditSubredditSearchInput],
366
+ ) -> RunResult[RedditSubredditSearchData]:
367
+ """Reddit Subreddit Search
368
+
369
+ Search posts within a single subreddit by query, sort, and timeframe,
370
+ normalized across providers with transparent failover.
371
+
372
+ Price: $0.002 per request.
373
+
374
+ Example:
375
+ res = client.reddit.subreddit_search(query="push ups", subreddit="Fitness")
376
+ """
377
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
378
+ "reddit.subreddit_search", dict(input), options
379
+ )
380
+ return RunResult[RedditSubredditSearchData].model_validate(raw)
381
+
382
+ def iter_subreddit_search(
383
+ self,
384
+ *,
385
+ options: RequestOptions | None = None,
386
+ **input: Unpack[RedditSubredditSearchInput],
387
+ ) -> Paginator[RedditSubredditSearchPost, RedditSubredditSearchData]:
388
+ """Iterate Reddit Subreddit Search results, following pagination cursors.
389
+
390
+ Yields validated `RedditSubredditSearchPost` items from the `posts` field of
391
+ each page. Use `.pages()` on the returned paginator to walk whole
392
+ `RunResult` pages.
393
+ """
394
+ return paginate(
395
+ self._client,
396
+ "reddit.subreddit_search",
397
+ dict(input),
398
+ "posts",
399
+ item_model=RedditSubredditSearchPost,
400
+ data_model=RedditSubredditSearchData,
401
+ bare=False,
402
+ options=options,
403
+ )
404
+
405
+
406
+ class AsyncRedditNamespace:
407
+ """Typed methods for this platform. Attached lazily to the client."""
408
+
409
+ def __init__(self, client: "AsyncAnyAPI") -> None:
410
+ self._client = client
411
+
412
+ async def post_comments(
413
+ self,
414
+ *,
415
+ options: RequestOptions | None = None,
416
+ **input: Unpack[RedditPostCommentsInput],
417
+ ) -> BareRunResult[RedditPostCommentsData]:
418
+ """Reddit Post Comments
419
+
420
+ List the top-level comments on a Reddit post by URL (author, body, score,
421
+ timestamp), normalized across providers with transparent failover.
422
+
423
+ Price: $0.002 per request.
424
+
425
+ Example:
426
+ res = client.reddit.post_comments(url="https://www.reddit.com/r/IAmA/comments/z1c9z/i_am_barack_obama_president_of_the_united_states/")
427
+ """
428
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
429
+ "reddit.post_comments", dict(input), options
430
+ )
431
+ return BareRunResult[RedditPostCommentsData].model_validate(raw)
432
+
433
+ async def post_transcript(
434
+ self,
435
+ *,
436
+ options: RequestOptions | None = None,
437
+ **input: Unpack[RedditPostTranscriptInput],
438
+ ) -> RunResult[RedditPostTranscriptData]:
439
+ """Reddit Post Transcript
440
+
441
+ Extract the spoken transcript from a Reddit video post by URL, normalized
442
+ across providers with transparent failover.
443
+
444
+ Price: $0.002 per request.
445
+
446
+ Example:
447
+ res = client.reddit.post_transcript(url="https://www.reddit.com/r/youseeingthisshit/comments/1oiu9xm/")
448
+ """
449
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
450
+ "reddit.post_transcript", dict(input), options
451
+ )
452
+ return RunResult[RedditPostTranscriptData].model_validate(raw)
453
+
454
+ async def search(
455
+ self,
456
+ *,
457
+ options: RequestOptions | None = None,
458
+ **input: Unpack[RedditSearchInput],
459
+ ) -> BareRunResult[RedditSearchData]:
460
+ """Reddit Search
461
+
462
+ Search Reddit posts across all subreddits by query, normalized across
463
+ providers with transparent failover.
464
+
465
+ Price: $0.001 per request.
466
+
467
+ Example:
468
+ res = client.reddit.search(query="mechanical keyboard")
469
+ """
470
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
471
+ "reddit.search", dict(input), options
472
+ )
473
+ return BareRunResult[RedditSearchData].model_validate(raw)
474
+
475
+ def iter_search(
476
+ self,
477
+ *,
478
+ options: RequestOptions | None = None,
479
+ **input: Unpack[RedditSearchInput],
480
+ ) -> AsyncPaginator[RedditSearchPost, RedditSearchData]:
481
+ """Iterate Reddit Search results, following pagination cursors.
482
+
483
+ Yields validated `RedditSearchPost` items from the `posts` field of
484
+ each page. Use `.pages()` on the returned paginator to walk whole
485
+ `BareRunResult` pages.
486
+ """
487
+ return apaginate(
488
+ self._client,
489
+ "reddit.search",
490
+ dict(input),
491
+ "posts",
492
+ item_model=RedditSearchPost,
493
+ data_model=RedditSearchData,
494
+ bare=True,
495
+ options=options,
496
+ )
497
+
498
+ async def subreddit_details(
499
+ self,
500
+ *,
501
+ options: RequestOptions | None = None,
502
+ **input: Unpack[RedditSubredditDetailsInput],
503
+ ) -> RunResult[RedditSubredditDetailsData]:
504
+ """Reddit Subreddit Details
505
+
506
+ Fetch a subreddit's metadata - weekly active users, description, and
507
+ category - normalized across providers with transparent failover.
508
+
509
+ Price: $0.001 per request.
510
+
511
+ Example:
512
+ res = client.reddit.subreddit_details(subreddit="programming")
513
+ """
514
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
515
+ "reddit.subreddit_details", dict(input), options
516
+ )
517
+ return RunResult[RedditSubredditDetailsData].model_validate(raw)
518
+
519
+ async def subreddit_posts(
520
+ self,
521
+ *,
522
+ options: RequestOptions | None = None,
523
+ **input: Unpack[RedditSubredditPostsInput],
524
+ ) -> BareRunResult[RedditSubredditPostsData]:
525
+ """Reddit Subreddit Posts
526
+
527
+ Fetch posts from a subreddit listing (hot, new, or top), normalized across
528
+ providers with transparent failover.
529
+
530
+ Price: $0.002 per request.
531
+
532
+ Example:
533
+ res = client.reddit.subreddit_posts(limit=5, subreddit="programming")
534
+ """
535
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
536
+ "reddit.subreddit_posts", dict(input), options
537
+ )
538
+ return BareRunResult[RedditSubredditPostsData].model_validate(raw)
539
+
540
+ async def subreddit_search(
541
+ self,
542
+ *,
543
+ options: RequestOptions | None = None,
544
+ **input: Unpack[RedditSubredditSearchInput],
545
+ ) -> RunResult[RedditSubredditSearchData]:
546
+ """Reddit Subreddit Search
547
+
548
+ Search posts within a single subreddit by query, sort, and timeframe,
549
+ normalized across providers with transparent failover.
550
+
551
+ Price: $0.002 per request.
552
+
553
+ Example:
554
+ res = client.reddit.subreddit_search(query="push ups", subreddit="Fitness")
555
+ """
556
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
557
+ "reddit.subreddit_search", dict(input), options
558
+ )
559
+ return RunResult[RedditSubredditSearchData].model_validate(raw)
560
+
561
+ def iter_subreddit_search(
562
+ self,
563
+ *,
564
+ options: RequestOptions | None = None,
565
+ **input: Unpack[RedditSubredditSearchInput],
566
+ ) -> AsyncPaginator[RedditSubredditSearchPost, RedditSubredditSearchData]:
567
+ """Iterate Reddit Subreddit Search results, following pagination cursors.
568
+
569
+ Yields validated `RedditSubredditSearchPost` items from the `posts` field of
570
+ each page. Use `.pages()` on the returned paginator to walk whole
571
+ `RunResult` pages.
572
+ """
573
+ return apaginate(
574
+ self._client,
575
+ "reddit.subreddit_search",
576
+ dict(input),
577
+ "posts",
578
+ item_model=RedditSubredditSearchPost,
579
+ data_model=RedditSubredditSearchData,
580
+ bare=False,
581
+ options=options,
582
+ )
@@ -0,0 +1,95 @@
1
+ # Generated - do not edit. Regenerate with: pnpm generate
2
+ """Generated namespace module for the redfin platform."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import TYPE_CHECKING
7
+
8
+ from pydantic import BaseModel, ConfigDict, Field
9
+ from typing_extensions import NotRequired, Required, TypedDict, Unpack
10
+
11
+ from ..types import RequestOptions, RunResult
12
+
13
+ if TYPE_CHECKING:
14
+ from .._async_client import AsyncAnyAPI
15
+ from .._client import AnyAPI
16
+
17
+
18
+ class RedfinSearchInput(TypedDict, total=False):
19
+ """Input for Redfin Search."""
20
+
21
+ limit: NotRequired[int]
22
+ """Maximum number of results to return (1-25, default 25). You are billed per result returned, so a lower limit costs less. Range: 1 to 25."""
23
+ url: Required[str]
24
+ """Redfin search results URL for a city, ZIP or map area (e.g. https://www.redfin.com/city/30772/CA/San-Francisco)."""
25
+
26
+
27
+ class RedfinSearchData(BaseModel):
28
+ items: list[RedfinSearchItem] = Field(
29
+ description="Home listing records: address, price, beds, baths, square footage, and listing status."
30
+ )
31
+
32
+
33
+ class RedfinSearchItem(BaseModel):
34
+ model_config = ConfigDict(extra="allow")
35
+
36
+ title: str | None = None
37
+ url: str
38
+
39
+
40
+ class RedfinNamespace:
41
+ """Typed methods for this platform. Attached lazily to the client."""
42
+
43
+ def __init__(self, client: "AnyAPI") -> None:
44
+ self._client = client
45
+
46
+ def search(
47
+ self,
48
+ *,
49
+ options: RequestOptions | None = None,
50
+ **input: Unpack[RedfinSearchInput],
51
+ ) -> RunResult[RedfinSearchData]:
52
+ """Redfin Search
53
+
54
+ Run a Redfin map search by URL and get matching home listings (price,
55
+ address, beds, baths, status) as normalized JSON with flat per-request USD
56
+ pricing.
57
+
58
+ Price: $0.0027 per request plus $0.00043 per result.
59
+
60
+ Example:
61
+ res = client.redfin.search(limit=3, url="https://www.redfin.com/city/30818/TX/Austin")
62
+ """
63
+ raw = self._client._run_raw( # pyright: ignore[reportPrivateUsage]
64
+ "redfin.search", dict(input), options
65
+ )
66
+ return RunResult[RedfinSearchData].model_validate(raw)
67
+
68
+
69
+ class AsyncRedfinNamespace:
70
+ """Typed methods for this platform. Attached lazily to the client."""
71
+
72
+ def __init__(self, client: "AsyncAnyAPI") -> None:
73
+ self._client = client
74
+
75
+ async def search(
76
+ self,
77
+ *,
78
+ options: RequestOptions | None = None,
79
+ **input: Unpack[RedfinSearchInput],
80
+ ) -> RunResult[RedfinSearchData]:
81
+ """Redfin Search
82
+
83
+ Run a Redfin map search by URL and get matching home listings (price,
84
+ address, beds, baths, status) as normalized JSON with flat per-request USD
85
+ pricing.
86
+
87
+ Price: $0.0027 per request plus $0.00043 per result.
88
+
89
+ Example:
90
+ res = client.redfin.search(limit=3, url="https://www.redfin.com/city/30818/TX/Austin")
91
+ """
92
+ raw = await self._client._arun_raw( # pyright: ignore[reportPrivateUsage]
93
+ "redfin.search", dict(input), options
94
+ )
95
+ return RunResult[RedfinSearchData].model_validate(raw)