Skip to content

Add asyncio support to the Python SDK#57

Draft
kvz wants to merge 45 commits into
py310-v2from
asyncio-v2
Draft

Add asyncio support to the Python SDK#57
kvz wants to merge 45 commits into
py310-v2from
asyncio-v2

Conversation

@kvz

@kvz kvz commented May 20, 2026

Copy link
Copy Markdown
Member

Experimental Status

Experimental work: this PR is part of an exploratory contract/generated docs and SDK effort, and is intentionally kept as a Draft while the approach is validated.

Why

Issue #9 asks for a Pythonic asyncio surface without changing sync callers. This PR adds a separate AsyncTransloadit API on top of the v2 runtime/security branch (#56) so async users can opt in without affecting the existing synchronous client.

This branch is also the Python companion for the API2 contract generator work in https://github.com/transloadit/api2/pull/7928. Low-level endpoint methods that the current Python transport can honestly express are generated from API2 endpoint contracts and verified byte-for-byte from API2. Checked-in devdock examples prove selected high-level flows against real API2 using contract-injected scenario JSON.

What changed

  • Added examples/api2-devdock-assembly-lifecycle/main.py, which reads the shared API2 transloaditAssemblyLifecycle scenario and exercises create_tus_assembly, get_assembly, list_assemblies, and cancel_assembly as ordinary Python SDK user code.
  • Added a checked-in api2-devdock-template-lifecycle example that exercises generated Template create/get/list/update/delete methods against devdock using API2-injected scenario JSON and result assertions.
  • The checked-in TUS Assembly example reads createTusAssembly from generic scenario.preparations[] and waitForAssembly from generic scenario.observations[] instead of removed API2 compatibility fields.
  • Added transloadit.async_client.AsyncTransloadit with async versions of the existing client helpers.
  • Added async request/assembly/template helpers and a shared Response wrapper that works for both sync and async responses.
  • Added async context manager cleanup plus explicit aclose()/close().
  • Kept the sync Transloadit API compatible with existing callers.
  • Added generated low-level sync and async endpoint methods for the non-blocked API2 contract operations. These methods live inside marked api2-generated-endpoints blocks so API2 can rewrite them directly.
  • Regenerated endpoint blocks after API2 removed its separate Python SDK plan/snippet file. The generator now reads endpoint contracts directly, including endpoint-local compatibility hints for existing Python method names.
  • Hardened sync Assembly edge cases found by council review: non-resumable retries rewind seekable files or reject non-seekable streams, wait/resumable paths reject unexpected non-JSON responses when they cannot safely proceed, polling stays pinned to the original Assembly URL, and repeated poll rate limits are capped.
  • Hardened follow-up council findings: same-service API URL signing no longer signs Transloadit regional URLs for custom services, string Template payloads are preserved, undecodable sync response bodies stay bytes, and missing resumable upload URLs no longer dump full response payloads into exceptions.
  • Made same-service API URL signing compare hostnames case-insensitively.

Latest Verification

  • Python SDK branch asyncio-v2 is pushed at 19186b1.
  • Local Python checks passed: .tox/py314/bin/python -m py_compile examples/api2-devdock-assembly-lifecycle/main.py && .tox/py314/bin/python -m pytest.
  • API2 generated-output comparison passed: node api2/bin/cli.ts contracts sdks --no-motd --target transloadit --platform python --sdk-root ../python-sdk-asyncio --compare-existing.
  • API2 Python/Transloadit dry-run passed with exampleCount: 3 and Assembly lifecycle endpoint IDs present.
  • API2 clone-based live Python/Transloadit wrapper passed against this pushed branch: core/bin/devdock.ts exec tstrun system/sdk_examples/python-transloadit-examples.test.ts -vv --max-time-per-test 900.
  • GitHub Actions for 19186b1 passed across Python 3.12, 3.13, 3.14 on Ubuntu/Windows plus python-e2e.

This PR is intentionally based on #56 and targets base branch py310-v2.

Companion PRs

Transloadit

TUS

Allowed outward links from Transloadit to the related tus companion PRs:

@kvz kvz self-assigned this May 20, 2026
@codecov-commenter

codecov-commenter commented May 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.53396% with 115 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.95%. Comparing base (89a52c3) to head (be626e0).

Files with missing lines Patch % Lines
transloadit/async_client.py 71.69% 45 Missing ⚠️
transloadit/client.py 66.66% 45 Missing ⚠️
transloadit/assembly.py 87.50% 12 Missing ⚠️
transloadit/async_request.py 95.67% 7 Missing ⚠️
transloadit/api_url.py 93.54% 2 Missing ⚠️
transloadit/async_assembly.py 99.28% 1 Missing ⚠️
transloadit/async_template.py 94.11% 1 Missing ⚠️
transloadit/request.py 95.23% 1 Missing ⚠️
transloadit/template.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           py310-v2      #57      +/-   ##
============================================
+ Coverage     86.60%   87.95%   +1.35%     
============================================
  Files             7       14       +7     
  Lines           209      980     +771     
  Branches         19      131     +112     
============================================
+ Hits            181      862     +681     
- Misses           28      118      +90     
Flag Coverage Δ
unittests 87.95% <86.53%> (+1.35%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kvz

kvz commented May 21, 2026

Copy link
Copy Markdown
Member Author

Setting this back to draft while we expand the feature scope: the v2 PR should also cover the full Transloadit API endpoint surface before we treat it as ready. I added a matching @todo to the 2.0.0 CHANGELOG section so the release notes get updated once the endpoint coverage is complete.

@kvz kvz marked this pull request as draft May 21, 2026 14:07
kvz and others added 10 commits June 2, 2026 05:37
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The API2 Python generator now converts contract identifiers to
snake_case for local variable names, so generated methods read like
idiomatic Python. No public API or behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The generator no longer emits function-local imports; base64, urljoin,
and requests (sync only) now live in the handwritten module headers
where Python convention expects them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants