# This server configuration will be used by Speakeasy when generating SDKs
openapi: 3.1.0
info:
  title: APItizing Burgers API
  version: 0.1.0
servers:
  - description: Local server
    url: http://127.0.0.1:8000/
```

After Speakeasy generates the SDK, this leads to the following abbreviated code in `sdk/src/openapi/sdkconfiguration.py`:

```python
from dataclasses import dataclass

SERVERS = [
    'http://127.0.0.1:8000/',
    # Local server
]
"""Contains the list of servers available to the SDK"""

@dataclass
class SDKConfiguration:
    ...
    server_url: Optional[str] = ""
    server_idx: Optional[int] = 0
    ...

    def __post_init__(self):
        self._hooks = SDKHooks()

    def get_server_details(self) -> Tuple[str, Dict[str, str]]:
        if self.server_url is not None and self.server_url:
            return remove_suffix(self.server_url, "/"), {}
        if self.server_idx is None:
            self.server_idx = 0

        return SERVERS[self.server_idx], {}
```

You'll find calls to `SDKConfiguration.get_server_details()` when the SDK builds API URLs:

```python
from dataclasses import dataclass

SERVERS = [
    'http://127.0.0.1:8000/',
    # Local server
]
"""Contains the list of servers available to the SDK"""

@dataclass
class SDKConfiguration:
    ...
    server_url: Optional[str] = ""
    server_idx: Optional[int] = 0
    ...

    def __post_init__(self):
        self._hooks = SDKHooks()

    def get_server_details(self) -> Tuple[str, Dict[str, str]]:
        if self.server_url is not None and self.server_url:
            return remove_suffix(self.server_url, "/"), {}
        if self.server_idx is None:
            self.server_idx = 0

        return SERVERS[self.server_idx], {}
```

Speakeasy uses the title, summary, and descriptions we provided earlier to add helpful text to the generated SDK documentation, including comments in the SDK code. For example, in `sdk/src/openapi/sdk.py`:

```python
class SDK(BaseSDK):
    r"""APItizing Burgers API: A simple API to manage burgers and orders

    This API is used to manage burgers and orders in a restaurant
    """
```

Speakeasy adds the version to the `SDKConfiguration` in `sdk/src/openapi/sdkconfiguration.py`. It also uses this version to construct the user agent (`user_agent`), which contains the version of the SDK, the version of the Speakeasy generator build, and the version of the OpenAPI documentation:

```python
from dataclasses import dataclass

@dataclass
class SDKConfiguration:
    ...
    openapi_doc_version: str = '0.1.0'
    user_agent: str = "speakeasy-sdk/python 0.2.0 2.607.0 0.1.0 openapi"
    ...
```

When users call your API using the generated SDK, the `user_agent` from `SDKConfiguration` is automatically added to the `user-agent` header. The `_build_request_with_client` method in `BaseSDK` constructs the HTTP request and sets the header using `headers[user_agent_header] = self.sdk_configuration.user_agent`:

```python
def _build_request_with_client(
    self,
    ...
    user_agent_header,
    ...
) -> httpx.Request:
    ...
    headers["Accept"] = accept_header_value
    headers[user_agent_header] = self.sdk_configuration.user_agent
    ...
```

### Operation ID issues and solutions

The unique `operation_id` generated by FastAPI does not translate well into an SDK. We need to customize the unique `operation_id` that FastAPI generates for better readability.

For instance, in the operation that returns a burger by `burger_id`, the default unique ID would be `read_burger_burger__burger_id__get`. This makes its way into SDK code, leading to class names such as `ReadBurgerBurgerBurgerIDGetRequest` or function names like `read_burger_burger_burger_id_get`.

Here's a usage example after generating an SDK without customizing the `operationId`:

```python
import sdk
from sdk.models import operations

s = sdk.SDK()

req = operations.ReadBurgerBurgerBurgerIDGetRequest(
    burger_id=847252,
)

res = s.burger.read_burger_burger_burger_id_get(req)
```

However, after using the custom function `generate_unique_id` we defined previously, the `read_burger` operation gets a friendlier operation ID, `readBurger`, and the usage example becomes easier to read:

```python
import sdk
from sdk.models import operations

s = sdk.SDK()

req = operations.ReadBurgerRequest(
    burger_id=847252,
)

res = s.burger.read_burger(req)
```

In addition to the two methods described earlier, there is a third way to customize the `operation_id`. We can add the top-level `x-speakeasy-name-override` [Speakeasy extension](https://www.speakeasy.com/docs/speakeasy-reference/extensions) to our OpenAPI document, allowing Speakeasy to override the generated names when it generates SDK code.
To add this extension, follow the Speakeasy guide to [changing method names](/docs/customize-sdks/methods).

```yaml filename="name-override.yaml"