# How to generate an OpenAPI document with FastAPI
Source: https://speakeasy.com/openapi/frameworks/fastapi

import { Callout, YouTube } from "@/mdx/components";



<div className="mt-10 flex items-center justify-center">
  <YouTube videoId="86hiib_OA4c" />
</div>

Many developers start their API development with FastAPI, and with good reason. FastAPI has rapidly gained traction in the Python community for its excellent performance, intuitive design, and flexibility. It enables developers to craft API solutions that not only run fast but also meet their users' unique needs.

FastAPI is great for building your core API, but you'll want to layer on SDKs and docs to provide your users with easy integration. For that, you'll want an OpenAPI document.

The good news is that FastAPI provides you with an OpenAPI document out of the box. The less good news is that you'll need some tweaking to get the OpenAPI document to a level where it becomes usable with other tooling.

This article will show you how to improve the default OpenAPI document generation to make the most of the generated schema.

## Generating an OpenAPI document with FastAPI

Understanding how FastAPI generates OpenAPI documents can help you make more informed decisions when you customize your FastAPI setup.

The process is fairly straightforward: FastAPI builds the OpenAPI document based on the routes and models you've defined in your application. For every route in your FastAPI application, FastAPI adds an operation to the OpenAPI document. For every model used in these routes, FastAPI adds a schema definition. The request and response bodies, parameters, and headers all draw from these schema definitions.

While this process works well out of the box, FastAPI also offers several customization options that can change the generated OpenAPI document. We'll cover some of these options in the following sections.

## Our FastAPI example app: APItizing Burgers

Let's get this out of the way: The name came in a daydream shortly before lunchtime.

To guide us through this journey, we'll use a simple example FastAPI application: the "APItizing Burgers" burger shop API. This API includes two models, `Burger` and `Order`, and provides basic CRUD operations for managing burgers and orders at our hypothetical burger shop. Additionally, we have a webhook defined for order status events.

We'll look at how we optimized this FastAPI application and refined our models and routes so that the generated OpenAPI document is intuitive and easy to use. We will also explore how we can use this schema to generate SDKs using Speakeasy. The source code for our example API is available in the [framework-fastapi](https://github.com/speakeasy-api/examples/tree/main/framework-fastapi) folder of the Speakeasy Examples repository.

The `framework-fastapi` directory consists of two directories: `app` and `sdk`.

The `app` directory contains the FastAPI server definition: `app/main.py`. This is where we'll look at what we customized.

The `sdk` directory and the two OpenAPI documents, `openapi.yaml` and `openapi.json`, are generated by running `gen.sh` in the root of the project.

Join us as we dive into FastAPI customization and discover how these tweaks can streamline your SDK generation process.

<Callout title="Warning" type="warning">
  When using Pydantic to define models, a known issue is that the serialization
  of `datetime` objects is not timezone-aware. This will cause a mismatch with
  the OpenAPI format `date-time`, which requires RFC 3339 date-time strings with
  timezones included. Consider using
  [`AwareDatetime`](https://docs.pydantic.dev/2.5/api/types/#pydantic.types.AwareDatetime)
  fields in Pydantic models to enable the appropriate
  [validation](https://docs.pydantic.dev/latest/errors/validation_errors/#timezone_aware)
  and ensure your SDK behavior matches the response definition from your server.
</Callout>

## Basic FastAPI setup

Let's get started with the basics – some things you probably do already.

These straightforward examples are trivial but will help you better understand the three steps in the automation pipeline: How FastAPI setup influences OpenAPI documents, which, in turn, influences SDK code.

### Scalar API documentation

FastAPI automatically generates API documentation using Swagger UI. This example also has [Scalar](https://scalar.com/) API documentation. Scalar is an alternative to Swagger UI. Its standout feature, as explained in our blog post, [Choosing a docs vendor: Mintlify vs Scalar vs Bump vs ReadMe vs Redocly](https://www.speakeasy.com/blog/choosing-a-docs-vendor#mintlify-seriously-beautiful-docs), is that it can be used as a standalone API client. Scalar is also easy to use and has a modern UI that can be customized to create branded documentation. We use it for our [Speakeasy docs](https://www.speakeasy.com/blog/release-speakeasy-docs#why-we-partnered-with-scalar).

We added Scalar to the FastAPI app by installing the [Scalar FastAPI plugin](https://github.com/scalar/scalar/blob/main/integrations/fastapi/README.md).

After installing the plugin, we added a "/scalar" route, in `app/main.py`, that returns the Scalar API Reference:

```python
from scalar_fastapi import get_scalar_api_reference