rephonic 1.0.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.
- rephonic-1.0.0/.gitignore +47 -0
- rephonic-1.0.0/LICENSE +21 -0
- rephonic-1.0.0/PKG-INFO +279 -0
- rephonic-1.0.0/README.md +221 -0
- rephonic-1.0.0/pyproject.toml +89 -0
- rephonic-1.0.0/src/rephonic/__init__.py +47 -0
- rephonic-1.0.0/src/rephonic/_base_client.py +266 -0
- rephonic-1.0.0/src/rephonic/_client.py +148 -0
- rephonic-1.0.0/src/rephonic/_exceptions.py +93 -0
- rephonic-1.0.0/src/rephonic/_version.py +1 -0
- rephonic-1.0.0/src/rephonic/pagination.py +84 -0
- rephonic-1.0.0/src/rephonic/py.typed +0 -0
- rephonic-1.0.0/src/rephonic/resources/__init__.py +21 -0
- rephonic-1.0.0/src/rephonic/resources/account.py +28 -0
- rephonic-1.0.0/src/rephonic/resources/charts.py +61 -0
- rephonic-1.0.0/src/rephonic/resources/common.py +68 -0
- rephonic-1.0.0/src/rephonic/resources/episodes.py +107 -0
- rephonic-1.0.0/src/rephonic/resources/podcasts.py +130 -0
- rephonic-1.0.0/src/rephonic/resources/search.py +221 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.so
|
|
5
|
+
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
share/python-wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
MANIFEST
|
|
24
|
+
|
|
25
|
+
.env
|
|
26
|
+
.venv
|
|
27
|
+
venv/
|
|
28
|
+
env/
|
|
29
|
+
ENV/
|
|
30
|
+
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.mypy_cache/
|
|
33
|
+
.ruff_cache/
|
|
34
|
+
htmlcov/
|
|
35
|
+
.coverage
|
|
36
|
+
.coverage.*
|
|
37
|
+
coverage.xml
|
|
38
|
+
*.cover
|
|
39
|
+
.hypothesis/
|
|
40
|
+
|
|
41
|
+
.idea/
|
|
42
|
+
.vscode/
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
.DS_Store
|
|
46
|
+
|
|
47
|
+
*.egg-info/
|
rephonic-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rephonic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
rephonic-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rephonic
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python client for the Rephonic podcast API.
|
|
5
|
+
Project-URL: Homepage, https://rephonic.com
|
|
6
|
+
Project-URL: Documentation, https://rephonic.com/developers
|
|
7
|
+
Project-URL: Repository, https://github.com/getrephonic/rephonic-python
|
|
8
|
+
Project-URL: Issues, https://github.com/getrephonic/rephonic-python/issues
|
|
9
|
+
Author-email: Rephonic <support@rephonic.com>
|
|
10
|
+
License: MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 Rephonic
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Keywords: api,charts,demographics,podcast,podcasts,rephonic,sdk,transcripts
|
|
33
|
+
Classifier: Development Status :: 4 - Beta
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Operating System :: OS Independent
|
|
37
|
+
Classifier: Programming Language :: Python :: 3
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
44
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
45
|
+
Classifier: Typing :: Typed
|
|
46
|
+
Requires-Python: >=3.8
|
|
47
|
+
Requires-Dist: httpx<1,>=0.24
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
50
|
+
Requires-Dist: mypy>=1.5; extra == 'dev'
|
|
51
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
52
|
+
Requires-Dist: pytest-cov>=4; extra == 'dev'
|
|
53
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
54
|
+
Requires-Dist: respx>=0.20; extra == 'dev'
|
|
55
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
56
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
57
|
+
Description-Content-Type: text/markdown
|
|
58
|
+
|
|
59
|
+
# Rephonic Python
|
|
60
|
+
|
|
61
|
+
Official Python client for the [Rephonic](https://rephonic.com) podcast API — covering 3+ million podcasts with listener estimates, demographics, contact details, chart rankings, episodes, full transcripts, and more.
|
|
62
|
+
|
|
63
|
+
This library is a thin, typed wrapper around the [Rephonic API](https://rephonic.com/developers). Looking to plug Rephonic into an AI assistant instead? See the [Rephonic MCP Server](https://github.com/getrephonic/rephonic-mcp).
|
|
64
|
+
|
|
65
|
+
## Ideas and Use Cases
|
|
66
|
+
|
|
67
|
+
- **Enrich a CRM** — pipe podcast metadata, listener estimates, and contacts into your existing customer records
|
|
68
|
+
- **Research podcasts for guest pitching** — filter by audience demographics, topic, and reach, then pull verified contacts in one pass
|
|
69
|
+
- **Monitor brand mentions** — poll `search.episodes` with a rolling `threshold` to catch new mentions within minutes of publication
|
|
70
|
+
- **Build a media list** — bulk-fetch verified emails, social accounts, and hosts across hundreds of shows
|
|
71
|
+
- **Analyse audience demographics** — age, gender, education, profession, income, interests, and location for any podcast
|
|
72
|
+
- **Track chart rankings** — daily Apple, Spotify, and YouTube chart data across every country and category
|
|
73
|
+
- **Audit sponsorships** — see who's advertising on which shows, with ad copy and promo codes extracted from transcripts
|
|
74
|
+
- **Summarise transcripts** — grab full-text, speaker-labelled transcripts for almost any episode and feed them into your own LLM pipeline
|
|
75
|
+
- **Power a podcast discovery app** — search, autocomplete, audience graph, and similar podcasts in one API
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install rephonic
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Requires Python 3.8 or newer.
|
|
84
|
+
|
|
85
|
+
## Quickstart
|
|
86
|
+
|
|
87
|
+
You need a Rephonic API key. [Get one here](https://rephonic.com/developers).
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from rephonic import Rephonic
|
|
91
|
+
|
|
92
|
+
client = Rephonic(api_key="your_api_key")
|
|
93
|
+
|
|
94
|
+
# Look up a podcast
|
|
95
|
+
podcast = client.podcasts.get("huberman-lab")
|
|
96
|
+
print(podcast["podcast"]["name"], podcast["podcast"]["downloads_per_episode"])
|
|
97
|
+
|
|
98
|
+
# Search for podcasts, with filters
|
|
99
|
+
results = client.search.podcasts(
|
|
100
|
+
query="artificial intelligence",
|
|
101
|
+
filters="listeners:gte:10000,active:is:true",
|
|
102
|
+
per_page=25,
|
|
103
|
+
)
|
|
104
|
+
for p in results["podcasts"]:
|
|
105
|
+
print(p["id"], p["name"])
|
|
106
|
+
|
|
107
|
+
# Get a full transcript
|
|
108
|
+
transcript = client.episodes.transcript("kzaca-huberman-lab-dr-brian-keating-charting-the-a")
|
|
109
|
+
for segment in transcript["transcript"]["segments"]:
|
|
110
|
+
print(segment["text"])
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The client will also pick up an API key from the `REPHONIC_API_KEY` environment variable:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
import os
|
|
117
|
+
os.environ["REPHONIC_API_KEY"] = "your_api_key"
|
|
118
|
+
|
|
119
|
+
from rephonic import Rephonic
|
|
120
|
+
client = Rephonic()
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Use it as a context manager to release the underlying HTTP connection pool when you're done:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
with Rephonic() as client:
|
|
127
|
+
quota = client.account.quota()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Async
|
|
131
|
+
|
|
132
|
+
`AsyncRephonic` has the same surface but returns coroutines. Use it when you want to fan out many calls concurrently — great for enrichment pipelines, media lists, and realtime monitoring.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
import asyncio
|
|
136
|
+
from rephonic import AsyncRephonic
|
|
137
|
+
|
|
138
|
+
async def main():
|
|
139
|
+
async with AsyncRephonic(api_key="your_api_key") as client:
|
|
140
|
+
# Look up a podcast
|
|
141
|
+
podcast = await client.podcasts.get("huberman-lab")
|
|
142
|
+
|
|
143
|
+
# Fan out — these run concurrently
|
|
144
|
+
podcast_ids = ["huberman-lab", "the-daily", "lex-fridman-podcast"]
|
|
145
|
+
contacts = await asyncio.gather(
|
|
146
|
+
*(client.podcasts.contacts(pid) for pid in podcast_ids)
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Auto-paginating async iterator
|
|
150
|
+
async for p in client.search.iter_podcasts(query="ai", limit=500):
|
|
151
|
+
print(p["name"])
|
|
152
|
+
|
|
153
|
+
asyncio.run(main())
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Resources
|
|
157
|
+
|
|
158
|
+
The full API is organised into six resource groups, each accessed as an attribute on the client. For the complete signature and response shape of every method, see [api.md](./api.md).
|
|
159
|
+
|
|
160
|
+
| Resource | Methods |
|
|
161
|
+
|---|---|
|
|
162
|
+
| `client.search` | `podcasts`, `iter_podcasts`, `episodes`, `iter_episodes`, `autocomplete` |
|
|
163
|
+
| `client.podcasts` | `get`, `people`, `demographics`, `promotions`, `contacts`, `social`, `feedback`, `reviews`, `trends`, `similar_graph` |
|
|
164
|
+
| `client.episodes` | `list`, `iter_list`, `get`, `transcript` |
|
|
165
|
+
| `client.charts` | `index`, `rankings` |
|
|
166
|
+
| `client.common` | `categories`, `countries`, `languages`, `sponsors`, `professions`, `interests` |
|
|
167
|
+
| `client.account` | `quota` |
|
|
168
|
+
|
|
169
|
+
## Pagination
|
|
170
|
+
|
|
171
|
+
Search endpoints and `episodes.list` return one page at a time. Each resource exposes an `iter_*` helper that transparently fetches subsequent pages:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
# Manual paging
|
|
175
|
+
page1 = client.search.podcasts(query="ai", per_page=50, page=1)
|
|
176
|
+
page2 = client.search.podcasts(query="ai", per_page=50, page=2)
|
|
177
|
+
|
|
178
|
+
# Auto-paging
|
|
179
|
+
for podcast in client.search.iter_podcasts(query="ai", limit=500):
|
|
180
|
+
print(podcast["name"])
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Error handling
|
|
184
|
+
|
|
185
|
+
Every non-2xx response is raised as a subclass of `RephonicError`:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from rephonic import (
|
|
189
|
+
Rephonic,
|
|
190
|
+
APIConnectionError,
|
|
191
|
+
AuthenticationError,
|
|
192
|
+
BadRequestError,
|
|
193
|
+
RateLimitError,
|
|
194
|
+
InternalServerError,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
client = Rephonic()
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
client.podcasts.get("does-not-exist")
|
|
201
|
+
except BadRequestError as exc:
|
|
202
|
+
# Rephonic returns 400 for missing resources too — inspect exc.message.
|
|
203
|
+
print(exc.status_code, exc.message)
|
|
204
|
+
except RateLimitError:
|
|
205
|
+
# Back off and retry later.
|
|
206
|
+
...
|
|
207
|
+
except APIConnectionError:
|
|
208
|
+
# Network-level problem (DNS, timeout, TLS).
|
|
209
|
+
...
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
> **Note:** The Rephonic API returns `400 Bad Request` for missing resources, not 404. Catch `BadRequestError` and check `.message` (e.g. `"Podcast not found."`, `"Unknown episode."`) to distinguish them.
|
|
213
|
+
|
|
214
|
+
The client automatically retries on 429 and 5xx responses with exponential backoff (up to `max_retries=2` by default). Pass `max_retries=0` to disable.
|
|
215
|
+
|
|
216
|
+
## Filters
|
|
217
|
+
|
|
218
|
+
Search endpoints accept a `filters` string with comma-separated `field:operator:value` clauses:
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
client.search.podcasts(
|
|
222
|
+
query="marketing",
|
|
223
|
+
filters=(
|
|
224
|
+
"listeners:gte:5000,"
|
|
225
|
+
"active:is:true,"
|
|
226
|
+
"categories:any:1482-1406,"
|
|
227
|
+
"locations:any:us,"
|
|
228
|
+
"professions:any:Doctor-Lawyer"
|
|
229
|
+
),
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
See the full list of filters and operators at [rephonic.com/developers/search-filters](https://rephonic.com/developers/search-filters). Use `client.common.categories()`, `countries()`, `languages()`, `sponsors()`, `professions()`, and `interests()` to look up valid IDs.
|
|
234
|
+
|
|
235
|
+
## Advanced configuration
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
import httpx
|
|
239
|
+
from rephonic import Rephonic, AsyncRephonic
|
|
240
|
+
|
|
241
|
+
client = Rephonic(
|
|
242
|
+
api_key="...",
|
|
243
|
+
timeout=60.0,
|
|
244
|
+
max_retries=3,
|
|
245
|
+
# Bring your own httpx.Client — useful for proxies, mTLS, custom transports.
|
|
246
|
+
http_client=httpx.Client(
|
|
247
|
+
proxies="http://corp-proxy:8080",
|
|
248
|
+
verify="/path/to/custom-ca.pem",
|
|
249
|
+
),
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# Same for async — pass an httpx.AsyncClient.
|
|
253
|
+
async_client = AsyncRephonic(
|
|
254
|
+
api_key="...",
|
|
255
|
+
http_client=httpx.AsyncClient(proxies="http://corp-proxy:8080"),
|
|
256
|
+
)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Rate limits and quota
|
|
260
|
+
|
|
261
|
+
The `$299/month` plan includes 10,000 requests per month. Check your current usage at any time:
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
client.account.quota()
|
|
265
|
+
# {"usage": 292, "quota": 10000}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
See [rephonic.com/developers](https://rephonic.com/developers#pricing) for plan details, or [contact us](https://rephonic.com/contact) for higher volume.
|
|
269
|
+
|
|
270
|
+
## Related resources
|
|
271
|
+
|
|
272
|
+
- [Rephonic API docs](https://rephonic.com/developers) — the source of truth
|
|
273
|
+
- [Markdown API reference for LLMs](https://rephonic.com/llms-full.txt) — feed to any model to generate integration code
|
|
274
|
+
- [Rephonic MCP Server](https://github.com/getrephonic/rephonic-mcp) — connect Claude, ChatGPT, and Cursor directly to Rephonic
|
|
275
|
+
- [Rephonic on the web](https://rephonic.com)
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
[MIT](./LICENSE)
|
rephonic-1.0.0/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Rephonic Python
|
|
2
|
+
|
|
3
|
+
Official Python client for the [Rephonic](https://rephonic.com) podcast API — covering 3+ million podcasts with listener estimates, demographics, contact details, chart rankings, episodes, full transcripts, and more.
|
|
4
|
+
|
|
5
|
+
This library is a thin, typed wrapper around the [Rephonic API](https://rephonic.com/developers). Looking to plug Rephonic into an AI assistant instead? See the [Rephonic MCP Server](https://github.com/getrephonic/rephonic-mcp).
|
|
6
|
+
|
|
7
|
+
## Ideas and Use Cases
|
|
8
|
+
|
|
9
|
+
- **Enrich a CRM** — pipe podcast metadata, listener estimates, and contacts into your existing customer records
|
|
10
|
+
- **Research podcasts for guest pitching** — filter by audience demographics, topic, and reach, then pull verified contacts in one pass
|
|
11
|
+
- **Monitor brand mentions** — poll `search.episodes` with a rolling `threshold` to catch new mentions within minutes of publication
|
|
12
|
+
- **Build a media list** — bulk-fetch verified emails, social accounts, and hosts across hundreds of shows
|
|
13
|
+
- **Analyse audience demographics** — age, gender, education, profession, income, interests, and location for any podcast
|
|
14
|
+
- **Track chart rankings** — daily Apple, Spotify, and YouTube chart data across every country and category
|
|
15
|
+
- **Audit sponsorships** — see who's advertising on which shows, with ad copy and promo codes extracted from transcripts
|
|
16
|
+
- **Summarise transcripts** — grab full-text, speaker-labelled transcripts for almost any episode and feed them into your own LLM pipeline
|
|
17
|
+
- **Power a podcast discovery app** — search, autocomplete, audience graph, and similar podcasts in one API
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install rephonic
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires Python 3.8 or newer.
|
|
26
|
+
|
|
27
|
+
## Quickstart
|
|
28
|
+
|
|
29
|
+
You need a Rephonic API key. [Get one here](https://rephonic.com/developers).
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from rephonic import Rephonic
|
|
33
|
+
|
|
34
|
+
client = Rephonic(api_key="your_api_key")
|
|
35
|
+
|
|
36
|
+
# Look up a podcast
|
|
37
|
+
podcast = client.podcasts.get("huberman-lab")
|
|
38
|
+
print(podcast["podcast"]["name"], podcast["podcast"]["downloads_per_episode"])
|
|
39
|
+
|
|
40
|
+
# Search for podcasts, with filters
|
|
41
|
+
results = client.search.podcasts(
|
|
42
|
+
query="artificial intelligence",
|
|
43
|
+
filters="listeners:gte:10000,active:is:true",
|
|
44
|
+
per_page=25,
|
|
45
|
+
)
|
|
46
|
+
for p in results["podcasts"]:
|
|
47
|
+
print(p["id"], p["name"])
|
|
48
|
+
|
|
49
|
+
# Get a full transcript
|
|
50
|
+
transcript = client.episodes.transcript("kzaca-huberman-lab-dr-brian-keating-charting-the-a")
|
|
51
|
+
for segment in transcript["transcript"]["segments"]:
|
|
52
|
+
print(segment["text"])
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The client will also pick up an API key from the `REPHONIC_API_KEY` environment variable:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import os
|
|
59
|
+
os.environ["REPHONIC_API_KEY"] = "your_api_key"
|
|
60
|
+
|
|
61
|
+
from rephonic import Rephonic
|
|
62
|
+
client = Rephonic()
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use it as a context manager to release the underlying HTTP connection pool when you're done:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
with Rephonic() as client:
|
|
69
|
+
quota = client.account.quota()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Async
|
|
73
|
+
|
|
74
|
+
`AsyncRephonic` has the same surface but returns coroutines. Use it when you want to fan out many calls concurrently — great for enrichment pipelines, media lists, and realtime monitoring.
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import asyncio
|
|
78
|
+
from rephonic import AsyncRephonic
|
|
79
|
+
|
|
80
|
+
async def main():
|
|
81
|
+
async with AsyncRephonic(api_key="your_api_key") as client:
|
|
82
|
+
# Look up a podcast
|
|
83
|
+
podcast = await client.podcasts.get("huberman-lab")
|
|
84
|
+
|
|
85
|
+
# Fan out — these run concurrently
|
|
86
|
+
podcast_ids = ["huberman-lab", "the-daily", "lex-fridman-podcast"]
|
|
87
|
+
contacts = await asyncio.gather(
|
|
88
|
+
*(client.podcasts.contacts(pid) for pid in podcast_ids)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Auto-paginating async iterator
|
|
92
|
+
async for p in client.search.iter_podcasts(query="ai", limit=500):
|
|
93
|
+
print(p["name"])
|
|
94
|
+
|
|
95
|
+
asyncio.run(main())
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Resources
|
|
99
|
+
|
|
100
|
+
The full API is organised into six resource groups, each accessed as an attribute on the client. For the complete signature and response shape of every method, see [api.md](./api.md).
|
|
101
|
+
|
|
102
|
+
| Resource | Methods |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `client.search` | `podcasts`, `iter_podcasts`, `episodes`, `iter_episodes`, `autocomplete` |
|
|
105
|
+
| `client.podcasts` | `get`, `people`, `demographics`, `promotions`, `contacts`, `social`, `feedback`, `reviews`, `trends`, `similar_graph` |
|
|
106
|
+
| `client.episodes` | `list`, `iter_list`, `get`, `transcript` |
|
|
107
|
+
| `client.charts` | `index`, `rankings` |
|
|
108
|
+
| `client.common` | `categories`, `countries`, `languages`, `sponsors`, `professions`, `interests` |
|
|
109
|
+
| `client.account` | `quota` |
|
|
110
|
+
|
|
111
|
+
## Pagination
|
|
112
|
+
|
|
113
|
+
Search endpoints and `episodes.list` return one page at a time. Each resource exposes an `iter_*` helper that transparently fetches subsequent pages:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
# Manual paging
|
|
117
|
+
page1 = client.search.podcasts(query="ai", per_page=50, page=1)
|
|
118
|
+
page2 = client.search.podcasts(query="ai", per_page=50, page=2)
|
|
119
|
+
|
|
120
|
+
# Auto-paging
|
|
121
|
+
for podcast in client.search.iter_podcasts(query="ai", limit=500):
|
|
122
|
+
print(podcast["name"])
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Error handling
|
|
126
|
+
|
|
127
|
+
Every non-2xx response is raised as a subclass of `RephonicError`:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from rephonic import (
|
|
131
|
+
Rephonic,
|
|
132
|
+
APIConnectionError,
|
|
133
|
+
AuthenticationError,
|
|
134
|
+
BadRequestError,
|
|
135
|
+
RateLimitError,
|
|
136
|
+
InternalServerError,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
client = Rephonic()
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
client.podcasts.get("does-not-exist")
|
|
143
|
+
except BadRequestError as exc:
|
|
144
|
+
# Rephonic returns 400 for missing resources too — inspect exc.message.
|
|
145
|
+
print(exc.status_code, exc.message)
|
|
146
|
+
except RateLimitError:
|
|
147
|
+
# Back off and retry later.
|
|
148
|
+
...
|
|
149
|
+
except APIConnectionError:
|
|
150
|
+
# Network-level problem (DNS, timeout, TLS).
|
|
151
|
+
...
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> **Note:** The Rephonic API returns `400 Bad Request` for missing resources, not 404. Catch `BadRequestError` and check `.message` (e.g. `"Podcast not found."`, `"Unknown episode."`) to distinguish them.
|
|
155
|
+
|
|
156
|
+
The client automatically retries on 429 and 5xx responses with exponential backoff (up to `max_retries=2` by default). Pass `max_retries=0` to disable.
|
|
157
|
+
|
|
158
|
+
## Filters
|
|
159
|
+
|
|
160
|
+
Search endpoints accept a `filters` string with comma-separated `field:operator:value` clauses:
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
client.search.podcasts(
|
|
164
|
+
query="marketing",
|
|
165
|
+
filters=(
|
|
166
|
+
"listeners:gte:5000,"
|
|
167
|
+
"active:is:true,"
|
|
168
|
+
"categories:any:1482-1406,"
|
|
169
|
+
"locations:any:us,"
|
|
170
|
+
"professions:any:Doctor-Lawyer"
|
|
171
|
+
),
|
|
172
|
+
)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
See the full list of filters and operators at [rephonic.com/developers/search-filters](https://rephonic.com/developers/search-filters). Use `client.common.categories()`, `countries()`, `languages()`, `sponsors()`, `professions()`, and `interests()` to look up valid IDs.
|
|
176
|
+
|
|
177
|
+
## Advanced configuration
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
import httpx
|
|
181
|
+
from rephonic import Rephonic, AsyncRephonic
|
|
182
|
+
|
|
183
|
+
client = Rephonic(
|
|
184
|
+
api_key="...",
|
|
185
|
+
timeout=60.0,
|
|
186
|
+
max_retries=3,
|
|
187
|
+
# Bring your own httpx.Client — useful for proxies, mTLS, custom transports.
|
|
188
|
+
http_client=httpx.Client(
|
|
189
|
+
proxies="http://corp-proxy:8080",
|
|
190
|
+
verify="/path/to/custom-ca.pem",
|
|
191
|
+
),
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# Same for async — pass an httpx.AsyncClient.
|
|
195
|
+
async_client = AsyncRephonic(
|
|
196
|
+
api_key="...",
|
|
197
|
+
http_client=httpx.AsyncClient(proxies="http://corp-proxy:8080"),
|
|
198
|
+
)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Rate limits and quota
|
|
202
|
+
|
|
203
|
+
The `$299/month` plan includes 10,000 requests per month. Check your current usage at any time:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
client.account.quota()
|
|
207
|
+
# {"usage": 292, "quota": 10000}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
See [rephonic.com/developers](https://rephonic.com/developers#pricing) for plan details, or [contact us](https://rephonic.com/contact) for higher volume.
|
|
211
|
+
|
|
212
|
+
## Related resources
|
|
213
|
+
|
|
214
|
+
- [Rephonic API docs](https://rephonic.com/developers) — the source of truth
|
|
215
|
+
- [Markdown API reference for LLMs](https://rephonic.com/llms-full.txt) — feed to any model to generate integration code
|
|
216
|
+
- [Rephonic MCP Server](https://github.com/getrephonic/rephonic-mcp) — connect Claude, ChatGPT, and Cursor directly to Rephonic
|
|
217
|
+
- [Rephonic on the web](https://rephonic.com)
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
[MIT](./LICENSE)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.24"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "rephonic"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Official Python client for the Rephonic podcast API."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "Rephonic", email = "support@rephonic.com" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"rephonic",
|
|
15
|
+
"podcast",
|
|
16
|
+
"podcasts",
|
|
17
|
+
"api",
|
|
18
|
+
"transcripts",
|
|
19
|
+
"demographics",
|
|
20
|
+
"charts",
|
|
21
|
+
"sdk",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 4 - Beta",
|
|
25
|
+
"Intended Audience :: Developers",
|
|
26
|
+
"License :: OSI Approved :: MIT License",
|
|
27
|
+
"Operating System :: OS Independent",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3.8",
|
|
30
|
+
"Programming Language :: Python :: 3.9",
|
|
31
|
+
"Programming Language :: Python :: 3.10",
|
|
32
|
+
"Programming Language :: Python :: 3.11",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
34
|
+
"Programming Language :: Python :: 3.13",
|
|
35
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
36
|
+
"Typing :: Typed",
|
|
37
|
+
]
|
|
38
|
+
dependencies = [
|
|
39
|
+
"httpx>=0.24,<1",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
dev = [
|
|
44
|
+
"pytest>=7",
|
|
45
|
+
"pytest-asyncio>=0.23",
|
|
46
|
+
"pytest-cov>=4",
|
|
47
|
+
"respx>=0.20",
|
|
48
|
+
"mypy>=1.5",
|
|
49
|
+
"ruff>=0.5",
|
|
50
|
+
"build>=1.0",
|
|
51
|
+
"twine>=5.0",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[project.urls]
|
|
55
|
+
Homepage = "https://rephonic.com"
|
|
56
|
+
Documentation = "https://rephonic.com/developers"
|
|
57
|
+
Repository = "https://github.com/getrephonic/rephonic-python"
|
|
58
|
+
Issues = "https://github.com/getrephonic/rephonic-python/issues"
|
|
59
|
+
|
|
60
|
+
[tool.hatch.version]
|
|
61
|
+
path = "src/rephonic/_version.py"
|
|
62
|
+
|
|
63
|
+
[tool.hatch.build.targets.sdist]
|
|
64
|
+
include = [
|
|
65
|
+
"src/rephonic",
|
|
66
|
+
"README.md",
|
|
67
|
+
"LICENSE",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.hatch.build.targets.wheel]
|
|
71
|
+
packages = ["src/rephonic"]
|
|
72
|
+
|
|
73
|
+
[tool.pytest.ini_options]
|
|
74
|
+
testpaths = ["tests"]
|
|
75
|
+
addopts = "-ra"
|
|
76
|
+
asyncio_mode = "auto"
|
|
77
|
+
|
|
78
|
+
[tool.ruff]
|
|
79
|
+
line-length = 100
|
|
80
|
+
target-version = "py38"
|
|
81
|
+
|
|
82
|
+
[tool.ruff.lint]
|
|
83
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
84
|
+
ignore = ["E501"]
|
|
85
|
+
|
|
86
|
+
[tool.mypy]
|
|
87
|
+
python_version = "3.9"
|
|
88
|
+
strict = true
|
|
89
|
+
warn_unused_ignores = true
|