一个简单的栗子
from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"}
FASTAPI继承Starlette,所以在Starlette中的全部可调用的对象在FASTAPI中能够直接引用
编写步骤
步骤一:导入FastAPI
from fastapi import FastAPI
步骤二:建立FastAPI实例
app = FastAPI()
步骤三:建立访问路径
@app.get("/")
这个路径告诉FastAPI,该装饰器下的方法是用来处理路径是“/”的GET请求api
步骤四:定义方法,处理请求
async def root():
步骤五:返回响应信息
return {"message": "Hello World"}
步骤六:运行
uvicorn main:app --reload
获取路径参数
from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id): return {"item_id": item_id}
路径中的item_id将会被解析,传递给方法中的item_id。请求http://127.0.0.1:8000/items/foo会返回以下结果:app
{"item_id":"foo"}
也能够在方法中定义参数类型:async
from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id: int): return {"item_id": item_id}
继续请求http://127.0.0.1:8000/items/3,会返回ui
{"item_id":3}
此时的item_id是int类型的3,而不是string类型,这是由于FastAPI在解析请求时,自动根据声明的类型进行了解析 若是请求http://127.0.0.1:8000/items/foo,此时会返回:spa
{ "detail": [ { "loc": [ "path", "item_id" ], "msg": "value is not a valid integer", "type": "type_error.integer" } ] }
这是由于foo并不能转换成int类型。请求http://127.0.0.1:8000/items/4.2也会出现上述错误code
全部的数据类型验证,都是经过Pydantic完成的对象
若是想对路径参数作一个预约义,可使用Enum:blog
from enum import Enum from fastapi import FastAPI class ModelName(str, Enum): alexnet = "alexnet" resnet = "resnet" lenet = "lenet" app = FastAPI() @app.get("/model/{model_name}") async def get_model(model_name: ModelName): if model_name == ModelName.alexnet: return {"model_name": model_name, "message": "Deep Learning FTW!"} if model_name.value == "lenet": return {"model_name": model_name, "message": "LeCNN all the images"} return {"model_name": model_name, "message": "Have some residuals"}
打开http://127.0.0.1:8000/docs: 继承
除此以外,假如想接收一个路径参数,它自己就是一个路径,就像/files/{file_path},而这个file_path是home/johndoe/myfile.txt时,能够写成/files/{file_path:path}:ip
from fastapi import FastAPI app = FastAPI() @app.get("/files/{file_path:path}") async def read_user_me(file_path: str): return {"file_path": file_path}
OpenAPI自己不支持在路径参数包含路径,可是能够看成Starlette内部的一个使用方法
此时访问http://127.0.0.1:8000/files/home/johndoe/myfile.txt,返回:
{"file_path":"home/johndoe/myfile.txt"}
若是将路径改成/files/{file_path},会返回:
{"detail":"Not Found"}
获取查询参数
这里依旧是一个例子:
from fastapi import FastAPI app = FastAPI() fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] @app.get("/items/") async def read_item(skip: int = 0, limit: int = 10): return fake_items_db[skip : skip + limit]
尝试访问http://127.0.0.1:8000/items/?skip=0&limit=2,返回:
[{"item_name":"Foo"},{"item_name":"Bar"}]
尝试访问http://127.0.0.1:8000/items/,返回:
[{"item_name":"Foo"},{"item_name":"Bar"},{"item_name":"Baz"}]
因为咱们在定义方法的时候,分别赋予skip和limit默认值,当不添加querystring时,会使用默认值。固然,咱们也能够将默认值赋值为None:
from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id: str, q: str = None): if q: return {"item_id": item_id, "q": q} return {"item_id": item_id}
此时,咱们请求http://127.0.0.1:8000/items/1?q=qqq:
{"item_id":"1","q":"qqq"}
值得放心的一点是,FastAPI很聪明,他知道参数来自哪里~
假如,咱们不给参数默认值会发生什么状况呢?这里仍是一个例子:
from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_user_item(item_id: str, needy: str): item = {"item_id": item_id, "needy": needy} return item
继续请求http://127.0.0.1:8000/items/1,会发现,返回报错:
{ "detail": [ { "loc": [ "query", "needy" ], "msg": "field required", "type": "value_error.missing" } ] }