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
74 changes: 60 additions & 14 deletions fern/products/openapi-def/pages/extensions/parameter-names.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
---
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.
OpenAPI extensions allow you to customize how parameters are handled in your generated SDKs.
</Note>

## Headers
## Renaming Parameters

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.
### x-fern-parameter-name

```yaml {8}
Use `x-fern-parameter-name` to customize the variable names of parameters in your generated SDKs:

#### Headers

Rename header parameters to make them more readable:

```yaml
paths:
"/user":
get:
Expand All @@ -26,12 +31,11 @@ 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:

```yaml {8}
```yaml
paths:
"/user/search":
get:
Expand All @@ -45,12 +49,11 @@ 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 path parameter names:

```yaml {8}
```yaml
paths:
"/user/{userId}":
get:
Expand All @@ -63,3 +66,46 @@ paths:
type: string
required: false
```

## SDK Variables

### x-fern-sdk-variables

Use `x-fern-sdk-variables` to define variables that can be set at the SDK client level and injected into requests:

```yaml
components:
x-fern-sdk-variables:
project_id:
type: string
description: "The project ID to use for all requests"
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
```

This allows users to set the variable once when instantiating the client:

```python
client = Client(project_id="proj_123")
```

Rather than passing it to every method:

```python
# No need to pass project_id to each call
accounts = client.accounts.list()
```

<Note>
SDK variables help reduce repetition and make your SDK more ergonomic by allowing common parameters to be configured once at the client level.
</Note>
111 changes: 66 additions & 45 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 exports to include in 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}>
Whether to exclude type definitions from being exported in the package's __init__.py file.
</ParamField>

<ParamField path="extra_dependencies" type="object" default="{}" required={false} toc={true}>
Expand All @@ -40,98 +42,83 @@ 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 dependency groups that can be installed with the package.
</ParamField>

<ParamField path="flat_layout" type="bool" default="false" required={false} toc={true}>
Whether to generate a flat file structure instead of nested directories.
</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, generates utility functions for working with union types.
</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.
If true, treats path parameters as named parameters in endpoint functions rather than using a request object.
</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="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 `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}>
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:
When enabled, generates a Pydantic `__root__` class containing utilities to visit unions. For example:

```
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),
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}>
By default, the generator generates pydantic models that are v1 and v2 compatible. However you can override them to:
Controls Pydantic version compatibility:
- `v1`: strictly use Pydantic v1
- `v2`: strictly use Pydantic v2
- `v2`: strictly use Pydantic v2
- `both`: maintain compatibility with both versions
- `v1_on_v2`: use Pydantic v1 compatibility layer on v2

Example:

```yaml
config:
pydantic_config:
version: v1 # or v2 or "both"
version: v2
```
</ParamField>

Expand All @@ -140,20 +127,23 @@ groups:
</ParamField>

<ParamField path="pyproject_toml" type="string" default="null" required={false} toc={true}>
Custom pyproject.toml contents 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}>
Whether to skip code formatting on the generated files.
</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}>
Whether to include 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 +158,48 @@ 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 generator supports extension headers through the `x-fern-sdk-variables` configuration in your OpenAPI spec. This allows you to define variables that will be included in the client configuration and injected into API paths.

For example, to define a project ID variable that will be included in all paths:

```yaml
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 your paths:

```yaml
paths:
/v1/connect/{project_id}/accounts:
parameters:
- name: project_id
in: path
required: true
schema:
type: string
x-fern-sdk-variable: project_id
```

The generated client will include this variable in its configuration and automatically inject it into request 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
Loading
Loading