Core functions
Define routes
There are two main ways to define routes in FastAPI, one is to use the FastAPI application instance method (for exampleapp.get()
), and the other is to use a decorator (for example @app.get()
), their usage and functions are slightly different.
-
Method 1: Using FastAPI application instance
app.get()
Methods such as ,app.post()
are used to define routes directly on the application instance.These methods accept a path string and a processing function as parameters, mapping the specified path to the corresponding processing function for processing requests on that path.
This approach is suitable for defining routes globally and adding routes directly to the application.
from fastapi import FastAPI def read_root(): return { "message": "Hello, World"} app = FastAPI() app.get("/", read_root)
-
Way 2: Use decorators
@app.get()
Decorator syntax such as ,@app.post()
, etc. is used to add decorators above routing processing functions to associate the processing functions with specific paths and HTTP methods.The decorator method allows you to use decorators directly on the route processing function to define attributes such as paths, HTTP methods, and response models.
This method is more intuitive and concentrates routing-related information on the processing function, making the code easier to read and maintain. Suitable for defining routes in a local scope.
from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return { "message": "Hello, World"}
-
Extension: a way to match all paths
@app.get("/files/{file_path:path}") # :path 代表任意路径 async def read_file(file_path: str): return { "file_path": file_path}
routing group
-
FastAPI allows routing to be organized into groups for better organization and management of API endpoints. This is particularly useful for applications with multiple related routes. Grouping keeps code clear and maintainable.
Route grouping helps keep your code clean and readable, and also allows for better organization and presentation of API endpoints in documentation.
You can create multiple groups according to your needs, put related routes together in the group, and you can also group the routes into different modules. For example, you can create a
items.py
file , which contains all items-related routes, is then imported in the main function modulemain.py
and adds the grouping to the application. -
APIRouter module method:
- APIRouter(): Create a routing group instance
-
FastAPI Module methods:
- include_router() : Add grouping to the application
- router Parameters: Specify the routing group. Default parameters, required
- prefix Parameter: Specify the prefix path of the group, optional transmission, the default is
""
- tags Parameters: Specify grouping tags to facilitate documentation and classification
- include_router() : Add grouping to the application
-
Example
from fastapi import FastAPI, APIRouter app = FastAPI() # 创建一个路由分组 router = APIRouter() # 将路由添加到分组 @router.get("/") def read_root(): return { "message": "Root"} @router.get("/items/") def read_items(): return { "message": "Items"} # 将分组添加到应用程序 app.include_router(router, prefix="/group1", tags=["Group 1"]) # 创建另一个路由分组 router2 = APIRouter() @router2.get("/") def read_another_root(): return { "message": "Another Root"} @router2.get("/things/") def read_things(): return { "message": "Things"} # 将第二个分组添加到应用程序 app.include_router(router2, prefix="/group2", tags=["Group 2"])
path parameters
Declare path parameters
-
Path parameters: FastAPI declares dynamic path parameters by adding
{}
on both sides of the path parameters.@app.get("/items/{item_id}") def read_item(item_id: int): return { "item_id": item_id}
The value of path parameteritem_id will be used as parameteritem_id passed to the function.
- If item_id does not declare (restrict) the type, you can enter either a string or a number, but it will be converted to a string by default.
- If item_id declares (restricts) the type, parameters can only be passed according to the type declared in advance
-
Routes containing path parameters must be declared after a normal path with the same path prefix!
As an example, assume there are two existing paths with the same path prefix:
/users/me
, a common path used to obtain data about the current user/users/{user_id}
, a route containing path parameters used to obtain data about a specific user by user ID
Since path operations are run sequentially, you need to ensure that the path
/users/me
is declared before the path/users/{user_id}
!Otherwise, the path of
/users/{user_id}
will also match/users/me
, "thinking" that it is receiving a value of "me" a>user_id parameter.from fastapi import FastAPI app = FastAPI() @app.get("/users/me") async def read_user_me(): return { "user_id": "the current user"} @app.get("/users/{user_id}") async def read_user(user_id: str): return { "user_id": user_id}
-
default value
Sometimes you only need to pass several common and fixed valid values to the path parameters, then you can customize the default value through enumeration .
Note: Enums are available in Python starting with 3.4 version.
from enum import Enum # 创建一个 Enum 类 class ModelName(str, Enum): yinyu = "yinyu_v" s1 = "s1_v" s2 = "s2_v" # 包含枚举的路径参数 ## 路径参数 model_name 的值将传递给函数 get_model 的参数 model_name,并且这个值的取值范围只能是 ModelName 枚举类中类属性的值。 @app.get("/models/{model_name}") async def get_model(model_name: ModelName): # 第 1 种判断方式 if model_name is ModelName.yinyu: return { "model_name": model_name, "message": "yinyu get"} # 第 2 种判断方式,效果一样 if model_name.value == "s1_name": return { "model_name": model_name, "message": "s1 get"} else: return { "model_name": ModelName.s2, "message": "s2 get"}
fastapi.Path (verification path parameters)
In FastAPI, fastapi.Path
is a class used to declare path parameters. It provides more parameter configuration options and allows defining the type, default value, and verification of path parameters. Rules etc. Use fastapi.Path
for more fine-grained control over the behavior of path parameters.
Commonly used optional parameters:
-
default
:Specifies the default value of the path parameter.Note: Since the path parameter is always required, if you want to pass the default parameter, you can only set
default=...
to explicitly mark it as a required parameter. -
title
: In automatically generated API documentation, used to display the title of the path parameter to provide better documentation. -
description
: In automatically generated API documents, used to display detailed descriptions of path parameters and provide more detailed documentation. -
min_length
andmax_length
: used to limit the string length range of path parameters. -
min
andmax
: used to limit the numerical range of path parameters, suitable for numeric path parameters. -
regex
: Use regular expressions to verify the value of path parameters. You can use regular expressions in string form. -
deprecated
: Marks the path parameter as deprecated to indicate to users that it should no longer be used. -
example
: In automatically generated API documentation, used to provide example values for path parameters to help users understand how to use the parameter. -
gt
,ge
,lt
,le
: used to set the size comparison of numeric type path parameters, respectively indicating greater than , greater than or equal to, less than, less than or equal to. -
const
: Set the path parameter to a constant value, which can be used to implement some specific route matching requirements.
query parameters
Declare query parameters
-
query parameters
In web development, query parameters (Query Parameters) are a way to pass additional information to the server through parameter key-value pairs in the URL. These parameters are usually used for operations such as filtering, sorting, paging, etc.
Query parameters usually appear after the question mark (?) in the URL. Each query parameter consists of a parameter name and a parameter value, connected with an equal sign (=). Use an ampersand (&) to separate multiple query parameters.
-
FastAPI declaration query parameters:
Declaring other function parameters that are not path parameters in the parameter list of the routing function will be Automaticallyinterpreted asquery parameters!
Query parameters can be set to default values:
- If a default value is set, this parameter is optional. Default value can be set to None
- If the default value is not set, this parameter must be passed. If it is not passed, an error will be reported.
FastAPI can add parameters directly to the parameter list of the routing function to obtain query parameters (default values can be set, if not set default values If so, an error will be reported if the meeting is not sent)
@app.get("/items/{item_id}") def read_item(item_id: int, q: str = None): # q是一个查询参数,可以接受字符串类型的值 return { "item_id": item_id, "q": q} # 调用:localhost:8000/items/2?q=hhh
-
bool type conversion
Declared as a bool type query parameter, the passed parameters can be automatically converted to True< /span>
fastapi.Query (verify query parameters)
-
typing.Union: is a type hint tool in Python, used to represent the union of multiple types. It is usually used with the Union type.
In type annotations, you can use typing.Union to explicitly specify that the type of a variable can be one of multiple types.
-
fastapi.Query: is a tool in the FastAPI framework forprocessing query parameters, and Allows specifying various parameters to control query parameter types, default values, validation, etc. The following are some commonly used optional parameters:
-
default
:Specifies the default value of query parameters. If the query parameter is not provided in the request, the default value will be used. Parameters can be passed by location.Declared as required parameters:
-
Method 1: If the default value is not specified, the parameters must be passed.
-
Method 2: Specify
default=...
-
Method 3: Specify
default=Required
Note: A guide package is required
from pydantic import Required
-
-
title
: Used for titles in automatically generated API documentation to make the documentation clearer and easier to understand. -
description
: Display detailed descriptions of query parameters in automatically generated API documentation. -
alias
: Specifies the alias of the query parameter. This parameter can be used when you want to use a different name to refer to query parameters in a function. -
regex
: Validate query parameters using regular expressions. Only parameter values matching the regular expression will be accepted. -
min_length
andmax_length
: Limit the minimum and maximum length of query parameter values. -
min
andmax
: Limit the minimum and maximum query parameter values (only applies to numeric type parameters). -
gt
,ge
,lt
,le
: used to specify greater than, greater than or equal to, less than, and A value less than or equal to (only applicable to numeric type parameters). -
multiple
: Specifies whether the query parameter can have multiple values, that is, whether multiple query parameters with the same name are allowed.Generally used for list type query parameters
-
deprecated
: Specifies whether the query parameter is deprecated.If set to
True
, a message that this parameter has been deprecated will be displayed in the automatically generated API documentation.
-
-
Code example:
from typing import Union from fastapi import FastAPI,Query @app.get("/items21/") async def read_items(q: Union[str, None] = Query(default=None), a: str = Query(default=None, max_length=50, min_length=3) b: Union[str, None] = Query(default=None, regex="^fixedquery$") ): query_items = { "q": q} return query_items
Request body and response model
-
Request body
The request body can be easily processed using the Pydantic library to define the data model.
from pydantic import BaseModel # 定义Item模型 class Item(BaseModel): name: str description: str = None price: float tax: float = None @app.post("/items/") def create_item(item: Item): # 使用Item模型定义了请求体的结构,并将其用作create_item函数的参数 return item
-
response model
By setting the response_model parameter for the route, you can define the structure of the response data.
from pydantic import BaseModel class Item(BaseModel): name: str description: str = None price: float tax: float = None @app.post("/items/", response_model=Item) def create_item(item: Item): return item
dependency injection
-
FastAPI supports dependency injection, which makes it easy to manage and reuse code.
In FastAPI, dependency injection is a powerful feature that allows functionality (such as database connections, validation logic, etc.) to be injected into route processing functions to better organize and manage code, and achieve decoupling and testability .
Dependency injection enables providing dependencies to functions when needed, rather than creating these dependencies inside the function.
The advantage of dependency injection is that it can separate complex logic from route processing functions, making the code clearer and maintainable.
from fastapi import FastAPI, Depends app = FastAPI() # 依赖项,模拟数据库连接 def get_db_connection(): db_connection = "fake_db_connection" return db_connection # 路由处理函数,注入依赖项 @app.get("/items/") async def read_items(db: str = Depends(get_db_connection)): return { "message": "Items retrieved", "db_connection": db}
Exception handling
-
Handle errors in your application with custom exception handlers
from fastapi import HTTPException @app.get("/items/{item_id}") def read_item(item_id: int): if item_id < 1: raise HTTPException(status_code=400, detail="Item not found") return { "item_id": item_id}
File Upload
-
Use fastapi.UploadFile type to receive uploaded file data
from fastapi import FastAPI, UploadFile from fastapi.staticfiles import StaticFiles import os app = FastAPI() # 配置静态文件路径 app.mount("/static", StaticFiles(directory="static"), name="static") @app.post("/file_upload") async def file_upload(file: UploadFile): # 接收文件 res = await file.read() # 写到本地 predict_img_path = os.path.join('static', file.filename) with open(predict_img_path, "wb") as f: f.write(res) return { "code": 1, "msg": "上传成功:{}".format(file.filename)} if __name__ == '__main__': import uvicorn uvicorn.run(app="main:app", host="0.0.0.0", port=2333)
Extension: upload files
-
Way 1:
import requests import json if __name__ == '__main__': # 上传一张图 file_path = r'E:\工具测试数据\封面上传测试\img\1825513ec0b.png' url = "http://127.0.0.1:2333/file_upload" data = { "file": open(file_path, 'rb')} res = requests.post(url=url, files=data, verify=False) print(json.loads(res.content)) # {'code': 1, 'msg': '上传成功:7f63f6711f5f57d9.jpg'}
-
Way 2:
import requests import json import os from urllib3 import encode_multipart_formdata if __name__ == '__main__': # 上传一张图 file_path = r'E:\工具测试数据\封面上传测试\img\1825513ec0b.png' url = "http://127.0.0.1:2333/file_upload" with open(file_path, 'rb') as f: file_name = os.path.split(file_path)[-1] file = { "file": (file_name, f.read())} encode_data = encode_multipart_formdata(file) data = encode_data[0] content_type = encode_data[1] headers = { 'Content-Type': content_type } res = requests.post(url, headers=headers, data=data) print(json.loads(res.content)) # {'code': 1, 'msg': '上传成功:1825513ec0b.png'}
Request (request object)
-
request 对象
FastAPI can use the fastapi.Request model in the route processing function to obtain request details, such as headers, query parameters, etc.
from fastapi import FastAPI, Request @app.get("/user-agent/") def read_user_agent(request: Request): # 获取请求头 headers = request.headers user_agent = headers.get("user-agent") return { "user_agent": user_agent}
-
Information in request headers
FastAPI can use the fastapi.Header model in the routing processing function to obtain the information in the request header, such as user_agent, etc.
from fastapi import FastAPI, Header @app.get("/headers/") def read_headers(user_agent: str = Header(None)): return { "User-Agent": user_agent}
safety
- FastAPI provides multiple security mechanisms to protect web applications from common security risks and attacks. The following are some common security mechanisms in FastAPI:
- Authentication: FastAPI supports multiple authentication methods, such as OAuth2, JWT (JSON Web Tokens), basic authentication, etc. You can use
Depends
to authenticate the user in the route, and only authenticated users can access protected resources. - Authorization: Once a user is authenticated, FastAPI also allows the implementation of an authorization mechanism to determine whether the user has permission to access a specific resource. This can be achieved through custom dependencies or decorators.
- CORS (Cross-Origin Resource Sharing): CORS is a security mechanism used to control cross-domain requests. FastAPI allows configuring CORS policies to ensure that only requests from specific origins can access your API.
- CSRF (Cross-site Request Forgery) Defense: FastAPI provides built-in CSRF protection to prevent CSRF attacks and protect your users from malicious websites.
- Security Headers: FastAPI automatically adds some security headers to the response to protect applications from some common network attacks, such as clickjacking, XSS ( cross-site scripting attacks), etc.
- Password Hashing and Storage: FastAPI encourages the use of password hashes to store user passwords to protect user privacy. Password hashing and verification can be done using the built-in
Passlib
library. - Request verification and input verification: FastAPI has built-in request verification and input verification mechanisms to filter and verify incoming data to prevent bad input and malicious data attacks.
- Logging and Auditing: FastAPI allows logging of application activity for auditing and analysis in the event of a security incident.
- HTTPS support: FastAPI supports encrypted connections over HTTPS to ensure the security of data during transmission.
- Authentication: FastAPI supports multiple authentication methods, such as OAuth2, JWT (JSON Web Tokens), basic authentication, etc. You can use
expand
Visit Fast API interface documentation
-
Swagger UI Provided api 文档
ip:port/docs (default 127.0.0.1:8000/docs)
-
ReDoc Provided api 文档
ip:port/docs (default 127.0.0.1:8000/redoc)
Basic directory structure of the FastAPI project
my_project/
├── app/
│ ├── apis/
│ │ ├── __init__.py
│ │ ├── auth.py
│ │ ├── items.py
│ │ └── users.py
│ ├── core/
│ │ ├── __init__.py
│ │ ├── config.py
│ │ ├── security.py
│ │ └── sqlalchemy.py
│ ├── db/
│ │ ├── __init__.py
│ │ └── base.py
│ ├── main.py
│ └── models/
│ ├── __init__.py
│ ├── item.py
│ └── user.py
├── docker-compose.yml
├── Dockerfile
├── README.md
└── requirements.txt
- app/: used to store the main code of the application. Contains API definition, business logic, database connection, etc.
- app/apis/: Directory for API routing and business logic implementation.
- app/core/: Implementation of core functions such as configuration, authentication, and database connection.
- app/db/: The definition of the database model and database-related code.
- app/models/: ORM model definition, realizing the mapping of business logic and database operations.
- app/main.py: The startup file of the FastAPI application, including application initialization, route registration, etc.
- docker-compose.yml: Docker-Compose configuration file
- Dockerfile: the build file for the application Docker image
- README.md: project documentation
- requirements.txt: project dependency list
In addition, other directories and files can be added according to project needs, such as static file directories, test directories, document directories, etc. However, no matter how you organize the FastAPI project structure, you need to ensure that the code is clear and easy to maintain.