Skip to main content

First steps

This tutorial will guide you through the fundamental concepts of FastAPI by building a simple API application.

The simplest FastAPI application

Let’s start with the most basic FastAPI application possible:
main.py

Breaking it down

Let’s examine each part of this code:

Import FastAPI

FastAPI is the main class that provides all the functionality for your API application.

Create a FastAPI instance

This creates your application instance. The app variable will be the main point of interaction for your entire API.
This app is the same one referred to by uvicorn when you run uvicorn main:app. It tells uvicorn to import the app object from the main module.

Create a path operation

This defines a path operation:
  • @app.get("/") - This is a decorator that tells FastAPI that the function below handles requests to the path / using the HTTP GET method
  • async def root() - This is the path operation function that will be executed when the endpoint is called
  • return {"message": "Hello World"} - FastAPI automatically converts the Python dictionary to JSON

Path operation decorators

FastAPI provides decorators for all standard HTTP methods:
  • @app.get() - Read data
  • @app.post() - Create data
  • @app.put() - Update data (full replacement)
  • @app.delete() - Delete data
  • @app.patch() - Update data (partial update)
  • @app.options() - Return allowed methods
  • @app.head() - Return headers only
  • @app.trace() - Message loop-back test

Example with multiple methods

Path parameters

You can declare path parameters with the same syntax used by Python format strings:
The value of the path parameter item_id will be passed to your function as the argument item_id.

Path parameters with types

You can declare the type of a path parameter using standard Python type annotations:
By declaring item_id: int, FastAPI will automatically:
  • Validate that the path parameter is an integer
  • Convert the string from the URL to an integer
  • Return an error if validation fails
  • Provide editor support with autocompletion and type checking

Data validation example

If you run the server and navigate to http://127.0.0.1:8000/items/3, you’ll see:
But if you go to http://127.0.0.1:8000/items/foo, you’ll get a validation error:

Query parameters

When you declare function parameters that are not part of the path, they are automatically interpreted as query parameters:
The query is the set of key-value pairs after the ? in a URL, separated by &: http://127.0.0.1:8000/items/?skip=0&limit=10 In this example:
  • skip=0
  • limit=10

Optional query parameters

You can declare optional query parameters by setting their default to None:
In this case, the parameter q is optional and will be None by default.
FastAPI is smart enough to know that item_id is a path parameter and q is a query parameter.

Running the application

Save your code in a file called main.py, then run it with:

Using the FastAPI CLI

This starts a development server with:
  • Auto-reload on code changes
  • Interactive API docs at /docs
  • Alternative docs at /redoc

Using uvicorn directly

Alternatively, you can use uvicorn:
Where:
  • main - The Python file main.py (a Python “module”)
  • app - The object created inside main.py with app = FastAPI()
  • --reload - Restart the server when code changes (development only)

Check the interactive API documentation

Once your server is running, open your browser at: http://127.0.0.1:8000/docs You’ll see the automatic interactive API documentation provided by Swagger UI:
  • All your endpoints are listed
  • You can test each endpoint directly from the browser
  • Request and response schemas are automatically generated
  • Try clicking “Try it out” on any endpoint to test it

Alternative documentation

You can also check the alternative automatic documentation at: http://127.0.0.1:8000/redoc

Async or not async?

In the examples above, we used async def for the path operation functions. You can also use regular def:
If you’re not sure, use async def. FastAPI will handle it correctly either way.

When to use async?

  • Use async def if your function performs async operations (database queries with async drivers, external API calls with async clients, etc.)
  • Use regular def if your function performs synchronous operations or you’re not sure

Recap

In this tutorial, you learned:
1

Creating a FastAPI instance

Import FastAPI and create an app instance that serves as your application’s main entry point.
2

Path operation decorators

Use decorators like @app.get(), @app.post(), etc., to define which HTTP method and path each function handles.
3

Path parameters

Declare path parameters in the decorator and as function arguments, with optional type annotations for automatic validation.
4

Query parameters

Function parameters that aren’t path parameters become query parameters automatically.
5

Running the app

Use fastapi dev or uvicorn to run your application with automatic documentation.

Next steps

Now that you understand the basics, explore more advanced topics:

Request body

Handle POST requests with JSON bodies using Pydantic models

Path parameters

Advanced path parameter usage and validation

Query parameters

Deep dive into query parameter validation

Dependencies

Learn FastAPI’s powerful dependency injection system