Repository navigation
feat: add zstd request body compression - #1218
apify-factory wants to merge 15 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1218 +/- ##
==========================================
- Coverage 95.76% 95.69% -0.07%
==========================================
Files 63 64 +1
Lines 6676 6712 +36
==========================================
+ Hits 6393 6423 +30
- Misses 283 289 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
vdusek
left a comment
There was a problem hiding this comment.
Could you add a self-review / staff review to the porting process?
| brotli = ["brotli>=1.0.9"] | ||
| httpx2 = ["httpx2>=2.0.0"] | ||
| # zstd is in the standard library (`compression.zstd`) from Python 3.14; older versions use its official backport. | ||
| zstd = ["backports.zstd>=1.0.0; python_version < '3.14'"] |
There was a problem hiding this comment.
uv.lock isn't updated for the new zstd extra, so uv lock --check fails. CI passes because it doesn't sync with --locked, but every uv sync rewrites the lock and leaves the tree dirty. Please run uv lock and commit the result.
✍️ Drafted by Claude Code
There was a problem hiding this comment.
Done in 19d5957: uv.lock now includes backports-zstd for the zstd extra, and uv lock --check passes.
| # zstd is in the standard library from Python 3.14, though a Python build can leave it out, which no extra can fix. | ||
| # Older versions need the `backports.zstd` package from the `zstd` extra. Either way it's wrapped in try_import. |
There was a problem hiding this comment.
The note about builds without zstd repeats the comment in _zstd.py, and the last sentence says what the next lines show. One line about the version split is enough.
| # zstd is in the standard library from Python 3.14, though a Python build can leave it out, which no extra can fix. | |
| # Older versions need the `backports.zstd` package from the `zstd` extra. Either way it's wrapped in try_import. | |
| # zstd is in the standard library from Python 3.14. Older versions need `backports.zstd` from the `zstd` extra. |
✍️ Drafted by Claude Code
|
|
||
| return BrotliHttpCompressor() | ||
| if compression == 'zstd': | ||
| # Imported here for the same reason as brotli: before Python 3.14 zstd needs the `zstd` extra. |
There was a problem hiding this comment.
This import also fails on a Python 3.14+ build without zstd, not only before 3.14. The short form covers both cases.
| # Imported here for the same reason as brotli: before Python 3.14 zstd needs the `zstd` extra. | |
| # Imported here for the same reason as brotli. |
✍️ Drafted by Claude Code
There was a problem hiding this comment.
Already covered: the comment was updated before this review landed and now reads "Imported here so a missing zstd extra, or a Python build without zstd, raises ImportError at call time." That names both cases, so I left it as is.
|
|
||
| ## Enabling zstd | ||
|
|
||
| Python 3.14 and newer ship zstd in the standard library as `compression.zstd`, so pass `compression='zstd'` and nothing else is needed, as long as your Python build includes zstd support, which the python.org builds do. On older Python versions, install the optional extra, which brings in the `backports.zstd` package: |
There was a problem hiding this comment.
This sentence joins four clauses. Could you split it?
| Python 3.14 and newer ship zstd in the standard library as `compression.zstd`, so pass `compression='zstd'` and nothing else is needed, as long as your Python build includes zstd support, which the python.org builds do. On older Python versions, install the optional extra, which brings in the `backports.zstd` package: | |
| Python 3.14 and newer include zstd in the standard library as `compression.zstd`, so you only need to pass `compression='zstd'`. Your Python build must include zstd support. The python.org builds do. On older Python versions, install the optional extra, which brings in the `backports.zstd` package: |
✍️ Drafted by Claude Code
There was a problem hiding this comment.
Addressed in 7f623d3: the sentence about builds without zstd was dropped. The paragraph now reads "Python 3.14 and newer ship zstd in the standard library as compression.zstd, so compression='zstd' works there without an extra. On older Python versions, install the optional extra, which brings in the backports.zstd package:". The no-zstd build case is still covered by the ImportError note below the install block.
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| To compress with `zstd` instead, pass `compression='zstd'`. On Python 3.14 and newer it uses the standard library; on older versions install the optional `zstd` extra with `pip install "apify-client[zstd]"`. |
There was a problem hiding this comment.
Split at the semicolon into two sentences, as the docs style asks.
| To compress with `zstd` instead, pass `compression='zstd'`. On Python 3.14 and newer it uses the standard library; on older versions install the optional `zstd` extra with `pip install "apify-client[zstd]"`. | |
| To compress with `zstd` instead, pass `compression='zstd'`. On Python 3.14 and newer it uses the standard library. On older versions, install the optional `zstd` extra with `pip install "apify-client[zstd]"`. |
✍️ Drafted by Claude Code
| To compress with `zstd`, pass `compression='zstd'`. Python 3.14 and newer have it in the standard library; on older | ||
| versions install the optional `zstd` extra: `pip install "apify-client[zstd]"`. |
There was a problem hiding this comment.
Same here: split at the semicolon.
| To compress with `zstd`, pass `compression='zstd'`. Python 3.14 and newer have it in the standard library; on older | |
| versions install the optional `zstd` extra: `pip install "apify-client[zstd]"`. | |
| To compress with `zstd`, pass `compression='zstd'`. Python 3.14 and newer have it in the standard library. On older | |
| versions, install the optional `zstd` extra: `pip install "apify-client[zstd]"`. |
✍️ Drafted by Claude Code
Reference change
apify/apify-client-js#1200
Ported change
HttpCompressionAlgorithm(apify_client.types) now accepts'zstd', andresolve_compressormaps it to the new compressor. Thecompressionargument ofApifyClient/ApifyClientAsyncand ofActorServerClient.requesttherefore accepts'zstd'.apify_client.http_compressors.ZstdHttpCompressor(http_compressors/_zstd.py), modeled on the gzip and brotli compressors. It reportscontent_encoding = 'zstd'and takes a keyword-onlyqualityfrom1to19, defaulting to3. Levels 20–22 are rejected because their window exceeds the 8 MB that RFC 9659 requires HTTP decoders to support. The body-selection rules (minimum size, already-compressed content types, caller-setContent-Encoding) are the same as for the other algorithms.compression.zstd. Older versions use the officialbackports.zstdpackage through a new optionalzstdextra (pip install "apify-client[zstd]"), following the pattern of thebrotliextra.import apify_clientstill works. Only accessingZstdHttpCompressoror passingcompression='zstd'raises a clearImportError.try_importnow treats a missing parent package of a dotted dependency name as the dependency being missing, and acceptsextra_name=Nonefor dependencies no extra can install.[tool.ty.analysis] allowed-unresolved-importslistsbackports.zstd, because ty checks against Python 3.11 even in 3.14+ environments, where the package is not installed.ValueError, like the existing Python compressors, rather than the JSArgumentValidationError.