5.12.3
(chore): Bump the python-sdk container’s Node.js stage from node:20.19.4-slim
(Node 20 went EOL March 24, 2026) to node:22.22-bookworm-slim, and
apply latest Debian trixie security updates at build time so OS-level
package CVEs are picked up. Addresses CVE-2025-55130 (Node 20.19.4
permission-model symlink bypass) and the OS-level CVE-2026-31789
against openssl 3.5.1-1.
5.12.2
(chore): Apply latest Debian security updates to the python pydantic generator container
(python:3.11.13) at build time so OS-level package CVEs are picked up.
5.12.1
(fix): Apply canonical “all user-specified examples, else first autogenerated” selection
in the Python v2 SDK snippet output path. Aligns the v2 generator’s snippet.json /
README example selection with the existing v1 behavior so dynamic-IR-driven
snippets are deterministic across runs.
5.12.0
(feat): Add a client-level max_retries: Optional[int] constructor parameter to generated SDK clients.
Consumers can now set a default retry count once at client construction (e.g. Client(max_retries=5))
instead of passing max_retries via request_options on every call. Per-request max_retries
in request_options continues to take precedence over the client-level default.
5.11.0
(feat): New flatten_union_request_bodies config flag (default false). When
enabled, endpoints whose referenced request body is a discriminated
oneOf/union expose all variants’ fields as flat kwargs (Stripe-style),
rather than a single request: Union[...] parameter. The discriminator
becomes a Union[Literal[...], ...] of every variant value; per-variant
fields with the same wire name are merged (with conflicting types
unioned). Existing customers see no change unless they opt in.
5.10.0
(feat): Generate CONTRIBUTING.md for Python SDKs.
5.9.2
(fix): Widen the generated pydantic-core constraint from >=2.18.2,<2.44.0 to
>=2.18.2,<3.0.0, unblocking customers who need newer pydantic-core (e.g.
2.46.x, required by pydantic 2.13). The previous cap targeted 2.44.0’s
missing wheels; that release is yanked on PyPI, so the explicit cap is no
longer needed.
5.9.1
(fix): Respect the customer’s smart-casing flag from generators.yml when computing
Python identifiers from compressed v66 IR strings. Previously the v1 Python
generator’s _smart_snake and v2’s PYTHON_CASE_CONVERTER were both hardcoded
with smartCasing: true, causing names produced by the generator to diverge
from the IR’s pre-computed snake_case values when the customer set
smart-casing: false. This manifested as wire-test method calls and Pydantic
field aliases that did not exist on the generated client (e.g. test calling
set_fcmv_1_provider() while the client method was named set_fcmv1provider).
_smart_snake and the v2 caseConverter now read casingsConfig.smartCasing
from the IR and switch between smart-casing semantics (default) and plain
lodash semantics (smart-casing: false). No effect for customers who use
the default; fixes generation for customers like auth0 that opt out.
5.9.0
(feat): Add retryStatusCodes config with "legacy" and "recommended" modes. Legacy (default)
preserves current behavior (408, 409, 429, >= 500). Recommended retries only transient
codes (408, 409, 429, 502, 503, 504), avoiding idempotency issues with 500. A 6.0.0
migration auto-pins legacy for upgrading users.
5.8.4
(chore): Bump @fern-api/generator-cli to 0.9.21, which includes @fern-api/replay
0.14.0 with fixes for silent customization loss across apply and resolve
paths, per-patch-region diff, and clean follow-up patch preservation.
5.8.3
(fix): Fix async SSE parsing to only split on SSE-spec line terminators (\n, \r, \r\n).
Previously, aiter_sse() used httpx’s aiter_lines() which splits on \u2028 and
\u2029 via Python’s str.splitlines(), corrupting data fields containing those
characters (common in LLM JSON output).
5.8.2
(chore): Bump @fern-api/generator-cli to 0.9.16, which bundles the autoversion
pipeline’s private workspace deps (@fern-api/logging-execa,
@fern-api/task-context, @fern-api/cli-ai) into the published dist/api.js
so consumers no longer hit ERR_MODULE_NOT_FOUND on
logging-execa/src/createLoggingExecutable.js under Vite/Vitest.
5.8.1
(chore): Tighten the generated urllib3 dev-dependency pin to >=2.6.3,<3.0.0
(Python >= 3.9) to address CVE-2026-21441 and several additional
HIGH-severity urllib3 advisories. Projects still supporting Python 3.8
fall back to the tightest safe constraint available for the 1.x line.
5.8.0
(feat): Support omitting username or password from basic auth when configured via
usernameOmit or passwordOmit in the IR. Omitted fields are removed from
the SDK’s public API and treated as empty strings internally (e.g., omitting
password encodes username:, omitting username encodes :password). When
both are omitted, the Authorization header is skipped entirely.
5.7.0
(feat): Use auth scheme placeholder values in README snippets when configured via
placeholder field on auth schemes.
5.6.1
(fix): Fix @fern-api/python-dynamic-snippets to respect the use_typeddict_requests
configuration option. When enabled, dynamic snippets now generate dict literals
instead of Pydantic model constructors for object and discriminated union types.
5.6.0
(feat): Support x-fern-default as fallback value for parameters in generated Python SDKs.
When a header, query parameter, or path parameter has a clientDefault value in the IR,
the generated Python function signature makes that parameter optional with the default
value automatically applied. This enables patterns like optional API version headers
that fall back to a pinned version.