This release is a pre-release and may not be stable for production use.
Rask Python SDK
The official Python client for the Rask API v3: upload media, localize it, edit transcripts,
dub, lip-sync and export. Sync and async, typed, with retries and idempotency built in. Version 3.0.0a0 (alpha, like
the API).
Install
Python 3.11 or newer.
pip install rask-sdk
Before the first release is on PyPI, install from a checkout of this repository instead, with pip install ..
Key and base URL
Rask() reads RASK_API_KEY and RASK_BASE_URL, and an argument wins over its variable.
from rask_sdk import AsyncRask, Rask
client = Rask(api_key="raskai_live_key_...") # https://api.rask.ai/v3 by default
client = Rask(api_key="...", base_url="https://gw.example.com/rask/v3") # a gateway: the path prefix is kept
client = AsyncRask() # the same API with await
The base URL applies to every operation and helper, and a trailing slash makes no difference. The key goes only to URLs
under it: presigned PUTs go without Authorization, a GET redirected elsewhere follows without the key, and a write
redirected elsewhere is not followed (it raises RaskError with the 3xx status).
Worked example
Upload a file, localize it, wait for the dub, download the result.
import httpx
from rask_sdk import Rask
client = Rask()
# Upload, then wait for the import. job.result holds the media id.
job = client.uploads.upload_file("talk.mp4", on_progress=lambda sent, total: print(f"{sent}/{total} bytes"))
media_id = client.jobs.wait(job.id).result.media_id
# Ask the price, then start. The cap is what you agree to pay; auto-dub follows the translation.
estimate = client.projects.estimate_project(media_id=media_id, target_language="es-es")
job = client.projects.create_project(
media_id=media_id, target_language="es-es", expected_cost_minutes=estimate.total_minutes
)
job = client.jobs.wait(job.id)
project_id = job.result.project_id
if job.result.auto_dub.dub_job_id:
client.jobs.wait(job.result.auto_dub.dub_job_id)
# Download. Output URLs are presigned and take no API key. A link that has expired answers with an error, not a video.
for output in client.exports.list_project_outputs(project_id).data:
if output.kind == "dubbed_video" and output.available:
with httpx.stream("GET", output.url) as response:
response.raise_for_status()
with open("talk.es.mp4", "wb") as file:
for chunk in response.iter_bytes():
file.write(chunk)
Using it
Operations are grouped by the contract's tags and named after their operationId: createFolder is
client.projects.create_folder(name=...), listVoices is client.voices.list_voices(target_language="ru-ru").
- Lists:
for project in client.projects.list_projects(limit=50)walks every page;page.data,page.next_cursorandpage.next_page()give page-level access. WithAsyncRask:async for project in await client.projects.list_projects(). - Status and headers:
result.http.status,.headers,.etag,.location,.request_id,.idempotency_keyand.idempotent_replayed, with no second call. A list has them on the page, and a 204 returns aNoContentthat has them too. - Edits:
client.segments.update_segment(project_id, segment_id, if_match=segment.etag, translation_text="Hola"). A stale ETag raisesPreconditionFailedError, whosecurrent_etagholds the current one.""clears a clearable field;Nonemeans "leave it out", and requests never send null. - Errors:
RaskErrorand one subclass per status (InsufficientBalanceError,RateLimitError, ...) carry every Problem member as an attribute, plusheaders,request_idandidempotency_key. Unknown codes are kept. - Retries: 429, 502, 503, 504, connection errors and timeouts, for up to 120 s from the start of the call, honouring
Retry-After. That limits the retries, not the call: the first attempt has the wholetimeout(60 s by default). Writes keep theirIdempotency-Keyacross retries; passidempotency_key=to choose it.max_retries=0turns retries off. A certificate that fails verification is not retried: the call andjobs.waitraiseRaskConnectionErrorat once, with httpx's error as its__cause__. - Forward compatibility: an enum value, a union variant (
rask_sdk.UnknownVariant) or a field this version does not know stays readable on the result and never fails the call.extra_body=,extra_query=andextra_headers=send what it does not know yet. - Debugging:
RASK_LOG=debuglogs traffic to stderr (or to yourrask_sdklogger), without the key or presigned signatures.
The API v2 client
The previous client talks to API v2 and stays available beside this one while you migrate. Only its import changes:
# pip install "rask-sdk[v2]"
from rask_sdk.v2 import RaskSDKClient, enums, schemas
from rask_sdk import clients, enums, schemas no longer works. To stay on the old layout, pin the last commit that had it,
bc87b59, with pip install "git+ssh://git@github.com/braskai/rask-sdk.git@bc87b59".
Development
uv and, for the acceptance tests, Node 22 or newer. make help lists everything.
make bootstrap # uv sync
make generate # rewrite rask_sdk/_generated from contract/openapi.json
make lint # ruff, mypy, and a check that the generated code matches the contract
make test # unit and acceptance tests; RUN_SLOW=1 adds the two slow scenarios
make build # sdist and wheel in dist/
The acceptance tests start rask-sdk-acceptance, found next to this checkout or through
RASK_SDK_ACCEPTANCE_DIR. rask_sdk/_generated is generated by tools/generate.py: never edit it by hand. examples/smoke.py checks a
real environment with RASK_API_KEY and RASK_BASE_URL set.
License
MIT. See LICENSE.
Metadata
Release files for rask-sdk 3.0.0a0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rask_sdk-3.0.0a0.tar.gz | 285.3 kB | Without provenance | Details for rask_sdk-3.0.0a0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rask_sdk-3.0.0a0-py3-none-any.whl | Python 3 | none | any | Details for rask_sdk-3.0.0a0-py3-none-any.whl |
Total release size: 400.2 kB
Release files / rask_sdk-3.0.0a0.tar.gz
| Download URL | rask_sdk-3.0.0a0.tar.gz |
|---|---|
| Size | 285.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2c65340ecd0b3b3b8826634a1d9580ac5090a57ecc872be6f1a4279f672be2fe
|
|
BLAKE2b-256 checksum How to use checksums |
d1d413bf4b328b33e76243e5419f784683bc6ac2ec8cf8b394e1367a51507cab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / rask_sdk-3.0.0a0-py3-none-any.whl
| Download URL | rask_sdk-3.0.0a0-py3-none-any.whl |
|---|---|
| Size | 114.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4b6f4e9b1bb880addd30a04bdcc378495cbf3e6a387635eef113622f6bdef42f
|
|
BLAKE2b-256 checksum How to use checksums |
f75039553da307cefdc2d88a4f182d16de4050d042851bf686201bc1dabc2d69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for rask-sdk 3.0.0a0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.