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.


4.56.0

(feat): Add support for URI and path-based pagination.

4.55.5

(fix): Compute Docker Compose project name during generation to avoid invalid characters from runtime directory names (e.g. .seed).

(chore): Cache client constructor signature check at module level and use httpx instead of requests for WireMock admin calls in generated wire test conftest.


4.58.0

(feat): Add support for logging to the generated SDK. Users can configure the logger by passing in a logging parameter to the client constructor.

1from acme import AcmeClient
2from acme.core import ConsoleLogger
3
4client = AcmeClient(
5 token="YOUR_TOKEN",
6 logging={
7 "level": "debug", # "info" is the default
8 "logger": ConsoleLogger(), # ConsoleLogger is the default
9 "silent": False, # True is the default, set to False to enable logging
10 }
11)

The logging parameter accepts a LogConfig dict with the following properties:

  • level: The log level to use. Defaults to "info".
  • logger: The logger to use. Defaults to ConsoleLogger.
  • silent: Whether to silence the logger. Defaults to True.

The level property can be one of the following values:

  • "debug"
  • "info"
  • "warn"
  • "error"

To provide a custom logger, pass an object implementing the ILogger protocol with debug, info, warn, and error methods.

Sensitive headers (authorization, x-api-key, cookie, etc.) are automatically redacted in logs.


4.55.4

(fix): Fix Python 3.14 compatibility by replacing pydantic.v1.datetime_parse imports with Pydantic V2 TypeAdapter-based parse_date/parse_datetime implementations. Remaining pydantic.v1 imports are wrapped with warning suppression to avoid the “Core Pydantic V1 functionality isn’t compatible with Python 3.14” warning.

4.55.3

(fix): Fix body property named json clashing with the json module import when generating json.dumps(jsonable_encoder(...)) for multipart file upload requests. The json module is now aliased as _json when a body property named json is detected.

4.55.2

(fix): Add websocket compatibility shim for websockets library v14. The generated SDK now uses a core/websocket_compat.py module that abstracts the InvalidStatusCode vs InvalidStatus exception difference, ensuring compatibility with both websockets v12-13 and v14+.



4.55.0

(feat): Add support for server URL templating with OpenAPI server variables. This enables dynamic base URL construction at runtime based on user-provided configuration.

OpenAPI definition example:

1servers:
2 - url: https://api.{region}.{environment}.example.com/v1
3 variables:
4 region:
5 default: us-east-1
6 enum: [us-east-1, us-west-2, eu-west-1]
7 environment:
8 default: prod
9 enum: [prod, staging, dev]

Generated constructor parameters: Server variables are exposed as optional constructor parameters with their default values:

  • region: typing.Optional[str] - defaults to "us-east-1"
  • server_url_environment: typing.Optional[str] - defaults to "prod" (prefixed to avoid shadowing)

Runtime URL interpolation: When server variables are provided, the SDK performs runtime URL template interpolation:

1from seed import SeedApi
2
3# Uses default: https://api.us-east-1.prod.example.com/v1
4client = SeedApi()
5
6# Custom region: https://api.eu-west-1.prod.example.com/v1
7client = SeedApi(region="eu-west-1")
8
9# Custom region and environment: https://api.us-west-2.staging.example.com/v1
10client = SeedApi(region="us-west-2", server_url_environment="staging")

Multiple base URL environments: For APIs with multiple base URLs (e.g., separate base and auth URLs), each URL template is interpolated independently with the same server variables.

x-fern-default-url extension: When present in the OpenAPI spec, this extension specifies which server URL should be used as the default environment, overriding the first server in the list.

4.54.4

(fix): The use_provided_defaults config option no longer applies defaults to inlined request body properties.


4.54.3

(fix): Fix mypy type checking compatibility with pydantic field aliases. When fields have aliases (e.g., bucket_id with alias bucketId), the pydantic.Field(alias=…) is now placed inside the Annotated type hint instead of as the default value. This makes mypy see the Python field name in the constructor signature while Pydantic still uses the alias for JSON serialization.