# Python configuration

> Configuration options for the Fern Python SDK.

You can customize the behavior of the Python SDK generator in `generators.yml`:

```yaml {6-15} title="generators.yml"
groups:
  python-sdk:
    generators:
      - name: fernapi/fern-python
        version: 4.50.1
        config:
          package_name: "your_package"
          client_class_name: "YourClient" 
          additional_init_exports:
            - from: file_with_custom_function
              imports:
                - custom_function
          pydantic_config:
            skip_validation: true
          environment_class_name: "AcmeEnvironment"
```

<ParamField path="additional_init_exports" type="array of objects" default="null" required={false} toc={true}>
  Additional modules or classes to export from the package's `__init__.py` file. This allows you to customize what's available when users import your package.

  Each object should specify which file to import from and what to import:

  ```yaml
  config:
    additional_init_exports:
      - from: core.oauth_flow
        imports:
          - validate_token
      - from: utils.helpers
        imports:
          - format_currency
          - PhoneValidator
  ```

  This enables users to access your custom functions directly:

  ```python
  from my_package import validate_token, format_currency, PhoneValidator
  ```
</ParamField>

<ParamField path="additional_init_exports[].from" type="string" required={true}>
  The module path to import from, using Python dot notation. Omit the `.py` extension and replace path separators with dots.

  For example, if you want to import from the file `core/oauth_flow.py`, specify that as `- from: core.oauth_flow`.
</ParamField>

<ParamField path="additional_init_exports[].imports" type="array of strings" required={true}>
  List of class names, function names, or other objects to import from the specified file.
</ParamField>

<ParamField path="client_class_name" type="string" default="null" required={false} toc={true}>
  The name of the generated client class. Must be PascalCase. For example, setting `client_class_name: "Acme"` generates a client that users import as `from your_package import Acme`.
</ParamField>

<ParamField path="default_bytes_stream_chunk_size" type="number" default="null" required={false} toc={true}>
  The chunk size to use (if any) when processing a response bytes stream within `iter_bytes` or `aiter_bytes` results in: `for chunk in response.iter_bytes(chunk_size=<default_bytes_stream_chunk_size>):`
</ParamField>

