FastAPI¶
FastAPI framework, hiệu năng cao, dễ học, dễ code, sẵn sàng để tạo ra sản phẩm
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 NodeJS và Go (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ợ¶
Ý 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."
"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] "
"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]"
"Tôi vô cùng hào hứng về FastAPI. Nó rất thú vị"
"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ó."
"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ó [...]"
"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ản và có 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."
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ề async
và await
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 tinmain.py
(một Python "module").app
: object được tạo trong tệp tinmain.py
tại dòngapp = 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
/
và/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ẫnitem_id
, nó là một tham số kiểuint
. - Đường dẫn
/items/{item_id}
có một tham số query stringq
, nó là một tham số tùy chọn kiểustr
.
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):
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):
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:
- 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:
- 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:
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:
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ế.
- Chuyển đổi kiểu dữ liệu Python (
- 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 requestGET
vàPUT
không? - Kiểm tra xem
item_id
có phải là kiểuint
trong các requestGET
vàPUT
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 requestGET
.- 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ủaPUT
).
- Tham số
- 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
str
làname
không? - Kiểm tra xem nó có một thuộc tính bắt buộc kiểu
float
làprice
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ểubool
. - Tất cả những kiểm tra này cũng được áp dụng với các JSON lồng nhau.
- Kiểm tra xem nó có một thuộc tính bắt buộc kiểu
- 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.
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 fields và files.
- Cách thiết lập các ràng buộc cho validation như
maximum_length
hoặcregex
. - 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:
email-validator
- cho email validation.
Sử dụng Starlette:
httpx
- Bắt buộc nếu bạn muốn sử dụngTestClient
.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ớirequest.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ụngORJSONResponse
.ujson
- Bắt buộc nếu bạn muốn sử dụngUJSONResponse
.
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.