Technical background: Py3.6+, Starlette, Pydantic
Install the plugin fastapi
pip install fastapi
Install startup plugin
pip install uvicorn
Windows installation is generally normal, and the following error will generally be reported under Linux:
Solution:
- Centos execute yum install python3-devel
- Ubuntu execute sudo apt-get install python3-dev
Simple example
Create the project file main.py in the root directory:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {
"我的第一个FastAPI": "Hello World!"}
@app.get("/test/{use_id}")
def read_item(use_id: int, key: str = None):
return {
"use_id": use_id, "key": key}
The simplest FastAPI application is built above, which looks exactly the same as Flask, inexplicably happy:
- url: / and /test/{use_id} Both urls can receive HTTP requests.
- / And /test/{use_id} both use GET HTTP request method
- /test/{use_id} contains the path parameter use_id, the format is int
- /test/{use_id} also contains an optional parameter key, the format is str, the default is null
- If /test/{use_id} is not given a default value and no parameters are passed, an error will be reported:
{
"detail":[{
"loc":["query","key"],"msg":"field required","type":"value_error.missing"}]}
As shown below:
- No reference:
- Need to pass parameters-single parameter
- Need to pass parameters-multiple parameters
If you want to make a predefined path parameter, you can use Enum (enumeration):
from enum import Enum
from fastapi import FastAPI
class ModelName(str, Enum):
add = "add"
update = "update"
delete = "delete"
app = FastAPI()
@app.get("/model/{model_name}")
async def get_model(model_name: ModelName, key: str = None):
if model_name == ModelName.add:
return {
"model_name": model_name, "message": "这是添加操作!", "key": key}
if model_name.value == "update":
return {
"model_name": model_name, "message": "这是更新操作!", "key": key}
return {
"model_name": model_name, "message": "这是删除操作!", "key": key}
The above example will limit the parameters passed in each time. If it is not the default value in the enumeration class, an error will be reported:
{
"detail":[{
"loc":["path","model_name"],"msg":"value is not a valid enumeration member; permitted: 'one', 'two', 'three'","type":"type_error.enum","ctx":{
"enum_values":["one","two","three"]}}]}
Get query parameters
data_dict = [{
'item': '01', 'name': 'one'}, {
'item': '02', 'name': 'two'}, {
'item': '03', 'name': 'three'}, {
'item': '04', 'name': 'four'}, {
'item': '05', 'name': 'five'}]
@app.get('/data')
async def get_data(start_indx: int = 1, step: int = 10):
return data_dict[start_indx : start_indx+step]
result:
- http://127.0.0.1:5000/data
[{
"item":"02","name":"two"},{
"item":"03","name":"three"},{
"item":"04","name":"four"},{
"item":"05","name":"five"}]
- http://127.0.0.1:5000/data?start_indx=0&step=1
[{
"item":"01","name":"one"}]
body parameter
For the case of body parameter passing, it is actually in the form of function parameter passing, but considering that there are many fields in the traditional form-data parameter passing method, we can use the application/json method and define a parameter class to control the parameters.
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel): # 定义一个类用作参数
name: str
age: int
height: float
is_offer: bool = None # 该字段可为空
app = FastAPI()
@app.get("/{people_id}")
async def update_item(people_id: str, item: Item): # item需要与Item对象定义保持一致
return {
"method": 'get',
"people_name": item.name,
"people_age": item.age,
"people_height": item.height,
'people':people_id
}
@app.put("/{people_id}")
async def update_item(people_id: str, item: Item): # item需要与Item对象定义保持一致
return {
"method": 'put',
"people_name": item.name,
"people_age": item.age,
"people_height": item.height,
'people':people_id
}
@app.post("/{people_id}")
async def update_item(people_id: str, item: Item): # item需要与Item对象定义保持一致
return {
"method": 'post',
"people_name": item.name,
"people_age": item.age,
"people_height": item.height,
'people':people_id
}
@app.delete("/{people_id}")
async def update_item(people_id: str, item: Item): # item需要与Item对象定义保持一致
return {
"method": 'delete',
"people_name": item.name,
"people_age": item.age,
"people_height": item.height,
'people':people_id
}
postman test
GET request:
PUT request:
POST request:
DELETE request:
Start service
uvicorn main:app --reload --port 5000 --host 0.0.0.0
FastAPI recommends using uvicorn to run services. Uvicorn is a lightning-fast ASGI server based on uvloop and httptools.
uvicorn main:app refers to:
-
main: file main.py
-
app: the enabled object created
-
--Reload: hot start, convenient for code development, refers to automatic reload when file changes are detected (this is very useful when debugging)
-
--Port port
-
--Host access ip
Automatically generate interface documentation
FastApi will generate interface documentation for you by itself, truly liberating your hands
FastApi provides two interface documents by default. In fact, the content is the same, but two open source document frameworks are used.
swagger
Thanks to the help of swagger, more uses of swagger will not be repeated here
The default document location is http://127.0.0.1:5000/docs and you can open it with a browser
When you update the code, the interface documentation will also be updated synchronously,
as shown below:
redoc
Thanks to the help of redoc, more uses of redoc will not be repeated here
The default document location is http://127.0.0.1:5000/redoc and you can open it with a browser
When you update the code, the interface documentation will also be updated synchronously,
as shown below:
RESTful interface specification of GET/POST/PUT/DELETE
REST is the abbreviation of Representational State Transfer, which translates as "presentation layer state transfer".
Resource-oriented is the most obvious feature of REST, a set of different operations for the same resource. Resource is an abstract concept that can be named on the server. Resources are organized with nouns as the core. The first thing to focus on is nouns. REST requires that various operations must be performed on resources through a unified interface. Only a limited set of operations can be performed for each resource.
7 HTTP methods: GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS
GET
Safe and idempotent
means to get
200(OK) - 表示已在响应中发出
204(无内容) - 资源有空表示
301(Moved Permanently) - 资源的URI已被更新 303(See Other) - 其他(如,负载均衡)
304(not modified)- 资源未更改(缓存)
400 (bad request)- 指代坏请求(如,参数错误) 404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务端当前无法处理请求
POST
Insecure and not idempotent
Create resources using server-managed (auto-generated) instance numbers
Create sub-resources
200(OK)- 如果现有资源已被更改
201(created)- 如果新资源被创建
202(accepted)- 已接受处理请求但尚未完成(异步处理) 301(Moved Permanently)- 资源的URI被更新
303(See Other)- 其他(如,负载均衡)
400(bad request)- 指代坏请求
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
409 (conflict)- 通用冲突
412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突) 415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务当前无法处理请求
PUT
Insecure but idempotent
Update the resource by replacement
If it has not been modified, update the resource (optimistic locking)
200 (OK)- 如果已存在资源被更改
201 (created)- 如果新资源被创建
301(Moved Permanently)- 资源的URI已更改
303 (See Other)- 其他(如,负载均衡)
400 (bad request)- 指代坏请求
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
409 (conflict)- 通用冲突
412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突) 415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务当前无法处理请求
DELETE
Insecure but idempotent
Delete resources
200 (OK)- 资源已被删除
301 (Moved Permanently)- 资源的URI已更改
303 (See Other)- 其他,如负载均衡
400 (bad request)- 指代坏请求
404 (not found)- 资源不存在
409 (conflict)- 通用冲突
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务端当前无法处理请求
If you think the article is helpful to you, please like, bookmark, comment and discuss!