fastapi教程進階


一個簡單的栗子

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請求

步驟四:定義方法,處理請求

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會返回如下結果:

{"item_id":"foo"}

也可以在方法中定義參數類型:

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,會返回

{"item_id":3}

此時的item_id是int類型的3,而不是string類型,這是因為FastAPI在解析請求時,自動根據聲明的類型進行了解析
如果請求http://127.0.0.1:8000/items/foo,此時會返回:

{
    "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也會出現上述錯誤

所有的數據類型驗證,都是通過Pydantic完成的

如果想對路徑參數做一個預定義,可以使用Enum:

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}:

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"
    }
  ]
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM