FastAPI Overview
Reference documentation:
- Chinese documentation
- Easily get started with Python’s web artifact: FastAPI tutorial
Introduction
FastAPI is a modern Python-based web framework designed to quickly build high-performance APIs.
FastAPI key features:
- Fast: Extremely high performance on par with NodeJS and Go (thanks to Starlette and Pydantic). One of the fastest Python web frameworks.
- Efficient Coding: Increase feature development speed by approximately 200% to 300%.
- Fewer bugs: About 40% fewer human (developer) caused bugs.
- Smart: Excellent editor support. Automatic completion is available everywhere, reducing debugging time.
- Simple: Designed to be easy to use and learn, it takes less time to read the documentation.
- Short: Minimize code duplication. Rich functionality is achieved through different parameter declarations. Fewer bugs.
- Robust: Production-usable level code. There are also automatically generated interactive documents.
- Standardization: Based on (and fully compatible with) relevant open standards for APIs: OpenAPI (formerly Swagger) and JSON Schema.
Introduction and differences of common Python web frameworks
Performance:
-
Django: is a full-featured framework that provides many built-in functions and extensions. Although it is relatively low in terms of performance, it is very suitable for building large applications.
-
Flask: It is a lightweight framework that pays more attention to simplicity and flexibility. Compared to Django, Flask has better performance, but it has relatively fewer features.
-
FastAPI: It is a high-performance framework based on asynchronous request processing and type annotations. FastAPI is more performant than Django and Flask, and it uses Python’s asyncio library to achieve efficient concurrent request processing.
Development Difficulty:
- Django: It is a full-featured framework that provides many ready-made functions and components to make development faster and simpler. However, Django can have a relatively steep learning curve for beginners.
- Flask: It is a concise and flexible framework that focuses more on customization and configuration. Compared with Django, Flask has a gentler learning curve and is suitable for small and simple projects.
- FastAPI: Uses type annotations and the function of automatically generating documents to make the code more readable and maintainable. It provides standards-based API patterns and powerful verification tools to reduce errors during the development process.
Promotion Level:
-
Django: is one of the most popular and widely used Python web frameworks. It has huge community support and rich documentation resources, making it easy to find relevant tutorials, plug-ins and solutions.
-
Flask: It is a relatively popular framework with a large community and rich extension library. Although it has a relatively small user base, it is very popular for small projects and rapid prototyping.
-
FastAPI: is a relatively new framework, but it is quickly gaining traction among developers. Its high performance and modern features have attracted many developers, and the community is gradually expanding.
FastAPI is a modern, fast (high-performance) web framework for building APIs using Python 3.6+ and based on standard Python type hints.
Getting Started Example
-
Install FastAPI and uvicorn
FastAPI uses uvicorn as the default web service. Therefore, you need to install FastAPI and uvicorn
uvicorn is a lightweight ASGI (Asynchronous Server Gateway Interface) server
pip install fastapi pip install uvicorn
-
Sample code
from fastapi import FastAPI import uvicorn # Create a FastAPI application instance app = FastAPI() # Define routes (use decorators to bind functions to specific paths and HTTP methods) @app.get("/") async def root(): return {<!-- -->"message": "Hello World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: str = None): return {<!-- -->"item_id": item_id, "q": q} # Allow FastAPI applications using uvicorn when launching the program uvicorn.run(app) #The default ip is 127.0.0.1, and the default port is 8000
Start web service
-
Method 1: uvicorn embedded
Use
uvicorn.run(app)
in the code to enable the uvicorn server to run the python service, and then use python to start the py moduleimport uvicorn app = FastAPI() uvicorn.run(app)
-
Method 2: uvicorn external opening
Enter the command at the command line:
uvicorn main:app --host 0.0.0.0 --port 80 --reload
- main: py file name to start the service
- app: service object name
- –host: ip address
- –port: port
- –reload: Automatically restart the service after the code is modified. Only used during development. Do not use this parameter after going online, as it will reduce performance.
Parameters supported by uvicorn.run
- app: Specifies the application app. Script name: FastAPI instance object’ or FastAPI instance object
- host: String, allowed to be accessed in the form: locahost, 127.0.0.1, current IP, 0.0.0.0. Default is 127.0.0.1
- port: Number, application port, default is 8000
- uds: string, the domain name of the socket service bound to UNIX
- fd: Number from which this file descriptor is bound to the socket
- loop: event loop mode. The option list is [auto|asyncio|uvloop], default is auto
- http: HTTP protocol implementation. The option list is [auto|h11|httptools], the default is auto
- ws: WebSocket protocol implementation. The option list is [auto|none|websockets|wsproto], the default is auto
- ws-max-size: Number, WebSocket maximum message size (bytes), default value is 16777216
- lifespan : Lifecycle implementation. The option list is [auto|on|off], default is auto
- env-file: PATH, environment configuration file
- log-config: PATH, log configuration file. Supported formats:
.ini
,.json
,.yaml
, the default is fastapi’s default log configuration - log-level: Log level. The option list is [critical|error|warning|info|debug|trace], the default is info
- access-log: boolean, access log switch, default is True
- use-colors: boolean, color log switch (log-config must be specified), default is None
- interface : Select ASGI3, ASGI2, or WSGI as the application interface. The option list is [auto|asgi3|asgi2|wsgi], default is auto
- debug: Whether to use debug mode, default False,
- reload: boolean, whether to automatically restart when the code is updated, default False,
- reload_dirs: String, set the reload directory. When this parameter is not passed in real time, the current working directory will be used.
- reload-delay: float, how often to detect code changes, default 0.25 seconds
- workers: Number, number of worker processes. Defaults to the
WEB_CONCURRENCY
environment variable if available or 1. Not valid for –reload. - proxy-headers: boolean, enable/disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to fill in remote address information, default is True
- forwarded-allow-ips : String, comma separated list of IPs to trust proxy header. Defaults to
FORWARDED_ALLOW_IPS
environment variable (if available), or None. When it is None, 127.0.0.1 is taken in the code. - root-path : String that sets the ASGI “root path” for applications installed at the given URL path.
- limit-concurrency : Number, the maximum number of concurrent connections or tasks allowed before an HTTP503 response is issued. Default is None
- limit-max-requests: Number, when the number of requests is reached, the process will be terminated. The default is None.
- backlog: Number, the maximum number of connections waiting to be processed, the default is 2048
- timeout-keep-alive : Number, if no new data is received within this timeout, the keep-alive connection will be closed, default is 5
- ssl-keyfile: String, SSL key file, default is None
- ssl-certfile: String, SSL certificate file, default is None
- ssl-keyfile-password: String, SSL key file password, default is None
- ssl-version: Number, SSL version to use (see stdlib SS L module for details), default is 2
- ssl-cert-reqs: Number, whether a client certificate is required (see stdlib SSL module for details), default is 0
- ssl-ca-certs: string, CA certificate file
- ssl-ciphers: string, CA certificate file password to be used (see stdlib SSL module for details), default is TLSv1
- header: dictionary, custom response header information, in the form of key-value pairs, the default is None
Common API
app=FastAPI(): Create a FastAPI application instance
-
app = FastAPI()
is a common practice for creating application instances in FastAPI. This line of code creates a FastAPI application object on which routing, middleware, exception handling, etc. can be defined. -
The application instance
app
has many properties and methods for configuring and managing various aspects of the application, such as routing, middleware, exception handling, dependency injection, etc. By creating anapp
instance, you can define and organize your application’s logic within it. -
code example
from fastapi import FastAPI app = FastAPI()
-
Supported parameters (all optional):
-
debug: debug mode, True/False. This property is inherited from starlette, in which the property decorator is used.
-
routes: Route list, default value is None
This property is inherited from starlette and is a list of BaseRoutes of type startlette. BaseRoute is related to starlette’s base type Scope.
-
title: The title of the API document, default value FastAPI
-
description: Description of the API document, empty by default
-
version: The version number of the API interface
-
openapi_url: OpenAPI file path, default is
/opanapi.json
-
openapi_prefix: OpenAPI file path prefix, empty by default
-
default_response_class: Default response type, default is JSONResponse
This parameter is inherited from startlette’s Response. There are seven types: HTMLResponse, PlainTextResponse, UJSONResponse, RedirectResponse, StreamingResponse, FileResponse and JSONResponse. The starlette.responses module needs to be loaded when using it.
-
docs_url: interactive document path, default is
/docs
-
redoc_url: optional document path, default is
/redoc
-
swagger_ui_oauth2_redirect_url: OAuth redirect path, the default is
/docs/oauth2-redirect
-
swagger_ui_init_oauth: OAuth redirect dictionary, default is None
-
middleware: middleware, empty by default
-
exception_handlers: Exception handling methods, default is None
-
on_startup: List of methods called when the app starts
-
on_shutdown: List of methods called when the app is shut down
-
extra : additional optional parameters
-
FastAPI() common API examples
get(), post(), etc.: define the routing of HTTP requests
In FastAPI, methods such as app.get()
and app.post()
are used to define the routing of HTTP requests. These methods accept multiple parameters that specify the route’s path, request handler function, dependencies, etc.
The following are the main parameters:
path
(required): The path used to specify the route. This is a string that represents a URL path and can contain path parameters and query parameters.response_model
: used to specify the response model. A response model is a data structure for response data, typically defined using Pydantic models.summary
: A short string describing the purpose or functionality of the route.description
: Used to provide more detailed routing instructions.tags
: A list of strings used to tag routes in order to categorize and organize them in the document.dependencies
: A list specifying the dependencies that need to be injected in the route handler function.response_description
: used to specify the description information of the response.deprecated
: A Boolean value indicating whether the route has been deprecated.status_code
: Specifies the HTTP status code of the response.response_model_include
andresponse_model_exclude
: Used to specify fields to include or exclude in the response model.response_model_by_alias
: A Boolean value indicating whether to use aliases in the Pydantic model to serialize the response.response_model_exclude_unset
: A Boolean value indicating to exclude unset fields in the response.response_model_exclude_defaults
: A Boolean value indicating to exclude fields with default values in the response.response_model_exclude_none
: A Boolean value indicating that fields with a value of None are excluded from the response.operation_id
: A unique identifier that specifies an operation.deprecated
: A Boolean value indicating whether the route has been deprecated.callbacks
: A dictionary used to specify callback functions.
These parameters can be flexibly configured according to needs. Generally speaking, the path
parameter is required, while other parameters are optional as needed.
add_middleware(): Add middleware
-
add_middleware() Function: It is the method used to add middleware in FastAPI.
Middleware is a function that can perform pre- and post-processing during request and response processing. Middleware can be used to implement various requirements, such as adding global headers, request logging, exception handling, etc.
Add custom middleware to your application via the
app.add_middleware
method. When a request arrives, FastAPI will execute the added middleware in sequence, and then call the route processing function. When the response is returned, the middleware’s post-processing logic will be executed in reverse order.By adding middleware, you can implement some common functionality during request and response processing without having to write the same code repeatedly in each route. This helps keep your code clean and maintainable.
-
Commonly used parameters:
-
middleware_class (required): A middleware class that you wish to add to the middleware of your application.
Middleware classes should inherit from fastapi.middleware.base.BaseHTTPMiddleware or a similar base class.
-
**options: This is the configuration option of the middleware. Different parameters can be passed according to the requirements of the middleware. The specific options depend on the middleware class used. In general, any custom parameters related to middleware can be passed for use in the middleware class.
-
CORSMiddleware
-
FastAPI’s built-in middleware is used to handle cross-origin resource sharing (CORS) issues.
CORS is a browser security mechanism used to control cross-origin requests. In applications with separate front-end and back-end, when the front-end code (running in the browser) makes a request from one domain to another, the browser performs a cross-domain check to ensure that only trusted domains can access the resource.
CORSMiddleware helps developers configure FastAPI applications to correctly handle cross-domain requests.
After configuring the middleware, FastAPI will automatically handle cross-origin requests and add appropriate header information to the response to meet CORS security requirements.
Please note that CORS configuration involves application security. In a production environment,
allow_origins
and other parameters should be configured according to actual needs. -
Common parameters (used to configure cross-domain policies):
-
allow_origins: List of domain names allowed to access the resource.
It is possible to use
["*"]
to allow all domains, but this is generally not recommended. -
allow_credentials: Whether to allow requests that send credentials (such as cookies, HTTP authentication headers).
If it is
True
, you need to ensure that the corresponding configuration is performed on both the client and the server, andallow_origins
must be a specific source and cannot be[" *"]
-
allow_methods: List of allowed HTTP methods such as
["GET", "POST"]
. The default is["GET"]
You can use
["*"]
to allow all methods -
allow_headers: List of allowed HTTP headers, such as
["Content-Type", "Authorization"]
. The default is[]
You can use
["*"]
to allow all headersNote: Accept, Accept-Language, Content-Language and Content-Type are always allowed
-
-
Code example:
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["http://localhost", "https://example.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
Custom middleware:
-
Method 1: Customize the middleware class and pass the object of the custom middleware class through the dispatch parameter when adding custom middleware
from fastapi import FastAPI, Request from fastapi.middleware.cors import BaseHTTPMiddleware # Custom middleware class MyMiddleware: def __init__(self, some_attribute: str = None): # some_attribute is not required, used here to demonstrate passing parameters to custom middleware self.some_attribute = some_attribute async def __call__(self, request: Request, call_next): # do something with the request object # process the request and get the response response = await call_next(request) # do something with the response object return response app = FastAPI() # Add custom middleware app.add_middleware(BaseHTTPMiddleware, dispatch=MyMiddleware())
-
Method 2: Custom middleware class inherits BaseHTTPMiddleware class
# Custom middleware class MyMiddleware(BaseHTTPMiddleware): def __init__(self, app, some_attribute: str): super().__init__(app) self.some_attribute = some_attribute async def dispatch(self, request: Request, call_next): # do something with the request object, for example content_type = request.headers.get('Content-Type') print(content_type) # process the request and get the response response = await call_next(request) return response app = FastAPI() # Add custom middleware app.add_middleware(MyMiddleware)
-
Method 3: @app.middleware decorator
In FastAPI, you can add application-scoped middleware using the
@app.middleware
decorator.That is, middleware added using the
@app.middleware
decorator applies to the entire FastAPI application and is usually used to perform global operations such as authentication, logging, exception handling, etc. This allows you to share the same middleware logic throughout your application without having to add the same middleware repeatedly for each route.This decorator can accept the following two parameters:
-
middleware_type (required): String parameter used to specify the type of middleware.
In FastAPI, middleware can be divided into the following two types:
-
“http”: HTTP middleware
This middleware will be executed during the processing of each HTTP request and is suitable for handling HTTP requests and responses.
-
“websocket”: WebSocket middleware
This middleware will be executed during the processing of a WebSocket connection and is suitable for handling WebSocket requests and responses.
-
-
priority (optional): Integer parameter used to specify the priority of the middleware.
If you have multiple middlewares in your application, you can use this parameter to control the order in which they execute.
A smaller number indicates a higher priority, and middleware will be executed in ascending order of priority.
If the priority parameter is not specified, the default priority of the middleware is 50.
app = FastAPI() # Custom middleware processing function @app.middleware("http") async def log_requests(request: Request, call_next): logger.info(f"Incoming request: {<!-- -->request.method} {<!-- -->request.url}") response = await call_next(request) logger.info(f"Outgoing response: {<!-- -->response.status_code}") return response
-
websocket(): Create WebSocket route
-
websocket() function: Creates a WebSocket route to achieve real-time two-way communication with the client.
WebSocket is a protocol for full-duplex communication on a single long connection. It is suitable for application scenarios that require real-time update of data, such as chat applications, real-time data display, etc.
On the client side, you can use the browser’s built-in WebSocket API or other WebSocket client libraries to communicate with FastAPI WebSocket routing.
-
Code example:
from fastapi import FastAPI, WebSocket app = FastAPI() # WebSocket routing @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() while True: data = await websocket.receive_text() await websocket.send_text(f"You said: {<!-- -->data}")
- A WebSocket route for
/ws
is created using theapp.websocket()
method. After the WebSocket connection is established, use theawait websocket.accept()
method to accept the connection. - Then, use the
await websocket.receive_text()
method in an infinite loop to receive the text message sent by the client, and use theawait websocket.send_text()
method to return the message to client.
- A WebSocket route for
mount(): Install sub-applications (static files)
-
mount() Function: Used to mount another ASGI application as a sub-application of the FastAPI application.
Using
mount
to install sub-applications can easily combine multiple applications to achieve a more complex application logic structure. For example, assemble multiple API applications into a gateway application, assemble multiple applications into a single page application, and so on.Support parameters:
- path: Type is string, parameters must be passed, specify the path accessed by url
- app: The type is ASGIApp, parameters must be passed, and the static file object is mounted.
- directory: Specifies the static file directory to be mounted.
- name: Specifies the name used internally by fastapi. Default is None
-
How to access static files: Enter
ip:port/path/full file name.suffix
directly into the browser. -
Code example (configuring static file path):
import uvicorn from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() #Configure static file path app.mount("/static", StaticFiles(directory="static"), name="static") uvicorn.run(app="main:app", host="0.0.0.0", port=8000, reload=True)