Bỏ qua

FastAPI

FastAPI

FastAPI framework, hiệu năng cao, dễ học, dễ code, sẵn sàng để tạo ra sản phẩm

Test Coverage Package version Supported Python versions


Tài liệu: https://fastapi.tiangolo.com

Mã nguồn: https://github.com/fastapi/fastapi


FastAPI là một web framework hiện đại, hiệu năng cao để xây dựng web APIs với Python dựa trên tiêu chuẩn Python type hints.

Những tính năng như:

  • Nhanh: Hiệu năng rất cao khi so sánh với NodeJSGo (cảm ơn Starlette và Pydantic). Một trong những Python framework nhanh nhất.
  • Code nhanh: Tăng tốc độ phát triển tính năng từ 200% tới 300%. *
  • Ít lỗi hơn: Giảm khoảng 40% những lỗi phát sinh bởi con người (nhà phát triển). *
  • Trực giác tốt hơn: Được các trình soạn thảo hỗ tuyệt vời. Completion mọi nơi. Ít thời gian gỡ lỗi.
  • Dễ dàng: Được thiết kế để dễ dàng học và sử dụng. Ít thời gian đọc tài liệu.
  • Ngắn: Tối thiểu code bị trùng lặp. Nhiều tính năng được tích hợp khi định nghĩa tham số. Ít lỗi hơn.
  • Tăng tốc: Có được sản phẩm cùng với tài liệu (được tự động tạo) có thể tương tác.
  • Được dựa trên các tiêu chuẩn: Dựa trên (và hoàn toàn tương thích với) các tiêu chuẩn mở cho APIs : OpenAPI (trước đó được biết đến là Swagger) và JSON Schema.

* ước tính được dựa trên những kiểm chứng trong nhóm phát triển nội bộ, xây dựng các ứng dụng sản phẩm.

Nhà tài trợ

Những nhà tài trợ khác

Ý kiến đánh giá

"[...] Tôi đang sử dụng FastAPI vô cùng nhiều vào những ngày này. [...] Tôi thực sự đang lên kế hoạch sử dụng nó cho tất cả các nhóm dịch vụ ML tại Microsoft. Một vài trong số đó đang tích hợp vào sản phẩm lõi của Window và một vài sản phẩm cho Office."

Kabir Khan - Microsoft (ref)

"Chúng tôi tích hợp thư viện FastAPI để sinh ra một REST server, nó có thể được truy vấn để thu được những dự đoán. [bởi Ludwid] "

Piero Molino, Yaroslav Dudin, và Sai Sumanth Miryala - Uber (ref)

"Netflix vui mừng thông báo việc phát hành framework mã nguồn mở của chúng tôi cho quản lí khủng hoảng tập trung: Dispatch! [xây dựng với FastAPI]"

Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)

"Tôi vô cùng hào hứng về FastAPI. Nó rất thú vị"

Brian Okken - Python Bytes podcast host (ref)

"Thành thật, những gì bạn đã xây dựng nhìn siêu chắc chắn và bóng bẩy. Theo nhiều cách, nó là những gì tôi đã muốn Hug trở thành - thật sự truyền cảm hứng để thấy ai đó xây dựng nó."

Timothy Crosley - người tạo ra Hug (ref)

"Nếu bạn đang tìm kiếm một framework hiện đại để xây dựng một REST APIs, thử xem xét FastAPI [...] Nó nhanh, dễ dùng và dễ học [...]"

"Chúng tôi đã chuyển qua FastAPI cho **APIs của chúng tôi [...] Tôi nghĩ bạn sẽ thích nó [...]"

Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
Ines Montani - Matthew Honnibal - nhà sáng lập Explosion AI - người tạo ra spaCy (ref) - (ref)

"Nếu ai đó đang tìm cách xây dựng sản phẩm API bằng Python, tôi sẽ đề xuất FastAPI. Nó được thiết kế đẹp đẽ, sử dụng đơn giảncó khả năng mở rộng cao, nó đã trở thành một thành phần quan trọng trong chiến lược phát triển API của chúng tôi và đang thúc đẩy nhiều dịch vụ và mảng tự động hóa như Kỹ sư TAC ảo của chúng tôi."

Deon Pillsbury - Cisco (ref)

Typer, giao diện dòng lệnh của FastAPI

Nếu bạn đang xây dựng một CLI - ứng dụng được sử dụng trong giao diện dòng lệnh, xem về Typer.

Typer là một người anh em của FastAPI. Và nó được dự định trở thành giao diện dòng lệnh cho FastAPI. ⌨️ 🚀

Yêu cầu

FastAPI đứng trên vai những người khổng lồ:

Cài đặt

$ pip install fastapi

---> 100%

Bạn cũng sẽ cần một ASGI server cho production như Uvicorn hoặc Hypercorn.

