FastAPI 的效能優勢源於其非同步程式設計模型和 Starlette 的高效能網路核心,使其能處理大量並發請求。內建的 Swagger UI 自動生成互動式 API 檔案,簡化開發流程。除了 RESTful API,FastAPI 也支援 WebSockets 和 GraphQL,提供更靈活的資料交換方式。型別提示的運用強化了程式碼可讀性和維護性,同時也減少了執行時期錯誤的風險。此外,FastAPI 提供了 OAuth2 和 JWT 等安全機制,並方便整合測試工具,確保應用程式的穩定性和安全性。最後,FastAPI 支援多種佈署方式,包含 Docker 容器和雲端平台,方便開發者快速上線應用服務。
深入理解FastAPI:建構現代化Python後端服務
FastAPI是一個現代化的Python Web框架,專為建構高效能且可擴充套件的API而設計。它結合了快速開發、強大的型別檢查和自動化的檔案生成,使其成為開發人員的首選框架之一。本文將探討FastAPI的核心功能、優勢以及如何利用它來建構強大的後端服務。
FastAPI的核心功能
1. 非同步程式設計
FastAPI全面支援非同步程式設計,這使得它能夠處理大量並發請求而不會阻塞主執行緒。這對於需要處理即時資料或高並發請求的應用程式來說至關重要。
from fastapi import FastAPI
import asyncio
app = FastAPI()
async def fetch_data():
await asyncio.sleep(1)
return {"data": "Fetched data"}
@app.get("/data")
async def read_data():
data = await fetch_data()
return data
內容解密:
這段程式碼展示瞭如何在FastAPI中使用非同步函式。fetch_data
函式模擬了一個非同步操作,例如從資料函式庫或外部API取得資料。read_data
端點呼叫這個非同步函式並傳回結果。
2. 自動檔案生成
FastAPI能夠根據你的程式碼自動生成互動式API檔案。這不僅節省了手動編寫檔案的時間,還確保了檔案的準確性和即時性。
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
內容解密:
這段程式碼定義了一個簡單的端點,當存取/items/{item_id}
時,它會傳回一個包含item_id
的JSON物件。FastAPI會自動為這個端點生成檔案,包括引數說明和範例請求。
3. 強大的型別檢查
FastAPI利用Python的型別提示來進行強大的型別檢查和驗證。這不僅提高了程式碼的可讀性,還減少了執行階段錯誤的可能性。
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
內容解密:
這段程式碼定義了一個Item
模型,用於驗證傳入的JSON資料。update_item
端點使用這個模型來確保請求體的正確性,並傳回更新後的專案資訊。
WebSockets支援
FastAPI提供了對WebSockets的原生支援,使得實作即時雙向通訊變得簡單。這對於需要即時更新的應用程式(如聊天應用或即時資料分析)非常有用。
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message text was: {data}")
內容解密:
這段程式碼建立了一個WebSocket端點。當客戶端連線時,伺服器會接受連線並進入一個無限迴圈,接收客戶端傳送的訊息並回傳確認訊息。
GraphQL整合
FastAPI可以與GraphQL整合,提供更靈活的資料查詢方式。這使得客戶端可以精確地請求所需的資料,減少不必要的資料傳輸。
import strawberry
from fastapi import FastAPI
from strawberry.asgi import GraphQL
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "Hello World"
schema = strawberry.Schema(Query)
graphql_app = GraphQL(schema)
app = FastAPI()
app.add_route("/graphql", graphql_app)
app.add_websocket_route("/graphql", graphql_app)
內容解密:
這段程式碼使用Strawberry函式庫在FastAPI中實作了一個簡單的GraphQL API。它定義了一個Query
型別,其中包含一個hello
欄位,傳回"Hello World"字串。
安全性與測試
FastAPI提供了多種安全功能,如OAuth2和JWT驗證。同時,它也支援全面的測試,包括對WebSockets和資料函式庫操作的測試。
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
app = FastAPI()
async def get_current_user(token: str = Depends(oauth2_scheme)):
if token != "fake_token":
raise HTTPException(status_code=401, detail="Invalid authentication credentials")
return token
@app.get("/users/me")
async def read_users_me(current_user: str = Depends(get_current_user)):
return {"username": current_user}
內容解密:
這段程式碼實作了一個簡單的OAuth2驗證機制。get_current_user
函式用於驗證傳入的token,如果token無效,則傳回401錯誤。read_users_me
端點依賴於這個驗證函式來取得當前使用者資訊。
佈署策略
FastAPI應用可以佈署在多種環境中,包括Docker容器、雲端平台如Google Cloud和AWS,以及傳統的WSGI伺服器。
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
內容解密:
這段Dockerfile用於將FastAPI應用容器化。它根據Python 3.9映像,安裝依賴項,複製應用程式碼,並設定使用Uvicorn執行應用。
第一章:FastAPI簡介
近年來,Python作為一門程式語言,其受歡迎程度大幅提升,主要歸因於其在資料科學領域的豐富函式庫。然而,Python同樣被廣泛應用於網頁應用程式開發,這得益於其豐富的網頁應用框架。
FastAPI是Python網頁應用框架的最新成員,但它並非只是另一個框架。FastAPI具備一些明顯的優勢,被認為是最快的框架之一,它充分利用了現代Python的功能。本章將介紹FastAPI函式庫所根據的重要功能。
本章涵蓋以下主題:
- 型別提示
- 非同步處理
- REST架構
- HTTP動詞
- FastAPI依賴項
- FastAPI安裝
型別提示
Python是一種動態型別語言。相反,C/C++和Java等語言是靜態型別語言,在這些語言中,變數的型別必須在指定之前宣告。在C/C++/Java程式的生命週期中,變數只能持有其宣告型別的資料。在Python中,情況恰恰相反。變數的型別由賦給它的值決定,並且可以在每次指定時動態更改。
清單1-1:動態型別
>>> x = 10
>>> # x是一個int變數
>>> x = (1, 2, 3)
>>> type(x)
<class 'tuple'>
>>> x = [1, 2, 3]
>>> # x現在是一個list
>>> type(x)
<class 'list'>
>>> x = "Hello World"
>>> # x現在變成了一個str變數
>>> type(x)
<class 'str'>
內容解密:
在上述範例中,變數x
的型別隨著指定不同而改變。初始時x
被指定為整數10
,隨後被指定為元組(1, 2, 3)
、列表[1, 2, 3]
和字串"Hello World"
。每次指定後,x
的型別都發生了變化。
雖然這種動態型別特性使得程式設計更加容易,但也容易遇到執行時錯誤,因為Python直譯器在執行之前不會強制進行任何型別檢查。
清單1-2:Python函式
# hint.py
def division(num, den):
return num / den
內容解密:
此函式接受兩個引數num
和den
,並傳回它們的除法結果。然而,如果傳入的引數型別不正確,例如將字串傳入,將導致執行時錯誤。
清單1-3:函式中的TypeError
>>> from hint import division
>>> division(10, 2)
5.0
>>> division(10, 2.5)
4.0
>>> division("Python", 2)
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
division("Python", 2)
File "F:\python36\hint.py", line 3, in division
return num / den
TypeError: unsupported operand type(s) for /: 'str' and 'int'
內容解密:
前兩次對division()
函式的呼叫成功,但第三次呼叫由於嘗試對字串和整數進行除法運算而丟擲了TypeError
例外。
標準Python安裝所附帶的預設Python直譯器(Python shell)功能相當基礎。更先進的Python執行環境,如IPython和Jupyter Notebook,以及許多Python IDE(如VS Code、PyCharm,包括隨標準函式庫附帶的基本IDE IDLE),都具有諸如自動完成、語法高亮和型別預測幫助等實用功能。圖1-1展示了IPython的自動完成功能。
IPython自動完成示意圖
graph LR; A[使用者輸入] --> B[IPython直譯器]; B --> C[自動完成建議]; C --> D[使用者選擇]; D --> E[程式碼自動補全];
圖表翻譯: 此圖示展示了IPython的自動完成功能的工作流程。當使用者輸入程式碼時,IPython直譯器會提供自動完成的建議。使用者可以從這些建議中選擇需要的選項,從而實作程式碼的自動補全。
型別提示的重要性
儘管Python是動態型別語言,但型別提示(Type Hints)可以幫助開發者更好地理解函式或方法的預期輸入和輸出型別,從而提高程式碼的可讀性和可維護性。
範例:使用型別提示的函式
def greeting(name: str) -> str:
return 'Hello ' + name
內容解密:
在這個範例中,greeting
函式接受一個字串引數name
,並傳回一個字串。這裡使用了型別提示來明確函式的輸入和輸出型別,使得函式的使用更加清晰。
FastAPI依賴項
FastAPI根據Starlette和Pydantic這兩個函式庫。Starlette是一個輕量級的ASGI框架/工具包,非常適合用於建立高效能的非同步服務。Pydantic則是一個執行時型別檢查和驗證的函式庫,用於確保資料模型的正確性。
範例:Pydantic模型定義
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
email: str
內容解密:
在這個範例中,我們定義了一個名為User
的Pydantic模型,它具有三個屬性:id
、name
和email
,分別對應整數、字串和字串型別。Pydantic會在執行時檢查賦給這些屬性的值的型別是否正確。
FastAPI安裝
要安裝FastAPI,可以使用pip命令。
pip install fastapi uvicorn
內容解密:
這條命令會安裝FastAPI及其所需的依賴項,以及用於執行ASGI應用的伺服器uvicorn。
隨著現代網頁應用程式對效能要求的提高,FastAPI憑藉其對非同步處理和型別提示的支援,已經成為開發高效能網頁應用的首選框架之一。未來,我們可以預期看到更多根據FastAPI構建的高效能網頁應用。
總之,本章介紹了FastAPI的一些基礎知識,包括型別提示、非同步處理、REST架構、HTTP動詞、FastAPI依賴項和安裝。這些知識為進一步學習和使用FastAPI打下了堅實的基礎。在接下來的章節中,我們將繼續探討FastAPI的其他重要功能和應用場景,以幫助讀者更好地掌握這一強大的網頁應用框架。
Python型別提示(Type Hinting)與非同步處理(Asynchronous Processing)詳解
Python型別提示(Type Hinting)
Python 3.5版本引入了型別提示(Type Hinting)功能,允許開發者在變數宣告、函式引數以及回傳值中指定預期的資料型別。雖然Python直譯器不會強制執行型別檢查,但IDE(整合開發環境)如VS Code可以利用這些提示提供更好的程式碼自動完成、型別檢查以及檔案產生。
型別提示的基本使用
以下是一個簡單的範例,展示如何在函式定義中使用型別提示:
def division(num: int, den: int) -> float:
return num / den
在上述範例中,num
和den
被指定為int
型別,而函式的回傳值則被指定為float
型別。
內容解密:
def division(num: int, den: int) -> float:
:這行程式碼定義了一個名為division
的函式,接受兩個整數引數num
和den
,並回傳一個浮點數。num: int
和den: int
:這兩個引數被指定為整數型別,IDE會根據這些提示提供相關的警告或自動完成建議。-> float
:表示該函式會回傳一個浮點數。
typing模組的進階型別提示
Python的typing
模組提供了更多進階的型別提示功能,例如List
、Tuple
、Dict
、Union
、Any
以及Optional
等。
from typing import List, Tuple, Union
# 使用List[float]指定列表中元素的型別為浮點數
l2: List[float] = [100, 25.50, 2.2E-2]
# 使用Tuple[Union[int, str]]指定元組中元素可以是整數或字串
l3: Tuple[Union[int, str]] = [5, "Python", 100]
內容解密:
from typing import List, Tuple, Union
:匯入typing
模組中的進階型別提示類別。l2: List[float]
:宣告一個名為l2
的列表變數,並指定其元素應為浮點數型別。l3: Tuple[Union[int, str]]
:宣告一個名為l3
的元組變數,並指定其元素可以是整數或字串。
非同步處理(Asynchronous Processing)
Python 3.5版本開始支援非同步處理,非同步處理允許多個任務在單一執行緒中協同工作,提高程式的平行處理能力。
asyncio模組與非同步函式
Python的asyncio
模組提供了非同步處理的核心功能,而async
和await
關鍵字則用於定義和呼叫非同步函式。
import asyncio
async def sayhello():
print("Hello Python")
async def main():
for _ in range(5):
await sayhello()
asyncio.run(main())
內容解密:
async def sayhello():
:定義一個名為sayhello
的非同步函式。async def main():
:定義一個名為main
的非同步函式,其中包含一個迴圈呼叫sayhello()
。await sayhello()
:在main()
函式中,使用await
關鍵字等待sayhello()
函式的完成。asyncio.run(main())
:使用asyncio.run()
函式執行main()
非同步函式。
隨著Python的不斷演進,型別提示和非同步處理將會變得更加完善和強大。未來,我們可以期待更多根據這些功能的框架和工具出現,以進一步簡化Python開發流程並提高程式效能。