跳到导航

5.41.17

(fix): Fix reference.md source links when package_name contains dots or package_path is set. Links previously used the dotted Python module path (e.g. src/acme.management/actions/client.py) instead of the directory path (src/acme/management/actions/client.py).

(fix): reference.md method links now point at the method’s line range in client.py (e.g. src/acme/management/actions/client.py#L54-L125) instead of the top of the file.

5.41.16

(fix): When whitelabel is enabled, the SDK’s logger is now named after the package, with dashes turned into dots (for example acme-orders logs as acme.orders), instead of {package name}_sdk_{version}. The name no longer changes on every release, and it sits under parent loggers such as acme.

(fix): The PyPI package name is now always normalized per the Python packaging spec: runs of ., _, and - become a single -, and the name is lowercased (for example Acme_Orders.v2 becomes acme-orders-v2). This applies to pyproject.toml, the SDK name header, and the User-Agent. PyPI already treats these spellings as the same package, so installs are unaffected.

5.41.15

(fix): When whitelabel is enabled, the SDK’s platform headers are now sent as X-Codegen-* (for example X-Codegen-Language) instead of X-Fern-*, and the SDK’s logger is named {package name}_sdk_{version} instead of fern.

5.41.14

(fix): README generation in self-hosted GitHub mode can clone a private repository with a personal access token again. Upgrades @fern-api/generator-cli to 0.12.1, which also sends the token as an Authorization header. Before this, git in the generator image (libcurl 8.23+) dropped the token from the clone URL and failed with could not read Username.

5.41.13

(fix): When whitelabel is enabled, every generated file now uses the unbranded header (“This file was auto-generated from our API Definition.”). Previously __init__.py files, most core/ utilities, _default_clients.py, webhook signature helpers, XML model tests, and test asset models still said “by Fern”. Files copied from disk no longer get the header twice.

5.41.12

(fix): Generated SDKs now keep the original copyright and license notices for core files adapted from open-source projects: core/jsonable_encoder.py (FastAPI, MIT), the four core/http_sse/ modules (httpx-sse, MIT), the Retry-After parsing in core/http_client.py (urllib3, MIT) and the file types in core/file.py (httpx, BSD-3-Clause).

5.41.11

(fix): Fix recursive aliases and undiscriminated unions under pydantic_config.version: v2 without wrapped_aliases. A plain alias that refers back to itself (e.g. JsonLike = Union[List["JsonLike"], ...], or a map whose values are a union containing that map) was expanded endlessly by Pydantic, so building the model raised RecursionError or ... is not fully defined. Such an alias is now a typing_extensions.TypeAliasType at runtime, which Pydantic v2 resolves lazily, and stays a plain alias under TYPE_CHECKING for mypy and pyright. Values come back as plain dicts and lists, with no root model to unwrap. Other aliases, and SDKs on Pydantic v1, both or wrapped_aliases, are unchanged.

5.41.10

(fix): Fix the README “Async Client” snippet dropping types imported from the package root. Previously the whole from <package> import <Client>, <Type>, ... line of the sync snippet was discarded, so the async example only imported the async client and referenced request types that were never imported. The async snippet now imports those names alongside the async client.

5.41.9

(fix): update_forward_refs now passes its namespace to model_rebuild under Pydantic v2. Models whose forward references go through a union alias (e.g. a recursive Union["Branch", Leaf, "Items"] whose members are imported under TYPE_CHECKING) were left incomplete, and parsing them raised PydanticUserError: ... is not fully defined.

5.41.8

(fix): Fix SDKs generated with tcp_keepalive.enabled: true ignoring the HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY environment variables. httpx skips environment proxies whenever a custom transport is passed, so the default sync and async clients now also pass mounts built from the environment proxies, each carrying the keepalive socket options.

5.41.7

(fix): Add the http_client_extra option. When set (e.g. http_client_extra: client), httpx is declared as an optional dependency exposed under that extra (pip install <pkg>[client]), so a plain install of a package used for its models only (e.g. TwiML) does not pull in the HTTP stack. Off by default; existing SDKs are unchanged.

5.41.6

(fix): Respect the retry-after-ms response header when computing retry delays. The header value was compared to 0 before being converted to a number, raising a TypeError that was silently swallowed, so the client always fell back to Retry-After or exponential backoff.

5.41.5

(fix): XML (TwiML) serialization drops characters outside the XML 1.0 Char production (e.g. \x01) from text and attribute values instead of emitting XML that no parser accepts.

5.41.4

(fix): Path parameter values of exactly . or .. now raise a ValueError before the request is sent. These are dot-segments that httpx resolves, so they could change which endpoint the request was sent to. When encode_path_params is off (the default), values are not percent-encoded, so any . or .. segment inside the value (including %2e forms) is also rejected.

5.41.3

(fix): WebhooksHelper.verifyRequest now parses name=value settings headers when webhook-signature.algorithm-header sets key-id-parameter/algorithm-parameter (e.g. Twilio’s X-Twilio-Webhooks-Signature-Settings: key=<id>,algorithm=HMAC_SHA256), so the key resolver receives the bare key ID instead of key=<id>. Requires IR 67.33.0.

5.41.2

(fix): The generated WebhooksHelper now consumes algorithm-header from api.settings.webhook-signature: a request-level verifyRequest helper reads the configured signature header first (missing or empty fails early with “could not run: missing signature header”), then the algorithm-selection header (e.g. X-Twilio-Webhook-Signature-Settings: <key_id>;HMAC_SHA256) to pick the HMAC algorithm from the configured wire values and hand the key ID to an application-supplied secret resolver. When the header is absent the configured default algorithm and the plain secret are used, so legacy auth-token flows keep working. The lower-level verifySignature is unchanged and still returns false without throwing.

5.41.1

(fix): Models that keep unknown JSON keys no longer keep one that matches a declared field except for case (e.g. VALUE next to value). Such a key used to be sent again after the declared field, so a case-insensitive decoder on the receiving end (e.g. Go’s encoding/json) read it instead of the field’s value. Other unknown keys (e.g. brand_new_field) are still kept and sent as before.

5.41.0

(feat): Wire tests now cover every example instead of only the first one per endpoint. Each user-specified example gets its own test (or the first autogenerated success example when there are none), and when none of an endpoint’s user examples is an error example, the autogenerated error examples are added too. Error tests assert the typed error the client raises for the status code (or the base ApiError when the client can’t dispatch to a typed error) along with its status_code and body. Each test is served by its own X-Test-Id-scoped WireMock stub with the declared status code, and the test client disables retries. Set wire_tests.fallback_to_autogenerated_error_examples: false to leave out autogenerated error examples.

5.40.0

(feat): Support inferred bearer auth with type: refresh-token. The generated InferredAuthTokenProvider always sends grant_type="refresh_token" to the get-token endpoint, and grant_type is no longer a client constructor parameter. Users pass only the refresh token (and any other non-literal token endpoint parameters).

(feat): Inferred auth now works next to other auth schemes (auth: any and endpoint-security) when it has credentials of its own, e.g. a type: refresh-token scheme next to OAuth client credentials. The client takes the inferred credentials as optional constructor parameters (shared ones such as client_id are added once) and uses the inferred token provider when they are passed, so Client(refresh_token=...) and Client(client_id=..., client_secret=...) both work.

5.39.5

(fix): Fix the root client docstring example for global headers and root path parameters that have a client-default. The example now passes the default as a keyword argument (e.g. version="2024-01-01") instead of a bare positional value, which was a SyntaxError when it followed another keyword argument.