# Define OpenAPI class with retry extension
class OpenAPIwithRetries(OpenAPI):
    """OpenAPI with x-speakeasy-retries extension"""
    xSpeakeasyRetries: Dict[str, Any] = Field(
        ...,
        description="Retry configuration for the API",
        alias="x-speakeasy-retries",
    )
    model_config = ConfigDict(populate_by_name=True)

def construct_base_open_api() -> OpenAPIwithRetries:
    return OpenAPIwithRetries(
        openapi="3.1.0",
        info=Info(title="Pet Sitter API", version="0.0.1"),
        servers=[{"url": "http://127.0.0.1:4010", "description": "Local prism server"}],
        # Add retry configuration
        xSpeakeasyRetries={
            "strategy": "backoff",
            "backoff": {
                "initialInterval": 500,
                "maxInterval": 60000,
                "maxElapsedTime": 3600000,
                "exponent": 1.5,
            },
            "statusCodes": ["5XX"],
            "retryConnectionErrors": True,
        },
        # Define API paths (endpoints)
        paths={
            # ... API endpoints defined the same as before ...
        }
    )
```

This produces an OpenAPI document with retry functionality:

```yaml filename="openapi.yaml"
x-speakeasy-retries:
  strategy: backoff
  backoff:
    initialInterval: 500
    maxInterval: 60000
    maxElapsedTime: 3600000
    exponent: 1.5
  statusCodes:
    - 5XX
  retryConnectionErrors: true
```

### Adding tags to the OpenAPI document

To group operations in the OpenAPI document, you can use tags. This also allows Speakeasy to structure the generated SDK code and documentation logically.

Add a `tags` field to the `OpenAPIwithRetries` object, then add a `tags` field to each operation in the `construct_base_open_api` function:

```python filename="api.py"
def construct_base_open_api() -> OpenAPIwithRetries:
    return OpenAPIwithRetries(
        # Basic API info
        openapi="3.1.0",
        info=Info(title="Pet Sitter API", version="0.0.1"),

        # Define tags for grouping operations
        tags=[
            {"name": "pets", "description": "Operations about pets"},
            {"name": "owners", "description": "Operations about owners"},
        ],

        # API endpoints with tags applied
        paths={
            "/pets": PathItem(
                get=Operation(
                    operationId="listPets",
                    tags=["pets"],
                    # other properties...
                ),
            ),
            # other endpoints...
        },
    )
```

Run `python api.py` to update the `openapi.yaml` file with the `tags` field, then regenerate the SDK using Speakeasy.

```bash filename="Terminal"
python api.py
speakeasy quickstart
```

Speakeasy will detect the changes to your OpenAPI document, generate the SDK with the updated tags, and automatically increment the SDK's version number.

Take a look at the generated SDK to see how Speakeasy groups operations by tags.

In the SDK `README.md` file, you'll find documentation about your Speakeasy SDK. TypeScript SDKs generated with Speakeasy include an installable [Model Context Protocol (MCP) server](/docs/standalone-mcp/build-server) where the various SDK methods are exposed as tools that AI applications can invoke. Your SDK documentation includes instructions for installing the MCP server.

Note that the SDK is not ready for production use. To get it production-ready, follow the steps outlined in your Speakeasy Studio workspace.

## How Speakeasy helps get your Pydantic models ready for SDK generation

In this tutorial, we learned how to generate an OpenAPI document from Pydantic models and use it to generate an SDK client using Speakeasy.

If you would like to discuss how to get your Pydantic models ready for SDK generation, give us feedback, or shoot the breeze about all things OpenAPI and SDKs, [join our Slack](https://go.speakeasy.com/slack).

If you haven't already, take a look at our [blog](/blog) to learn more about API design, SDK generation, and our latest features, including:

- [Native JSONL support in your SDKs](/blog/release-jsonl-support)
- [Introducing comprehensive SDK testing](/blog/release-sdk-testing)
- [Model Context Protocol: TypeScript SDKs for the agentic AI ecosystem](/blog/release-model-context-protocol)
- [Python generation with async and Pydantic support](/blog/release-python)
- [Choosing your Python REST API framework](/blog/choosing-your-framework-python)