4.61.2

(fix): Re-add @fern-api/generator-cli to Python SDK Docker image. The CLI was inadvertently removed in 4.60.1 when JS-based generators migrated to using the generator-cli JS API directly. The Python generator still relies on the CLI binary via subprocess for README.md and reference.md generation.

4.61.1

(fix): Fix positional_single_property_constructors breaking pydantic response deserialization. The custom __init__ now uses @typing.overload with a permissive *args, **kwargs runtime signature, so pydantic can pass alias-keyed data freely during deserialization while still allowing positional construction like Wrapper("value").


4.61.0

(feat): Add support for DATE_TIME_RFC_2822 primitive type. Fields with format: date-time-rfc-2822 in OpenAPI specs now generate as Rfc2822DateTime (a datetime.datetime subclass) that parses RFC 2822 date strings (e.g., “Wed, 02 Oct 2002 13:00:00 GMT”) using Python’s email.utils.parsedate_to_datetime. Compatible with both Pydantic V1 (__get_validators__) and V2 (__get_pydantic_core_schema__), passing mypy strict type checking.

(fix): Fix code snippet generation for RFC 2822 datetime fields to use email.utils.parsedate_to_datetime() with RFC 2822 format strings instead of datetime.fromisoformat() with ISO 8601 format.

4.60.2

(fix): Fix explode: false query parameter serialization for array types. When an OpenAPI spec sets explode: false on an array query parameter, the generated SDK now serializes values as comma-separated strings (e.g. tags=A,B,C) instead of repeated keys (e.g. tags=A&tags=B&tags=C). This applies to both regular and streaming endpoints.

4.60.1

(chore): Use generator-cli JS API directly instead of subprocess spawning. Remove generator-cli from Docker image since it is now bundled via esbuild.


4.60.0

(feat): Support connectMethodName on WebSocket channels. When a channel specifies a custom connection method name via x-fern-sdk-method-name, the generated SDK uses that name (converted to snake_case) instead of the default connect.

4.59.4

(fix): Fix wire test import generation for organizations with hyphens in their name. Use package_name from custom config when available, and auto-convert hyphens to underscores in the fallback module path to produce valid Python import statements.


4.59.3

(fix): Fix bytes body snippet generation to use request parameter name instead of dynamic IR body key.

(fix): Skip wire test generation for bytes request body endpoints, which lack IR example support.


4.59.1

(fix): Fix wire test imports to respect package_name custom config, preventing import errors when users specify custom package names


4.59.2

(fix): Generate an appropriate client.py file when client.exported_filename differs from client.filename. Previously, the __init__.py would import from the exported filename (e.g., client.py) but that file was never created, causing mypy import-not-found errors.


4.58.1

(fix): Export ConsoleLogger and ILogger from the core module, allowing users to import and use them directly:

1from acme.core import ConsoleLogger, ILogger

4.59.0

(feat): Add offsetSemantics custom config option. When set to "page-index", offset pagination increments by 1 each page instead of by the number of items returned ("item-index", the default).


4.57.3

(fix): Handle optional access tokens in OAuth token provider by raising RuntimeError when the token is None. Fix wire test setup to use client_id/client_secret for OAuth client credentials and expect 2 requests when testing the token endpoint.

4.57.2

(fix): Fix path-based pagination to pass the next page path as path= instead of url= in the generated HTTP client request call.


4.57.1

(fix): Only copy custom_pagination.py into generated SDKs when custom pagination endpoints are present, and only copy pagination.py when standard pagination endpoints are present.

4.57.0

(feat): Add custom_transport: true generator config option that exposes an http_client parameter on generated client constructors for custom httpx transport injection.

Primary use case: Enables PKCE (Proof Key for Code Exchange) OAuth flows and other authentication schemes that require request interception at the transport layer.

Configuration:

1generators:
2 - name: fernapi/fern-python-sdk
3 config:
4 custom_transport: true

Generated parameter types:

  • Sync client: http_client: typing.Optional[httpx.BaseTransport]
  • Async client: http_client: typing.Optional[httpx.AsyncBaseTransport]

Use cases:

  • PKCE OAuth authentication flows requiring code challenge/verifier injection
  • Custom request signing or authentication header manipulation
  • Request/response interception and modification
  • Mock transports for testing without network calls
  • Custom retry logic beyond the built-in exponential backoff

Example pattern (Twilio SDK style):

1# SDK developer provides a factory method in custom code
2class ValidationClient:
3 @classmethod
4 def create(cls, account_sid: str, auth_token: str) -> httpx.BaseTransport:
5 # Custom transport with PKCE or validation logic
6 return CustomValidationTransport(account_sid, auth_token)
7
8# End-user usage
9from myapi import MyClient, ValidationClient
10
11validation_transport = ValidationClient.create("account_sid", "auth_token")
12client = MyClient(http_client=validation_transport, base_url="https://api.example.com")

This feature allows SDK developers to defer transport-specific logic to custom code while the generator simply threads the transport through to httpx.Client/httpx.AsyncClient.