$ pip install "uvicorn[standard]"

---> 100%

Ví dụ

Khởi tạo

  • Tạo một tệp tin main.py như sau:
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}
Hoặc sử dụng async def...

Nếu code của bạn sử dụng async / await, hãy sử dụng async def:

from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

Lưu ý:

Nếu bạn không biết, xem phần "In a hurry?" về asyncawait trong tài liệu này.

Chạy ứng dụng

Chạy server như sau:

$ uvicorn main:app --reload

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [28720]
INFO:     Started server process [28722]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
Về lệnh uvicorn main:app --reload...

Lệnh uvicorn main:app tham chiếu tới những thành phần sau:

  • main: tệp tin main.py (một Python "module").
  • app: object được tạo trong tệp tin main.py tại dòng app = FastAPI().
  • --reload: chạy lại server sau khi code thay đổi. Chỉ sử dụng trong quá trình phát triển.

Kiểm tra

Mở trình duyệt của bạn tại http://127.0.0.1:8000/items/5?q=somequery.

Bạn sẽ thấy một JSON response:

{"item_id": 5, "q": "somequery"}

Bạn đã sẵn sàng để tạo một API như sau:

  • Nhận HTTP request với đường dẫn //items/{item_id}.
  • Cả hai đường dẫn sử dụng toán tử GET (cũng đươc biết đến là phương thức HTTP).
  • Đường dẫn /items/{item_id} có một tham số đường dẫn item_id, nó là một tham số kiểu int.
  • Đường dẫn /items/{item_id} có một tham số query string q, nó là một tham số tùy chọn kiểu str.

Tài liệu tương tác API

Truy cập http://127.0.0.1:8000/docs.

Bạn sẽ thấy tài liệu tương tác API được tạo tự động (cung cấp bởi Swagger UI):

Swagger UI

Tài liệu API thay thế

Và bây giờ, hãy truy cập tới http://127.0.0.1:8000/redoc.

Bạn sẽ thấy tài liệu được thay thế (cung cấp bởi ReDoc):

ReDoc

Nâng cấp ví dụ

Bây giờ sửa tệp tin main.py để nhận body từ một request PUT.

Định nghĩa của body sử dụng kiểu dữ liệu chuẩn của Python, cảm ơn Pydantic.

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float
    is_offer: Union[bool, None] = None


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}


@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "item_id": item_id}

Server nên tự động chạy lại (bởi vì bạn đã thêm --reload trong lệnh uvicorn ở trên).

Nâng cấp tài liệu API

Bây giờ truy cập tới http://127.0.0.1:8000/docs.

  • Tài liệu API sẽ được tự động cập nhật, bao gồm body mới:

Swagger UI

  • Click vào nút "Try it out", nó cho phép bạn điền những tham số và tương tác trực tiếp với API:

Swagger UI interaction

  • Sau khi click vào nút "Execute", giao diện người dùng sẽ giao tiếp với API của bạn bao gồm: gửi các tham số, lấy kết quả và hiển thị chúng trên màn hình:

Swagger UI interaction

Nâng cấp tài liệu API thay thế

Và bây giờ truy cập tới http://127.0.0.1:8000/redoc.

  • Tài liệu thay thế cũng sẽ phản ánh tham số và body mới:

ReDoc

Tóm lại

Bạn khai báo một lần kiểu dữ liệu của các tham số, body, etc là các tham số của hàm số.

Bạn định nghĩa bằng cách sử dụng các kiểu dữ liệu chuẩn của Python.

Bạn không phải học một cú pháp mới, các phương thức và class của một thư viện cụ thể nào.

Chỉ cần sử dụng các chuẩn của Python.

Ví dụ, với một tham số kiểu int:

item_id: int

hoặc với một model Item phức tạp hơn:

item: Item

...và với định nghĩa đơn giản đó, bạn có được:

  • Sự hỗ trợ từ các trình soạn thảo, bao gồm:
    • Completion.
    • Kiểm tra kiểu dữ liệu.
  • Kiểm tra kiểu dữ liệu:
    • Tự động sinh lỗi rõ ràng khi dữ liệu không hợp lệ .
    • Kiểm tra JSON lồng nhau .
  • Chuyển đổi dữ liệu đầu vào: tới từ network sang dữ liệu kiểu Python. Đọc từ:
    • JSON.
    • Các tham số trong đường dẫn.
    • Các tham số trong query string.
    • Cookies.
    • Headers.
    • Forms.
    • Files.
  • Chuyển đổi dữ liệu đầu ra: chuyển đổi từ kiểu dữ liệu Python sang dữ liệu network (như JSON):
    • Chuyển đổi kiểu dữ liệu Python (str, int, float, bool, list,...).
    • datetime objects.
    • UUID objects.
    • Database models.
    • ...và nhiều hơn thế.
  • Tự động tạo tài liệu tương tác API, bao gồm 2 giao diện người dùng:
    • Swagger UI.
    • ReDoc.

