Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 49 additions & 11 deletions fern/products/openapi-def/pages/extensions/parameter-names.mdx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
---
title: Customize parameter names
description: Use `x-fern-parameter-name` to customize query parameter, header and path parameter naming.
description: Use extensions to customize parameter naming and behavior in your generated SDKs.
---

<Note>
The `x-fern-parameter-name` extension allows you to customize the variable names of parameters in your generated SDKs.
Extensions allow you to customize how parameters are handled in your generated SDKs. This includes renaming parameters and injecting values via constructors.
</Note>

## Headers
## Parameter naming with x-fern-parameter-name

In the example below, the header `X-API-Version` is renamed to `version` in the
generated SDK. The rename makes the SDK more human readable.
Use `x-fern-parameter-name` to customize variable names for parameters in your generated SDKs.

### Headers

Rename header parameters to make them more idiomatic in your SDK:

```yaml {8}
paths:
Expand All @@ -26,10 +29,9 @@ paths:
required: true
```

## Query parameters
### Query parameters

In the example below, the query parameter `q` is renamed to `search_terms` in the
generated SDK. The rename makes the parameter more approachable for end users.
Make query parameter names more descriptive and user-friendly:

```yaml {8}
paths:
Expand All @@ -45,10 +47,9 @@ paths:
required: false
```

## Path parameters
### Path parameters

In the example below, the path parameter `userId` is renamed to `id` in the
generated SDK. The rename makes the SDK less verbose.
Simplify verbose path parameter names:

```yaml {8}
paths:
Expand All @@ -63,3 +64,40 @@ paths:
type: string
required: false
```

## Constructor Variables with x-fern-sdk-variables

Use `x-fern-sdk-variables` to define variables that can be set once in the client constructor and automatically injected into requests.

```yaml
components:
x-fern-sdk-variables:
project_id:
type: string
description: "The ID of the project"
pattern: "^proj_[a-zA-Z0-9]+$"
```

This variable can then be referenced in path parameters:

```yaml
paths:
"/v1/connect/{project_id}/accounts":
parameters:
- name: project_id
in: path
required: true
schema:
type: string
pattern: "^proj_[a-zA-Z0-9]+$"
x-fern-sdk-variable: project_id
```

The generated SDK will now:
1. Accept the `project_id` in the client constructor
2. Automatically inject it into requests that require it
3. Free users from having to pass it on every request

<Note>
SDK variables are currently supported in TypeScript and Python SDKs (version 4.24.0+).
</Note>
96 changes: 66 additions & 30 deletions fern/products/sdks/overview/python/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ groups:
## SDK Configuration Options

<ParamField path="additional_init_exports" type="array" default="null" required={false} toc={true}>
Additional objects to export from the package's __init__.py file.
</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="exclude_types_from_init_exports" type="bool" default="false" required={false} toc={true}>
When true, types will not be exported from the package's __init__.py file.
</ParamField>

<ParamField path="extra_dependencies" type="object" default="{}" required={false} toc={true}>
Expand All @@ -40,27 +42,31 @@ groups:
</ParamField>

<ParamField path="extra_dev_dependencies" type="object" default="{}" required={false} toc={true}>
Additional development dependencies to include in the generated package.
</ParamField>

<ParamField path="extras" type="object" default="{}" required={false} toc={true}>
Optional extras/features to include in the generated package setup.
</ParamField>

<ParamField path="flat_layout" type="bool" default="false" required={false} toc={true}>
When true, generates a flatter directory structure without nested subdirectories.
</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
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
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, includes additional utility functions for working with union types.
</ParamField>

<ParamField path="inline_path_params" type="bool" default="false" required={false} toc={true}>
Expand All @@ -72,26 +78,18 @@ groups:
</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.
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:
For example, setting `package_name: "my_custom_package"` enables users to use `from my_custom_package import Client` to import your client:

```yaml {7-10}
default-group: local
groups:
local:
generators:
- name: fernapi/fern-python
version: 0.7.1
config:
package_name: "my_custom_package"
```
```yaml
config:
package_name: "my_custom_package"
```
</ParamField>

<ParamField path="pydantic_config" type="SdkPydanticModelCustomConfig" default="SdkPydanticModelCustomConfig()" required={false} toc={true}>
Configuration options for Pydantic model generation.
</ParamField>

<ParamField path="pydantic_config.include_union_utils" type="bool" default="false" required={false} toc={true}>
Expand All @@ -112,12 +110,10 @@ groups:
# 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),
circle=lambda circle: do_something_with_circle(circle),
triangle=lambda triangle: do_something_with_triangle(triangle),
)
```

When enabled, the python generator will not run Black formatting in the generated code. Black is slow so this can potentially speed up code generation quite a bit.
</ParamField>

<ParamField path="pydantic_config.version" type="'v1' | 'v2' | 'both' | 'v1_on_v2'" default="both" required={false} toc={true}>
Expand All @@ -140,20 +136,23 @@ groups:
</ParamField>

<ParamField path="pyproject_toml" type="string" default="null" required={false} toc={true}>
Custom pyproject.toml content to include in the generated package.
</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 true, skips code formatting of the generated SDK.
</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 true, includes the API name in the generated package name.
</ParamField>

<ParamField path="use_inheritance_for_extended_models" type="bool" default="true" required={false} toc={true}>
Expand All @@ -168,17 +167,54 @@ groups:
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>

### Extension Headers

The Python SDK generator supports setting extension headers via the `x-fern-sdk-variables` OpenAPI extension. This allows you to define variables that will be passed to the SDK constructor and injected into API paths.

For example, to have a `project_id` variable injected into paths:

```yaml
# OpenAPI spec
x-fern-sdk-variables:
project_id:
type: string
description: The ID of the project
pattern: "^proj_[a-zA-Z0-9]+$"

paths:
/v1/connect/{project_id}/accounts:
parameters:
- name: project_id
in: path
required: true
schema:
type: string
pattern: "^proj_[a-zA-Z0-9]+$"
x-fern-sdk-variable: project_id
```

The variable will be available in the SDK client constructor:

```python
from my_sdk import Client

client = Client(
project_id="proj_123" # Will be injected into paths
)
```

### client
Configuration for the generated client class and file structure.

```yaml
config:
client:
filename: "my_client.py"
class_name: "MyClient"
exported_filename: "my_client.py"
exported_class_name: "MyClient"
```
Configuration for the generated client class and file structure.

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

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