Python SDK
The stophy package for Python: a client for search, video details, transcripts, comments, channels, and playlists.
Call the Stophy API from Python without wiring up HTTP requests. The stophy package
gives you a Stophy class over every REST endpoint. It returns the same response
envelope as the API reference.
Install
pip install stophyRequires Python 3.9 or later.
Initialize
Create one client and reuse it. Pass your API key explicitly and keep it in an environment variable, never in source.
import os
from stophy import Stophy
stophy = Stophy(os.environ["STOPHY_API_KEY"])Keep keys out of source code. Store them in environment variables and never commit them to git. See Authentication.
Make a request
Every method returns the standard response envelope as a dict. Read data for the
result, or read creditsRemaining, requestId, and cacheState off the top level.
result = stophy.video(
type="transcript",
video_url="https://www.youtube.com/watch?v=D7liwdjvhWc",
)
print(result["data"]["text"]) # full transcript as a stringThe returned dict matches the response envelope:
{
"success": True,
"requestId": str,
"cacheState": "hit" | "miss",
"creditsUsed": int,
"creditsRemaining": int,
"warning": str, # present only when a result is partial or degraded
"data": dict,
}Methods
Arguments are keyword-only and snake_case. The SDK maps them to the API's field names
for you, so video_url becomes videoUrl, continuation_token becomes
continuationToken, and so on. Response keys stay as the API returns them, so you read
data["continuationToken"] and data["items"][0]["repliesToken"].
| Method | Endpoint | Description |
|---|---|---|
stophy.video(...) | POST /v1/video | Details, transcript, comments, replies, or live chat (set type) |
stophy.search(...) | POST /v1/search | Search with filters for type, sort, date, duration, features |
stophy.channel(...) | POST /v1/channel | Channel metadata and content by tab |
stophy.playlist(...) | POST /v1/playlist | Playlist items, paginated |
stophy.credits() | GET /v1/credits | Current credit balance |
stophy.logs(...) | GET /v1/logs | Recent request logs |
stophy.usage(...) | GET /v1/usage | Daily credit and request counts |
video() is overloaded on type, so the returned data is typed for the variant you
ask for (transcript, comments, details, replies, livechat).
Examples
# Search
results = stophy.search(q="typescript tutorial", sort_by="popularity", duration="long")["data"]
# Channel videos
channel = stophy.channel(channel_url="https://www.youtube.com/@mkbhd", tab="video")["data"]
# Comments, then replies to the first comment
comments = stophy.video(type="comments", video_url=url, sort_by="top")
token = comments["data"]["items"][0].get("repliesToken")
if token:
replies = stophy.video(type="replies", continuation_token=token)
# Autocomplete
# Account
print(stophy.credits()["data"]["credits"])Pagination
Comments, replies, live chat, search, channel tabs, and playlists return a
continuationToken. Pass it back as continuation_token to fetch the next page, and
stop when it is None.
token = None
while True:
kwargs = {"video_url": "https://www.youtube.com/watch?v=D7liwdjvhWc", "type": "comments"}
if token:
kwargs["continuation_token"] = token
data = stophy.video(**kwargs)["data"]
print(data["items"])
token = data.get("continuationToken")
if not token:
breakError handling
Non-2xx responses raise StophyError, carrying status, code, the message, and
request_id. Branch on code so unknown codes fall through to your default case (see
Error handling).
import os
from stophy import Stophy, StophyError
stophy = Stophy(os.environ["STOPHY_API_KEY"])
try:
result = stophy.video(
type="details",
video_url="https://www.youtube.com/watch?v=D7liwdjvhWc",
)
print(result["data"])
except StophyError as err:
# err.status, err.code, str(err), err.request_id
if err.code == "INSUFFICIENT_CREDITS":
pass # top up from dashboard
elif err.code == "CONCURRENCY_LIMITED":
pass # too many requests in flight; retry once one finishes
elif err.code == "UNAUTHORIZED":
pass # check your API key
else:
print(err.status, err.code, err)