test(python-sdk): regression tests for template upload Content-Length#1293
test(python-sdk): regression tests for template upload Content-Length#1293mishushakov wants to merge 1 commit into
Conversation
…ngth Guards against future changes swapping the buffered bytes for a generator/stream, which would trigger Transfer-Encoding: chunked and break S3 presigned PUT uploads with 501 NotImplemented. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR SummaryLow Risk Overview The tests also assert the upload does not use Reviewed by Cursor Bugbot for commit bc3f865. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
Package ArtifactsBuilt from 3155e27. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.19.1-mishushakov-py-upload-tests.0.tgzCLI ( npm install ./e2b-cli-2.9.1-mishushakov-py-upload-tests.0.tgzPython SDK ( pip install ./e2b-2.20.0+mishushakov.py.upload.tests-py3-none-any.whl |
There was a problem hiding this comment.
Test-only regression guard for upload_file Content-Length behavior — straightforward and self-contained.
Extended reasoning...
Overview
This PR adds two new test files (sync + async) under packages/python-sdk/tests/ that spin up a local HTTPServer on 127.0.0.1:0, invoke upload_file against it, and assert the request carries a matching Content-Length and no Transfer-Encoding: chunked. No runtime SDK code is modified.
Security risks
None. Tests bind to loopback only, use ephemeral ports, and run in daemon threads that are torn down in a finally block. No credentials, network egress, or filesystem writes outside pytest's tmp_path.
Level of scrutiny
Low. This is a pure test addition guarding against a previously-seen class of bug (JS SDK #1285/#1243 where presigned S3 PUTs failed under chunked encoding). The tests exercise the public function signature and assert on observable HTTP behavior — no mocking of internals, no brittle coupling.
Other factors
The mock server pattern is simple and correct: server.shutdown() + server_close() + thread.join(timeout=5) in finally ensures cleanup even on failure. The async test correctly relies on the fact that the sync HTTPServer in a daemon thread does not block the asyncio event loop, since httpx.AsyncClient uses asyncio sockets to talk to it. The assertions are precise (Content-Length > 0, matches received body length, no chunked TE) and fail-loud.
…n tests (#1294) ## Summary Consolidates the fix and tests from #1285 and #1293 into a single PR. - **js-sdk**: `uploadFile` used to pass a Node `Readable` directly to `fetch`, causing undici to fall back to `Transfer-Encoding: chunked`. S3 presigned PUT URLs reject chunked with 501 NotImplemented. Fix buffers the archive first so `Content-Length` is set. Includes: - Regression test that spins up a local HTTP server and asserts `Content-Length` is set and matches the body, and `Transfer-Encoding` is not chunked. - Type-fix for the CLI's typecheck (cast `Pack` → `AsyncIterable<Buffer>`). - Dynamic import of `node:stream/consumers` so the browser bundle doesn't pull it in. - **python-sdk**: Adds sync + async regression tests for `upload_file` that guard against the same class of bug (someone swapping `tar_buffer.getvalue()` for a stream/generator). No Python code change — the current implementation already passes bytes to `httpx.put(..., content=...)`. Authorship of the original JS fix commit preserved (truffle-dev). Closes #1243. ## Test plan - [x] `pnpm run test tests/template/uploadFile.test.ts` — passes - [x] `pnpm run typecheck` / `lint` clean across js-sdk and cli - [x] `poetry run pytest tests/sync/template_sync/test_upload_file.py tests/async/template_async/test_upload_file.py -v` — both pass - [x] `poetry run make format` / `make lint` / `make typecheck` clean 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: truffle <truffleagent@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
upload_fileintemplate_sync/template_async. Both spin up a local HTTP server on127.0.0.1:0, PUT the archive at it, and assert the request carries aContent-Lengthmatching the body and does not useTransfer-Encoding: chunked.tar_buffer.getvalue()) for a generator/stream, which would trigger chunked encoding and break S3 presigned PUT uploads with 501 NotImplemented — the same class of bug that hit the JS SDK in fix(js-sdk): buffer template upload to avoid S3 chunked PUT 501 #1285 / [JS SDK] uploadFile uses chunked transfer encoding, causing 501 NotImplemented on S3 presigned PUT URLs #1243.No Python SDK code changes — the current implementation already passes bytes to
httpx.put(..., content=...), so this is purely a regression guard.Test plan
poetry run pytest tests/sync/template_sync/test_upload_file.py tests/async/template_async/test_upload_file.py -v— both pass locallypoetry run make format/make lint/make typecheckclean🤖 Generated with Claude Code