Quay trở lại ví dụ trước, FastAPI sẽ thực hiện:

  • Kiểm tra xem có một item_id trong đường dẫn với các request GETPUT không?
  • Kiểm tra xem item_id có phải là kiểu int trong các request GETPUT không?
    • Nếu không, client sẽ thấy một lỗi rõ ràng và hữu ích.
  • Kiểm tra xem nếu có một tham số q trong query string (ví dụ như http://127.0.0.1:8000/items/foo?q=somequery) cho request GET.
    • Tham số q được định nghĩa = None, nó là tùy chọn.
    • Nếu không phải None, nó là bắt buộc (như body trong trường hợp của PUT).
  • Với request PUT tới /items/{item_id}, đọc body như JSON:
    • Kiểm tra xem nó có một thuộc tính bắt buộc kiểu strname không?
    • Kiểm tra xem nó có một thuộc tính bắt buộc kiểu floatprice không?
    • Kiểm tra xem nó có một thuộc tính tùy chọn là is_offer không? Nếu có, nó phải có kiểu bool.
    • Tất cả những kiểm tra này cũng được áp dụng với các JSON lồng nhau.
  • Chuyển đổi tự động các JSON object đến và JSON object đi.
  • Tài liệu hóa mọi thứ với OpenAPI, tài liệu đó có thể được sử dụng bởi:

    • Các hệ thống tài liệu có thể tương tác.
    • Hệ thống sinh code tự động, cho nhiều ngôn ngữ lập trình.
    • Cung cấp trực tiếp 2 giao diện web cho tài liệu tương tác

Chúng tôi chỉ trình bày những thứ cơ bản bên ngoài, nhưng bạn đã hiểu cách thức hoạt động của nó.

Thử thay đổi dòng này:

    return {"item_name": item.name, "item_id": item_id}

...từ:

        ... "item_name": item.name ...

...sang:

        ... "item_price": item.price ...

...và thấy trình soạn thảo của bạn nhận biết kiểu dữ liệu và gợi ý hoàn thiện các thuộc tính.

trình soạn thảo hỗ trợ

Ví dụ hoàn chỉnh bao gồm nhiều tính năng hơn, xem Tutorial - User Guide.

Cảnh báo tiết lỗ: Tutorial - User Guide:

  • Định nghĩa tham số từ các nguồn khác nhau như: headers, cookies, form fieldsfiles.
  • Cách thiết lập các ràng buộc cho validation như maximum_length hoặc regex.
  • Một hệ thống **Dependency Injection vô cùng mạnh mẽ và dễ dàng sử dụng.
  • Bảo mật và xác thực, hỗ trợ OAuth2(với JWT tokens) và HTTP Basic.
  • Những kĩ thuật nâng cao hơn (nhưng tương đối dễ) để định nghĩa JSON models lồng nhau (cảm ơn Pydantic).
  • Tích hợp GraphQL với Strawberry và các thư viện khác.
  • Nhiều tính năng mở rộng (cảm ơn Starlette) như:
    • WebSockets
    • kiểm thử vô cùng dễ dàng dựa trên HTTPX và pytest
    • CORS
    • Cookie Sessions
    • ...và nhiều hơn thế.

Hiệu năng

Independent TechEmpower benchmarks cho thấy các ứng dụng FastAPI chạy dưới Uvicorn là một trong những Python framework nhanh nhất, chỉ đứng sau Starlette và Uvicorn (được sử dụng bên trong FastAPI). (*)

Để hiểu rõ hơn, xem phần Benchmarks.

Các dependency tùy chọn

Sử dụng bởi Pydantic:

Sử dụng Starlette:

  • httpx - Bắt buộc nếu bạn muốn sử dụng TestClient.
  • jinja2 - Bắt buộc nếu bạn muốn sử dụng cấu hình template engine mặc định.
  • python-multipart - Bắt buộc nếu bạn muốn hỗ trợ "parsing", form với request.form().
  • itsdangerous - Bắt buộc để hỗ trợ SessionMiddleware.
  • pyyaml - Bắt buộc để hỗ trợ SchemaGenerator cho Starlette (bạn có thể không cần nó trong FastAPI).

Sử dụng bởi FastAPI / Starlette:

  • uvicorn - Server để chạy ứng dụng của bạn.
  • orjson - Bắt buộc nếu bạn muốn sử dụng ORJSONResponse.
  • ujson - Bắt buộc nếu bạn muốn sử dụng UJSONResponse.

Bạn có thể cài đặt tất cả những dependency trên với pip install "fastapi[all]".

Giấy phép

Dự án này được cấp phép dưới những điều lệ của giấy phép MIT.