<ParamField path="enable_wire_tests" type="bool" default="false" required={false} toc={true}>
  When enabled, generates [mock server (wire) tests](/sdks/deep-dives/testing#mock-server-tests) to verify that the SDK sends and receives HTTP requests as expected.
</ParamField>

<ParamField path="exclude_types_from_init_exports" type="boolean" default="false" required={false} toc={true}>
  When enabled, excludes type definitions from being exported in the package's `__init__.py` file, reducing the public API surface.
</ParamField>

<ParamField path="environment_class_name" type="string" default="{ClientName}Environment" required={false} toc={true}>
  Customize the name of the generated environment class/enum. By default, the environment class is named `{ClientName}Environment` (e.g., `AcmeEnvironment` for a client named `Acme`).
</ParamField>

<ParamField path="extra_dependencies" type="object" default="{}" required={false} toc={true}>
  <Warning title="Pro and Enterprise feature">
    This feature is available only for the [Pro and Enterprise plans](https://buildwithfern.com/pricing). To get started, reach out to [support@buildwithfern.com](mailto:support@buildwithfern.com).
  </Warning>

  If you want to add custom dependencies to your generated SDK, you can specify them using this configuration. For example, to add a dependency on boto3, your config would look like:

  ```yaml
  config:
    extra_dependencies:
      boto3: 1.28.15
  ```
</ParamField>

<ParamField path="extra_dev_dependencies" type="object" default="{}" required={false} toc={true}>
  <Warning title="Pro and Enterprise feature">
    This feature is available only for the [Pro and Enterprise plans](https://buildwithfern.com/pricing). To get started, reach out to [support@buildwithfern.com](mailto:support@buildwithfern.com).
  </Warning>

  Specify additional development dependencies to include in the generated SDK's setup configuration. These are dependencies used for development and testing but not required by end users.
</ParamField>

<ParamField path="extras" type="object" default="{}" required={false} toc={true}>
  Define optional dependency groups that users can install with your package using pip extras (e.g., `pip install your-package[extra-name]`).
</ParamField>

<ParamField path="flat_layout" type="bool" default="false" required={false} toc={true}>
  When enabled, generates a flatter package structure by reducing nested directories and modules.
</ParamField>

<ParamField path="follow_redirects_by_default" type="bool" default="true" required={false} toc={true}>
  Whether to follow redirects by default in HTTP requests.
</ParamField>

<ParamField path="improved_imports" type="bool" default="true" required={false} toc={true}>
  Feature flag that improves imports in the Python SDK by removing nested `resources` directory
</ParamField>

<ParamField path="include_legacy_wire_tests" type="bool" default="false" required={false} toc={true}>
  Whether or not to include legacy wire tests in the generated SDK
</ParamField>

<ParamField path="include_union_utils" type="bool" default="false" required={false} toc={true}>
  When enabled, generates utility methods for working with union types, including factory methods and visitor patterns.
</ParamField>

<ParamField path="inline_path_params" type="bool" default="false" required={false} toc={true}>
  If true, treats path parameters as named parameters in endpoint functions.
</ParamField>

<ParamField path="inline_request_params" type="bool" default="true" required={false} toc={true}>
  Feature flag that removes the usage of request objects, and instead uses parameters in function signatures where possible.
</ParamField>

<ParamField path="lazy_import" type="bool" default="true" required={false} toc={true}>
  Enables lazy loading of client imports. When enabled, modules and classes are imported only when first accessed rather than at package initialization. This reduces memory footprint when using a small portion of a large API, at the cost of a latency penalty when first accessing a client.

  Set to `false` to restore eager loading behavior.
</ParamField>

<ParamField path="package_name" type="string" default="null" required={false} toc={true}>
  Specifies the Python package name that users will import your generated client
  from.

  For example, setting `package_name: "my_custom_package"` enables users to use
  `my_custom_package import Client` to import your client.
</ParamField>

<ParamField path="pyproject_python_version" type="string" default="^3.8" required={false} toc={true}>
  <Warning>
    This changes your declared python dependency, which is not meant to be done often if at all. This is a last resort if any dependencies force you to change your version requirements.
  </Warning>
</ParamField>

<ParamField path="pyproject_toml" type="string" default="null" required={false} toc={true}>
  Allow specifying arbitrary configuration to your packages `pyproject.toml` by adding a `pyproject_toml` block to your configuration
  whatever you include in this block will be added as-is to the `pyproject.toml` file. The config, as an example is:

  ```yaml
  config:
    pyproject_toml: |
      [tool.covcheck.group.unit.coverage]
      branch = 26.0
      line = 62.0
      [tool.covcheck.group.service.coverage]
      branch = 30.0
      line = 67.0
  ```
</ParamField>

<ParamField path="should_generate_websocket_clients" type="bool" default="false" required={false} toc={true}>
  Feature flag that enables generation of Python websocket clients.
</ParamField>

<ParamField path="skip_formatting" type="bool" default="false" required={false} toc={true}>
  When enabled, skips code formatting (like black) on the generated Python code.
</ParamField>

<ParamField path="timeout_in_seconds" type="number | 'infinity'" default="60" required={false} toc={true}>
  By default, the generator generates a client that times out after 60 seconds. You can customize this value by providing a different number or setting to `infinity` to get rid of timeouts.
</ParamField>

<ParamField path="use_api_name_in_package" type="bool" default="false" required={false} toc={true}>
  When enabled, includes the API name as part of the package structure and naming.
</ParamField>

<ParamField path="use_inheritance_for_extended_models" type="bool" default="true" required={false} toc={true}>
  Whether to generate Pydantic models that implement inheritance when a model utilizes the Fern `extends` keyword.
</ParamField>

<ParamField path="use_typeddict_requests" type="bool" default="false" required={false} toc={true}>
  Whether or not to generate `TypedDicts` instead of Pydantic Models for request objects.
</ParamField>

<ParamField path="use_typeddict_requests_for_file_upload" type="bool" default="false" required={false} toc={true}>
  Whether or not to generate TypedDicts instead of Pydantic Models for file upload request objects. Note that this flag was only introduced due to an oversight in the `use_typeddict_requests` flag implementation; it should be removed in the future.
</ParamField>

### client

The `client` block provides advanced configuration for the generated client class and file structure. For most use cases, the top-level `client_class_name` option is sufficient. Use the `client` block when you need to customize filenames or have different internal and exported class names.

```yaml
config:
  client:
    filename: "my_client.py"
    class_name: "MyClient"
    exported_filename: "my_client.py"
    exported_class_name: "MyClient"
```

<ParamField path="client.filename" type="string" default="client.py" required={false} toc={true}>
  The filename for the generated client file.
</ParamField>

<ParamField path="client.class_name" type="string" default="null" required={false} toc={true}>
  The name of the generated client class. For most use cases, use the top-level `client_class_name` option instead.
</ParamField>

<ParamField path="client.exported_filename" type="string" default="client.py" required={false} toc={true}>
  The filename of the exported client which will be used in code snippets.
</ParamField>

<ParamField path="client.exported_class_name" type="string" default="null" required={false} toc={true}>
  The name of the exported client class that will be used in code snippets.
</ParamField>

### pydantic\_config

Configure Pydantic model generation settings for your Python SDK.

```yaml
config:
  pydantic_config:
    enum_type: "literals"
    extra_fields: "forbid"
    frozen: true
    include_union_utils: false
    include_validators: true
    orm_mode: false
    positional_single_property_constructors: false
    require_optional_fields: false
    skip_formatting: false
    skip_validation: true
    smart_union: true
    union_naming: "v0"
    use_inheritance_for_extended_models: true
    use_pydantic_field_aliases: false
    use_provided_defaults: true
    use_str_enums: true
    use_typeddict_requests: false
    wrapped_aliases: false
```

<ParamField path="enum_type" type="'literals' | 'forward_compatible_python_enums' | 'python_enums'" default="literals" toc={true}>
  The type of enums to use in the generated models:

  * `literals`: Use Python Literal types, e.g. `MyEnum = Literal["foo", "bar"]`
  * `forward_compatible_python_enums`: Use Python Enum classes, with a `MyEnum._UNKNOWN` member for forward compatibility. `MyEnum._UNKNOWN.value` contains the raw unrecognized value.
  * `python_enums`: Your vanilla Python enum class, with the members defined within your API.
</ParamField>

<ParamField path="extra_fields" type="literal<'allow' | 'forbid' | 'ignore'>" default="allow" toc={true}>
  How to handle extra fields not defined in the model schema.
</ParamField>

<ParamField path="frozen" type="bool" default="true" toc={true}>
  Whether Pydantic models should be frozen (immutable after creation).
</ParamField>

<ParamField path="include_union_utils" type="bool" default="false" toc={true}>
  When enabled, the generator will output a Pydantic `__root__` class that will contain utilities to visit the union. For example, for the following union type:

  ```
  types:
  Shape:
    union:
      circle: Circle
      triangle: Triangle
  ```

  you will get a generated `Shape` class that has a factory and visitor:

  ```python
  # Use a factory to instantiate the union
  Shape.factory.circle(Circle(...))

  # Visit every case in the union
  shape = get_shape()
  shape.visit(
    circle: lambda circle: do_something_with_circle(circle),
    triangle: lambda triangle: do_something_with_triangle(triangle),
  )
  ```
</ParamField>

<ParamField path="include_validators" type="bool" default="false" toc={true}>
  Include custom validators in generated Pydantic models.
</ParamField>

<ParamField path="orm_mode" type="bool" default="false" toc={true}>
  Enable ORM mode for Pydantic models to work with ORMs like SQLAlchemy.
</ParamField>

<ParamField path="positional_single_property_constructors" type="bool" default="false" toc={true}>
  When enabled, generates a custom `__init__` method for models with a single required field, allowing positional argument construction instead of requiring keyword arguments.

  ```python
  # Without positional_single_property_constructors (default)
  wrapper = Wrapper(value="my_value")

  # With positional_single_property_constructors enabled
  wrapper = Wrapper("my_value")
  ```

  <Warning>
    Enabling this option can cause backwards compatibility issues. If a model later adds another required field, the positional `__init__` will no longer be generated, causing runtime failures for existing code that uses positional arguments. Use keyword arguments for long-term stability.
  </Warning>
</ParamField>

<ParamField path="package_name" type="string" required={false} toc={true}>
  Custom package name for the generated models.
</ParamField>

<ParamField path="require_optional_fields" type="bool" default="false" toc={true}>
  Whether optional fields must be explicitly provided (cannot be omitted).
</ParamField>

<ParamField path="skip_formatting" type="bool" default="false" toc={true}>
  Skip code formatting for generated Pydantic models.
</ParamField>

<ParamField path="skip_validation" type="bool" default="false" toc={true}>
  When enabled, disables Pydantic validation for API responses. This ensures that Pydantic does not immediately fail if the model being returned from an API does not exactly match the Pydantic model.

  This is meant to add flexibility should your SDK fall behind your API, but should be used sparingly, as the type-hinting for users will still reflect the Pydantic model exactly.
</ParamField>

<ParamField path="smart_union" type="bool" default="true" toc={true}>
  Enable smart union handling in Pydantic models for better type discrimination.
</ParamField>

<ParamField path="union_naming" type="'v0' | 'v1'" default="v0" toc={true}>
  Control union naming strategy. If you are dealing with discriminated union members that already have the discriminant property on them (and they're only used in one union), you should prefer the global API config within your `generators.yml`:

  ```yaml
  - name: fernapi/fern-python-sdk
    version: 3.0.0-rc0
    api:
      settings:
        unions: v1
  ```
</ParamField>

<ParamField path="use_pydantic_field_aliases" type="bool" default="false" toc={true}>
  Use Pydantic field aliases for property names that differ from wire format.
</ParamField>

<ParamField path="use_provided_defaults" type="bool" default="false" toc={true}>
  Leverage defaults specified in the API specification.
</ParamField>

<ParamField path="use_typeddict_requests" type="bool" default="false" toc={true}>
  Generate TypedDicts instead of Pydantic Models for request objects.
</ParamField>

<ParamField path="version" type="'v1' | 'v2' | 'both' | 'v1_on_v2'" default="both" toc={true}>
  By default, the generator generates pydantic models that are v1 and v2 compatible. However you can override them to:

  * `v1`: strictly use Pydantic v1
  * `v2`: strictly use Pydantic v2
  * `both`: maintain compatibility with both versions
  * `v1_on_v2`: use Pydantic v1 compatibility layer on v2
</ParamField>

<ParamField path="wrapped_aliases" type="bool" default="false" toc={true}>
  Enable wrapped aliases for Pydantic models. Only supported in Pydantic V1, V1\_ON\_V2, or V2.
</ParamField>

<ParamField path="use_inheritance_for_extended_models" type="bool" default="true" toc={true}>
  Generate Pydantic models that implement inheritance when a model utilizes the Fern `extends` keyword.
</ParamField>