Fastapi Step1
This section takes you through a complete example to create a FastAPI application from scratch and understand the meaning of each line of code.
* * *
## Simplest Application
Create a file named main.py and add the following code:
## Example
from fastapi import FastAPI
# Step 1: Import FastAPI class
# Step 2: Create application instance
app = FastAPI()
# Step 3: Define path operation decorator
# Step 4: Define path operation function
@app.get("/")
async def root():
# Step 5: Return response content
return{"message": "Hello World"}
Start the application:
$ uvicorn main:app --reload
Access **http://127.0.0.1:8000**, returns:
{"message": "Hello World"}
* * *
## Code Breakdown
### 1. Import FastAPI
from fastapi import FastAPI
`FastAPI` is a Python class that provides all the core functionality for your API. It inherits directly from Starlette, so you can also use all of Starlette's features.
### 2. Create Application Instance
app = FastAPI()
Create a FastAPI instance, the variable name is usually `app`. This instance is the main interaction object for creating all APIs. Unlike Flask, FastAPI does not require passing the `__name__` parameter.
### 3. Define Path Operation Decorator
@app.get("/")
This line tells FastAPI: when the user accesses the root path / via **GET** method, execute the function below.
This involves two concepts:
| Concept | Description | Example |
| --- | --- | --- |
| **Path** | The second half of the URL starting from the first `/`, also called "endpoint" or "route" | `/items/foo` |
| **Operation** | HTTP method, corresponding to different operation semantics | GET, POST, PUT, DELETE |
FastAPI supports decorators for all HTTP methods:
| Decorator | HTTP Method | Common Usage |
| --- | --- | --- |
| `@app.get()` | GET | Get/Read data |
| `@app.post()` | POST | Create new data |
| `@app.put()` | PUT | Complete data update |
| `@app.patch()` | PATCH | Partial data update |
| `@app.delete()` | DELETE | Delete data |
### 4. Define Path Operation Function
async def root():
This is the path operation function, which is called whenever FastAPI receives a `GET /` request. The function name can be arbitrary, but it is recommended to use a meaningful name.
> You can use `async def` or regular `def` to define the function. FastAPI will automatically handle the difference between the two. If you are not familiar with asynchronous programming, using regular `def` is fine. Asynchronous programming will be covered in detail in later chapters.
### 5. Return Response Content
return {"message": "Hello World"}
The function returns a dictionary, and FastAPI will automatically convert it to JSON format response. You can return `dict`, `list`, `str`, `int` and other types, FastAPI will automatically handle JSON conversion.
* * *
## Add More Routes
Next, we add path parameters and query parameters to enrich the application functionality:
## Example
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
"""Root path, returns welcome message"""
return{"message": "Hello World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None=None):
"""Get item by ID, supports optional query parameter q"""
return{"item_id": item_id,"q": q}
Parameter description for new routes:
| Parameter | Type | Source | Description |
| --- | --- | --- | --- |
| `item_id` | `int` | Path parameter | Obtained from URL path, FastAPI automatically converts string to integer |
| `q` | `str | None` | Query parameter | Obtained from URL's `?q=xxx` part, default value is `None`, meaning optional |
Access test:
# Access root path GET http://127.0.0.1:8000/Response: {"message": "Hello World"}# Access route with path parameter GET http://127.0.0.1:8000/items/5Response: {"item_id": 5, "q": null}# Pass both path parameter and query parameter GET {"item_id": 5, "q": "tutorial"}
Note that the value of `item_id` is integer `5` instead of string `"5"`, this is FastAPI's type declaration data conversion feature. If a non-integer is passed (such as `/items/foo`), FastAPI will return a clear validation error message.
* * *
## Add POST Request
Next, we add a POST route that uses request body:
## Example
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# Define request body data model
class Item(BaseModel):
name: str# Required: Item name
description: str | None=None# Optional: Item description
price: float# Required: Item price
tax: float | None=None# Optional: Tax
@app.post("/items/")
async def create_item(item: Item):
"""Create new item, receives JSON request body"""
return item
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
"""Update specified item, uses both path parameter and request body"""
return{"item_id": item_id,"item_name": item.name}
Here we use Pydantic's `BaseModel` to define the structure of the request body. FastAPI will automatically:
* Parse JSON data from the request into `Item` object
* Validate data types and required fields
* Display request body structure in API documentation
> Pydantic is a core dependency of FastAPI, used for data validation and serialization. Its usage will be covered in detail in later chapters.
* * *
## FastAPI Parameter Recognition Rules
FastAPI automatically identifies parameter sources through the following rules:
| Parameter Source | Recognition Condition | Example |
| --- | --- | --- |
| Path parameter | Parameter name appears in route path's `{}` | `item_id` in `/items/{item_id}` |
| Query parameter | Parameter is a single type (`int`, `str`, `bool`, etc.) | `q: str | None = None` |
| Request body | Parameter type is a Pydantic model | `item: Item` |
You can mix these three types of parameters in the same function, and FastAPI will automatically get data from the correct location.
* * *
## Summary
Core steps to create a FastAPI application:
1. Import `FastAPI`
2. Create application instance `app = FastAPI()`
3. Use decorators (such as `@app.get()`) to define path operations
4. Define path operation functions, use type annotations to declare parameters
5. Run development server with `uvicorn main:app --reload`
YouTip