mirror of https://github.com/tiangolo/fastapi.git
🌐 Update translations for zh-hant (update-outdated) (#15178)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
This commit is contained in:
parent
b7bd1874fe
commit
fe98ea307a
|
|
@ -11,7 +11,7 @@
|
|||
* 檢查翻譯是否正確。
|
||||
* 如有需要,改進你的語言特定提示、通用提示,或英文原文。
|
||||
* 然後手動修正翻譯中剩下的問題,讓它成為一個好的譯文。
|
||||
* 重新翻譯,並保留這份好的譯文。理想結果是 LLM 不再對該譯文做任何變更。這代表通用提示與你的語言特定提示已經盡可能完善(有時它仍可能做出幾個看似隨機的變更,原因是<a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">LLMs 並非決定性演算法</a>)。
|
||||
* 重新翻譯,並保留這份好的譯文。理想結果是 LLM 不再對該譯文做任何變更。這代表通用提示與你的語言特定提示已經盡可能完善(有時它仍可能做出幾個看似隨機的變更,原因是[LLMs 並非決定性演算法](https://doublespeak.chat/#/handbook#deterministic-output))。
|
||||
|
||||
測試:
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ $ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid
|
|||
...以及另一個主控台範例...
|
||||
|
||||
```console
|
||||
// 建立目錄 "code"
|
||||
// 建立目錄 "Code"
|
||||
$ mkdir code
|
||||
// 切換到該目錄
|
||||
$ cd code
|
||||
|
|
@ -169,15 +169,15 @@ Some text
|
|||
連結文字應被翻譯,連結位址應保持不變:
|
||||
|
||||
* [連結到上方標題](#code-snippets)
|
||||
* [內部連結](index.md#installation){.internal-link target=_blank}
|
||||
* <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">外部連結</a>
|
||||
* <a href="https://fastapi.tiangolo.com/css/styles.css" class="external-link" target="_blank">連結到樣式</a>
|
||||
* <a href="https://fastapi.tiangolo.com/js/logic.js" class="external-link" target="_blank">連結到腳本</a>
|
||||
* <a href="https://fastapi.tiangolo.com/img/foo.jpg" class="external-link" target="_blank">連結到圖片</a>
|
||||
* [內部連結](index.md#installation)
|
||||
* [外部連結](https://sqlmodel.tiangolo.com/)
|
||||
* [連結到樣式](https://fastapi.tiangolo.com/css/styles.css)
|
||||
* [連結到腳本](https://fastapi.tiangolo.com/js/logic.js)
|
||||
* [連結到圖片](https://fastapi.tiangolo.com/img/foo.jpg)
|
||||
|
||||
連結文字應被翻譯,連結位址應指向對應的翻譯版本:
|
||||
|
||||
* <a href="https://fastapi.tiangolo.com/zh-hant/" class="external-link" target="_blank">FastAPI 連結</a>
|
||||
* [FastAPI 連結](https://fastapi.tiangolo.com/zh-hant/)
|
||||
|
||||
////
|
||||
|
||||
|
|
@ -291,7 +291,7 @@ Hello again.
|
|||
* 即時
|
||||
* 標準
|
||||
* 預設
|
||||
* 區分大小寫
|
||||
* 区分大小寫
|
||||
* 不區分大小寫
|
||||
|
||||
* 提供應用程式服務
|
||||
|
|
|
|||
|
|
@ -243,5 +243,5 @@ new_dict = {**old_dict, "new key": "new value"}
|
|||
|
||||
若要查看回應中究竟可以包含哪些內容,你可以參考 OpenAPI 規範中的這些章節:
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object" class="external-link" target="_blank">OpenAPI Responses 物件</a>,其中包含 `Response Object`。
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object" class="external-link" target="_blank">OpenAPI Response 物件</a>,你可以把這裡的任何內容直接放到 `responses` 參數內各個回應中。包含 `description`、`headers`、`content`(在其中宣告不同的媒體型別與 JSON Schemas)、以及 `links`。
|
||||
* [OpenAPI Responses 物件](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object),其中包含 `Response Object`。
|
||||
* [OpenAPI Response 物件](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object),你可以把這裡的任何內容直接放到 `responses` 參數內各個回應中。包含 `description`、`headers`、`content`(在其中宣告不同的媒體型別與 JSON Schemas)、以及 `links`。
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
///
|
||||
|
||||
/// note | 注意
|
||||
/// note | 技術細節
|
||||
|
||||
你也可以使用 `from starlette.responses import JSONResponse`。
|
||||
|
||||
|
|
@ -38,4 +38,4 @@
|
|||
|
||||
如果你直接回傳額外的狀態碼與回應,它們不會被包含進 OpenAPI 綱要(API 文件)中,因為 FastAPI 無法事先知道你會回傳什麼。
|
||||
|
||||
但你可以在程式碼中補充文件,使用:[額外的回應](additional-responses.md){.internal-link target=_blank}。
|
||||
但你可以在程式碼中補充文件,使用:[額外的回應](additional-responses.md)。
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ checker(q="somequery")
|
|||
|
||||
如此一來,該 session 就會釋放資料庫連線,讓其他請求可以使用。
|
||||
|
||||
如果你有不同的情境,需要從含有 `yield` 的相依中提早結束,請建立一個 <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub 討論問題</a>,描述你的具體情境,以及為何提早關閉含有 `yield` 的相依對你有幫助。
|
||||
如果你有不同的情境,需要從含有 `yield` 的相依中提早結束,請建立一個 [GitHub 討論問題](https://github.com/fastapi/fastapi/discussions/new?category=questions),描述你的具體情境,以及為何提早關閉含有 `yield` 的相依對你有幫助。
|
||||
|
||||
如果有令人信服的案例需要在含有 `yield` 的相依中提前關閉,我會考慮加入一種新的選項,讓你可以選擇性啟用提前關閉。
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ checker(q="somequery")
|
|||
|
||||
### 背景任務與含有 `yield` 的相依,技術細節 { #background-tasks-and-dependencies-with-yield-technical-details }
|
||||
|
||||
在 FastAPI 0.106.0 之前,不可能在 `yield` 之後拋出例外;含有 `yield` 的相依的結束程式碼會在回應送出之後才執行,因此[例外處理器](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} 早就已經跑完了。
|
||||
在 FastAPI 0.106.0 之前,不可能在 `yield` 之後拋出例外;含有 `yield` 的相依的結束程式碼會在回應送出之後才執行,因此[例外處理器](../tutorial/handling-errors.md#install-custom-exception-handlers) 早就已經跑完了。
|
||||
|
||||
當初這樣設計主要是為了允許在背景任務中使用由相依「yield」出來的同一組物件,因為結束程式碼會在背景任務結束後才執行。
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
`TestClient` 在內部做了一些魔法,讓我們能在一般的 `def` 測試函式中,使用標準 pytest 來呼叫非同步的 FastAPI 應用。但當我們在非同步函式中使用它時,這個魔法就不再奏效了。也就是說,當以非同步方式執行測試時,就不能在測試函式內使用 `TestClient`。
|
||||
|
||||
`TestClient` 是建立在 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> 之上,所幸我們可以直接使用它來測試 API。
|
||||
`TestClient` 是建立在 [HTTPX](https://www.python-httpx.org) 之上,所幸我們可以直接使用它來測試 API。
|
||||
|
||||
## 範例 { #example }
|
||||
|
||||
作為簡單範例,讓我們考慮與[更大型的應用](../tutorial/bigger-applications.md){.internal-link target=_blank}與[測試](../tutorial/testing.md){.internal-link target=_blank}中描述的類似檔案結構:
|
||||
作為簡單範例,讓我們考慮與[更大型的應用](../tutorial/bigger-applications.md)與[測試](../tutorial/testing.md)中描述的類似檔案結構:
|
||||
|
||||
```
|
||||
.
|
||||
|
|
@ -84,7 +84,7 @@ response = client.get('/')
|
|||
|
||||
/// warning
|
||||
|
||||
如果你的應用仰賴 lifespan 事件,`AsyncClient` 不會觸發這些事件。若要確保它們被觸發,請使用 <a href="https://github.com/florimondmanca/asgi-lifespan#usage" class="external-link" target="_blank">florimondmanca/asgi-lifespan</a> 的 `LifespanManager`。
|
||||
如果你的應用仰賴 lifespan 事件,`AsyncClient` 不會觸發這些事件。若要確保它們被觸發,請使用 [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage) 的 `LifespanManager`。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -94,6 +94,6 @@ response = client.get('/')
|
|||
|
||||
/// tip
|
||||
|
||||
如果在將非同步呼叫整合進測試時遇到 `RuntimeError: Task attached to a different loop`(例如使用 <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB 的 MotorClient</a> 時),請記得:需要事件迴圈的物件只應在非同步函式內實例化,例如在 `@app.on_event("startup")` 回呼中。
|
||||
如果在將非同步呼叫整合進測試時遇到 `RuntimeError: Task attached to a different loop`(例如使用 [MongoDB 的 MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop) 時),請記得:需要事件迴圈的物件只應在非同步函式內實例化,例如在 `@app.on_event("startup")` 回呼中。
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
代理相關的標頭有:
|
||||
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
|
||||
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
|
||||
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
|
||||
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ https://mysuperapp.com/items/
|
|||
|
||||
/// tip
|
||||
|
||||
如果你想了解更多 HTTPS 的內容,請參考指南[[關於 HTTPS](../deployment/https.md){.internal-link target=_blank}]。
|
||||
如果你想了解更多 HTTPS 的內容,請參考指南[[關於 HTTPS](../deployment/https.md)]。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
|||
|
||||
請記住,伺服器(Uvicorn)除了把 `root_path` 傳給應用之外,不會拿它做其他用途。
|
||||
|
||||
但如果你用瀏覽器前往 <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>,你會看到一般的回應:
|
||||
但如果你用瀏覽器前往 [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app) ,你會看到一般的回應:
|
||||
|
||||
```JSON
|
||||
{
|
||||
|
|
@ -251,9 +251,9 @@ Uvicorn 會預期代理以 `http://127.0.0.1:8000/app` 來存取 Uvicorn,而
|
|||
|
||||
## 在本機使用 Traefik 測試 { #testing-locally-with-traefik }
|
||||
|
||||
你可以很容易地用 <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a> 在本機跑一個「移除路徑前綴」的測試。
|
||||
你可以很容易地用 [Traefik](https://docs.traefik.io/) 在本機跑一個「移除路徑前綴」的測試。
|
||||
|
||||
<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">下載 Traefik</a>,它是一個單一的執行檔,你可以解壓縮後直接在終端機執行。
|
||||
[下載 Traefik](https://github.com/containous/traefik/releases),它是一個單一的執行檔,你可以解壓縮後直接在終端機執行。
|
||||
|
||||
然後建立一個 `traefik.toml` 檔案,內容如下:
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
|||
|
||||
### 檢查回應 { #check-the-responses }
|
||||
|
||||
現在,如果你前往 Uvicorn 的埠:<a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>,你會看到一般的回應:
|
||||
現在,如果你前往 Uvicorn 的埠:[http://127.0.0.1:8000/app](http://127.0.0.1:8000/app),你會看到一般的回應:
|
||||
|
||||
```JSON
|
||||
{
|
||||
|
|
@ -345,7 +345,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
|||
|
||||
///
|
||||
|
||||
接著打開使用 Traefik 埠且包含路徑前綴的 URL:<a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>。
|
||||
接著打開使用 Traefik 埠且包含路徑前綴的 URL:[http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app)。
|
||||
|
||||
我們會得到相同的回應:
|
||||
|
||||
|
|
@ -370,13 +370,13 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
|||
|
||||
「正式」的存取方式應該是透過我們定義了路徑前綴的代理。因此,如我們預期,如果你直接透過 Uvicorn 供應的文件 UI、而 URL 中沒有該路徑前綴,那它不會運作,因為它預期要透過代理來存取。
|
||||
|
||||
你可以在 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> 檢查:
|
||||
你可以在 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) 檢查:
|
||||
|
||||
<img src="/img/tutorial/behind-a-proxy/image01.png">
|
||||
|
||||
但如果我們改用「正式」的 URL,也就是使用埠號 `9999` 的代理、並在 `/api/v1/docs`,它就能正確運作了!🎉
|
||||
|
||||
你可以在 <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> 檢查:
|
||||
你可以在 [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) 檢查:
|
||||
|
||||
<img src="/img/tutorial/behind-a-proxy/image02.png">
|
||||
|
||||
|
|
@ -433,7 +433,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
|||
|
||||
///
|
||||
|
||||
在位於 <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> 的文件 UI 中看起來會像這樣:
|
||||
在位於 [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) 的文件 UI 中看起來會像這樣:
|
||||
|
||||
<img src="/img/tutorial/behind-a-proxy/image03.png">
|
||||
|
||||
|
|
@ -461,6 +461,6 @@ OpenAPI 規格中的 `servers` 屬性是可選的。
|
|||
|
||||
## 掛載子應用 { #mounting-a-sub-application }
|
||||
|
||||
如果你需要在同時使用具有 `root_path` 的代理時,掛載一個子應用(如[[子應用 - 掛載](sub-applications.md){.internal-link target=_blank}]中所述),可以像平常一樣操作,正如你所預期的那樣。
|
||||
如果你需要在同時使用具有 `root_path` 的代理時,掛載一個子應用(如[[子應用 - 掛載](sub-applications.md)]中所述),可以像平常一樣操作,正如你所預期的那樣。
|
||||
|
||||
FastAPI 會在內部智慧地使用 `root_path`,所以一切都能順利運作。✨
|
||||
|
|
|
|||
|
|
@ -1,52 +1,36 @@
|
|||
# 自訂回應——HTML、串流、檔案與其他 { #custom-response-html-stream-file-others }
|
||||
|
||||
預設情況下,**FastAPI** 會使用 `JSONResponse` 傳回回應。
|
||||
預設情況下,**FastAPI** 會回傳 JSON 回應。
|
||||
|
||||
你可以像在[直接回傳 Response](response-directly.md){.internal-link target=_blank} 中所示,直接回傳一個 `Response` 來覆寫它。
|
||||
你可以像在[直接回傳 Response](response-directly.md)中所示,直接回傳一個 `Response` 來覆寫它。
|
||||
|
||||
但如果你直接回傳一個 `Response`(或其子類別,如 `JSONResponse`),資料將不會被自動轉換(即使你宣告了 `response_model`),而且文件也不會自動產生(例如,在產生的 OpenAPI 中包含 HTTP 標頭 `Content-Type` 的特定「media type」)。
|
||||
但如果你直接回傳一個 `Response`(或其子類別,例如 `JSONResponse`),資料將不會被自動轉換(即使你宣告了 `response_model`),而且文件也不會自動產生(例如,在產生的 OpenAPI 中包含 HTTP 標頭 `Content-Type` 的特定「media type」)。
|
||||
|
||||
你也可以在「路徑操作裝飾器」中使用 `response_class` 參數,宣告要使用的 `Response`(例如任意 `Response` 子類別)。
|
||||
|
||||
你從「路徑操作函式」回傳的內容,會被放進該 `Response` 中。
|
||||
|
||||
若該 `Response` 的 media type 是 JSON(`application/json`),像 `JSONResponse` 與 `UJSONResponse`,則你回傳的資料會自動以你在「路徑操作裝飾器」中宣告的 Pydantic `response_model` 進行轉換(與過濾)。
|
||||
|
||||
/// note
|
||||
|
||||
若你使用的回應類別沒有 media type,FastAPI 會假設你的回應沒有內容,因此不會在產生的 OpenAPI 文件中記錄回應格式。
|
||||
|
||||
///
|
||||
|
||||
## 使用 `ORJSONResponse` { #use-orjsonresponse }
|
||||
## JSON 回應 { #json-responses }
|
||||
|
||||
例如,若你在追求效能,你可以安裝並使用 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>,並將回應設為 `ORJSONResponse`。
|
||||
FastAPI 預設回傳 JSON 回應。
|
||||
|
||||
匯入你想使用的 `Response` 類別(子類),並在「路徑操作裝飾器」中宣告它。
|
||||
如果你宣告了[回應模型](../tutorial/response-model.md),FastAPI 會使用 Pydantic 將資料序列化為 JSON。
|
||||
|
||||
對於大型回應,直接回傳 `Response` 會比回傳 `dict` 快得多。
|
||||
如果你沒有宣告回應模型,FastAPI 會使用在[JSON 相容編碼器](../tutorial/encoder.md)中解釋的 `jsonable_encoder`,並將結果放進 `JSONResponse`。
|
||||
|
||||
這是因為預設情況下,FastAPI 會檢查每個項目並確認它能被序列化為 JSON,使用與教學中說明的相同[JSON 相容編碼器](../tutorial/encoder.md){.internal-link target=_blank}。這使你可以回傳「任意物件」,例如資料庫模型。
|
||||
如果你宣告的 `response_class` 具有 JSON 的 media type(`application/json`),像 `JSONResponse`,你回傳的資料會自動以你在「路徑操作裝飾器」中宣告的任何 Pydantic `response_model` 進行轉換(與過濾)。但資料不會由 Pydantic 直接序列化成 JSON 位元組;取而代之,會先經由 `jsonable_encoder` 轉換,然後交給 `JSONResponse` 類別,該類別會使用 Python 標準的 JSON 函式庫將其序列化為位元組。
|
||||
|
||||
但如果你確定你回傳的內容「可以用 JSON 序列化」,你可以直接將它傳給回應類別,避免 FastAPI 在把你的回傳內容交給回應類別之前,先經過 `jsonable_encoder` 所帶來的額外開銷。
|
||||
### JSON 效能 { #json-performance }
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
|
||||
簡而言之,若你想要最佳效能,請使用[回應模型](../tutorial/response-model.md),並且不要在「路徑操作裝飾器」中宣告 `response_class`。
|
||||
|
||||
/// info
|
||||
|
||||
參數 `response_class` 也會用來定義回應的「media type」。
|
||||
|
||||
在此情況下,HTTP 標頭 `Content-Type` 會被設為 `application/json`。
|
||||
|
||||
而且它會以此形式被記錄到 OpenAPI 中。
|
||||
|
||||
///
|
||||
|
||||
/// tip
|
||||
|
||||
`ORJSONResponse` 只在 FastAPI 中可用,在 Starlette 中不可用。
|
||||
|
||||
///
|
||||
{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
|
||||
|
||||
## HTML 回應 { #html-response }
|
||||
|
||||
|
|
@ -69,7 +53,7 @@
|
|||
|
||||
### 回傳 `Response` { #return-a-response }
|
||||
|
||||
如[直接回傳 Response](response-directly.md){.internal-link target=_blank} 所示,你也可以在「路徑操作」中直接回傳以覆寫回應。
|
||||
如[直接回傳 Response](response-directly.md)所示,你也可以在「路徑操作」中直接回傳以覆寫回應。
|
||||
|
||||
上面的相同範例,回傳 `HTMLResponse`,可以像這樣:
|
||||
|
||||
|
|
@ -154,37 +138,11 @@ FastAPI(實際上是 Starlette)會自動包含 Content-Length 標頭。也
|
|||
|
||||
這是 **FastAPI** 的預設回應,如上所述。
|
||||
|
||||
### `ORJSONResponse` { #orjsonresponse }
|
||||
/// note | 技術細節
|
||||
|
||||
使用 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> 的快速替代 JSON 回應,如上所述。
|
||||
但如果你宣告了回應模型或回傳型別,將會直接用它來把資料序列化為 JSON,並直接回傳具有正確 JSON media type 的回應,而不會使用 `JSONResponse` 類別。
|
||||
|
||||
/// info
|
||||
|
||||
這需要安裝 `orjson`,例如使用 `pip install orjson`。
|
||||
|
||||
///
|
||||
|
||||
### `UJSONResponse` { #ujsonresponse }
|
||||
|
||||
使用 <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a> 的替代 JSON 回應。
|
||||
|
||||
/// info
|
||||
|
||||
這需要安裝 `ujson`,例如使用 `pip install ujson`。
|
||||
|
||||
///
|
||||
|
||||
/// warning
|
||||
|
||||
`ujson` 在處理某些邊界情況時,沒那麼嚴謹,較 Python 內建實作更「隨意」。
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
|
||||
|
||||
/// tip
|
||||
|
||||
`ORJSONResponse` 可能是更快的替代方案。
|
||||
這是取得最佳效能的理想方式。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -214,31 +172,25 @@ FastAPI(實際上是 Starlette)會自動包含 Content-Length 標頭。也
|
|||
|
||||
### `StreamingResponse` { #streamingresponse }
|
||||
|
||||
接收一個 async 產生器或一般的產生器/疊代器,並以串流方式傳送回應本文。
|
||||
接收一個 async 產生器或一般的產生器/疊代器(帶有 `yield` 的函式),並以串流方式傳送回應本文。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
|
||||
{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}
|
||||
|
||||
#### 對「類檔案物件」使用 `StreamingResponse` { #using-streamingresponse-with-file-like-objects }
|
||||
/// note | 技術細節
|
||||
|
||||
如果你有一個<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">類檔案(file-like)</a>物件(例如 `open()` 回傳的物件),你可以建立一個產生器函式來疊代該類檔案物件。
|
||||
一個 `async` 任務只能在抵達某個 `await` 時才能被取消。如果沒有 `await`,該產生器(帶有 `yield` 的函式)將無法被正確取消,甚至在請求取消後仍可能持續執行。
|
||||
|
||||
如此一來,你不必先把它全部讀進記憶體,就能將那個產生器函式傳給 `StreamingResponse` 並回傳。
|
||||
因為這個小範例不需要任何 `await` 陳述式,我們加入 `await anyio.sleep(0)`,讓事件迴圈有機會處理取消。
|
||||
|
||||
這也包含許多用於雲端儲存、影像/影音處理等的函式庫。
|
||||
對於大型或無限的串流來說,這點更為重要。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
|
||||
|
||||
1. 這是產生器函式。因為它內含 `yield` 陳述式,所以是「產生器函式」。
|
||||
2. 透過 `with` 區塊,我們確保在產生器函式結束後關閉類檔案物件。因此,在完成傳送回應後就會關閉。
|
||||
3. 這個 `yield from` 告訴函式去疊代名為 `file_like` 的東西。對於每個被疊代到的部分,就把該部分當作此產生器函式(`iterfile`)的輸出進行 `yield`。
|
||||
|
||||
因此,這是一個把「生成」工作在內部轉交給其他東西的產生器函式。
|
||||
|
||||
透過這樣做,我們可以把它放進 `with` 區塊,藉此確保在完成後關閉類檔案物件。
|
||||
///
|
||||
|
||||
/// tip
|
||||
|
||||
注意,這裡我們使用的是標準的 `open()`,它不支援 `async` 與 `await`,因此我們用一般的 `def` 來宣告路徑操作。
|
||||
與其直接回傳 `StreamingResponse`,你大概會想遵循[資料串流](./stream-data.md)中的作法,這樣更方便,並且會在底層幫你處理取消。
|
||||
|
||||
如果你要串流 JSON Lines,請參考教學:[串流 JSON Lines](../tutorial/stream-json-lines.md)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -267,7 +219,7 @@ FastAPI(實際上是 Starlette)會自動包含 Content-Length 標頭。也
|
|||
|
||||
你可以建立自己的自訂回應類別,繼承自 `Response` 並加以使用。
|
||||
|
||||
例如,假設你要使用 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>,但想套用一些未包含在 `ORJSONResponse` 類別中的自訂設定。
|
||||
例如,假設你要使用 [`orjson`](https://github.com/ijl/orjson) 並套用一些設定。
|
||||
|
||||
假設你想回傳縮排且格式化的 JSON,因此要使用 orjson 選項 `orjson.OPT_INDENT_2`。
|
||||
|
||||
|
|
@ -281,7 +233,7 @@ FastAPI(實際上是 Starlette)會自動包含 Content-Length 標頭。也
|
|||
{"message": "Hello World"}
|
||||
```
|
||||
|
||||
……這個回應會回傳:
|
||||
...這個回應會回傳:
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -291,13 +243,21 @@ FastAPI(實際上是 Starlette)會自動包含 Content-Length 標頭。也
|
|||
|
||||
當然,你大概能找到比格式化 JSON 更好的方式來利用這個能力。😉
|
||||
|
||||
### `orjson` 或回應模型 { #orjson-or-response-model }
|
||||
|
||||
如果你追求效能,使用[回應模型](../tutorial/response-model.md) 大概會比使用 `orjson` 回應更好。
|
||||
|
||||
有了回應模型,FastAPI 會使用 Pydantic 直接將資料序列化為 JSON,而不需要像其他情況那樣先經過 `jsonable_encoder` 之類的中介步驟。
|
||||
|
||||
而且在底層,Pydantic 用來序列化為 JSON 的 Rust 機制和 `orjson` 相同,因此用回應模型已經能獲得最佳效能。
|
||||
|
||||
## 預設回應類別 { #default-response-class }
|
||||
|
||||
在建立 **FastAPI** 類別實例或 `APIRouter` 時,你可以指定預設要使用哪個回應類別。
|
||||
|
||||
用來設定的是 `default_response_class` 參數。
|
||||
|
||||
在下面的例子中,**FastAPI** 會在所有「路徑操作」中預設使用 `ORJSONResponse`,而不是 `JSONResponse`。
|
||||
在下面的例子中,**FastAPI** 會在所有「路徑操作」中預設使用 `HTMLResponse`,而不是 JSON。
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
|
||||
|
||||
|
|
@ -309,4 +269,4 @@ FastAPI(實際上是 Starlette)會自動包含 Content-Length 標頭。也
|
|||
|
||||
## 其他文件化選項 { #additional-documentation }
|
||||
|
||||
你也可以在 OpenAPI 中使用 `responses` 宣告 media type 與其他許多細節:[在 OpenAPI 中的額外回應](additional-responses.md){.internal-link target=_blank}。
|
||||
你也可以在 OpenAPI 中使用 `responses` 宣告 media type 與其他許多細節:[在 OpenAPI 中的額外回應](additional-responses.md)。
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
FastAPI 建立在 **Pydantic** 之上,我之前示範過如何使用 Pydantic 模型來宣告請求與回應。
|
||||
|
||||
但 FastAPI 也同樣支援以相同方式使用 <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>:
|
||||
但 FastAPI 也同樣支援以相同方式使用 [`dataclasses`](https://docs.python.org/3/library/dataclasses.html):
|
||||
|
||||
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
|
||||
|
||||
這之所以可行,要感謝 **Pydantic**,因為它 <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">內建支援 `dataclasses`</a>。
|
||||
這之所以可行,要感謝 **Pydantic**,因為它 [內建支援 `dataclasses`](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel)。
|
||||
|
||||
所以,即使上面的程式碼沒有明確使用 Pydantic,FastAPI 仍會使用 Pydantic 將那些標準的 dataclass 轉換為 Pydantic 版本的 dataclass。
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ FastAPI 建立在 **Pydantic** 之上,我之前示範過如何使用 Pydantic
|
|||
|
||||
一如往常,在 FastAPI 中你可以視需要混用 `def` 與 `async def`。
|
||||
|
||||
如果需要複習何時用哪個,請參考文件中關於 [`async` 與 `await`](../async.md#in-a-hurry){.internal-link target=_blank} 的章節「In a hurry?」。
|
||||
如果需要複習何時用哪個,請參考文件中關於 [`async` 與 `await`](../async.md#in-a-hurry) 的章節「In a hurry?」。
|
||||
9. 這個「路徑操作函式」回傳的不是 dataclass(雖然也可以),而是一個包含內部資料的字典清單。
|
||||
|
||||
FastAPI 會使用 `response_model` 參數(其中包含 dataclass)來轉換回應。
|
||||
|
|
@ -80,7 +80,7 @@ FastAPI 建立在 **Pydantic** 之上,我之前示範過如何使用 Pydantic
|
|||
|
||||
你也可以將 `dataclasses` 與其他 Pydantic 模型結合、從它們繼承、把它們包含進你的自訂模型等。
|
||||
|
||||
想了解更多,請參考 <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">Pydantic 關於 dataclasses 的文件</a>。
|
||||
想了解更多,請參考 [Pydantic 關於 dataclasses 的文件](https://docs.pydantic.dev/latest/concepts/dataclasses/)。
|
||||
|
||||
## 版本 { #version }
|
||||
|
||||
|
|
|
|||
|
|
@ -150,11 +150,11 @@ async with lifespan(app):
|
|||
|
||||
給有興趣鑽研的同好一點技術細節。🤓
|
||||
|
||||
在底層的 ASGI 技術規範中,這屬於 <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Lifespan Protocol</a> 的一部分,並定義了 `startup` 與 `shutdown` 兩種事件。
|
||||
在底層的 ASGI 技術規範中,這屬於 [Lifespan Protocol](https://asgi.readthedocs.io/en/latest/specs/lifespan.html) 的一部分,並定義了 `startup` 與 `shutdown` 兩種事件。
|
||||
|
||||
/// info
|
||||
|
||||
你可以在 <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">Starlette 的 Lifespan 文件</a> 讀到更多關於 Starlette `lifespan` 處理器的資訊。
|
||||
你可以在 [Starlette 的 Lifespan 文件](https://www.starlette.dev/lifespan/) 讀到更多關於 Starlette `lifespan` 處理器的資訊。
|
||||
|
||||
也包含如何處理可在程式其他區域使用的 lifespan 狀態。
|
||||
|
||||
|
|
@ -162,4 +162,4 @@ async with lifespan(app):
|
|||
|
||||
## 子應用程式 { #sub-applications }
|
||||
|
||||
🚨 請記住,這些生命週期事件(startup 與 shutdown)只會在主應用程式上執行,不會在[子應用程式 - 掛載](sub-applications.md){.internal-link target=_blank}上執行。
|
||||
🚨 請記住,這些生命週期事件(startup 與 shutdown)只會在主應用程式上執行,不會在[子應用程式 - 掛載](sub-applications.md)上執行。
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
|
||||
## 開源 SDK 產生器 { #open-source-sdk-generators }
|
||||
|
||||
其中一個相當萬用的選擇是 <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>,它支援**多種程式語言**,並能從你的 OpenAPI 規格產生 SDK。
|
||||
其中一個相當萬用的選擇是 [OpenAPI Generator](https://openapi-generator.tech/),它支援**多種程式語言**,並能從你的 OpenAPI 規格產生 SDK。
|
||||
|
||||
針對 **TypeScript 用戶端**,<a href="https://heyapi.dev/" class="external-link" target="_blank">Hey API</a> 是專門打造的解決方案,為 TypeScript 生態系提供最佳化的體驗。
|
||||
針對 **TypeScript 用戶端**,[Hey API](https://heyapi.dev/) 是專門打造的解決方案,為 TypeScript 生態系提供最佳化的體驗。
|
||||
|
||||
你可以在 <a href="https://openapi.tools/#sdk" class="external-link" target="_blank">OpenAPI.Tools</a> 找到更多 SDK 產生器。
|
||||
你可以在 [OpenAPI.Tools](https://openapi.tools/#sdk) 找到更多 SDK 產生器。
|
||||
|
||||
/// tip
|
||||
|
||||
|
|
@ -24,15 +24,15 @@ FastAPI 會自動產生 **OpenAPI 3.1** 規格,因此你使用的任何工具
|
|||
|
||||
本節重點介紹由贊助 FastAPI 的公司提供的**創投支持**與**公司維運**的解決方案。這些產品在高品質的自動產生 SDK 之外,還提供**額外功能**與**整合**。
|
||||
|
||||
透過 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,這些公司幫助確保框架與其**生態系**維持健康且**永續**。
|
||||
透過 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author) ✨,這些公司幫助確保框架與其**生態系**維持健康且**永續**。
|
||||
|
||||
他們的贊助也展現對 FastAPI **社群**(你)的高度承諾,不僅關心提供**優良服務**,也支持 **FastAPI** 作為一個**穩健且蓬勃的框架**。🙇
|
||||
|
||||
例如,你可以嘗試:
|
||||
|
||||
* <a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a>
|
||||
* <a href="https://www.stainless.com/?utm_source=fastapi&utm_medium=referral" class="external-link" target="_blank">Stainless</a>
|
||||
* <a href="https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi" class="external-link" target="_blank">liblab</a>
|
||||
* [Speakeasy](https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship)
|
||||
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
|
||||
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
|
||||
|
||||
其中有些方案也可能是開源或提供免費方案,讓你不需財務承諾就能試用。其他商業的 SDK 產生器也不少,你可以在網路上找到。🤓
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
|
|||
|
||||
這會在 `./src/client` 產生一個 TypeScript SDK。
|
||||
|
||||
你可以在他們的網站了解如何<a href="https://heyapi.dev/openapi-ts/get-started" class="external-link" target="_blank">安裝 `@hey-api/openapi-ts`</a>,以及閱讀<a href="https://heyapi.dev/openapi-ts/output" class="external-link" target="_blank">產生的輸出內容</a>。
|
||||
你可以在他們的網站了解如何[安裝 `@hey-api/openapi-ts`](https://heyapi.dev/openapi-ts/get-started),以及閱讀[產生的輸出內容](https://heyapi.dev/openapi-ts/output)。
|
||||
|
||||
### 使用 SDK { #using-the-sdk }
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
|
|||
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
|
||||
```
|
||||
|
||||
……那是因為用戶端產生器對每個 *路徑操作* 都使用 OpenAPI 內部的**操作 ID(operation ID)**。
|
||||
...那是因為用戶端產生器對每個 *路徑操作* 都使用 OpenAPI 內部的**操作 ID(operation ID)**。
|
||||
|
||||
OpenAPI 要求每個操作 ID 在所有 *路徑操作* 之間必須唯一,因此 FastAPI 會用**函式名稱**、**路徑**與 **HTTP 方法/操作**來產生該操作 ID,如此便能確保操作 ID 的唯一性。
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
## 更多功能 { #additional-features }
|
||||
|
||||
主要的[教學 - 使用者指南](../tutorial/index.md){.internal-link target=_blank} 應足以帶你快速瀏覽 **FastAPI** 的所有核心功能。
|
||||
主要的[教學 - 使用者指南](../tutorial/index.md) 應足以帶你快速瀏覽 **FastAPI** 的所有核心功能。
|
||||
|
||||
在接下來的章節中,你會看到其他選項、設定,以及更多功能。
|
||||
|
||||
/// tip
|
||||
|
||||
接下來的章節不一定「進階」。
|
||||
接下來的章節**不一定是「進階」**。
|
||||
|
||||
而且對於你的使用情境,解法很可能就在其中某一節。
|
||||
|
||||
|
|
@ -16,6 +16,6 @@
|
|||
|
||||
## 先閱讀教學 { #read-the-tutorial-first }
|
||||
|
||||
只要掌握主要[教學 - 使用者指南](../tutorial/index.md){.internal-link target=_blank} 的內容,你就能使用 **FastAPI** 的大多數功能。
|
||||
只要掌握主要[教學 - 使用者指南](../tutorial/index.md) 的內容,你就能使用 **FastAPI** 的大多數功能。
|
||||
|
||||
接下來的章節也假設你已經讀過,並已了解那些主要觀念。
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# 進階中介軟體 { #advanced-middleware }
|
||||
|
||||
在主要教學中你已學過如何將[自訂中介軟體](../tutorial/middleware.md){.internal-link target=_blank}加入到你的應用程式。
|
||||
在主要教學中你已學過如何將[自訂中介軟體](../tutorial/middleware.md)加入到你的應用程式。
|
||||
|
||||
你也讀過如何使用 `CORSMiddleware` 處理 [CORS](../tutorial/cors.md){.internal-link target=_blank}。
|
||||
你也讀過如何處理 [使用 `CORSMiddleware` 的 CORS](../tutorial/cors.md)。
|
||||
|
||||
本節將示範如何使用其他中介軟體。
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
|
|||
|
||||
例如:
|
||||
|
||||
- <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn 的 `ProxyHeadersMiddleware`</a>
|
||||
- <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>
|
||||
- [Uvicorn 的 `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
|
||||
- [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
|
||||
|
||||
想瞭解更多可用的中介軟體,請參考 <a href="https://www.starlette.dev/middleware/" class="external-link" target="_blank">Starlette 的中介軟體文件</a> 與 <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">ASGI 精選清單</a>。
|
||||
想瞭解更多可用的中介軟體,請參考 [Starlette 的中介軟體文件](https://www.starlette.dev/middleware/) 與 [ASGI 精選清單](https://github.com/florimondmanca/awesome-asgi)。
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
/// tip
|
||||
|
||||
`callback_url` 查詢參數使用的是 Pydantic 的 <a href="https://docs.pydantic.dev/latest/api/networks/" class="external-link" target="_blank">Url</a> 型別。
|
||||
`callback_url` 查詢參數使用的是 Pydantic 的 [Url](https://docs.pydantic.dev/latest/api/networks/) 型別。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
|
|||
|
||||
實際的回呼就是一個 HTTP 請求。
|
||||
|
||||
當你自己實作回呼時,可以使用像是 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> 或 <a href="https://requests.readthedocs.io/" class="external-link" target="_blank">Requests</a>。
|
||||
當你自己實作回呼時,可以使用像是 [HTTPX](https://www.python-httpx.org) 或 [Requests](https://requests.readthedocs.io/)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -106,11 +106,11 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
|
|||
和一般「路徑操作」相比有兩個主要差異:
|
||||
|
||||
* 不需要任何實際程式碼,因為你的應用永遠不會呼叫這段程式。它只用來文件化「外部 API」。因此函式可以只有 `pass`。
|
||||
* 「路徑」可以包含一個 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 表達式</a>(見下文),可使用參數與原始送到「你的 API」的請求中的部分欄位。
|
||||
* 「路徑」可以包含一個 [OpenAPI 3 表達式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)(見下文),可使用參數與原始送到「你的 API」的請求中的部分欄位。
|
||||
|
||||
### 回呼路徑表達式 { #the-callback-path-expression }
|
||||
|
||||
回呼的「路徑」可以包含一個 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 表達式</a>,能引用原本送到「你的 API」的請求中的部分內容。
|
||||
回呼的「路徑」可以包含一個 [OpenAPI 3 表達式](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression),能引用原本送到「你的 API」的請求中的部分內容。
|
||||
|
||||
在這個例子中,它是一個 `str`:
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ https://www.external.org/events/invoices/2expen51ve
|
|||
|
||||
### 檢查文件 { #check-the-docs }
|
||||
|
||||
現在你可以啟動應用,並前往 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
|
||||
現在你可以啟動應用,並前往 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
你會在文件中看到你的「路徑操作」包含一個「Callbacks」區塊,顯示「外部 API」應該長什麼樣子:
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Webhook 功能自 OpenAPI 3.1.0 起提供,FastAPI `0.99.0` 以上版本支援
|
|||
|
||||
### 查看文件 { #check-the-docs }
|
||||
|
||||
現在你可以啟動應用,然後前往 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
|
||||
現在你可以啟動應用,然後前往 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
你會在文件中看到一般的路徑操作,另外還有一些 webhook:
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
你也可以宣告額外的回應及其模型、狀態碼等。
|
||||
|
||||
文件中有完整章節說明,請見 [OpenAPI 中的額外回應](additional-responses.md){.internal-link target=_blank}。
|
||||
文件中有完整章節說明,請見 [OpenAPI 中的額外回應](additional-responses.md)。
|
||||
|
||||
## OpenAPI 額外資訊 { #openapi-extra }
|
||||
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
/// note | 技術細節
|
||||
|
||||
在 OpenAPI 規格中,這稱為 <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation 物件</a>。
|
||||
在 OpenAPI 規格中,這稱為 [Operation 物件](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
這是一個較低階的擴充介面。
|
||||
|
||||
如果你只需要宣告額外回應,更方便的方式是使用 [OpenAPI 中的額外回應](additional-responses.md){.internal-link target=_blank}。
|
||||
如果你只需要宣告額外回應,更方便的方式是使用 [OpenAPI 中的額外回應](additional-responses.md)。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 回應 - 變更狀態碼 { #response-change-status-code }
|
||||
|
||||
你可能已經讀過,可以設定預設的[回應狀態碼](../tutorial/response-status-code.md){.internal-link target=_blank}。
|
||||
你可能已經讀過,可以設定預設的[回應狀態碼](../tutorial/response-status-code.md)。
|
||||
|
||||
但有些情況你需要回傳與預設不同的狀態碼。
|
||||
|
||||
|
|
@ -26,6 +26,6 @@
|
|||
|
||||
若你宣告了 `response_model`,它仍會被用來過濾並轉換你回傳的物件。
|
||||
|
||||
FastAPI 會使用那個「*暫時的*」回應來取得狀態碼(以及 Cookies 和標頭),並將它們放入最終回應中;最終回應包含你回傳的值,且會被任何 `response_model` 過濾。
|
||||
**FastAPI** 會使用那個「*暫時的*」回應來取得狀態碼(以及 Cookies 和標頭),並將它們放入最終回應中;最終回應包含你回傳的值,且會被任何 `response_model` 過濾。
|
||||
|
||||
你也可以在相依性(dependencies)中宣告 `Response` 參數,並在其中設定狀態碼。但請注意,最後被設定的值會生效。
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ FastAPI 會使用那個暫時的 `Response` 取出 Cookie(以及標頭與狀
|
|||
|
||||
當你在程式碼中直接回傳 `Response` 時,也可以建立 Cookie。
|
||||
|
||||
要這麼做,你可以依照 [直接回傳 Response](response-directly.md){.internal-link target=_blank} 中的說明建立一個回應。
|
||||
要這麼做,你可以依照 [直接回傳 Response](response-directly.md) 中的說明建立一個回應。
|
||||
|
||||
接著在其中設定 Cookie,然後回傳它:
|
||||
|
||||
|
|
@ -48,4 +48,4 @@ FastAPI 會使用那個暫時的 `Response` 取出 Cookie(以及標頭與狀
|
|||
|
||||
///
|
||||
|
||||
想查看所有可用的參數與選項,請參閱 <a href="https://www.starlette.dev/responses/#set-cookie" class="external-link" target="_blank">Starlette 文件</a>。
|
||||
想查看所有可用的參數與選項,請參閱 [Starlette 文件](https://www.starlette.dev/responses/#set-cookie)。
|
||||
|
|
|
|||
|
|
@ -2,19 +2,23 @@
|
|||
|
||||
當你建立一個 **FastAPI** 的路徑操作 (path operation) 時,通常可以從中回傳任何資料:`dict`、`list`、Pydantic 模型、資料庫模型等。
|
||||
|
||||
預設情況下,**FastAPI** 會使用在[JSON 相容編碼器](../tutorial/encoder.md){.internal-link target=_blank}中說明的 `jsonable_encoder`,自動將回傳值轉為 JSON。
|
||||
如果你宣告了 [回應模型](../tutorial/response-model.md),FastAPI 會用 Pydantic 將資料序列化為 JSON。
|
||||
|
||||
然後在幕後,它會把這些與 JSON 相容的資料(例如 `dict`)放進 `JSONResponse`,用來把回應傳回給用戶端。
|
||||
如果你沒有宣告回應模型,FastAPI 會使用在[JSON 相容編碼器](../tutorial/encoder.md)中說明的 `jsonable_encoder`,並把它放進 `JSONResponse`。
|
||||
|
||||
但你也可以直接從路徑操作回傳 `JSONResponse`。
|
||||
|
||||
例如,當你需要回傳自訂的 headers 或 cookies 時就很有用。
|
||||
/// tip
|
||||
|
||||
通常使用 [回應模型](../tutorial/response-model.md) 會有更好的效能,因為那樣會在 Rust 端使用 Pydantic 來序列化資料,而不是直接回傳 `JSONResponse`。
|
||||
|
||||
///
|
||||
|
||||
## 回傳 `Response` { #return-a-response }
|
||||
|
||||
其實,你可以回傳任何 `Response`,或其任何子類別。
|
||||
|
||||
/// tip
|
||||
/// info
|
||||
|
||||
`JSONResponse` 本身就是 `Response` 的子類別。
|
||||
|
||||
|
|
@ -26,6 +30,8 @@
|
|||
|
||||
這給了你很大的彈性。你可以回傳任何資料型別、覆寫任何資料宣告或驗證等。
|
||||
|
||||
同時也帶來了很大的責任。你必須確保你回傳的資料是正確的、格式正確、可被序列化等。
|
||||
|
||||
## 在 `Response` 中使用 `jsonable_encoder` { #using-the-jsonable-encoder-in-a-response }
|
||||
|
||||
因為 **FastAPI** 不會對你回傳的 `Response` 做任何更動,你需要自行確保它的內容已經準備好。
|
||||
|
|
@ -50,16 +56,28 @@
|
|||
|
||||
現在來看看如何用它來回傳自訂回應。
|
||||
|
||||
假設你想要回傳一個 <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a> 回應。
|
||||
假設你想要回傳一個 [XML](https://en.wikipedia.org/wiki/XML) 回應。
|
||||
|
||||
你可以把 XML 內容放進一個字串,把它放進 `Response`,然後回傳它:
|
||||
|
||||
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
|
||||
|
||||
## 回應模型如何運作 { #how-a-response-model-works }
|
||||
|
||||
當你在路徑操作中宣告 [回應模型 - 回傳型別](../tutorial/response-model.md) 時,**FastAPI** 會用 Pydantic 將資料序列化為 JSON。
|
||||
|
||||
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
|
||||
|
||||
由於這會在 Rust 端發生,效能會比用一般的 Python 與 `JSONResponse` 類別來完成好得多。
|
||||
|
||||
當使用 `response_model` 或回傳型別時,FastAPI 不會使用 `jsonable_encoder` 來轉換資料(那會較慢),也不會使用 `JSONResponse` 類別。
|
||||
|
||||
相反地,它會取用用回應模型(或回傳型別)透過 Pydantic 產生的 JSON 位元組,並直接回傳具備正確 JSON 媒體型別(`application/json`)的 `Response`。
|
||||
|
||||
## 注意事項 { #notes }
|
||||
|
||||
當你直接回傳 `Response` 時,其資料不會自動被驗證、轉換(序列化)或文件化。
|
||||
|
||||
但你仍然可以依照[在 OpenAPI 中的額外回應](additional-responses.md){.internal-link target=_blank}中的說明進行文件化。
|
||||
但你仍然可以依照[在 OpenAPI 中的額外回應](additional-responses.md)中的說明進行文件化。
|
||||
|
||||
在後續章節中,你會看到如何在仍保有自動資料轉換、文件化等的同時,使用/宣告這些自訂的 `Response`。
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ FastAPI 會使用那個暫時性的回應來擷取標頭(還有 Cookie 與狀
|
|||
|
||||
當你直接回傳 `Response` 時,也能加入標頭。
|
||||
|
||||
依照[直接回傳 Response](response-directly.md){.internal-link target=_blank}中的說明建立回應,並把標頭作為額外參數傳入:
|
||||
依照[直接回傳 Response](response-directly.md)中的說明建立回應,並把標頭作為額外參數傳入:
|
||||
|
||||
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
|
||||
|
||||
|
|
@ -36,6 +36,6 @@ FastAPI 會使用那個暫時性的回應來擷取標頭(還有 Cookie 與狀
|
|||
|
||||
## 自訂標頭 { #custom-headers }
|
||||
|
||||
請記住,專有的自訂標頭可以<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">使用 `X-` 前綴</a>來新增。
|
||||
請記住,專有的自訂標頭可以[使用 `X-` 前綴](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)來新增。
|
||||
|
||||
但如果你有自訂標頭並希望瀏覽器端的客戶端能看見它們,你需要把這些標頭加入到 CORS 設定中(詳見 [CORS(跨來源資源共用)](../tutorial/cors.md){.internal-link target=_blank}),使用在<a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">Starlette 的 CORS 文件</a>中記載的 `expose_headers` 參數。
|
||||
但如果你有自訂標頭並希望瀏覽器端的客戶端能看見它們,你需要把這些標頭加入到 CORS 設定中(詳見 [CORS(跨來源資源共用)](../tutorial/cors.md)),使用在[Starlette 的 CORS 文件](https://www.starlette.dev/middleware/#corsmiddleware)中記載的 `expose_headers` 參數。
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
使用一個依賴來檢查使用者名稱與密碼是否正確。
|
||||
|
||||
為此,使用 Python 標準模組 <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a> 來比對使用者名稱與密碼。
|
||||
為此,使用 Python 標準模組 [`secrets`](https://docs.python.org/3/library/secrets.html) 來比對使用者名稱與密碼。
|
||||
|
||||
`secrets.compare_digest()` 需要接收 `bytes`,或是只包含 ASCII 字元(英文字符)的 `str`。這表示它無法處理像 `á` 這樣的字元,例如 `Sebastián`。
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
## 額外功能 { #additional-features }
|
||||
|
||||
除了[教學 - 使用者指南:安全性](../../tutorial/security/index.md){.internal-link target=_blank}中涵蓋的內容外,還有一些用來處理安全性的額外功能。
|
||||
除了[教學 - 使用者指南:安全性](../../tutorial/security/index.md)中涵蓋的內容外,還有一些用來處理安全性的額外功能。
|
||||
|
||||
/// tip
|
||||
|
||||
以下各節不一定是「進階」內容。
|
||||
以下各節**不一定是「進階」**內容。
|
||||
|
||||
而且你的情境很可能可以在其中找到解決方案。
|
||||
|
||||
|
|
@ -14,6 +14,6 @@
|
|||
|
||||
## 請先閱讀教學 { #read-the-tutorial-first }
|
||||
|
||||
以下各節假設你已閱讀主要的[教學 - 使用者指南:安全性](../../tutorial/security/index.md){.internal-link target=_blank}。
|
||||
以下各節假設你已閱讀主要的[教學 - 使用者指南:安全性](../../tutorial/security/index.md)。
|
||||
|
||||
它們都建立在相同的概念之上,但提供一些額外的功能。
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ OAuth2 規格將「scopes」定義為以空白分隔的一串字串列表。
|
|||
|
||||
## 全局概觀 { #global-view }
|
||||
|
||||
先快速看看相對於主教學「使用密碼(與雜湊)、Bearer 與 JWT token 的 OAuth2」的差異([OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank})。現在加入了 OAuth2 scopes:
|
||||
先快速看看相對於主教學「使用密碼(與雜湊)、Bearer 與 JWT token 的 OAuth2」的差異([OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md))。現在加入了 OAuth2 scopes:
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
|
||||
|
||||
|
|
@ -271,4 +271,4 @@ FastAPI 在 `fastapi.security.oauth2` 中提供了所有這些 OAuth2 驗證流
|
|||
|
||||
## 在裝飾器 `dependencies` 中使用 `Security` { #security-in-decorator-dependencies }
|
||||
|
||||
就像你可以在裝飾器的 `dependencies` 參數中定義一個 `Depends` 的 `list` 一樣(詳見[路徑操作裝飾器中的相依性](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}),你也可以在那裡使用帶有 `scopes` 的 `Security`。
|
||||
就像你可以在裝飾器的 `dependencies` 參數中定義一個 `Depends` 的 `list` 一樣(詳見[路徑操作裝飾器中的相依性](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md)),你也可以在那裡使用帶有 `scopes` 的 `Security`。
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
/// tip
|
||||
|
||||
若想了解環境變數,你可以閱讀[環境變數](../environment-variables.md){.internal-link target=_blank}。
|
||||
若想了解環境變數,你可以閱讀[環境變數](../environment-variables.md)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -20,11 +20,11 @@
|
|||
|
||||
## Pydantic `Settings` { #pydantic-settings }
|
||||
|
||||
幸好,Pydantic 提供了很好的工具,可用來處理由環境變數而來的設定:<a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" class="external-link" target="_blank">Pydantic:設定管理</a>。
|
||||
幸好,Pydantic 提供了很好的工具,可用來處理由環境變數而來的設定:[Pydantic:設定管理](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)。
|
||||
|
||||
### 安裝 `pydantic-settings` { #install-pydantic-settings }
|
||||
|
||||
首先,請先建立你的[虛擬環境](../virtual-environments.md){.internal-link target=_blank},啟用它,然後安裝 `pydantic-settings` 套件:
|
||||
首先,請先建立你的[虛擬環境](../virtual-environments.md),啟用它,然後安裝 `pydantic-settings` 套件:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
|
|||
|
||||
## 在另一個模組中的設定 { #settings-in-another-module }
|
||||
|
||||
你也可以把這些設定放在另一個模組檔案中,就像在[更大的應用程式 - 多個檔案](../tutorial/bigger-applications.md){.internal-link target=_blank}所示。
|
||||
你也可以把這些設定放在另一個模組檔案中,就像在[更大的應用程式 - 多個檔案](../tutorial/bigger-applications.md)所示。
|
||||
|
||||
例如,你可以有一個 `config.py` 檔案如下:
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
|
|||
|
||||
/// tip
|
||||
|
||||
你也需要一個 `__init__.py` 檔案,詳見[更大的應用程式 - 多個檔案](../tutorial/bigger-applications.md){.internal-link target=_blank}。
|
||||
你也需要一個 `__init__.py` 檔案,詳見[更大的應用程式 - 多個檔案](../tutorial/bigger-applications.md)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
|
|||
|
||||
///
|
||||
|
||||
Pydantic 透過外部函式庫支援讀取這類型的檔案。你可以閱讀更多:<a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic Settings:Dotenv (.env) 支援</a>。
|
||||
Pydantic 透過外部函式庫支援讀取這類型的檔案。你可以閱讀更多:[Pydantic Settings:Dotenv (.env) 支援](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support)。
|
||||
|
||||
/// tip
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ APP_NAME="ChimichangApp"
|
|||
|
||||
/// tip
|
||||
|
||||
`model_config` 屬性僅用於 Pydantic 的設定。你可以閱讀更多:<a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic:概念:設定</a>。
|
||||
`model_config` 屬性僅用於 Pydantic 的設定。你可以閱讀更多:[Pydantic:概念:設定](https://docs.pydantic.dev/latest/concepts/config/)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -291,7 +291,7 @@ participant execute as Execute function
|
|||
|
||||
如此一來,它的行為幾乎就像全域變數。但因為它使用相依函式,因此我們可以在測試時輕鬆將其覆寫。
|
||||
|
||||
`@lru_cache` 是 `functools` 的一部分,而 `functools` 是 Python 標準程式庫的一部分。你可以在<a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">Python 文件中閱讀 `@lru_cache`</a> 以了解更多。
|
||||
`@lru_cache` 是 `functools` 的一部分,而 `functools` 是 Python 標準程式庫的一部分。你可以在[Python 文件中閱讀 `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache) 以了解更多。
|
||||
|
||||
## 回顧 { #recap }
|
||||
|
||||
|
|
|
|||
|
|
@ -30,25 +30,25 @@
|
|||
|
||||
### 檢查自動 API 文件 { #check-the-automatic-api-docs }
|
||||
|
||||
現在,用你的檔案執行 `fastapi` 指令:
|
||||
現在,執行 `fastapi` 指令:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
然後開啟位於 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> 的文件。
|
||||
然後開啟位於 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) 的文件。
|
||||
|
||||
你會看到主應用的自動 API 文件,只包含它自己的*路徑操作*:
|
||||
|
||||
<img src="/img/tutorial/sub-applications/image01.png">
|
||||
|
||||
接著,開啟子應用程式的文件:<a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>。
|
||||
接著,開啟子應用程式的文件:[http://127.0.0.1:8000/subapi/docs](http://127.0.0.1:8000/subapi/docs)。
|
||||
|
||||
你會看到子應用程式的自動 API 文件,只包含它自己的*路徑操作*,而且都在正確的子路徑前綴 `/subapi` 之下:
|
||||
|
||||
|
|
@ -64,4 +64,4 @@ $ fastapi dev main.py
|
|||
|
||||
而且子應用程式也能再掛載自己的子應用程式,一切都能正確運作,因為 FastAPI 會自動處理所有這些 `root_path`。
|
||||
|
||||
你可以在[在代理伺服器之後](behind-a-proxy.md){.internal-link target=_blank}一節中進一步了解 `root_path` 與如何顯式使用它。
|
||||
你可以在[在代理伺服器之後](behind-a-proxy.md)一節中進一步了解 `root_path` 與如何顯式使用它。
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
## 安裝相依套件 { #install-dependencies }
|
||||
|
||||
請先建立一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank}、啟用它,然後安裝 `jinja2`:
|
||||
請先建立一個[虛擬環境](../virtual-environments.md)、啟用它,然後安裝 `jinja2`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -123,4 +123,4 @@ Item ID: 42
|
|||
|
||||
## 更多細節 { #more-details }
|
||||
|
||||
想了解更多細節(包含如何測試模板),請參考 <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">Starlette 的模板說明文件</a>。
|
||||
想了解更多細節(包含如何測試模板),請參考 [Starlette 的模板說明文件](https://www.starlette.dev/templates/)。
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
|
||||
/// note | 注意
|
||||
|
||||
想了解更多,請參考 Starlette 的 <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">測試 WebSocket</a> 文件。
|
||||
想了解更多,請參考 Starlette 的[測試 WebSocket](https://www.starlette.dev/testclient/#testing-websocket-sessions)文件。
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
## 關於 `Request` 物件的細節 { #details-about-the-request-object }
|
||||
|
||||
由於 FastAPI 底層其實是 Starlette,再加上一層工具,因此在需要時你可以直接使用 Starlette 的 <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`</a> 物件。
|
||||
由於 FastAPI 底層其實是 Starlette,再加上一層工具,因此在需要時你可以直接使用 Starlette 的 [`Request`](https://www.starlette.dev/requests/) 物件。
|
||||
|
||||
同時也代表,如果你直接從 `Request` 物件取得資料(例如讀取 body),FastAPI 不會替它做驗證、轉換或文件化(透過 OpenAPI 為自動化的 API 介面產生文件)。
|
||||
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
## `Request` 文件 { #request-documentation }
|
||||
|
||||
你可以在 <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">Starlette 官方文件站點中的 `Request` 物件</a> 了解更多細節。
|
||||
你可以在 [Starlette 官方文件站點中的 `Request` 物件](https://www.starlette.dev/requests/) 了解更多細節。
|
||||
|
||||
/// note | 技術細節
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# WebSockets { #websockets }
|
||||
|
||||
你可以在 **FastAPI** 中使用 <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a>。
|
||||
你可以在 **FastAPI** 中使用 [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)。
|
||||
|
||||
## 安裝 `websockets` { #install-websockets }
|
||||
|
||||
請先建立[虛擬環境](../virtual-environments.md){.internal-link target=_blank}、啟用它,然後安裝 `websockets`(一個讓你更容易使用「WebSocket」通訊協定的 Python 套件):
|
||||
請先建立[虛擬環境](../virtual-environments.md)、啟用它,然後安裝 `websockets`(一個讓你更容易使用「WebSocket」通訊協定的 Python 套件):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -69,14 +69,14 @@ $ pip install websockets
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
在瀏覽器開啟 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>。
|
||||
在瀏覽器開啟 [http://127.0.0.1:8000](http://127.0.0.1:8000)。
|
||||
|
||||
你會看到一個像這樣的簡單頁面:
|
||||
|
||||
|
|
@ -115,25 +115,25 @@ $ fastapi dev main.py
|
|||
|
||||
因為這是 WebSocket,拋出 `HTTPException` 並沒有意義,因此我們改為拋出 `WebSocketException`。
|
||||
|
||||
你可以使用規範中定義的<a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">有效關閉代碼</a>之一。
|
||||
你可以使用規範中定義的[有效關閉代碼](https://tools.ietf.org/html/rfc6455#section-7.4.1)之一。
|
||||
|
||||
///
|
||||
|
||||
### 用依賴試用 WebSocket { #try-the-websockets-with-dependencies }
|
||||
|
||||
如果你的檔案名為 `main.py`,用以下指令執行應用:
|
||||
執行你的應用:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
在瀏覽器開啟 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>。
|
||||
在瀏覽器開啟 [http://127.0.0.1:8000](http://127.0.0.1:8000)。
|
||||
|
||||
在那裡你可以設定:
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ Client #1596980209979 left the chat
|
|||
|
||||
但請注意,因為所有狀態都在記憶體中的單一 list 裡管理,它只會在該程序執行期間生效,且僅適用於單一程序。
|
||||
|
||||
如果你需要一個容易與 FastAPI 整合、但更健壯,且可由 Redis、PostgreSQL 等後端支援的方案,請參考 <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a>。
|
||||
如果你需要一個容易與 FastAPI 整合、但更健壯,且可由 Redis、PostgreSQL 等後端支援的方案,請參考 [encode/broadcaster](https://github.com/encode/broadcaster)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -182,5 +182,5 @@ Client #1596980209979 left the chat
|
|||
|
||||
想了解更多選項,請參考 Starlette 的文件:
|
||||
|
||||
* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">`WebSocket` 類別</a>。
|
||||
* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">以類別為基礎的 WebSocket 處理</a>。
|
||||
* [`WebSocket` 類別](https://www.starlette.dev/websockets/)。
|
||||
* [以類別為基礎的 WebSocket 處理](https://www.starlette.dev/endpoints/#websocketendpoint)。
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 包含 WSGI:Flask、Django 等 { #including-wsgi-flask-django-others }
|
||||
|
||||
你可以像在 [子應用程式 - 掛載](sub-applications.md){.internal-link target=_blank}、[在 Proxy 後方](behind-a-proxy.md){.internal-link target=_blank} 中所見那樣掛載 WSGI 應用。
|
||||
你可以像在 [子應用程式 - 掛載](sub-applications.md)、[在 Proxy 後方](behind-a-proxy.md) 中所見那樣掛載 WSGI 應用。
|
||||
|
||||
為此,你可以使用 `WSGIMiddleware` 來包住你的 WSGI 應用,例如 Flask、Django 等。
|
||||
|
||||
|
|
@ -36,13 +36,13 @@
|
|||
|
||||
其餘則由 **FastAPI** 處理。
|
||||
|
||||
如果你啟動它並前往 <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a>,你會看到來自 Flask 的回應:
|
||||
如果你啟動它並前往 [http://localhost:8000/v1/](http://localhost:8000/v1/),你會看到來自 Flask 的回應:
|
||||
|
||||
```txt
|
||||
Hello, World from Flask!
|
||||
```
|
||||
|
||||
如果你前往 <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a>,你會看到來自 FastAPI 的回應:
|
||||
如果你前往 [http://localhost:8000/v2](http://localhost:8000/v2),你會看到來自 FastAPI 的回應:
|
||||
|
||||
```JSON
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
## 先前的工具 { #previous-tools }
|
||||
|
||||
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> { #django }
|
||||
### [Django](https://www.djangoproject.com/) { #django }
|
||||
|
||||
它是最受歡迎且廣受信任的 Python 框架。像 Instagram 等系統就是用它打造的。
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
它一開始是為在後端產生 HTML 而設計,而非為了建立提供現代前端(如 React、Vue.js、Angular)或其他系統(如 <abbr title="Internet of Things - 物聯網">IoT</abbr> 裝置)使用的 API。
|
||||
|
||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
|
||||
### [Django REST Framework](https://www.django-rest-framework.org/) { #django-rest-framework }
|
||||
|
||||
Django REST framework 的目標是成為一套在 Django 之上構建 Web API 的彈性工具組,以強化其 API 能力。
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ Django REST framework 的目標是成為一套在 Django 之上構建 Web API
|
|||
|
||||
它是「自動 API 文件」的早期典範之一,而這正是啟發我「尋找」**FastAPI** 的第一個想法。
|
||||
|
||||
/// note | 注意
|
||||
/// note
|
||||
|
||||
Django REST Framework 由 Tom Christie 創建。他同時也是 Starlette 與 Uvicorn 的作者,而 **FastAPI** 就是建立在它們之上。
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ Django REST Framework 由 Tom Christie 創建。他同時也是 Starlette 與 Uv
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> { #flask }
|
||||
### [Flask](https://flask.palletsprojects.com) { #flask }
|
||||
|
||||
Flask 是一個「微框架」,它不包含資料庫整合,也沒有像 Django 那樣內建許多功能。
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ Flask 是一個「微框架」,它不包含資料庫整合,也沒有像 Djan
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> { #requests }
|
||||
### [Requests](https://requests.readthedocs.io) { #requests }
|
||||
|
||||
**FastAPI** 其實不是 **Requests** 的替代品。兩者的範疇截然不同。
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ def read_url():
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a> { #swagger-openapi }
|
||||
### [Swagger](https://swagger.io/) / [OpenAPI](https://github.com/OAI/OpenAPI-Specification/) { #swagger-openapi }
|
||||
|
||||
我想從 Django REST Framework 得到的主要功能是自動 API 文件。
|
||||
|
||||
|
|
@ -124,8 +124,8 @@ def read_url():
|
|||
|
||||
並整合基於標準的使用者介面工具:
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>
|
||||
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui)
|
||||
* [ReDoc](https://github.com/Rebilly/ReDoc)
|
||||
|
||||
選擇這兩個是因為它們相當受歡迎且穩定,但稍加搜尋,你會發現有數十種 OpenAPI 的替代使用者介面(都能與 **FastAPI** 一起使用)。
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ def read_url():
|
|||
|
||||
有幾個 Flask 的 REST 框架,但在投入時間調查後,我發現許多已停止維護或被棄置,且存在一些關鍵問題使之不適用。
|
||||
|
||||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
|
||||
### [Marshmallow](https://marshmallow.readthedocs.io/en/stable/) { #marshmallow }
|
||||
|
||||
API 系統需要的主要功能之一是資料「<dfn title="也稱為 marshalling、轉換">序列化</dfn>」,也就是把程式中的資料(Python)轉成能透過網路傳輸的形式。例如,將含有資料庫資料的物件轉成 JSON 物件、把 `datetime` 物件轉成字串等等。
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ API 需要的另一個重要功能是資料驗證,確保資料在特定條件
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
|
||||
### [Webargs](https://webargs.readthedocs.io/en/latest/) { #webargs }
|
||||
|
||||
API 所需的另一項大功能,是從傳入請求中<dfn title="讀取並轉換為 Python 資料">解析</dfn>資料。
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ Webargs 由與 Marshmallow 相同的開發者創建。
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> { #apispec }
|
||||
### [APISpec](https://apispec.readthedocs.io/en/stable/) { #apispec }
|
||||
|
||||
Marshmallow 與 Webargs 以外掛提供驗證、解析與序列化。
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ APISpec 由與 Marshmallow 相同的開發者創建。
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a> { #flask-apispec }
|
||||
### [Flask-apispec](https://flask-apispec.readthedocs.io/en/latest/) { #flask-apispec }
|
||||
|
||||
這是一個 Flask 外掛,把 Webargs、Marshmallow 與 APISpec 串在一起。
|
||||
|
||||
|
|
@ -219,11 +219,11 @@ APISpec 由與 Marshmallow 相同的開發者創建。
|
|||
|
||||
使用它促成了數個 Flask 全端(full-stack)產生器。這些是我(以及若干外部團隊)至今主要使用的技術組合:
|
||||
|
||||
* <a href="https://github.com/tiangolo/full-stack" class="external-link" target="_blank">https://github.com/tiangolo/full-stack</a>
|
||||
* <a href="https://github.com/tiangolo/full-stack-flask-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchbase</a>
|
||||
* <a href="https://github.com/tiangolo/full-stack-flask-couchdb" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchdb</a>
|
||||
* [https://github.com/tiangolo/full-stack](https://github.com/tiangolo/full-stack)
|
||||
* [https://github.com/tiangolo/full-stack-flask-couchbase](https://github.com/tiangolo/full-stack-flask-couchbase)
|
||||
* [https://github.com/tiangolo/full-stack-flask-couchdb](https://github.com/tiangolo/full-stack-flask-couchdb)
|
||||
|
||||
而這些全端產生器,也成為了 [**FastAPI** 專案產生器](project-generation.md){.internal-link target=_blank} 的基礎。
|
||||
而這些全端產生器,也成為了 [**FastAPI** 專案產生器](project-generation.md) 的基礎。
|
||||
|
||||
/// info
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ Flask-apispec 由與 Marshmallow 相同的開發者創建。
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a>(與 <a href="https://angular.io/" class="external-link" target="_blank">Angular</a>) { #nestjs-and-angular }
|
||||
### [NestJS](https://nestjs.com/)(與 [Angular](https://angular.io/)) { #nestjs-and-angular }
|
||||
|
||||
這甚至不是 Python。NestJS 是受 Angular 啟發的 JavaScript(TypeScript)NodeJS 框架。
|
||||
|
||||
|
|
@ -259,13 +259,13 @@ Flask-apispec 由與 Marshmallow 相同的開發者創建。
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a> { #sanic }
|
||||
### [Sanic](https://sanic.readthedocs.io/en/latest/) { #sanic }
|
||||
|
||||
它是最早基於 `asyncio` 的極高速 Python 框架之一,並做得很像 Flask。
|
||||
|
||||
/// note | 技術細節
|
||||
|
||||
它使用 <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a> 取代預設的 Python `asyncio` 事件圈。這也是它如此之快的原因。
|
||||
它使用 [`uvloop`](https://github.com/MagicStack/uvloop) 取代預設的 Python `asyncio` 事件圈。這也是它如此之快的原因。
|
||||
|
||||
它明顯啟發了 Uvicorn 與 Starlette,而在公開的基準測試中,它們目前比 Sanic 更快。
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ Flask-apispec 由與 Marshmallow 相同的開發者創建。
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> { #falcon }
|
||||
### [Falcon](https://falconframework.org/) { #falcon }
|
||||
|
||||
Falcon 是另一個高效能 Python 框架,設計上極簡,並作為其他框架(如 Hug)的基礎。
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ Falcon 是另一個高效能 Python 框架,設計上極簡,並作為其他
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> { #molten }
|
||||
### [Molten](https://moltenframework.com/) { #molten }
|
||||
|
||||
我在 **FastAPI** 打造的早期發現了 Molten。它有一些相當類似的想法:
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ Falcon 是另一個高效能 Python 框架,設計上極簡,並作為其他
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a> { #hug }
|
||||
### [Hug](https://github.com/hugapi/hug) { #hug }
|
||||
|
||||
Hug 是最早使用 Python 型別提示來宣告 API 參數型別的框架之一。這是個很棒的點子,也啟發了其他工具。
|
||||
|
||||
|
|
@ -337,7 +337,7 @@ Hug 是最早使用 Python 型別提示來宣告 API 參數型別的框架之一
|
|||
|
||||
/// info
|
||||
|
||||
Hug 由 Timothy Crosley 創建,他同時也是 <a href="https://github.com/timothycrosley/isort" class="external-link" target="_blank">`isort`</a> 的作者,一個自動排序 Python 匯入的好工具。
|
||||
Hug 由 Timothy Crosley 創建,他同時也是 [`isort`](https://github.com/timothycrosley/isort) 的作者,一個自動排序 Python 匯入的好工具。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ Hug 啟發 **FastAPI** 在函式中宣告 `response` 參數以設定標頭與 Co
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5) { #apistar-0-5 }
|
||||
### [APIStar](https://github.com/encode/apistar) (<= 0.5) { #apistar-0-5 }
|
||||
|
||||
在決定打造 **FastAPI** 之前,我找到了 **APIStar** 伺服器。它幾乎具備我所尋找的一切,而且設計很出色。
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ APIStar 由 Tom Christie 創建。他也創建了:
|
|||
|
||||
## **FastAPI** 所採用的工具 { #used-by-fastapi }
|
||||
|
||||
### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> { #pydantic }
|
||||
### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
|
||||
|
||||
Pydantic 是基於 Python 型別提示,定義資料驗證、序列化與文件(使用 JSON Schema)的函式庫。
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ Pydantic 是基於 Python 型別提示,定義資料驗證、序列化與文件
|
|||
|
||||
///
|
||||
|
||||
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
|
||||
### [Starlette](https://www.starlette.dev/) { #starlette }
|
||||
|
||||
Starlette 是一個輕量的 <dfn title="用於構建非同步 Python 網頁應用的新標準">ASGI</dfn> 框架/工具集,非常適合用來建構高效能的 asyncio 服務。
|
||||
|
||||
|
|
@ -458,11 +458,11 @@ ASGI 是由 Django 核心團隊成員正在開發的新「標準」。它尚未
|
|||
|
||||
`FastAPI` 這個類別本身直接繼承自 `Starlette` 類別。
|
||||
|
||||
因此,凡是你能用 Starlette 做的事,你幾乎都能直接用 **FastAPI** 完成,因為它基本上就是加強版的 Starlette。
|
||||
因此,凡是你能用 Starlette 做的事,你都能直接用 **FastAPI** 完成,因為它基本上就是加強版的 Starlette。
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
|
||||
### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
|
||||
|
||||
Uvicorn 是基於 uvloop 與 httptools 的極速 ASGI 伺服器。
|
||||
|
||||
|
|
@ -476,10 +476,10 @@ Uvicorn 是基於 uvloop 與 httptools 的極速 ASGI 伺服器。
|
|||
|
||||
你也可以使用 `--workers` 命令列選項,取得非同步的多製程伺服器。
|
||||
|
||||
更多細節請見[部署](deployment/index.md){.internal-link target=_blank}章節。
|
||||
更多細節請見[部署](deployment/index.md)章節。
|
||||
|
||||
///
|
||||
|
||||
## 效能與速度 { #benchmarks-and-speed }
|
||||
|
||||
想了解、比較並看出 Uvicorn、Starlette 與 FastAPI 之間的差異,請參考[效能評測](benchmarks.md){.internal-link target=_blank}。
|
||||
想了解、比較並看出 Uvicorn、Starlette 與 FastAPI 之間的差異,請參考[效能評測](benchmarks.md)。
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ def results():
|
|||
|
||||
/// info
|
||||
|
||||
漂亮的插畫來自 <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
|
||||
漂亮的插畫來自 [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot)。 🎨
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ def results():
|
|||
|
||||
/// info
|
||||
|
||||
漂亮的插畫來自 <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
|
||||
漂亮的插畫來自 [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot)。 🎨
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -245,13 +245,13 @@ def results():
|
|||
|
||||
這種「等待」 🕙 通常以微秒來衡量,但累加起來,最終還是花費了很多等待時間。
|
||||
|
||||
這就是為什麼對於 Web API 來說,使用非同步程式碼 ⏸🔀⏯ 是非常有意義的。
|
||||
這就是為什麼對於 Web API 來說,使用非同步程式碼 ⏸🔀⏯ 是非常有意味的。
|
||||
|
||||
這種類型的非同步性正是 NodeJS 成功的原因(儘管 NodeJS 不是平行的),這也是 Go 語言作為程式語言的一個強大優勢。
|
||||
|
||||
這與 **FastAPI** 所能提供的性能水平相同。
|
||||
|
||||
你可以同時利用並行性和平行性,進一步提升效能,這比大多數已測試的 NodeJS 框架都更快,並且與 Go 語言相當,而 Go 是一種更接近 C 的編譯語言(<a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">感謝 Starlette</a>)。
|
||||
你可以同時利用並行性和平行性,進一步提升效能,這比大多數已測試的 NodeJS 框架都更快,並且與 Go 語言相當,而 Go 是一種更接近 C 的編譯語言([感謝 Starlette](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1))。
|
||||
|
||||
### 並行比平行更好嗎? { #is-concurrency-better-than-parallelism }
|
||||
|
||||
|
|
@ -298,7 +298,7 @@ def results():
|
|||
|
||||
這一點,再加上 Python 是 **資料科學**、機器學習,尤其是深度學習的主要語言,讓 **FastAPI** 成為資料科學/機器學習 Web API 和應用程式(以及許多其他應用程式)的絕佳選擇。
|
||||
|
||||
想了解如何在生產環境中實現這種平行性,請參見 [部屬](deployment/index.md){.internal-link target=_blank}。
|
||||
想了解如何在生產環境中實現這種平行性,請參見 [部屬](deployment/index.md)。
|
||||
|
||||
## `async` 和 `await` { #async-and-await }
|
||||
|
||||
|
|
@ -363,13 +363,13 @@ async def read_burgers():
|
|||
|
||||
### 編寫自己的非同步程式碼 { #write-your-own-async-code }
|
||||
|
||||
Starlette(和 **FastAPI**)是基於 <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> 實作的,這使得它們與 Python 標準函式庫 <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> 和 <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a> 相容。
|
||||
Starlette(和 **FastAPI**)是基於 [AnyIO](https://anyio.readthedocs.io/en/stable/) 實作的,這使得它們與 Python 標準函式庫 [asyncio](https://docs.python.org/3/library/asyncio-task.html) 和 [Trio](https://trio.readthedocs.io/en/stable/) 相容。
|
||||
|
||||
特別是,你可以直接使用 <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> 來處理更複雜的並行使用案例,這些案例需要你在自己的程式碼中使用更高階的模式。
|
||||
特別是,你可以直接使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 來處理更複雜的並行使用案例,這些案例需要你在自己的程式碼中使用更高階的模式。
|
||||
|
||||
即使你不使用 **FastAPI**,你也可以使用 <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> 來撰寫自己的非同步應用程式,並獲得高相容性及一些好處(例如「結構化並行」)。
|
||||
即使你不使用 **FastAPI**,你也可以使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 來撰寫自己的非同步應用程式,並獲得高相容性及一些好處(例如「結構化並行」)。
|
||||
|
||||
我另外在 AnyIO 之上做了一個薄封裝的函式庫,稍微改進型別註解以獲得更好的**自動補全**、**即時錯誤**等。同時它也提供友善的介紹與教學,幫助你**理解**並撰寫**自己的非同步程式碼**:<a href="https://asyncer.tiangolo.com/" class="external-link" target="_blank">Asyncer</a>。當你需要**將非同步程式碼與一般**(阻塞/同步)**程式碼整合**時,它特別實用。
|
||||
我另外在 AnyIO 之上做了一個薄封裝的函式庫,稍微改進型別註解以獲得更好的**自動補全**、**即時錯誤**等。同時它也提供友善的介紹與教學,幫助你**理解**並撰寫**自己的非同步程式碼**:[Asyncer](https://asyncer.tiangolo.com/)。當你需要**將非同步程式碼與一般**(阻塞/同步)**程式碼整合**時,它特別實用。
|
||||
|
||||
### 其他形式的非同步程式碼 { #other-forms-of-asynchronous-code }
|
||||
|
||||
|
|
@ -381,7 +381,7 @@ Starlette(和 **FastAPI**)是基於 <a href="https://anyio.readthedocs.io/en
|
|||
|
||||
但在此之前,處理非同步程式碼要更加複雜和困難。
|
||||
|
||||
在較舊的 Python 版本中,你可能會使用多執行緒或 <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a>。但這些程式碼要更難以理解、調試和思考。
|
||||
在較舊的 Python 版本中,你可能會使用多執行緒或 [Gevent](https://www.gevent.org/)。但這些程式碼要更難以理解、調試和思考。
|
||||
|
||||
在較舊的 NodeJS / 瀏覽器 JavaScript 中,你會使用「回呼」,這可能會導致“回呼地獄”。
|
||||
|
||||
|
|
@ -419,15 +419,15 @@ Starlette(和 **FastAPI**)是基於 <a href="https://anyio.readthedocs.io/en
|
|||
|
||||
如果你來自於其他不以這種方式運作的非同步框架,而且你習慣於使用普通的 `def` 定義僅進行簡單計算的*路徑操作函式*,目的是獲得微小的性能增益(大約 100 奈秒),請注意,在 FastAPI 中,效果會完全相反。在這些情況下,最好使用 `async def`,除非你的*路徑操作函式*執行阻塞的 <abbr title="Input/Output - 輸入/輸出: 磁碟讀寫或網路通訊。">I/O</abbr> 的程式碼。
|
||||
|
||||
不過,在這兩種情況下,**FastAPI** [仍然很快](index.md#performance){.internal-link target=_blank},至少與你之前的框架相當(或者更快)。
|
||||
不過,在這兩種情況下,**FastAPI** [仍然很快](index.md#performance),至少與你之前的框架相當(或者更快)。
|
||||
|
||||
### 依賴項(Dependencies) { #dependencies }
|
||||
|
||||
同樣適用於[依賴項](tutorial/dependencies/index.md){.internal-link target=_blank}。如果依賴項是一個標準的 `def` 函式,而不是 `async def`,那麼它在外部的執行緒池被運行。
|
||||
同樣適用於[依賴項](tutorial/dependencies/index.md)。如果依賴項是一個標準的 `def` 函式,而不是 `async def`,那麼它在外部的執行緒池被運行。
|
||||
|
||||
### 子依賴項 { #sub-dependencies }
|
||||
|
||||
你可以擁有多個相互依賴的依賴項和[子依賴項](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank}(作為函式定義的參數),其中一些可能是用 `async def` 宣告,也可能是用 `def` 宣告。它們仍然可以正常運作,用 `def` 定義的那些將會在外部的執行緒中呼叫(來自執行緒池),而不是被「等待」。
|
||||
你可以擁有多個相互依賴的依賴項和[子依賴項](tutorial/dependencies/sub-dependencies.md)(作為函式定義的參數),其中一些可能是用 `async def` 宣告,也可能是用 `def` 宣告。它們仍然可以正常運作,用 `def` 定義的那些將會在外部的執行緒中呼叫(來自執行緒池),而不是被「等待」。
|
||||
|
||||
### 其他輔助函式 { #other-utility-functions }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 基準測試 { #benchmarks }
|
||||
|
||||
由第三方機構 TechEmpower 的基準測試表明在 Uvicorn 下運行的 **FastAPI** 應用程式是 <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">最快的 Python 可用框架之一</a>,僅次於 Starlette 和 Uvicorn 本身(於 FastAPI 內部使用)。
|
||||
由第三方機構 TechEmpower 的基準測試表明在 Uvicorn 下運行的 **FastAPI** 應用程式是 [最快的 Python 可用框架之一](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7),僅次於 Starlette 和 Uvicorn 本身(於 FastAPI 內部使用)。
|
||||
|
||||
但是在查看基準得分和對比時,請注意以下幾點。
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## FastAPI Cloud { #fastapi-cloud }
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** 由 **FastAPI** 的同一位作者與團隊打造。
|
||||
**[FastAPI Cloud](https://fastapicloud.com)** 由 **FastAPI** 的同一位作者與團隊打造。
|
||||
|
||||
它讓你以最少的投入,簡化 **建置**、**部署** 與 **存取** API 的流程。
|
||||
|
||||
|
|
@ -16,9 +16,9 @@ FastAPI Cloud 是 *FastAPI and friends* 開源專案的主要贊助與資金提
|
|||
|
||||
## 雲端供應商 - 贊助商 { #cloud-providers-sponsors }
|
||||
|
||||
其他一些雲端供應商也會 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨。🙇
|
||||
其他一些雲端供應商也會 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author) ✨。🙇
|
||||
|
||||
你也可以參考他們的指南並試用其服務:
|
||||
|
||||
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
|
||||
* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>
|
||||
* [Render](https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi)
|
||||
* [Railway](https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
## 安全性 - HTTPS { #security-https }
|
||||
|
||||
在[前一章關於 HTTPS](https.md){.internal-link target=_blank} 中,我們學到 HTTPS 如何為你的 API 提供加密。
|
||||
在[前一章關於 HTTPS](https.md) 中,我們學到 HTTPS 如何為你的 API 提供加密。
|
||||
|
||||
我們也看到,HTTPS 通常由應用伺服器外部的元件提供,即 TLS Termination Proxy。
|
||||
|
||||
|
|
@ -190,7 +190,7 @@
|
|||
|
||||
### 工作行程與連接埠 { #worker-processes-and-ports }
|
||||
|
||||
還記得文件中[關於 HTTPS](https.md){.internal-link target=_blank} 的說明嗎:在一台伺服器上,一組 IP 與連接埠的組合只能由「一個行程」監聽?
|
||||
還記得文件中[關於 HTTPS](https.md) 的說明嗎:在一台伺服器上,一組 IP 與連接埠的組合只能由「一個行程」監聽?
|
||||
|
||||
這裡同樣適用。
|
||||
|
||||
|
|
@ -243,7 +243,7 @@
|
|||
|
||||
先別擔心這裡提到的「容器」、Docker 或 Kubernetes 如果現在還不太懂。
|
||||
|
||||
我會在未來的章節進一步說明容器映像、Docker、Kubernetes 等等:[容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank}。
|
||||
我會在未來的章節進一步說明容器映像、Docker、Kubernetes 等等:[容器中的 FastAPI - Docker](docker.md)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -281,7 +281,7 @@
|
|||
|
||||
/// tip
|
||||
|
||||
我會在未來關於容器的章節提供更具體的範例:[容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank}。
|
||||
我會在未來關於容器的章節提供更具體的範例:[容器中的 FastAPI - Docker](docker.md)。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 在容器中使用 FastAPI - Docker { #fastapi-in-containers-docker }
|
||||
|
||||
部署 FastAPI 應用時,一個常見做法是建置一個「Linux 容器映像(container image)」。通常使用 <a href="https://www.docker.com/" class="external-link" target="_blank">Docker</a> 來完成。之後你可以用多種方式部署該容器映像。
|
||||
部署 FastAPI 應用時,一個常見做法是建置一個「Linux 容器映像(container image)」。通常使用 [Docker](https://www.docker.com/) 來完成。之後你可以用多種方式部署該容器映像。
|
||||
|
||||
使用 Linux 容器有多種優點,包括安全性、可重現性、簡單性等。
|
||||
|
||||
|
|
@ -60,16 +60,16 @@ Linux 容器使用與主機(機器、虛擬機、雲端伺服器等)相同
|
|||
|
||||
Docker 是用來建立與管理容器映像與容器的主要工具之一。
|
||||
|
||||
也有一個公開的 <a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a>,內含許多工具、環境、資料庫與應用的預先製作「官方映像」。
|
||||
也有一個公開的 [Docker Hub](https://hub.docker.com/),內含許多工具、環境、資料庫與應用的預先製作「官方映像」。
|
||||
|
||||
例如,有官方的 <a href="https://hub.docker.com/_/python" class="external-link" target="_blank">Python 映像</a>。
|
||||
例如,有官方的 [Python 映像](https://hub.docker.com/_/python)。
|
||||
|
||||
也有許多其他針對不同用途的映像,例如資料庫:
|
||||
|
||||
* <a href="https://hub.docker.com/_/postgres" class="external-link" target="_blank">PostgreSQL</a>
|
||||
* <a href="https://hub.docker.com/_/mysql" class="external-link" target="_blank">MySQL</a>
|
||||
* <a href="https://hub.docker.com/_/mongo" class="external-link" target="_blank">MongoDB</a>
|
||||
* <a href="https://hub.docker.com/_/redis" class="external-link" target="_blank">Redis</a> 等。
|
||||
* [PostgreSQL](https://hub.docker.com/_/postgres)
|
||||
* [MySQL](https://hub.docker.com/_/mysql)
|
||||
* [MongoDB](https://hub.docker.com/_/mongo)
|
||||
* [Redis](https://hub.docker.com/_/redis) 等。
|
||||
|
||||
使用預製的容器映像很容易「組合」並使用不同工具。例如,嘗試一個新資料庫。多數情況下,你可以使用官方映像,並僅用環境變數加以設定。
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ Docker 是用來建立與管理容器映像與容器的主要工具之一。
|
|||
|
||||
最常見的方式是準備一個 `requirements.txt` 檔案,逐行列出套件名稱與版本。
|
||||
|
||||
當然,你會用與在 [關於 FastAPI 版本](versions.md){.internal-link target=_blank} 中讀到的相同概念,來設定版本範圍。
|
||||
當然,你會用與在 [關於 FastAPI 版本](versions.md) 中讀到的相同概念,來設定版本範圍。
|
||||
|
||||
例如,你的 `requirements.txt` 可能像這樣:
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
|||
|
||||
#### 使用 `CMD` 的 Exec 形式 { #use-cmd-exec-form }
|
||||
|
||||
Docker 的 <a href="https://docs.docker.com/reference/dockerfile/#cmd" class="external-link" target="_blank">`CMD`</a> 指令可以有兩種寫法:
|
||||
Docker 的 [`CMD`](https://docs.docker.com/reference/dockerfile/#cmd) 指令可以有兩種寫法:
|
||||
|
||||
✅ Exec 形式:
|
||||
|
||||
|
|
@ -254,11 +254,11 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
|||
CMD fastapi run app/main.py --port 80
|
||||
```
|
||||
|
||||
務必總是使用 exec 形式,以確保 FastAPI 能夠優雅地關閉,並觸發 [lifespan events](../advanced/events.md){.internal-link target=_blank}。
|
||||
務必總是使用 exec 形式,以確保 FastAPI 能夠優雅地關閉,並觸發 [lifespan events](../advanced/events.md)。
|
||||
|
||||
你可以在 <a href="https://docs.docker.com/reference/dockerfile/#shell-and-exec-form" class="external-link" target="_blank">Docker 關於 shell 與 exec 形式的文件</a>閱讀更多。
|
||||
你可以在 [Docker 關於 shell 與 exec 形式的文件](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form) 閱讀更多。
|
||||
|
||||
使用 `docker compose` 時這會特別明顯。技術細節請見這段 Docker Compose 常見問題:<a href="https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop" class="external-link" target="_blank">為什麼我的服務要花 10 秒才重新建立或停止?</a>
|
||||
使用 `docker compose` 時這會特別明顯。技術細節請見這段 Docker Compose 常見問題:[為什麼我的服務要花 10 秒才重新建立或停止?](https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop)
|
||||
|
||||
#### 目錄結構 { #directory-structure }
|
||||
|
||||
|
|
@ -352,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
|
|||
|
||||
## 檢查 { #check-it }
|
||||
|
||||
你應該可以透過 Docker 容器的網址檢查,例如:<a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> 或 <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a>(或等效的、使用你的 Docker 主機)。
|
||||
你應該可以透過 Docker 容器的網址檢查,例如:[http://192.168.99.100/items/5?q=somequery](http://192.168.99.100/items/5?q=somequery) 或 [http://127.0.0.1/items/5?q=somequery](http://127.0.0.1/items/5?q=somequery)(或等效的、使用你的 Docker 主機)。
|
||||
|
||||
你會看到類似這樣:
|
||||
|
||||
|
|
@ -362,17 +362,17 @@ $ docker run -d --name mycontainer -p 80:80 myimage
|
|||
|
||||
## 互動式 API 文件 { #interactive-api-docs }
|
||||
|
||||
現在你可以前往 <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> 或 <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a>(或等效的、使用你的 Docker 主機)。
|
||||
現在你可以前往 [http://192.168.99.100/docs](http://192.168.99.100/docs) 或 [http://127.0.0.1/docs](http://127.0.0.1/docs)(或等效的、使用你的 Docker 主機)。
|
||||
|
||||
你會看到自動產生的互動式 API 文件(由 <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> 提供):
|
||||
你會看到自動產生的互動式 API 文件(由 [Swagger UI](https://github.com/swagger-api/swagger-ui) 提供):
|
||||
|
||||

|
||||
|
||||
## 替代的 API 文件 { #alternative-api-docs }
|
||||
|
||||
你也可以前往 <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> 或 <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a>(或等效的、使用你的 Docker 主機)。
|
||||
你也可以前往 [http://192.168.99.100/redoc](http://192.168.99.100/redoc) 或 [http://127.0.0.1/redoc](http://127.0.0.1/redoc)(或等效的、使用你的 Docker 主機)。
|
||||
|
||||
你會看到另一種自動產生的文件(由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> 提供):
|
||||
你會看到另一種自動產生的文件(由 [ReDoc](https://github.com/Rebilly/ReDoc) 提供):
|
||||
|
||||

|
||||
|
||||
|
|
@ -413,7 +413,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
|
|||
|
||||
## 部署概念 { #deployment-concepts }
|
||||
|
||||
我們用容器的角度再談一次部分相同的[部署概念](concepts.md){.internal-link target=_blank}。
|
||||
我們用容器的角度再談一次部分相同的[部署概念](concepts.md)。
|
||||
|
||||
容器主要是簡化應用「建置與部署」流程的工具,但它們不強制特定的方式來處理這些「部署概念」,而是有多種策略可選。
|
||||
|
||||
|
|
@ -432,7 +432,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
|
|||
|
||||
若僅聚焦於 FastAPI 應用的「容器映像」(以及稍後的執行中「容器」),HTTPS 通常會由另一個工具在「外部」處理。
|
||||
|
||||
它可以是另一個容器,例如使用 <a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>,來處理「HTTPS」以及「自動」取得「憑證」。
|
||||
它可以是另一個容器,例如使用 [Traefik](https://traefik.io/),來處理「HTTPS」以及「自動」取得「憑證」。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
|
|
@ -454,7 +454,7 @@ Traefik 與 Docker、Kubernetes 等整合良好,因此為你的容器設定與
|
|||
|
||||
## 複本 - 行程數量 { #replication-number-of-processes }
|
||||
|
||||
如果你在有 Kubernetes、Docker Swarm Mode、Nomad,或其他類似的分散式容器管理系統的「叢集」上運作,那你大概會希望在「叢集層級」處理「複本」,而不是在每個容器內使用「行程管理器」(例如帶有 workers 的 Uvicorn)。
|
||||
如果你在有 Kubernetes、Docker Swarm Mode、Nomad,或其他類似的分散式容器管理系統的「<dfn title="一組配置為連接並共同運作的機器">叢集</dfn>」上運作,那你大概會希望在「叢集層級」處理「複本」,而不是在每個容器內使用「行程管理器」(例如帶有 workers 的 Uvicorn)。
|
||||
|
||||
像 Kubernetes 這類的分散式容器管理系統,通常內建處理「容器複本」以及支援進入請求的「負載平衡」的能力——全部都在「叢集層級」。
|
||||
|
||||
|
|
@ -558,7 +558,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
|
|||
|
||||
/// info | 資訊
|
||||
|
||||
如果你使用 Kubernetes,這大概會是一個 <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init Container</a>。
|
||||
如果你使用 Kubernetes,這大概會是一個 [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -570,7 +570,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
|
|||
|
||||
### 基底 Docker 映像 { #base-docker-image }
|
||||
|
||||
曾經有一個官方的 FastAPI Docker 映像:<a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>。但現在已被棄用。⛔️
|
||||
曾經有一個官方的 FastAPI Docker 映像:[tiangolo/uvicorn-gunicorn-fastapi](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker)。但現在已被棄用。⛔️
|
||||
|
||||
你大概「不應該」使用這個基底 Docker 映像(或其他類似的)。
|
||||
|
||||
|
|
@ -600,7 +600,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
|
|||
|
||||
## 使用 `uv` 的 Docker 映像 { #docker-image-with-uv }
|
||||
|
||||
如果你使用 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> 來安裝與管理專案,你可以參考他們的 <a href="https://docs.astral.sh/uv/guides/integration/docker/" class="external-link" target="_blank">uv Docker 指南</a>。
|
||||
如果你使用 [uv](https://github.com/astral-sh/uv) 來安裝與管理專案,你可以參考他們的 [uv Docker 指南](https://docs.astral.sh/uv/guides/integration/docker/)。
|
||||
|
||||
## 總結 { #recap }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# FastAPI Cloud { #fastapi-cloud }
|
||||
|
||||
你可以用「一行指令」把你的 FastAPI 應用程式部署到 <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>。如果你還沒加入,快去登記等候名單吧!🚀
|
||||
你可以用「一行指令」把你的 FastAPI 應用程式部署到 [FastAPI Cloud](https://fastapicloud.com)。如果你還沒加入,快去登記等候名單吧!🚀
|
||||
|
||||
## 登入 { #login }
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ Deploying to FastAPI Cloud...
|
|||
|
||||
## 關於 FastAPI Cloud { #about-fastapi-cloud }
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** 由 **FastAPI** 的作者與團隊打造。
|
||||
**[FastAPI Cloud](https://fastapicloud.com)** 由 **FastAPI** 的作者與團隊打造。
|
||||
|
||||
它以最少的心力,精簡化建立、部署與存取 API 的流程。
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
///
|
||||
|
||||
想從使用者角度學習 HTTPS 基礎,請參考 <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>。
|
||||
想從使用者角度學習 HTTPS 基礎,請參考 [https://howhttps.works/](https://howhttps.works/)。
|
||||
|
||||
接著以開發者角度,談幾個關於 HTTPS 需要注意的重點:
|
||||
|
||||
|
|
@ -28,13 +28,13 @@
|
|||
* **預設**情況下,這表示你每個 IP 位址**只能**使用**一張 HTTPS 憑證**。
|
||||
* 不論你的伺服器多強或你在上面跑的應用多小。
|
||||
* 不過,這是有**解法**的。
|
||||
* 在 **TLS** 協定(在 HTTP 之前於 TCP 層處理加密的協定)上有個**擴充**稱為 **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication - 伺服器名稱指示">SNI</abbr></a>**。
|
||||
* 在 **TLS** 協定(在 HTTP 之前於 TCP 層處理加密的協定)上有個**擴充**稱為 **[<abbr title="Server Name Indication - 伺服器名稱指示">SNI</abbr>](https://en.wikipedia.org/wiki/Server_Name_Indication)**。
|
||||
* 這個 SNI 擴充讓單一伺服器(單一 IP 位址)可以擁有**多張 HTTPS 憑證**,並服務**多個 HTTPS 網域/應用**。
|
||||
* 要讓它運作,伺服器上必須有一個**單一**的元件(程式)在**公用 IP**上監聽,且持有伺服器上的**所有 HTTPS 憑證**。
|
||||
* 在取得安全連線**之後**,通訊協定**仍然是 HTTP**。
|
||||
* 雖然透過 **HTTP 協定**傳送,但內容是**加密**的。
|
||||
|
||||
常見做法是讓伺服器(機器、主機等)上跑**一個程式/HTTP 伺服器**來**管理所有 HTTPS 相關工作**:接收**加密的 HTTPS 請求**、將其**解密**成**純 HTTP 請求**轉交給同台伺服器上實際運行的 HTTP 應用(本例為 **FastAPI** 應用)、從應用取得 **HTTP 回應**、再用合適的 **HTTPS 憑證**將其**加密**並以 **HTTPS** 傳回給用戶端。這類伺服器常被稱為 **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS 終止代理 (TLS Termination Proxy)</a>**。
|
||||
常見做法是讓伺服器(機器、主機等)上跑**一個程式/HTTP 伺服器**來**管理所有 HTTPS 相關工作**:接收**加密的 HTTPS 請求**、將其**解密**成**純 HTTP 請求**轉交給同台伺服器上實際運行的 HTTP 應用(本例為 **FastAPI** 應用)、從應用取得 **HTTP 回應**、再用合適的 **HTTPS 憑證**將其**加密**並以 **HTTPS** 傳回給用戶端。這類伺服器常被稱為 **[TLS 終止代理](https://en.wikipedia.org/wiki/TLS_termination_proxy)**。
|
||||
|
||||
可作為 TLS 終止代理的選項包括:
|
||||
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
取得這些憑證的流程過去相當繁瑣,需要許多手續,且憑證相當昂貴。
|
||||
|
||||
之後出現了 **<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>**。
|
||||
之後出現了 **[Let's Encrypt](https://letsencrypt.org/)**。
|
||||
|
||||
它是 Linux Foundation 的專案,能**免費**且自動化地提供 **HTTPS 憑證**。這些憑證採用標準的密碼學安全機制,且有效期較短(約 3 個月),因此因為壽命短,**安全性其實更好**。
|
||||
|
||||
|
|
@ -200,9 +200,9 @@ TLS 終止代理接著會依照先前協商(起點是 `someapp.example.com`
|
|||
|
||||
這些代理標頭包括:
|
||||
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
|
||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
|
||||
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
|
||||
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
|
||||
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -218,7 +218,7 @@ TLS 終止代理接著會依照先前協商(起點是 `someapp.example.com`
|
|||
|
||||
/// tip
|
||||
|
||||
你可以在文件 [在代理後方 - 啟用代理轉發標頭](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} 中了解更多。
|
||||
你可以在文件 [在代理後方 - 啟用代理轉發標頭](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers) 中了解更多。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
你可以使用一些工具自行**部署伺服器**,你也可以使用能為你完成部分工作的**雲端服務**,或其他可能的選項。
|
||||
|
||||
例如,我們(FastAPI 的團隊)打造了 <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>,讓將 FastAPI 應用程式部署到雲端變得盡可能流暢,並保持與使用 FastAPI 開發時相同的開發者體驗。
|
||||
例如,我們(FastAPI 的團隊)打造了 [**FastAPI Cloud**](https://fastapicloud.com),讓 FastAPI 應用程式部署到雲端變得盡可能流暢,並保持與使用 FastAPI 開發時相同的開發者體驗。
|
||||
|
||||
我將向你展示在部署 **FastAPI** 應用程式時你可能應該記住的一些主要概念(儘管其中大部分適用於任何其他類型的 Web 應用程式)。
|
||||
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ FastAPI 採用建立 Python 網頁框架與伺服器的標準 <abbr title="Async
|
|||
|
||||
有數個替代方案,包括:
|
||||
|
||||
* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>:高效能 ASGI 伺服器。
|
||||
* <a href="https://hypercorn.readthedocs.io/" class="external-link" target="_blank">Hypercorn</a>:支援 HTTP/2 與 Trio 等功能的 ASGI 伺服器。
|
||||
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>:為 Django Channels 打造的 ASGI 伺服器。
|
||||
* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>:針對 Python 應用的 Rust HTTP 伺服器。
|
||||
* <a href="https://unit.nginx.org/howto/fastapi/" class="external-link" target="_blank">NGINX Unit</a>:NGINX Unit 是輕量且多功能的網頁應用執行環境。
|
||||
* [Uvicorn](https://www.uvicorn.dev/):高效能 ASGI 伺服器。
|
||||
* [Hypercorn](https://hypercorn.readthedocs.io/):支援 HTTP/2 與 Trio 等功能的 ASGI 伺服器。
|
||||
* [Daphne](https://github.com/django/daphne):為 Django Channels 打造的 ASGI 伺服器。
|
||||
* [Granian](https://github.com/emmett-framework/granian):針對 Python 應用的 Rust HTTP 伺服器。
|
||||
* [NGINX Unit](https://unit.nginx.org/howto/fastapi/):NGINX Unit 是輕量且多功能的網頁應用執行環境。
|
||||
|
||||
## 伺服器機器與伺服器程式 { #server-machine-and-server-program }
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ FastAPI 採用建立 Python 網頁框架與伺服器的標準 <abbr title="Async
|
|||
|
||||
但你也可以手動安裝 ASGI 伺服器。
|
||||
|
||||
請先建立並啟用一個 [虛擬環境](../virtual-environments.md){.internal-link target=_blank},接著再安裝伺服器程式。
|
||||
請先建立並啟用一個 [虛擬環境](../virtual-environments.md),接著再安裝伺服器程式。
|
||||
|
||||
例如,安裝 Uvicorn:
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@
|
|||
|
||||
在部署應用時,你通常會希望有一些處理序的複製來善用多核心,並能處理更多請求。
|
||||
|
||||
如同前一章關於 [部署概念](concepts.md){.internal-link target=_blank} 所示,你可以採用多種策略。
|
||||
如同前一章關於 [部署概念](concepts.md) 所示,你可以採用多種策略。
|
||||
|
||||
這裡會示範如何使用 `fastapi` 指令或直接使用 `uvicorn` 指令,搭配 Uvicorn 的工作處理序(worker processes)。
|
||||
|
||||
/// info
|
||||
|
||||
如果你使用容器(例如 Docker 或 Kubernetes),我會在下一章說明更多:[容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank}。
|
||||
如果你使用容器(例如 Docker 或 Kubernetes),我會在下一章說明更多:[容器中的 FastAPI - Docker](docker.md)。
|
||||
|
||||
特別是,在 **Kubernetes** 上執行時,你多半會選擇不要使用 workers,而是每個容器只跑一個 **Uvicorn 單一處理序**。我會在該章節中進一步說明。
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
|||
|
||||
## 容器與 Docker { #containers-and-docker }
|
||||
|
||||
在下一章 [容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank} 我會說明一些策略,幫你處理其他的**部署概念**。
|
||||
在下一章 [容器中的 FastAPI - Docker](docker.md) 我會說明一些策略,幫你處理其他的**部署概念**。
|
||||
|
||||
我會示範如何**從零建立你的映像檔**來執行單一 Uvicorn 處理序。這個流程相當簡單,而且在使用像 **Kubernetes** 這類分散式容器管理系統時,大多情況也會這麼做。
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
經常加入新功能、定期修復錯誤,程式碼也在持續改進。
|
||||
|
||||
這就是為什麼目前版本仍為 `0.x.x`,這表示每個版本都可能包含破壞性變更。這遵循 <a href="https://semver.org/" class="external-link" target="_blank">語意化版本(Semantic Versioning)</a> 的慣例。
|
||||
這就是為什麼目前版本仍為 `0.x.x`,這表示每個版本都可能包含破壞性變更。這遵循 [語意化版本(Semantic Versioning)](https://semver.org/) 的慣例。
|
||||
|
||||
你現在就可以用 **FastAPI** 建置生產環境的應用(而且你可能已經這麼做一段時間了),只要確保你使用的版本能與其餘程式碼正確相容。
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ fastapi[standard]>=0.112.0,<0.113.0
|
|||
|
||||
## 可用版本 { #available-versions }
|
||||
|
||||
你可以在 [發行說明](../release-notes.md){.internal-link target=_blank} 查看可用版本(例如用來確認目前最新版本)。
|
||||
你可以在 [發行說明](../release-notes.md) 查看可用版本(例如用來確認目前最新版本)。
|
||||
|
||||
## 關於版本 { #about-versions }
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ fastapi>=0.45.0,<0.46.0
|
|||
|
||||
你應該為你的應用撰寫測試。
|
||||
|
||||
在 **FastAPI** 中這很容易(感謝 Starlette),請參考文件:[測試](../tutorial/testing.md){.internal-link target=_blank}
|
||||
在 **FastAPI** 中這很容易(感謝 Starlette),請參考文件:[測試](../tutorial/testing.md)
|
||||
|
||||
有了測試之後,你就可以將 **FastAPI** 升級到較新的版本,並透過執行測試來確保所有程式碼都能正確運作。
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ print(f"Hello {name} from Python")
|
|||
|
||||
/// tip
|
||||
|
||||
第二個參數是 <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> 的預設回傳值。
|
||||
第二個參數是 [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) 的預設回傳值。
|
||||
|
||||
如果沒有提供,預設值為 `None`,這裡我們提供 `"World"` 作為預設值。
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ Hello World from Python
|
|||
|
||||
/// tip
|
||||
|
||||
你可以在 <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: 配置</a>中了解更多資訊。
|
||||
你可以在 [The Twelve-Factor App: 配置](https://12factor.net/config) 中了解更多資訊。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ Hello World from Python
|
|||
|
||||
這意味著從環境變數中讀取的**任何值**在 Python 中都將是一個 `str`,任何型別轉換或驗證都必須在程式碼中完成。
|
||||
|
||||
你將在[進階使用者指南 - 設定和環境變數](./advanced/settings.md){.internal-link target=_blank}中了解更多關於使用環境變數處理**應用程式設定**的資訊。
|
||||
你將在[進階使用者指南 - 設定和環境變數](./advanced/settings.md)中了解更多關於使用環境變數處理**應用程式設定**的資訊。
|
||||
|
||||
## `PATH` 環境變數 { #path-environment-variable }
|
||||
|
||||
|
|
@ -285,13 +285,13 @@ $ C:\opt\custompython\bin\python
|
|||
|
||||
////
|
||||
|
||||
當學習[虛擬環境](virtual-environments.md){.internal-link target=_blank}時,這些資訊將會很有用。
|
||||
當學習[虛擬環境](virtual-environments.md)時,這些資訊將會很有用。
|
||||
|
||||
## 結論 { #conclusion }
|
||||
|
||||
透過這個教學,你應該對**環境變數**是什麼以及如何在 Python 中使用它們有了基本的了解。
|
||||
|
||||
你也可以在 <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">環境變數的維基百科條目</a> 中閱讀更多。
|
||||
你也可以在 [環境變數的維基百科條目](https://en.wikipedia.org/wiki/Environment_variable) 中閱讀更多。
|
||||
|
||||
在許多情況下,環境變數的用途和適用性可能不會立刻顯現。但是在開發過程中,它們會在許多不同的場景中出現,因此瞭解它們是非常必要的。
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# FastAPI CLI { #fastapi-cli }
|
||||
|
||||
**FastAPI CLI** 是一個命令列程式,能用來運行你的 FastAPI 應用程式、管理你的 FastAPI 專案等。
|
||||
**FastAPI <abbr title="command line interface - 命令列介面">CLI</abbr>** 是一個命令列程式,你可以用它來啟動你的 FastAPI 應用程式、管理你的 FastAPI 專案,等等。
|
||||
|
||||
當你安裝 FastAPI(例如使用 `pip install "fastapi[standard]"`),它會包含一個叫做 `fastapi-cli` 的套件,這個套件提供了 `fastapi` 命令。
|
||||
當你安裝 FastAPI(例如使用 `pip install "fastapi[standard]"`)時,會附帶一個可以在終端機執行的命令列程式。
|
||||
|
||||
要運行你的 FastAPI 應用程式來進行開發,你可以使用 `fastapi dev` 命令:
|
||||
要在開發時運行你的 FastAPI 應用程式,你可以使用 `fastapi dev` 指令:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
|
||||
$ <font color="#4E9A06">fastapi</font> dev
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
|
|
@ -46,13 +46,66 @@ $ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid
|
|||
|
||||
</div>
|
||||
|
||||
名為 `fastapi` 的命令列程式就是 **FastAPI CLI**。
|
||||
/// tip
|
||||
|
||||
FastAPI CLI 接收你的 Python 程式路徑(例如 `main.py`),並自動檢測 `FastAPI` 實例(通常命名為 `app`),確定正確的引入模組流程,然後運行該應用程式。
|
||||
在生產環境請改用 `fastapi run`,不要用 `fastapi dev`。🚀
|
||||
|
||||
在生產環境,你應該使用 `fastapi run` 命令。 🚀
|
||||
///
|
||||
|
||||
**FastAPI CLI** 內部使用了 <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>,這是一個高效能、適合生產環境的 ASGI 伺服器。 😎
|
||||
在內部,**FastAPI CLI** 使用 [Uvicorn](https://www.uvicorn.dev),這是一個高效能、適用於生產環境的 ASGI 伺服器。😎
|
||||
|
||||
`fastapi` CLI 會嘗試自動偵測要執行的 FastAPI 應用程式,預設假設它是檔案 `main.py` 中名為 `app` 的物件(或其他幾種變體)。
|
||||
|
||||
不過你也可以明確設定要使用的 app。
|
||||
|
||||
## 在 `pyproject.toml` 中設定應用程式的 `entrypoint` { #configure-the-app-entrypoint-in-pyproject-toml }
|
||||
|
||||
你可以在 `pyproject.toml` 檔案中指定你的 app 位置,例如:
|
||||
|
||||
```toml
|
||||
[tool.fastapi]
|
||||
entrypoint = "main:app"
|
||||
```
|
||||
|
||||
這個 `entrypoint` 會告訴 `fastapi` 指令應該像這樣匯入 app:
|
||||
|
||||
```python
|
||||
from main import app
|
||||
```
|
||||
|
||||
如果你的程式碼結構是這樣:
|
||||
|
||||
```
|
||||
.
|
||||
├── backend
|
||||
│ ├── main.py
|
||||
│ ├── __init__.py
|
||||
```
|
||||
|
||||
那麼你應該把 `entrypoint` 設為:
|
||||
|
||||
```toml
|
||||
[tool.fastapi]
|
||||
entrypoint = "backend.main:app"
|
||||
```
|
||||
|
||||
這等同於:
|
||||
|
||||
```python
|
||||
from backend.main import app
|
||||
```
|
||||
|
||||
### 帶路徑的 `fastapi dev` { #fastapi-dev-with-path }
|
||||
|
||||
你也可以把檔案路徑傳給 `fastapi dev` 指令,它會推測要使用的 FastAPI app 物件:
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
```
|
||||
|
||||
但這樣每次呼叫 `fastapi` 指令時都得記得傳入正確的路徑。
|
||||
|
||||
此外,其他工具可能找不到它,例如 [VS Code 擴充套件](editor-support.md) 或 [FastAPI Cloud](https://fastapicloud.com),因此建議在 `pyproject.toml` 中使用 `entrypoint`。
|
||||
|
||||
## `fastapi dev` { #fastapi-dev }
|
||||
|
||||
|
|
@ -70,6 +123,6 @@ FastAPI CLI 接收你的 Python 程式路徑(例如 `main.py`),並自動
|
|||
|
||||
/// tip
|
||||
|
||||
你可以在[部署文件](deployment/index.md){.internal-link target=_blank}中了解更多相關資訊。
|
||||
你可以在[部署文件](deployment/index.md)中了解更多相關資訊。
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
### 建立在開放標準的基礎上 { #based-on-open-standards }
|
||||
|
||||
* 使用 <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> 來建立 API,包含 <dfn title="也稱為:端點、路由">路徑</dfn>、<dfn title="也稱為 HTTP 方法,例如 POST、GET、PUT、DELETE">操作</dfn>、參數、請求內文、安全性等宣告。
|
||||
* 使用 <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a>(因為 OpenAPI 本身就是基於 JSON Schema)自動生成資料模型文件。
|
||||
* 使用 [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) 來建立 API,包含 <dfn title="也稱為:端點、路由">路徑</dfn>、<dfn title="也稱為 HTTP 方法,例如 POST、GET、PUT、DELETE">操作</dfn>、參數、請求內文、安全性等宣告。
|
||||
* 使用 [**JSON Schema**](https://json-schema.org/)(因為 OpenAPI 本身就是基於 JSON Schema)自動生成資料模型文件。
|
||||
* 經過縝密的研究後圍繞這些標準進行設計,而不是事後在已有系統上附加的一層功能。
|
||||
* 這也讓我們在多種語言中可以使用自動**用戶端程式碼生成**。
|
||||
|
||||
|
|
@ -15,11 +15,11 @@
|
|||
|
||||
FastAPI 能生成互動式 API 文件和探索性的 Web 使用者介面。由於該框架基於 OpenAPI,因此有多種選擇,預設提供了兩種。
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a> 提供互動式探索,讓你可以直接從瀏覽器呼叫並測試你的 API 。
|
||||
* [**Swagger UI**](https://github.com/swagger-api/swagger-ui) 提供互動式探索,讓你可以直接從瀏覽器呼叫並測試你的 API 。
|
||||
|
||||

|
||||
|
||||
* 使用 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a> 的替代 API 文件。
|
||||
* 使用 [**ReDoc**](https://github.com/Rebilly/ReDoc) 的替代 API 文件。
|
||||
|
||||

|
||||
|
||||
|
|
@ -27,7 +27,7 @@ FastAPI 能生成互動式 API 文件和探索性的 Web 使用者介面。由
|
|||
|
||||
這一切都基於標準的 **Python 型別**宣告(感謝 Pydantic)。無需學習新的語法,只需使用標準的現代 Python。
|
||||
|
||||
如果你需要 2 分鐘來學習如何使用 Python 型別(即使你不使用 FastAPI),可以看看這個簡短的教學:[Python 型別](python-types.md){.internal-link target=_blank}。
|
||||
如果你需要 2 分鐘來學習如何使用 Python 型別(即使你不使用 FastAPI),可以看看這個簡短的教學:[Python 型別](python-types.md)。
|
||||
|
||||
如果你寫帶有 Python 型別的程式碼:
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ my_second_user: User = User(**second_user_data)
|
|||
|
||||
整個框架的設計是為了讓使用變得簡單且直觀,在開始開發之前,所有決策都在多個編輯器上進行了測試,以確保提供最佳的開發體驗。
|
||||
|
||||
在最近的 Python 開發者調查中,我們能看到<a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank"> 被使用最多的功能是 autocompletion</a>。
|
||||
在最近的 Python 開發者調查中,我們能看到[被使用最多的功能是 autocompletion](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features)。
|
||||
|
||||
整個 **FastAPI** 框架就是基於這一點,任何地方都可以進行自動補齊。
|
||||
|
||||
|
|
@ -83,11 +83,11 @@ my_second_user: User = User(**second_user_data)
|
|||
|
||||
在這裡,你的編輯器可能會這樣幫助你:
|
||||
|
||||
* 在 <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a> 中:
|
||||
* 在 [Visual Studio Code](https://code.visualstudio.com/) 中:
|
||||
|
||||

|
||||
|
||||
* 在 <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> 中:
|
||||
* 在 [PyCharm](https://www.jetbrains.com/pycharm/) 中:
|
||||
|
||||

|
||||
|
||||
|
|
@ -124,13 +124,13 @@ FastAPI 已經整合了安全性和身份驗證的功能,但不會強制與特
|
|||
OpenAPI 中定義的安全模式,包括:
|
||||
|
||||
* HTTP 基本認證。
|
||||
* **OAuth2**(也使用 **JWT tokens**)。在 [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank} 查看教學。
|
||||
* **OAuth2**(也使用 **JWT tokens**)。在 [OAuth2 with JWT](tutorial/security/oauth2-jwt.md) 查看教學。
|
||||
* API 密鑰,在:
|
||||
* 標頭(Header)
|
||||
* 查詢參數
|
||||
* Cookies,等等。
|
||||
|
||||
加上来自 Starlette(包括 **session cookie**)的所有安全特性。
|
||||
加上來自 Starlette(包括 **session cookie**)的所有安全特性。
|
||||
|
||||
所有的這些都是可重複使用的工具和套件,可以輕鬆與你的系統、資料儲存(Data Stores)、關聯式資料庫(RDBMS)以及非關聯式資料庫(NoSQL)等等整合。
|
||||
|
||||
|
|
@ -159,11 +159,11 @@ FastAPI 有一個使用簡單,但是非常強大的 <dfn title='也稱為「co
|
|||
|
||||
## Starlette 特性 { #starlette-features }
|
||||
|
||||
**FastAPI** 完全相容且基於 <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a>。所以,你有其他的 Starlette 程式碼也能正常運作。`FastAPI` 實際上是 `Starlette` 的一個子類別。所以,如果你已經知道或者使用過 Starlette,大部分的功能會以相同的方式運作。
|
||||
**FastAPI** 完全相容且基於 [**Starlette**](https://www.starlette.dev/)。所以,你有其他的 Starlette 程式碼也能正常運作。`FastAPI` 實際上是 `Starlette` 的一個子類別。所以,如果你已經知道或者使用過 Starlette,大部分的功能會以相同的方式運作。
|
||||
|
||||
通過 **FastAPI** 你可以獲得所有 **Starlette** 的特性(FastAPI 就像加強版的 Starlette):
|
||||
|
||||
* 性能極其出色。它是 <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">Python 可用的最快框架之一,和 **NodeJS** 及 **Go** 相當</a>。
|
||||
* 性能極其出色。它是 [Python 可用的最快框架之一,和 **NodeJS** 及 **Go** 相當](https://github.com/encode/starlette#performance)。
|
||||
* **支援 WebSocket**。
|
||||
* 能在行程內處理背景任務。
|
||||
* 支援啟動和關閉事件。
|
||||
|
|
@ -175,7 +175,7 @@ FastAPI 有一個使用簡單,但是非常強大的 <dfn title='也稱為「co
|
|||
|
||||
## Pydantic 特性 { #pydantic-features }
|
||||
|
||||
**FastAPI** 完全相容且基於 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>。所以,你有其他 Pydantic 程式碼也能正常工作。
|
||||
**FastAPI** 完全相容且基於 [**Pydantic**](https://docs.pydantic.dev/)。所以,你有其他 Pydantic 程式碼也能正常工作。
|
||||
|
||||
相容包括基於 Pydantic 的外部函式庫,例如用於資料庫的 <abbr title="Object-Relational Mapper - 物件關聯對映器">ORM</abbr>s、<abbr title="Object-Document Mapper - 物件文件對映器">ODM</abbr>s。
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
## 訂閱電子報 { #subscribe-to-the-newsletter }
|
||||
|
||||
你可以訂閱(不常發送的)[**FastAPI 與夥伴**電子報](newsletter.md){.internal-link target=_blank},隨時掌握:
|
||||
你可以訂閱(不常發送的)[**FastAPI 與夥伴**電子報](newsletter.md),隨時掌握:
|
||||
|
||||
* 關於 FastAPI 與夥伴的最新消息 🚀
|
||||
* 教學指南 📝
|
||||
|
|
@ -22,17 +22,17 @@
|
|||
|
||||
## 在 X(Twitter)關注 FastAPI { #follow-fastapi-on-x-twitter }
|
||||
|
||||
<a href="https://x.com/fastapi" class="external-link" target="_blank">在 **X(Twitter)** 關注 @fastapi</a>,獲取 **FastAPI** 的最新消息。🐦
|
||||
[在 **X(Twitter)** 關注 @fastapi](https://x.com/fastapi),獲取 **FastAPI** 的最新消息。🐦
|
||||
|
||||
## 在 GitHub 為 **FastAPI** 加星 { #star-fastapi-in-github }
|
||||
|
||||
你可以在 GitHub 為 FastAPI「加星」(點擊右上角的 star 星號按鈕):<a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。⭐️
|
||||
你可以在 GitHub 為 FastAPI「加星」(點擊右上角的 star 星號按鈕):[https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)。⭐️
|
||||
|
||||
加上星標後,其他使用者會更容易發現它,並看到它已經對許多人很有幫助。
|
||||
|
||||
## 追蹤 GitHub 儲存庫的發行版 { #watch-the-github-repository-for-releases }
|
||||
|
||||
你可以在 GitHub「watch」FastAPI(點擊右上角的「watch」按鈕):<a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。👀
|
||||
你可以在 GitHub「watch」FastAPI(點擊右上角的「watch」按鈕):[https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)。👀
|
||||
|
||||
在那裡你可以選擇「Releases only」。
|
||||
|
||||
|
|
@ -40,45 +40,45 @@
|
|||
|
||||
## 與作者連結 { #connect-with-the-author }
|
||||
|
||||
你可以與作者 <a href="https://tiangolo.com" class="external-link" target="_blank">我(Sebastián Ramírez / `tiangolo`)</a> 建立連結。
|
||||
你可以與作者 [我(Sebastián Ramírez / `tiangolo`)](https://tiangolo.com) 建立連結。
|
||||
|
||||
你可以:
|
||||
|
||||
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">在 **GitHub** 關注我</a>。
|
||||
* [在 **GitHub** 關注我](https://github.com/tiangolo)。
|
||||
* 看看我建立的其他開源專案,可能對你有幫助。
|
||||
* 關注我以便知道我何時建立新的開源專案。
|
||||
* <a href="https://x.com/tiangolo" class="external-link" target="_blank">在 **X(Twitter)**</a> 或 <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a> 關注我。
|
||||
* [在 **X(Twitter)**](https://x.com/tiangolo) 或 [Mastodon](https://fosstodon.org/@tiangolo) 關注我。
|
||||
* 告訴我你如何使用 FastAPI(我很愛聽這些)。
|
||||
* 接收我發布公告或釋出新工具時的消息。
|
||||
* 你也可以<a href="https://x.com/fastapi" class="external-link" target="_blank">在 X(Twitter)關注 @fastapi</a>(另外的帳號)。
|
||||
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">在 **LinkedIn** 關注我</a>。
|
||||
* 你也可以[在 X(Twitter)關注 @fastapi](https://x.com/fastapi)(另外的帳號)。
|
||||
* [在 **LinkedIn** 關注我](https://www.linkedin.com/in/tiangolo/)。
|
||||
* 接收我發布公告或釋出新工具時的消息(不過我更常用 X(Twitter)🤷♂)。
|
||||
* 在 <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> 或 <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a> 閱讀我寫的內容(或關注我)。
|
||||
* 在 [**Dev.to**](https://dev.to/tiangolo) 或 [**Medium**](https://medium.com/@tiangolo) 閱讀我寫的內容(或關注我)。
|
||||
* 閱讀我的想法、文章,以及我建立的工具。
|
||||
* 關注我以便在我發佈新內容時能第一時間看到。
|
||||
|
||||
## 在 X(Twitter)發文談談 **FastAPI** { #tweet-about-fastapi }
|
||||
|
||||
<a href="https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">發一則關於 **FastAPI** 的推文</a>,讓我與其他人知道你為什麼喜歡它。🎉
|
||||
[發一則關於 **FastAPI** 的推文](https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi),讓我與其他人知道你為什麼喜歡它。🎉
|
||||
|
||||
我很樂於聽到 **FastAPI** 是如何被使用、你喜歡它的哪些地方、在哪個專案/公司使用它等等。
|
||||
|
||||
## 為 FastAPI 投票 { #vote-for-fastapi }
|
||||
|
||||
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">在 Slant 為 **FastAPI** 投票</a>。
|
||||
* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">在 AlternativeTo 為 **FastAPI** 投票</a>。
|
||||
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">在 StackShare 表示你使用 **FastAPI**</a>。
|
||||
* [在 Slant 為 **FastAPI** 投票](https://www.slant.co/options/34241/~fastapi-review)。
|
||||
* [在 AlternativeTo 為 **FastAPI** 投票](https://alternativeto.net/software/fastapi/about/)。
|
||||
* [在 StackShare 表示你使用 **FastAPI**](https://stackshare.io/pypi-fastapi)。
|
||||
|
||||
## 在 GitHub 幫助他人解答問題 { #help-others-with-questions-in-github }
|
||||
|
||||
你可以嘗試幫助他人回答以下地方的問題:
|
||||
|
||||
* <a href="https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
|
||||
* <a href="https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
|
||||
* [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered)
|
||||
* [GitHub Issues](https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+)
|
||||
|
||||
很多時候你可能已經知道這些問題的解答。🤓
|
||||
|
||||
如果你經常幫大家解決問題,你會成為官方的 [FastAPI 專家](fastapi-people.md#fastapi-experts){.internal-link target=_blank}。🎉
|
||||
如果你經常幫大家解決問題,你會成為官方的 [FastAPI 專家](fastapi-people.md#fastapi-experts)。🎉
|
||||
|
||||
請記得,最重要的是:盡量友善。大家可能帶著挫折而來,很多時候提問方式不夠理想,但請盡你所能保持友善。🤗
|
||||
|
||||
|
|
@ -104,7 +104,7 @@
|
|||
|
||||
很多時候他們只會貼出一小段程式碼,但那不足以**重現問題**。
|
||||
|
||||
* 你可以請他們提供一個<a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">最小可重現範例</a>,讓你可以**複製貼上**並在本機執行,看到與他們相同的錯誤或行為,或更好地理解他們的使用情境。
|
||||
* 你可以請他們提供一個[最小可重現範例](https://stackoverflow.com/help/minimal-reproducible-example),讓你可以**複製貼上**並在本機執行,看到與他們相同的錯誤或行為,或更好地理解他們的使用情境。
|
||||
|
||||
* 如果你有心力,你也可以嘗試自己**建立一個範例**,僅依據問題描述來還原。不過請記得這可能很耗時,或許更好的是先請他們把問題說清楚。
|
||||
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
|
||||
## 追蹤 GitHub 儲存庫 { #watch-the-github-repository }
|
||||
|
||||
你可以在 GitHub「watch」FastAPI(點擊右上角的「watch」按鈕):<a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。👀
|
||||
你可以在 GitHub「watch」FastAPI(點擊右上角的「watch」按鈕):[https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)。👀
|
||||
|
||||
如果你選擇「Watching」而不是「Releases only」,當有人建立新的 issue 或問題時你會收到通知。你也可以指定只想被通知新的 issues、discussions、PR 等等。
|
||||
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
|
||||
## 提問 { #ask-questions }
|
||||
|
||||
你可以在 GitHub 儲存庫<a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">建立一個新的問題(Question)</a>,例如用來:
|
||||
你可以在 GitHub 儲存庫[建立一個新的問題(Question)](https://github.com/fastapi/fastapi/discussions/new?category=questions),例如用來:
|
||||
|
||||
* 提出**問題**或詢問某個**疑難**。
|
||||
* 建議一個新的**功能**。
|
||||
|
|
@ -195,12 +195,12 @@
|
|||
|
||||
## 建立 Pull Request { #create-a-pull-request }
|
||||
|
||||
你可以透過 Pull Request 來[貢獻](contributing.md){.internal-link target=_blank}原始碼,例如:
|
||||
你可以透過 Pull Request 來[貢獻](contributing.md)原始碼,例如:
|
||||
|
||||
* 修正文檔中你發現的錯字。
|
||||
* 分享你建立或發現的 FastAPI 相關文章、影片或 podcast,方法是<a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">編輯這個檔案</a>。
|
||||
* 分享你建立或發現的 FastAPI 相關文章、影片或 podcast,方法是[編輯這個檔案](https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml)。
|
||||
* 請確保把你的連結加到對應章節的開頭。
|
||||
* 協助把[文件翻譯](contributing.md#translations){.internal-link target=_blank}成你的語言。
|
||||
* 協助把[文件翻譯](contributing.md#translations)成你的語言。
|
||||
* 你也可以幫忙審查他人提交的翻譯。
|
||||
* 提議新的文件章節。
|
||||
* 修復既有的 issue/bug。
|
||||
|
|
@ -217,8 +217,8 @@
|
|||
|
||||
你現在就能做的主要任務有:
|
||||
|
||||
* [在 GitHub 幫助他人解答問題](#help-others-with-questions-in-github){.internal-link target=_blank}(見上方章節)。
|
||||
* [審核 Pull Request](#review-pull-requests){.internal-link target=_blank}(見上方章節)。
|
||||
* [在 GitHub 幫助他人解答問題](#help-others-with-questions-in-github)(見上方章節)。
|
||||
* [審核 Pull Request](#review-pull-requests)(見上方章節)。
|
||||
|
||||
這兩件事是**最耗時**的。這也是維護 FastAPI 的主要工作。
|
||||
|
||||
|
|
@ -226,11 +226,11 @@
|
|||
|
||||
## 加入聊天室 { #join-the-chat }
|
||||
|
||||
加入 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord 聊天伺服器</a> 👥,與 FastAPI 社群的其他人一起交流。
|
||||
加入 👥 [Discord 聊天伺服器](https://discord.gg/VQjSZaeJmf) 👥,與 FastAPI 社群的其他人一起交流。
|
||||
|
||||
/// tip
|
||||
|
||||
若要提問,請到 <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a>,在那裡更有機會獲得[FastAPI 專家](fastapi-people.md#fastapi-experts){.internal-link target=_blank}的協助。
|
||||
若要提問,請到 [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/new?category=questions),在那裡更有機會獲得[FastAPI 專家](fastapi-people.md#fastapi-experts)的協助。
|
||||
|
||||
聊天室請僅用於其他一般性的交流。
|
||||
|
||||
|
|
@ -242,13 +242,13 @@
|
|||
|
||||
在 GitHub 上,模板會引導你寫出合適的提問,讓你更容易得到好的解答,甚至在提問前就自己解決問題。而且在 GitHub 上,我能確保最終都會回覆(即使需要一些時間)。我個人無法在聊天系統做到這一點。😅
|
||||
|
||||
聊天系統中的對話也不像 GitHub 那樣容易被搜尋,因此問題與答案可能在對話中淹沒。而且只有 GitHub 上的問題與回答才會被計入成為[FastAPI 專家](fastapi-people.md#fastapi-experts){.internal-link target=_blank},因此你在 GitHub 上更有機會獲得關注。
|
||||
聊天系統中的對話也不像 GitHub 那樣容易被搜尋,因此問題與答案可能在對話中淹沒。而且只有 GitHub 上的問題與回答才會被計入成為[FastAPI 專家](fastapi-people.md#fastapi-experts),因此你在 GitHub 上更有機會獲得關注。
|
||||
|
||||
另一方面,聊天室裡有成千上萬的使用者,所以幾乎隨時都有很大的機會能找到人聊天。😄
|
||||
|
||||
## 贊助作者 { #sponsor-the-author }
|
||||
|
||||
如果你的**產品/公司**依賴或與 **FastAPI** 相關,且你想觸及它的使用者,你可以透過 <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a> 贊助作者(我)。依據不同級別,你可能會得到一些額外福利,例如在文件中顯示徽章。🎁
|
||||
如果你的**產品/公司**依賴或與 **FastAPI** 相關,且你想觸及它的使用者,你可以透過 [GitHub sponsors](https://github.com/sponsors/tiangolo) 贊助作者(我)。依據不同級別,你可能會得到一些額外福利,例如在文件中顯示徽章。🎁
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 歷史、設計與未來 { #history-design-and-future }
|
||||
|
||||
不久之前,<a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">一位 **FastAPI** 使用者提問</a>:
|
||||
不久之前,[一位 **FastAPI** 使用者提問](https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920):
|
||||
|
||||
> 這個專案的歷史是什麼?看起來它在短短幾週內從默默無名變得非常厲害 [...]
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
**FastAPI** 的歷史,在很大程度上也是其前身工具的歷史。
|
||||
|
||||
如在[替代方案](alternatives.md){.internal-link target=_blank}章節所述:
|
||||
如在[替代方案](alternatives.md)一節所述:
|
||||
|
||||
<blockquote markdown="1">
|
||||
|
||||
|
|
@ -44,9 +44,9 @@
|
|||
|
||||
我在最受歡迎的 Python 編輯器中測試了多個想法:PyCharm、VS Code、基於 Jedi 的編輯器。
|
||||
|
||||
根據最新的 <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">Python 開發者調查</a>,這些工具涵蓋約 80% 的使用者。
|
||||
根據最新的 [Python 開發者調查](https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools),這些工具涵蓋約 80% 的使用者。
|
||||
|
||||
這表示 **FastAPI** 已針對 80% 的 Python 開發者所使用的編輯器進行過專門測試。而由於其他多數編輯器的行為也類似,這些優點幾乎在所有編輯器上都能生效。
|
||||
這表示 **FastAPI** 已針對 80% 的 Python 開發者所使用的編輯器進行過專門測試。而由於其他多數編輯器的行為也類似,這些優點擴及實際上幾乎所有編輯器。
|
||||
|
||||
藉此我找到了盡可能減少程式碼重複、在各處提供自動補全、型別與錯誤檢查等的最佳方式。
|
||||
|
||||
|
|
@ -54,11 +54,11 @@
|
|||
|
||||
## 需求 { #requirements }
|
||||
|
||||
在測試多種替代方案後,我決定採用 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">**Pydantic**</a>,因為它的優勢。
|
||||
在測試多種替代方案後,我決定採用 [**Pydantic**](https://docs.pydantic.dev/),因為它的優勢。
|
||||
|
||||
隨後我也對它做出貢獻,使其完全符合 JSON Schema、支援以不同方式定義約束,並依據在多款編輯器中的測試結果改進編輯器支援(型別檢查、自動補全)。
|
||||
|
||||
在開發過程中,我也對 <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>(另一個關鍵依賴)做出貢獻。
|
||||
在開發過程中,我也對 [**Starlette**](https://www.starlette.dev/)(另一個關鍵依賴)做出貢獻。
|
||||
|
||||
## 開發 { #development }
|
||||
|
||||
|
|
@ -76,4 +76,4 @@
|
|||
|
||||
**FastAPI** 的前景非常光明。
|
||||
|
||||
也非常感謝[你的幫助](help-fastapi.md){.internal-link target=_blank}。
|
||||
也非常感謝[你的幫助](help-fastapi.md)。
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
在 FastAPI 版本 `0.122.0` 之前,當內建的安全工具在身分驗證失敗後回傳錯誤給用戶端時,會使用 HTTP 狀態碼 `403 Forbidden`。
|
||||
|
||||
從 FastAPI 版本 `0.122.0` 起,改為使用更合適的 HTTP 狀態碼 `401 Unauthorized`,並在回應中依據 HTTP 規範加上合理的 `WWW-Authenticate` 標頭,參考 <a href="https://datatracker.ietf.org/doc/html/rfc7235#section-3.1" class="external-link" target="_blank">RFC 7235</a>、<a href="https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized" class="external-link" target="_blank">RFC 9110</a>。
|
||||
從 FastAPI 版本 `0.122.0` 起,改為使用更合適的 HTTP 狀態碼 `401 Unauthorized`,並在回應中依據 HTTP 規範加上合理的 `WWW-Authenticate` 標頭,參考 [RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-3.1)、[RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized)。
|
||||
|
||||
但如果你的用戶端因某些原因依賴於舊行為,你可以在你的 security 類別中覆寫 `make_not_authenticated_error` 方法以恢復舊的行為。
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
若你的程式碼有安全性缺陷,它依然會存在。
|
||||
|
||||
隱藏文件只會讓他人更難理解如何與你的 API 互動,也可能讓你在正式環境除錯更困難。這通常僅被視為一種 <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">以隱匿求安全</a>。
|
||||
隱藏文件只會讓他人更難理解如何與你的 API 互動,也可能讓你在正式環境除錯更困難。這通常僅被視為一種 [以隱匿求安全](https://en.wikipedia.org/wiki/Security_through_obscurity)。
|
||||
|
||||
如果你想保護 API,有許多更好的作法,例如:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
# 設定 Swagger UI { #configure-swagger-ui }
|
||||
|
||||
你可以設定一些額外的 <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/" class="external-link" target="_blank">Swagger UI 參數</a>。
|
||||
你可以設定一些額外的 [Swagger UI 參數](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/)。
|
||||
|
||||
要設定它們,建立 `FastAPI()` 應用物件時,或呼叫 `get_swagger_ui_html()` 函式時,傳入參數 `swagger_ui_parameters`。
|
||||
|
||||
`swagger_ui_parameters` 接受一個 dict,內容會直接傳給 Swagger UI 作為設定。
|
||||
|
||||
FastAPI 會把這些設定轉換成 JSON,以便與 JavaScript 相容,因為 Swagger UI 需要的是這種格式。
|
||||
FastAPI 會把這些設定轉換成 **JSON**,以便與 JavaScript 相容,因為 Swagger UI 需要的是這種格式。
|
||||
|
||||
## 停用語法醒目提示 { #disable-syntax-highlighting }
|
||||
|
||||
|
|
@ -50,11 +50,11 @@ FastAPI 內建一些預設參數,適用於大多數情境。
|
|||
|
||||
## 其他 Swagger UI 參數 { #other-swagger-ui-parameters }
|
||||
|
||||
若要查看所有可用的設定,請參考官方的 <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/" class="external-link" target="_blank">Swagger UI 參數文件</a>。
|
||||
若要查看所有可用的設定,請參考官方的 [Swagger UI 參數文件](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/)。
|
||||
|
||||
## 僅限 JavaScript 的設定 { #javascript-only-settings }
|
||||
|
||||
Swagger UI 也允許某些設定是僅限 JavaScript 的物件(例如 JavaScript 函式)。
|
||||
Swagger UI 也允許某些設定是**僅限 JavaScript** 的物件(例如 JavaScript 函式)。
|
||||
|
||||
FastAPI 也包含以下僅限 JavaScript 的 `presets` 設定:
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ Swagger UI 會在背後幫你處理,不過它需要這個「redirect」輔助
|
|||
|
||||
### 測試 { #test-it }
|
||||
|
||||
現在你應該能造訪 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>,重新載入頁面後,資源會從新的 CDN 載入。
|
||||
現在你應該能造訪 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs),重新載入頁面後,資源會從新的 CDN 載入。
|
||||
|
||||
## 自行託管文件所需的 JavaScript 與 CSS { #self-hosting-javascript-and-css-for-docs }
|
||||
|
||||
|
|
@ -93,12 +93,12 @@ Swagger UI 會在背後幫你處理,不過它需要這個「redirect」輔助
|
|||
|
||||
Swagger UI 需要以下檔案:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
|
||||
* [`swagger-ui-bundle.js`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js)
|
||||
* [`swagger-ui.css`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css)
|
||||
|
||||
而 ReDoc 需要以下檔案:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a>
|
||||
* [`redoc.standalone.js`](https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js)
|
||||
|
||||
之後,你的檔案結構可能如下:
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ Swagger UI 需要以下檔案:
|
|||
|
||||
### 測試靜態檔案 { #test-the-static-files }
|
||||
|
||||
啟動你的應用並前往 <a href="http://127.0.0.1:8000/static/redoc.standalone.js" class="external-link" target="_blank">http://127.0.0.1:8000/static/redoc.standalone.js</a>。
|
||||
啟動你的應用並前往 [http://127.0.0.1:8000/static/redoc.standalone.js](http://127.0.0.1:8000/static/redoc.standalone.js)。
|
||||
|
||||
你應該會看到一個很長的 **ReDoc** JavaScript 檔案。
|
||||
|
||||
|
|
@ -180,6 +180,6 @@ Swagger UI 會在背後幫你處理,不過它需要這個「redirect」輔助
|
|||
|
||||
### 測試使用靜態檔案的 UI { #test-static-files-ui }
|
||||
|
||||
現在,你應該可以關閉 WiFi,造訪你的文件 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>,並重新載入頁面。
|
||||
現在,你應該可以關閉 WiFi,造訪你的文件 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs),並重新載入頁面。
|
||||
|
||||
即使沒有網際網路,也能看到你的 API 文件並與之互動。
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
可能的使用情境包括:
|
||||
|
||||
* 將非 JSON 的請求本文轉換為 JSON(例如 <a href="https://msgpack.org/index.html" class="external-link" target="_blank">`msgpack`</a>)。
|
||||
* 將非 JSON 的請求本文轉換為 JSON(例如 [`msgpack`](https://msgpack.org/index.html))。
|
||||
* 解壓縮以 gzip 壓縮的請求本文。
|
||||
* 自動記錄所有請求本文。
|
||||
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
/// tip
|
||||
|
||||
這是一個示範用的簡化範例;如果你需要 Gzip 支援,可以直接使用提供的 [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank}。
|
||||
這是一個示範用的簡化範例;如果你需要 Gzip 支援,可以直接使用提供的 [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
如果標頭中沒有 `gzip`,它就不會嘗試解壓縮本文。
|
||||
|
||||
如此一來,相同的路由類別即可同時處理經 gzip 壓縮與未壓縮的請求.
|
||||
如此一來,相同的路由類別即可同時處理經 gzip 壓縮與未壓縮的請求。
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
|
||||
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
|
||||
而 `scope` 與 `receive` 這兩者,就是建立一個新的 `Request` 實例所需的資料。
|
||||
|
||||
想了解更多 `Request`,請參考 <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">Starlette 的 Request 文件</a>。
|
||||
想了解更多 `Request`,請參考 [Starlette 的 Request 文件](https://www.starlette.dev/requests/)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
/// tip
|
||||
|
||||
要解決相同問題,使用針對 `RequestValidationError` 的自訂處理器來讀取 `body` 通常更簡單([處理錯誤](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank})。
|
||||
要解決相同問題,使用針對 `RequestValidationError` 的自訂處理器來讀取 `body` 通常更簡單([處理錯誤](../tutorial/handling-errors.md#use-the-requestvalidationerror-body))。
|
||||
|
||||
但本範例仍然有效,並示範了如何與內部元件互動。
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
基於上述資訊,你可以用相同的工具函式來產生 OpenAPI 結構,並覆寫你需要客製的部分。
|
||||
|
||||
例如,我們要加入 <a href="https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo" class="external-link" target="_blank">ReDoc 的 OpenAPI 擴充,插入自訂 logo</a>。
|
||||
例如,我們要加入 [ReDoc 的 OpenAPI 擴充,插入自訂 logo](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo)。
|
||||
|
||||
### 一般的 **FastAPI** { #normal-fastapi }
|
||||
|
||||
|
|
@ -75,6 +75,6 @@
|
|||
|
||||
### 檢查看看 { #check-it }
|
||||
|
||||
造訪 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> 後,你會看到自訂的 logo(此例為 **FastAPI** 的 logo):
|
||||
造訪 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) 後,你會看到自訂的 logo(此例為 **FastAPI** 的 logo):
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image01.png">
|
||||
|
|
|
|||
|
|
@ -4,36 +4,40 @@
|
|||
|
||||
## 篩選資料 - 安全性 { #filter-data-security }
|
||||
|
||||
為確保你不會回傳超出應有的資料,請參閱[教學 - 回應模型 - 回傳型別](../tutorial/response-model.md){.internal-link target=_blank}。
|
||||
為確保你不會回傳超出應有的資料,請參閱[教學 - 回應模型 - 回傳型別](../tutorial/response-model.md)。
|
||||
|
||||
## 最佳化回應效能 - 回應模型 - 回傳型別 { #optimize-response-performance-response-model-return-type }
|
||||
|
||||
為了在回傳 JSON 資料時最佳化效能,請使用回傳型別或回應模型,如此 Pydantic 會在 Rust 端處理序列化為 JSON,而不經過 Python。更多內容請參閱[教學 - 回應模型 - 回傳型別](../tutorial/response-model.md)。
|
||||
|
||||
## 文件標籤 - OpenAPI { #documentation-tags-openapi }
|
||||
|
||||
要在你的*路徑操作(path operation)*加入標籤,並在文件 UI 中分組,請參閱[教學 - 路徑操作設定 - 標籤](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}。
|
||||
要在你的*路徑操作(path operation)*加入標籤,並在文件 UI 中分組,請參閱[教學 - 路徑操作設定 - 標籤](../tutorial/path-operation-configuration.md#tags)。
|
||||
|
||||
## 文件摘要與描述 - OpenAPI { #documentation-summary-and-description-openapi }
|
||||
|
||||
要為你的*路徑操作*加入摘要與描述,並在文件 UI 中顯示,請參閱[教學 - 路徑操作設定 - 摘要與描述](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}。
|
||||
要為你的*路徑操作*加入摘要與描述,並在文件 UI 中顯示,請參閱[教學 - 路徑操作設定 - 摘要與描述](../tutorial/path-operation-configuration.md#summary-and-description)。
|
||||
|
||||
## 文件回應描述 - OpenAPI { #documentation-response-description-openapi }
|
||||
|
||||
要定義在文件 UI 中顯示的回應描述,請參閱[教學 - 路徑操作設定 - 回應描述](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}。
|
||||
要定義在文件 UI 中顯示的回應描述,請參閱[教學 - 路徑操作設定 - 回應描述](../tutorial/path-operation-configuration.md#response-description)。
|
||||
|
||||
## 文件將*路徑操作*標記為已棄用 - OpenAPI { #documentation-deprecate-a-path-operation-openapi }
|
||||
|
||||
要將*路徑操作*標記為已棄用,並在文件 UI 中顯示,請參閱[教學 - 路徑操作設定 - 棄用](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}。
|
||||
要將*路徑操作*標記為已棄用,並在文件 UI 中顯示,請參閱[教學 - 路徑操作設定 - 棄用](../tutorial/path-operation-configuration.md#deprecate-a-path-operation)。
|
||||
|
||||
## 將任意資料轉換為 JSON 相容格式 { #convert-any-data-to-json-compatible }
|
||||
|
||||
要將任意資料轉換為 JSON 相容格式,請參閱[教學 - JSON 相容編碼器](../tutorial/encoder.md){.internal-link target=_blank}。
|
||||
要將任意資料轉換為 JSON 相容格式,請參閱[教學 - JSON 相容編碼器](../tutorial/encoder.md)。
|
||||
|
||||
## OpenAPI 中繼資料 - 文件 { #openapi-metadata-docs }
|
||||
|
||||
要在你的 OpenAPI 綱要中加入中繼資料(包含授權、版本、聯絡方式等),請參閱[教學 - 中繼資料與文件 URL](../tutorial/metadata.md){.internal-link target=_blank}。
|
||||
要在你的 OpenAPI 綱要中加入中繼資料(包含授權、版本、聯絡方式等),請參閱[教學 - 中繼資料與文件 URL](../tutorial/metadata.md)。
|
||||
|
||||
## 自訂 OpenAPI URL { #openapi-custom-url }
|
||||
|
||||
要自訂(或移除)OpenAPI 的 URL,請參閱[教學 - 中繼資料與文件 URL](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}。
|
||||
要自訂(或移除)OpenAPI 的 URL,請參閱[教學 - 中繼資料與文件 URL](../tutorial/metadata.md#openapi-url)。
|
||||
|
||||
## OpenAPI 文件 URL { #openapi-docs-urls }
|
||||
|
||||
要更新自動產生的文件使用者介面所使用的 URL,請參閱[教學 - 中繼資料與文件 URL](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}。
|
||||
要更新自動產生的文件使用者介面所使用的 URL,請參閱[教學 - 中繼資料與文件 URL](../tutorial/metadata.md#docs-urls)。
|
||||
|
|
|
|||
|
|
@ -18,18 +18,18 @@ GraphQL 解決某些非常特定的使用情境。
|
|||
|
||||
下面是支援 ASGI 的部分 GraphQL 函式庫,你可以與 FastAPI 一起使用:
|
||||
|
||||
* <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a> 🍓
|
||||
* 提供 <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">FastAPI 文件</a>
|
||||
* <a href="https://ariadnegraphql.org/" class="external-link" target="_blank">Ariadne</a>
|
||||
* 提供 <a href="https://ariadnegraphql.org/docs/fastapi-integration" class="external-link" target="_blank">FastAPI 文件</a>
|
||||
* <a href="https://tartiflette.io/" class="external-link" target="_blank">Tartiflette</a>
|
||||
* 使用 <a href="https://tartiflette.github.io/tartiflette-asgi/" class="external-link" target="_blank">Tartiflette ASGI</a> 提供 ASGI 整合
|
||||
* <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>
|
||||
* 搭配 <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>
|
||||
* [Strawberry](https://strawberry.rocks/) 🍓
|
||||
* 提供 [FastAPI 文件](https://strawberry.rocks/docs/integrations/fastapi)
|
||||
* [Ariadne](https://ariadnegraphql.org/)
|
||||
* 提供 [FastAPI 文件](https://ariadnegraphql.org/docs/fastapi-integration)
|
||||
* [Tartiflette](https://tartiflette.io/)
|
||||
* 使用 [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) 提供 ASGI 整合
|
||||
* [Graphene](https://graphene-python.org/)
|
||||
* 搭配 [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3)
|
||||
|
||||
## 使用 Strawberry 的 GraphQL { #graphql-with-strawberry }
|
||||
|
||||
如果你需要或想使用 GraphQL,<a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a> 是推薦的函式庫,因為它的設計與 FastAPI 最接近,全部都基於型別註解 (type annotations)。
|
||||
如果你需要或想使用 GraphQL,[Strawberry](https://strawberry.rocks/) 是推薦的函式庫,因為它的設計與 FastAPI 最接近,全部都基於型別註解 (type annotations)。
|
||||
|
||||
視你的使用情境而定,你可能會偏好其他函式庫,但如果你問我,我大概會建議你先試試 Strawberry。
|
||||
|
||||
|
|
@ -37,24 +37,24 @@ GraphQL 解決某些非常特定的使用情境。
|
|||
|
||||
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
|
||||
|
||||
你可以在 <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry 文件</a> 中進一步了解 Strawberry。
|
||||
你可以在 [Strawberry 文件](https://strawberry.rocks/) 中進一步了解 Strawberry。
|
||||
|
||||
也可以參考關於 <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">Strawberry 與 FastAPI</a> 的文件。
|
||||
也可以參考關於 [Strawberry 與 FastAPI](https://strawberry.rocks/docs/integrations/fastapi) 的文件。
|
||||
|
||||
## 來自 Starlette 的較舊 `GraphQLApp` { #older-graphqlapp-from-starlette }
|
||||
|
||||
早期版本的 Starlette 提供 `GraphQLApp` 類別以整合 <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>。
|
||||
早期版本的 Starlette 提供 `GraphQLApp` 類別以整合 [Graphene](https://graphene-python.org/)。
|
||||
|
||||
它已在 Starlette 中被棄用,但如果你的程式碼使用了它,可以輕鬆遷移到 <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>,涵蓋相同的使用情境,且介面幾乎相同。
|
||||
它已在 Starlette 中被棄用,但如果你的程式碼使用了它,可以輕鬆遷移到 [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3),涵蓋相同的使用情境,且介面幾乎相同。
|
||||
|
||||
/// tip
|
||||
|
||||
如果你需要 GraphQL,我仍建議你看看 <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a>,因為它基於型別註解,而不是自訂的類別與型別。
|
||||
如果你需要 GraphQL,我仍建議你看看 [Strawberry](https://strawberry.rocks/),因為它基於型別註解,而不是自訂的類別與型別。
|
||||
|
||||
///
|
||||
|
||||
## 進一步了解 { #learn-more }
|
||||
|
||||
你可以在 <a href="https://graphql.org/" class="external-link" target="_blank">官方 GraphQL 文件</a> 中進一步了解 GraphQL。
|
||||
你可以在 [官方 GraphQL 文件](https://graphql.org/) 中進一步了解 GraphQL。
|
||||
|
||||
你也可以透過上述連結閱讀各個函式庫的更多內容。
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
|
||||
/// tip
|
||||
|
||||
如果你想要以結構化的方式**學習 FastAPI**(推薦),請前往[教學 - 使用者指南](../tutorial/index.md){.internal-link target=_blank}逐章閱讀。
|
||||
如果你想要以結構化的方式**學習 FastAPI**(推薦),請前往[教學 - 使用者指南](../tutorial/index.md)逐章閱讀。
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Pydantic 團隊自 **Python 3.14** 起,已停止在最新的 Python 版本中
|
|||
|
||||
## 官方指南 { #official-guide }
|
||||
|
||||
Pydantic 提供從 v1 遷移到 v2 的官方<a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">遷移指南</a>。
|
||||
Pydantic 提供從 v1 遷移到 v2 的官方[遷移指南](https://docs.pydantic.dev/latest/migration/)。
|
||||
|
||||
其中包含變更內容、驗證如何更正確且更嚴格、可能的注意事項等。
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ Pydantic 提供從 v1 遷移到 v2 的官方<a href="https://docs.pydantic.dev/l
|
|||
|
||||
## 測試 { #tests }
|
||||
|
||||
確保你的應用有[測試](../tutorial/testing.md){.internal-link target=_blank},並在 CI(持續整合)上執行。
|
||||
確保你的應用有[測試](../tutorial/testing.md),並在 CI(持續整合)上執行。
|
||||
|
||||
如此一來,你可以升級後確認一切仍如預期運作。
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ Pydantic 提供從 v1 遷移到 v2 的官方<a href="https://docs.pydantic.dev/l
|
|||
|
||||
在許多情況下,若你使用的是未自訂的標準 Pydantic 模型,多數遷移步驟都能自動化完成。
|
||||
|
||||
你可以使用 Pydantic 團隊提供的 <a href="https://github.com/pydantic/bump-pydantic" class="external-link" target="_blank">`bump-pydantic`</a>。
|
||||
你可以使用 Pydantic 團隊提供的 [`bump-pydantic`](https://github.com/pydantic/bump-pydantic)。
|
||||
|
||||
這個工具會自動修改大部分需要變更的程式碼。
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# 測試資料庫 { #testing-a-database }
|
||||
|
||||
你可以在 <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel 文件</a> 中學習關於資料庫、SQL 與 SQLModel。 🤓
|
||||
你可以在 [SQLModel 文件](https://sqlmodel.tiangolo.com/) 中學習關於資料庫、SQL 與 SQLModel。 🤓
|
||||
|
||||
有一個迷你 <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">將 SQLModel 與 FastAPI 搭配使用的教學</a>。 ✨
|
||||
有一個迷你 [將 SQLModel 與 FastAPI 搭配使用的教學](https://sqlmodel.tiangolo.com/tutorial/fastapi/)。 ✨
|
||||
|
||||
該教學包含一節介紹 <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/" class="external-link" target="_blank">測試 SQL 資料庫</a>。 😎
|
||||
該教學包含一節介紹 [測試 SQL 資料庫](https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/)。 😎
|
||||
|
|
|
|||
|
|
@ -11,25 +11,25 @@
|
|||
<em>FastAPI 框架,高效能,易於學習,快速開發,適用於生產環境</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster">
|
||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<a href="https://pypi.org/project/fastapi">
|
||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<a href="https://pypi.org/project/fastapi">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**文件**: <a href="https://fastapi.tiangolo.com/zh-hant" target="_blank">https://fastapi.tiangolo.com/zh-hant</a>
|
||||
**文件**: [https://fastapi.tiangolo.com/zh-hant](https://fastapi.tiangolo.com/zh-hant)
|
||||
|
||||
**程式碼**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
|
||||
**程式碼**: [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ FastAPI 是一個現代、快速(高效能)的 Web 框架,用於以 Python
|
|||
* **簡單**:設計上易於使用與學習。更少的讀文件時間。
|
||||
* **簡潔**:最小化程式碼重複性。每個參數宣告可帶來多個功能。更少的錯誤。
|
||||
* **穩健**:立即獲得可投入生產的程式碼,並自動生成互動式文件。
|
||||
* **標準化**:基於(且完全相容於)API 的開放標準:<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>(之前稱為 Swagger)和 <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>。
|
||||
* **標準化**:基於(且完全相容於)API 的開放標準:[OpenAPI](https://github.com/OAI/OpenAPI-Specification)(之前稱為 Swagger)和 [JSON Schema](https://json-schema.org/)。
|
||||
|
||||
<small>* 基於內部開發團隊在建立生產應用程式時的測試預估。</small>
|
||||
|
||||
|
|
@ -55,51 +55,51 @@ FastAPI 是一個現代、快速(高效能)的 Web 框架,用於以 Python
|
|||
### 基石贊助商 { #keystone-sponsor }
|
||||
|
||||
{% for sponsor in sponsors.keystone -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}
|
||||
|
||||
### 金級與銀級贊助商 { #gold-and-silver-sponsors }
|
||||
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}
|
||||
{%- for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/zh-hant/fastapi-people/#sponsors" class="external-link" target="_blank">其他贊助商</a>
|
||||
[其他贊助商](https://fastapi.tiangolo.com/zh-hant/fastapi-people/#sponsors)
|
||||
|
||||
## 評價 { #opinions }
|
||||
|
||||
"_[...] 近期大量使用 **FastAPI**。[...] 我實際上打算在我在**微軟**團隊的所有**機器學習**服務上使用它。其中一些正在整合到核心的 **Windows** 產品,以及一些 **Office** 產品。_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_我們採用了 **FastAPI** 函式庫來啟動一個 **REST** 伺服器,供查詢以取得**預測**。[for Ludwig]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**Netflix** 很高興宣布我們的**危機管理**協調框架 **Dispatch** 開源![使用 **FastAPI** 建構]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_我對 **FastAPI** 興奮得不得了。超好玩!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast 主持人</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>[Python Bytes](https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855) podcast 主持人</strong> <a href="https://x.com/brianokken/status/1112220079972728832"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_老實說,你們做的看起來非常穩健又精緻。很多方面都正是我希望 **Hug** 成為的樣子——看到有人把它建出來真的很鼓舞人心。_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> 創作者</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>[Hug](https://github.com/hugapi/hug) 創作者</strong> <a href="https://news.ycombinator.com/item?id=19455465"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -107,27 +107,27 @@ FastAPI 是一個現代、快速(高效能)的 Web 框架,用於以 Python
|
|||
|
||||
"_我們的 **API** 已經改用 **FastAPI** [...] 我想你會喜歡它 [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> 創辦人 - <a href="https://spacy.io" target="_blank">spaCy</a> 創作者</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>[Explosion AI](https://explosion.ai) 創辦人 - [spaCy](https://spacy.io) 創作者</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_如果有人想要建立一個可投入生產的 Python API,我強烈推薦 **FastAPI**。它**設計精美**、**使用簡單**且**高度可擴充**,已成為我們 API 優先開發策略中的**關鍵組件**,推動了許多自動化與服務,例如我們的 Virtual TAC Engineer。_"
|
||||
"_如果有人想要打造一個可用於生產環境的 Python API,我強力推薦 **FastAPI**。它**設計優雅**、**簡單易用**且**高度可擴展**,已經成為我們 API first 開發策略中的**關鍵元件**,推動了許多自動化與服務,例如我們的 Virtual TAC Engineer。_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
## FastAPI 迷你紀錄片 { #fastapi-mini-documentary }
|
||||
|
||||
在 2025 年底發布了一支 <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI 迷你紀錄片</a>,你可以在線上觀看:
|
||||
在 2025 年底發布了一支 [FastAPI 迷你紀錄片](https://www.youtube.com/watch?v=mpR8ngthqiE),你可以在線上觀看:
|
||||
|
||||
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
|
||||
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
|
||||
|
||||
## **Typer**,命令列的 FastAPI { #typer-the-fastapi-of-clis }
|
||||
|
||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
||||
<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
||||
|
||||
如果你不是在做 Web API,而是要建立一個在終端機中使用的 <abbr title="Command Line Interface - 命令列介面">CLI</abbr> 應用程式,可以看看 <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>。
|
||||
如果你不是在做 Web API,而是要建立一個在終端機中使用的 <abbr title="Command Line Interface - 命令列介面">CLI</abbr> 應用程式,可以看看 [**Typer**](https://typer.tiangolo.com/)。
|
||||
|
||||
**Typer** 是 FastAPI 的小老弟。他立志成為命令列世界的 **FastAPI**。⌨️ 🚀
|
||||
|
||||
|
|
@ -135,12 +135,12 @@ FastAPI 是一個現代、快速(高效能)的 Web 框架,用於以 Python
|
|||
|
||||
FastAPI 是站在以下巨人的肩膀上:
|
||||
|
||||
* <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> 負責 Web 部分。
|
||||
* <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> 負責資料部分。
|
||||
* [Starlette](https://www.starlette.dev/) 負責 Web 部分。
|
||||
* [Pydantic](https://docs.pydantic.dev/) 負責資料部分。
|
||||
|
||||
## 安裝 { #installation }
|
||||
|
||||
建立並啟用一個<a href="https://fastapi.tiangolo.com/zh-hant/virtual-environments/" class="external-link" target="_blank">虛擬環境</a>,然後安裝 FastAPI:
|
||||
建立並啟用一個[虛擬環境](https://fastapi.tiangolo.com/zh-hant/virtual-environments/),然後安裝 FastAPI:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ async def read_item(item_id: int, q: str | None = None):
|
|||
|
||||
**注意**:
|
||||
|
||||
如果你不確定,請查看文件中 _"In a hurry?"_ 章節的 <a href="https://fastapi.tiangolo.com/zh-hant/async/#in-a-hurry" target="_blank">`async` 與 `await`</a>。
|
||||
如果你不確定,請查看文件中 _"In a hurry?"_ 章節的[關於文件中的 `async` 與 `await`](https://fastapi.tiangolo.com/zh-hant/async/#in-a-hurry)。
|
||||
|
||||
</details>
|
||||
|
||||
|
|
@ -210,7 +210,7 @@ async def read_item(item_id: int, q: str | None = None):
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ fastapi dev
|
||||
|
||||
╭────────── FastAPI CLI - Development mode ───────────╮
|
||||
│ │
|
||||
|
|
@ -235,19 +235,19 @@ INFO: Application startup complete.
|
|||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>關於指令 <code>fastapi dev main.py</code>...</summary>
|
||||
<summary>關於指令 <code>fastapi dev</code>...</summary>
|
||||
|
||||
指令 `fastapi dev` 會讀取你的 `main.py`,偵測其中的 **FastAPI** 應用,並使用 <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> 啟動伺服器。
|
||||
指令 `fastapi dev` 會讀取你的 `main.py`,偵測其中的 **FastAPI** 應用,並使用 [Uvicorn](https://www.uvicorn.dev) 啟動伺服器。
|
||||
|
||||
預設情況下,`fastapi dev` 會在本機開發時啟用自動重新載入。
|
||||
|
||||
可在 <a href="https://fastapi.tiangolo.com/zh-hant/fastapi-cli/" target="_blank">FastAPI CLI 文件</a>中閱讀更多資訊。
|
||||
可在 [FastAPI CLI 文件](https://fastapi.tiangolo.com/zh-hant/fastapi-cli/)中閱讀更多資訊。
|
||||
|
||||
</details>
|
||||
|
||||
### 檢查 { #check-it }
|
||||
|
||||
使用瀏覽器開啟 <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>。
|
||||
使用瀏覽器開啟 [http://127.0.0.1:8000/items/5?q=somequery](http://127.0.0.1:8000/items/5?q=somequery)。
|
||||
|
||||
你將會看到以下 JSON 回應:
|
||||
|
||||
|
|
@ -264,17 +264,17 @@ INFO: Application startup complete.
|
|||
|
||||
### 互動式 API 文件 { #interactive-api-docs }
|
||||
|
||||
接著前往 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
|
||||
接著前往 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
你會看到自動生成的互動式 API 文件(由 <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> 提供):
|
||||
你會看到自動生成的互動式 API 文件(由 [Swagger UI](https://github.com/swagger-api/swagger-ui) 提供):
|
||||
|
||||

|
||||
|
||||
### 替代 API 文件 { #alternative-api-docs }
|
||||
|
||||
現在前往 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>。
|
||||
現在前往 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc)。
|
||||
|
||||
你會看到另一種自動文件(由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> 提供):
|
||||
你會看到另一種自動文件(由 [ReDoc](https://github.com/Rebilly/ReDoc) 提供):
|
||||
|
||||

|
||||
|
||||
|
|
@ -316,7 +316,7 @@ def update_item(item_id: int, item: Item):
|
|||
|
||||
### 互動式 API 文件升級 { #interactive-api-docs-upgrade }
|
||||
|
||||
前往 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
|
||||
前往 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
* 互動式 API 文件會自動更新,包含新的 body:
|
||||
|
||||
|
|
@ -332,7 +332,7 @@ def update_item(item_id: int, item: Item):
|
|||
|
||||
### 替代 API 文件升級 { #alternative-api-docs-upgrade }
|
||||
|
||||
現在前往 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>。
|
||||
現在前往 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc)。
|
||||
|
||||
* 替代文件也會反映新的查詢參數與 body:
|
||||
|
||||
|
|
@ -433,7 +433,7 @@ item: Item
|
|||
|
||||

|
||||
|
||||
若想看包含更多功能的完整範例,請參考 <a href="https://fastapi.tiangolo.com/zh-hant/tutorial/">教學 - 使用者指南</a>。
|
||||
若想看包含更多功能的完整範例,請參考 <a href="https://fastapi.tiangolo.com/zh-hant/tutorial/">Tutorial - User Guide</a>。
|
||||
|
||||
**劇透警告**:教學 - 使用者指南包含:
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ item: Item
|
|||
* 一個非常強大且易用的 **<dfn title="也稱為:components、resources、providers、services、injectables">依賴注入</dfn>** 系統。
|
||||
* 安全與驗證,包含支援 **OAuth2** 搭配 **JWT tokens** 與 **HTTP Basic** 驗證。
|
||||
* 宣告**深度巢狀 JSON 模型**的進階(但同樣簡單)技巧(感謝 Pydantic)。
|
||||
* 與 <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> 及其他函式庫的 **GraphQL** 整合。
|
||||
* 與 [Strawberry](https://strawberry.rocks) 及其他函式庫的 **GraphQL** 整合。
|
||||
* 許多額外功能(感謝 Starlette),例如:
|
||||
* **WebSockets**
|
||||
* 基於 HTTPX 與 `pytest` 的極其簡單的測試
|
||||
|
|
@ -452,24 +452,10 @@ item: Item
|
|||
|
||||
### 部署你的應用(可選) { #deploy-your-app-optional }
|
||||
|
||||
你也可以選擇將 FastAPI 應用部署到 <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>,如果你還沒加入,去登記等候名單吧。🚀
|
||||
你也可以選擇將 FastAPI 應用部署到 [FastAPI Cloud](https://fastapicloud.com),如果你還沒加入,去登記等候名單吧。🚀
|
||||
|
||||
如果你已經有 **FastAPI Cloud** 帳號(我們已從等候名單邀請你 😉),你可以用一個指令部署你的應用。
|
||||
|
||||
部署前,先確認你已登入:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
接著部署你的應用:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
|
|
@ -488,7 +474,7 @@ Deploying to FastAPI Cloud...
|
|||
|
||||
#### 關於 FastAPI Cloud { #about-fastapi-cloud }
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** 由 **FastAPI** 的同一位作者與團隊打造。
|
||||
**[FastAPI Cloud](https://fastapicloud.com)** 由 **FastAPI** 的同一位作者與團隊打造。
|
||||
|
||||
它讓你以最小的努力精簡地完成 API 的**建置**、**部署**與**存取**流程。
|
||||
|
||||
|
|
@ -504,9 +490,9 @@ FastAPI 是開源且基於標準。你可以把 FastAPI 應用部署到任何你
|
|||
|
||||
## 效能 { #performance }
|
||||
|
||||
獨立的 TechEmpower 基準測試顯示,在 Uvicorn 下運行的 **FastAPI** 應用是<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">最快的 Python 框架之一</a>,僅次於 Starlette 與 Uvicorn 本身(FastAPI 內部使用它們)。(*)
|
||||
獨立的 TechEmpower 基準測試顯示,在 Uvicorn 下運行的 **FastAPI** 應用是[最快的 Python 框架之一](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7),僅次於 Starlette 與 Uvicorn 本身(FastAPI 內部使用它們)。(*)
|
||||
|
||||
想了解更多,請參閱<a href="https://fastapi.tiangolo.com/zh-hant/benchmarks/" class="internal-link" target="_blank">測試結果</a>。
|
||||
想了解更多,請參閱[測試結果](https://fastapi.tiangolo.com/zh-hant/benchmarks/)。
|
||||
|
||||
## 依賴套件 { #dependencies }
|
||||
|
||||
|
|
@ -518,19 +504,19 @@ FastAPI 依賴 Pydantic 與 Starlette。
|
|||
|
||||
Pydantic 會使用:
|
||||
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - 用於電子郵件驗證。
|
||||
* [`email-validator`](https://github.com/JoshData/python-email-validator) - 用於電子郵件驗證。
|
||||
|
||||
Starlette 會使用:
|
||||
|
||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - 若要使用 `TestClient` 必須安裝。
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - 若要使用預設的模板設定必須安裝。
|
||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - 若要支援表單 <dfn title="將來自 HTTP 請求的字串轉換為 Python 資料">"解析"</dfn>,搭配 `request.form()`。
|
||||
* [`httpx`](https://www.python-httpx.org) - 若要使用 `TestClient` 必須安裝。
|
||||
* [`jinja2`](https://jinja.palletsprojects.com) - 若要使用預設的模板設定必須安裝。
|
||||
* [`python-multipart`](https://github.com/Kludex/python-multipart) - 若要支援表單 <dfn title="將來自 HTTP 請求的字串轉換為 Python 資料">"解析"</dfn>,搭配 `request.form()`。
|
||||
|
||||
FastAPI 會使用:
|
||||
|
||||
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - 用於載入並服務你的應用的伺服器。這包含 `uvicorn[standard]`,其中含有一些高效能服務所需的依賴(例如 `uvloop`)。
|
||||
* [`uvicorn`](https://www.uvicorn.dev) - 用於載入並服務你的應用的伺服器。這包含 `uvicorn[standard]`,其中含有一些高效能服務所需的依賴(例如 `uvloop`)。
|
||||
* `fastapi-cli[standard]` - 提供 `fastapi` 指令。
|
||||
* 其中包含 `fastapi-cloud-cli`,可讓你將 FastAPI 應用部署到 <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>。
|
||||
* 其中包含 `fastapi-cloud-cli`,可讓你將 FastAPI 應用部署到 [FastAPI Cloud](https://fastapicloud.com)。
|
||||
|
||||
### 不含 `standard` 依賴套件 { #without-standard-dependencies }
|
||||
|
||||
|
|
@ -546,13 +532,13 @@ FastAPI 會使用:
|
|||
|
||||
Pydantic 的額外可選依賴:
|
||||
|
||||
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - 設定管理。
|
||||
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - 與 Pydantic 一起使用的額外型別。
|
||||
* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) - 設定管理。
|
||||
* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) - 與 Pydantic 一起使用的額外型別。
|
||||
|
||||
FastAPI 的額外可選依賴:
|
||||
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - 若要使用 `ORJSONResponse` 必須安裝。
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - 若要使用 `UJSONResponse` 必須安裝。
|
||||
* [`orjson`](https://github.com/ijl/orjson) - 若要使用 `ORJSONResponse` 必須安裝。
|
||||
* [`ujson`](https://github.com/esnme/ultrajson) - 若要使用 `UJSONResponse` 必須安裝。
|
||||
|
||||
## 授權 { #license }
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
你可以使用此範本快速起步,裡面已替你完成大量初始設定、安全性、資料庫,以及部分 API 端點。
|
||||
|
||||
GitHub 儲存庫:<a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">全端 FastAPI 範本</a>
|
||||
GitHub 儲存庫:[全端 FastAPI 範本](https://github.com/tiangolo/full-stack-fastapi-template)
|
||||
|
||||
## 全端 FastAPI 範本 - 技術堆疊與功能 { #full-stack-fastapi-template-technology-stack-and-features }
|
||||
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ def some_function(data: Any):
|
|||
|
||||
## Pydantic 模型 { #pydantic-models }
|
||||
|
||||
<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> 是一個用來做資料驗證的 Python 程式庫。
|
||||
[Pydantic](https://docs.pydantic.dev/) 是一個用來做資料驗證的 Python 程式庫。
|
||||
|
||||
你以帶有屬性的類別來宣告資料的「形狀」。
|
||||
|
||||
|
|
@ -285,13 +285,13 @@ def some_function(data: Any):
|
|||
|
||||
/// info | 資訊
|
||||
|
||||
想了解更多 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic,請查看它的文件</a>。
|
||||
想了解更多 [Pydantic,請查看它的文件](https://docs.pydantic.dev/)。
|
||||
|
||||
///
|
||||
|
||||
**FastAPI** 完全是以 Pydantic 為基礎。
|
||||
|
||||
你會在[教學 - 使用者指南](tutorial/index.md){.internal-link target=_blank}中看到更多實際範例。
|
||||
你會在[教學 - 使用者指南](tutorial/index.md)中看到更多實際範例。
|
||||
|
||||
## 含中繼資料的型別提示 { #type-hints-with-metadata-annotations }
|
||||
|
||||
|
|
@ -337,12 +337,12 @@ Python 本身不會對這個 `Annotated` 做任何事。對編輯器與其他工
|
|||
* 使用 OpenAPI 書寫 API 文件:
|
||||
* 之後會由自動的互動式文件介面所使用
|
||||
|
||||
這些現在聽起來可能有點抽象。別擔心。你會在[教學 - 使用者指南](tutorial/index.md){.internal-link target=_blank}中看到它們的實際運作。
|
||||
這些現在聽起來可能有點抽象。別擔心。你會在[教學 - 使用者指南](tutorial/index.md)中看到它們的實際運作。
|
||||
|
||||
重點是,透過在單一位置使用標準的 Python 型別(而不是新增更多類別、裝飾器等),**FastAPI** 會幫你完成很多工作。
|
||||
|
||||
/// info | 資訊
|
||||
|
||||
如果你已經完整讀完整個教學,並回來想多看一些關於型別的內容,一個不錯的資源是 <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">`mypy` 的「小抄」</a>。
|
||||
如果你已經完整讀完整個教學,並回來想多看一些關於型別的內容,一個不錯的資源是 [`mypy` 的「小抄」](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)。
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
## 技術細節 { #technical-details }
|
||||
|
||||
類別 `BackgroundTasks` 直接來自 <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>。
|
||||
類別 `BackgroundTasks` 直接來自 [`starlette.background`](https://www.starlette.dev/background/)。
|
||||
|
||||
它被直接匯入/包含到 FastAPI 中,因此你可以從 `fastapi` 匯入它,並避免不小心從 `starlette.background` 匯入另一個同名的 `BackgroundTask`(結尾沒有 s)。
|
||||
|
||||
|
|
@ -69,11 +69,11 @@
|
|||
|
||||
在 FastAPI 中仍可單獨使用 `BackgroundTask`,但你需要在程式碼中自行建立該物件,並回傳包含它的 Starlette `Response`。
|
||||
|
||||
更多細節請參閱 <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">Starlette 官方的 Background Tasks 文件</a>。
|
||||
更多細節請參閱 [Starlette 官方的 Background Tasks 文件](https://www.starlette.dev/background/)。
|
||||
|
||||
## 注意事項 { #caveat }
|
||||
|
||||
如果你需要執行繁重的背景計算,且不一定要由同一個行程執行(例如不需要共用記憶體、變數等),可以考慮使用更大型的工具,例如 <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>。
|
||||
如果你需要執行繁重的背景計算,且不一定要由同一個行程執行(例如不需要共用記憶體、變數等),可以考慮使用更大型的工具,例如 [Celery](https://docs.celeryq.dev)。
|
||||
|
||||
這類工具通常需要較複雜的設定,以及訊息/工作佇列管理器(如 RabbitMQ 或 Redis),但它們允許你在多個行程,甚至多台伺服器上執行背景任務。
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ from app.routers import items
|
|||
|
||||
為了簡化範例,我們使用了一個虛構的標頭。
|
||||
|
||||
但在真實情況下,使用內建的[安全工具](security/index.md){.internal-link target=_blank}會有更好的效果。
|
||||
但在真實情況下,使用內建的 [安全工具](security/index.md) 會有更好的效果。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ async def read_item(item_id: str):
|
|||
|
||||
/// tip | 提示
|
||||
|
||||
請注意,就像在[路徑操作裝飾器中的相依性](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}一樣,不會把任何值傳遞給你的路徑操作函式(path operation function)。
|
||||
請注意,就像在[路徑操作裝飾器中的相依性](dependencies/dependencies-in-path-operation-decorators.md)一樣,不會把任何值傳遞給你的路徑操作函式(path operation function)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -185,8 +185,8 @@ async def read_item(item_id: str):
|
|||
* 它們都會包含預先定義的 `responses`。
|
||||
* 這些路徑操作都會在執行前評估 / 執行其 `dependencies` 清單。
|
||||
* 如果你也在特定的路徑操作中宣告了相依性,這些相依性也會被執行。
|
||||
* Router 的相依性會先執行,然後是[裝飾器中的 `dependencies`](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank},最後是一般參數相依性。
|
||||
* 你也可以加入帶有 `scopes` 的 [`Security` 相依性](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}。
|
||||
* Router 的相依性會先執行,然後是[裝飾器中的 `dependencies`](dependencies/dependencies-in-path-operation-decorators.md),最後是一般參數相依性。
|
||||
* 你也可以加入帶有 `scopes` 的 [`Security` 相依性](../advanced/security/oauth2-scopes.md)。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
|
|
@ -303,7 +303,7 @@ from ...dependencies import get_token_header
|
|||
|
||||
照常匯入並建立 `FastAPI` 類別。
|
||||
|
||||
我們甚至可以宣告[全域相依性](dependencies/global-dependencies.md){.internal-link target=_blank},它們會與各 `APIRouter` 的相依性合併:
|
||||
我們甚至可以宣告[全域相依性](dependencies/global-dependencies.md),它們會與各 `APIRouter` 的相依性合併:
|
||||
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
|
||||
|
||||
|
|
@ -353,7 +353,7 @@ from .routers import items, users
|
|||
from app.routers import items, users
|
||||
```
|
||||
|
||||
想了解更多關於 Python 套件與模組,請閱讀<a href="https://docs.python.org/3/tutorial/modules.html" class="external-link" target="_blank">官方的模組說明文件</a>。
|
||||
想了解更多關於 Python 套件與模組,請閱讀[官方的模組說明文件](https://docs.python.org/3/tutorial/modules.html)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -465,6 +465,37 @@ from .routers.users import router
|
|||
|
||||
///
|
||||
|
||||
## 在 `pyproject.toml` 設定 `entrypoint` { #configure-the-entrypoint-in-pyproject-toml }
|
||||
|
||||
因為你的 FastAPI `app` 物件位在 `app/main.py`,你可以在 `pyproject.toml` 檔案中這樣設定 `entrypoint`:
|
||||
|
||||
```toml
|
||||
[tool.fastapi]
|
||||
entrypoint = "app.main:app"
|
||||
```
|
||||
|
||||
這等同於這樣匯入:
|
||||
|
||||
```python
|
||||
from app.main import app
|
||||
```
|
||||
|
||||
如此一來 `fastapi` 指令就會知道去哪裡找到你的 app。
|
||||
|
||||
/// Note | 注意
|
||||
|
||||
你也可以把路徑直接傳給指令,例如:
|
||||
|
||||
```console
|
||||
$ fastapi dev app/main.py
|
||||
```
|
||||
|
||||
但你每次呼叫 `fastapi` 指令時都得記得傳入正確的路徑。
|
||||
|
||||
此外,其他工具可能找不到它,例如 [VS Code 擴充套件](../editor-support.md) 或 [FastAPI Cloud](https://fastapicloud.com),因此建議在 `pyproject.toml` 中使用 `entrypoint`。
|
||||
|
||||
///
|
||||
|
||||
## 檢查自動產生的 API 文件 { #check-the-automatic-api-docs }
|
||||
|
||||
現在,執行你的應用:
|
||||
|
|
@ -472,14 +503,14 @@ from .routers.users import router
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev app/main.py
|
||||
$ fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
然後開啟位於 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> 的文件。
|
||||
然後開啟位於 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) 的文件。
|
||||
|
||||
你會看到自動產生的 API 文件,包含來自所有子模組的路徑,使用正確的路徑(與前綴)與正確的標籤:
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ my_list: list[str]
|
|||
|
||||
除了 `str`、`int`、`float` 等一般的單一型別外,你也可以使用繼承自 `str` 的更複雜單一型別。
|
||||
|
||||
若要查看所有可用選項,請參閱 <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Pydantic 的型別總覽</a>。你會在下一章看到一些範例。
|
||||
若要查看所有可用選項,請參閱 [Pydantic 的型別總覽](https://docs.pydantic.dev/latest/concepts/types/)。你會在下一章看到一些範例。
|
||||
|
||||
例如,在 `Image` 模型中有一個 `url` 欄位,我們可以將其宣告為 Pydantic 的 `HttpUrl`,而不是 `str`:
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## 使用 `PUT` 取代式更新 { #update-replacing-with-put }
|
||||
|
||||
要更新一個項目,你可以使用 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a> 操作。
|
||||
要更新一個項目,你可以使用 [HTTP `PUT`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) 操作。
|
||||
|
||||
你可以使用 `jsonable_encoder` 將輸入資料轉換為可儲存為 JSON 的資料(例如用於 NoSQL 資料庫)。例如把 `datetime` 轉成 `str`。
|
||||
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
## 使用 `PATCH` 進行部分更新 { #partial-updates-with-patch }
|
||||
|
||||
你也可以使用 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> 操作來進行*部分*更新。
|
||||
你也可以使用 [HTTP `PATCH`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) 操作來進行*部分*更新。
|
||||
|
||||
這表示你只需傳送想要更新的資料,其餘保持不變。
|
||||
|
||||
|
|
@ -95,6 +95,6 @@
|
|||
|
||||
因此,如果你希望接收可以省略所有屬性的部分更新,你需要一個所有屬性皆為可選(具預設值或為 `None`)的模型。
|
||||
|
||||
為了區分用於更新(全部可選)與用於建立(欄位為必填)的模型,你可以參考 [額外模型](extra-models.md){.internal-link target=_blank} 中的做法。
|
||||
為了區分用於更新(全部可選)與用於建立(欄位為必填)的模型,你可以參考 [額外模型](extra-models.md) 中的做法。
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
你的 API 幾乎總是需要傳回**回應**本文。但用戶端不一定每次都要送出**請求本文**,有時只會請求某個路徑,可能帶一些查詢參數,但不會傳送本文。
|
||||
|
||||
要宣告**請求**本文,你會使用 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> 模型,享受其完整的功能與優點。
|
||||
要宣告**請求**本文,你會使用 [Pydantic](https://docs.pydantic.dev/) 模型,享受其完整的功能與優點。
|
||||
|
||||
/// info
|
||||
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
- 若資料無效,會回傳清楚易懂的錯誤,指出哪裡、哪筆資料不正確。
|
||||
- 把接收到的資料放在參數 `item` 中提供給你。
|
||||
- 由於你在函式中將其宣告為 `Item` 型別,你也會獲得完整的編輯器支援(自動完成等)以及所有屬性與其型別。
|
||||
- 為你的模型產生 <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> 定義,如有需要,你也可以在專案中的其他地方使用。
|
||||
- 為你的模型產生 [JSON Schema](https://json-schema.org) 定義,如有需要,你也可以在專案中的其他地方使用。
|
||||
- 這些 schema 會成為產生的 OpenAPI schema 的一部分,並由自動文件 <abbr title="User Interfaces - 使用者介面">UIs</abbr> 使用。
|
||||
|
||||
## 自動文件 { #automatic-docs }
|
||||
|
|
@ -101,15 +101,15 @@
|
|||
|
||||
甚至為了支援這點,Pydantic 本身也做了些修改。
|
||||
|
||||
前面的螢幕截圖是使用 <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a> 拍的。
|
||||
前面的螢幕截圖是使用 [Visual Studio Code](https://code.visualstudio.com) 拍的。
|
||||
|
||||
但你在 <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> 與大多數其它 Python 編輯器中也會得到相同的編輯器支援:
|
||||
但你在 [PyCharm](https://www.jetbrains.com/pycharm/) 與大多數其它 Python 編輯器中也會得到相同的編輯器支援:
|
||||
|
||||
<img src="/img/tutorial/body/image05.png">
|
||||
|
||||
/// tip
|
||||
|
||||
如果你使用 <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> 作為編輯器,可以安裝 <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>。
|
||||
如果你使用 [PyCharm](https://www.jetbrains.com/pycharm/) 作為編輯器,可以安裝 [Pydantic PyCharm Plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin/)。
|
||||
|
||||
它能增強 Pydantic 模型的編輯器支援,包含:
|
||||
|
||||
|
|
@ -161,4 +161,4 @@ FastAPI 會因為預設值 `= None` 而知道 `q` 的值不是必填。
|
|||
|
||||
## 不使用 Pydantic { #without-pydantic }
|
||||
|
||||
若你不想使用 Pydantic 模型,也可以使用 **Body** 參數。請參考[Body - 多個參數:本文中的單一值](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}。
|
||||
若你不想使用 Pydantic 模型,也可以使用 **Body** 參數。請參考[Body - 多個參數:本文中的單一值](body-multiple-params.md#singular-values-in-body)。
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# CORS(跨來源資源共用) { #cors-cross-origin-resource-sharing }
|
||||
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORS 或「Cross-Origin Resource Sharing」</a>指的是:當在瀏覽器中執行的前端以 JavaScript 與後端通訊,而後端與前端位於不同「來源(origin)」時的情境。
|
||||
[CORS 或「Cross-Origin Resource Sharing」](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)指的是:當在瀏覽器中執行的前端以 JavaScript 與後端通訊,而後端與前端位於不同「來源(origin)」時的情境。
|
||||
|
||||
## 來源(Origin) { #origin }
|
||||
|
||||
|
|
@ -55,10 +55,10 @@
|
|||
* `allow_origins` - 允許進行跨來源請求的來源清單。例如 `['https://example.org', 'https://www.example.org']`。你可以使用 `['*']` 來允許任何來源。
|
||||
* `allow_origin_regex` - 允許進行跨來源請求的來源,使用正規表示式字串比對。例如 `'https://.*\.example\.org'`。
|
||||
* `allow_methods` - 允許跨來源請求的 HTTP 方法清單。預設為 `['GET']`。你可以使用 `['*']` 來允許所有標準方法。
|
||||
* `allow_headers` - 允許跨來源請求所支援的 HTTP 請求標頭清單。預設為 `[]`。你可以使用 `['*']` 來允許所有標頭。對於<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests" class="external-link" rel="noopener" target="_blank">簡單 CORS 請求</a>,`Accept`、`Accept-Language`、`Content-Language` 與 `Content-Type` 標頭一律被允許。
|
||||
* `allow_headers` - 允許跨來源請求所支援的 HTTP 請求標頭清單。預設為 `[]`。你可以使用 `['*']` 來允許所有標頭。對於[簡單 CORS 請求](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests),`Accept`、`Accept-Language`、`Content-Language` 與 `Content-Type` 標頭一律被允許。
|
||||
* `allow_credentials` - 指示是否支援跨來源請求的 Cookie。預設為 `False`。
|
||||
|
||||
當 `allow_credentials` 設為 `True` 時,`allow_origins`、`allow_methods` 與 `allow_headers` 都不能設為 `['*']`。上述各項必須<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards" class="external-link" rel="noopener" target="_blank">明確指定</a>。
|
||||
當 `allow_credentials` 設為 `True` 時,`allow_origins`、`allow_methods` 與 `allow_headers` 都不能設為 `['*']`。上述各項必須[明確指定](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards)。
|
||||
|
||||
* `expose_headers` - 指示哪些回應標頭應該讓瀏覽器可存取。預設為 `[]`。
|
||||
* `max_age` - 設定瀏覽器快取 CORS 回應的最長秒數。預設為 `600`。
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
|
||||
## 更多資訊 { #more-info }
|
||||
|
||||
想進一步了解 <abbr title="Cross-Origin Resource Sharing - 跨來源資源共用">CORS</abbr>,請參考 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla 的 CORS 文件</a>。
|
||||
想進一步了解 <abbr title="Cross-Origin Resource Sharing - 跨來源資源共用">CORS</abbr>,請參考 [Mozilla 的 CORS 文件](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)。
|
||||
|
||||
/// note | 技術細節
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ $ python myapp.py
|
|||
```Python
|
||||
from myapp import app
|
||||
|
||||
# Some more code
|
||||
# 其他程式碼
|
||||
```
|
||||
|
||||
在那種情況下,`myapp.py` 中自動建立的變數 `__name__` 就不會是 `"__main__"`。
|
||||
|
|
@ -74,7 +74,7 @@ from myapp import app
|
|||
|
||||
/// info | 說明
|
||||
|
||||
想了解更多,參考 <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">Python 官方文件</a>。
|
||||
想了解更多,參考 [Python 官方文件](https://docs.python.org/3/library/__main__.html)。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
在這個範例中我們使用了自訂的(虛構的)標頭 `X-Key` 與 `X-Token`。
|
||||
|
||||
但在實際情況下,當你實作安全機制時,使用整合的 [Security utilities(下一章)](../security/index.md){.internal-link target=_blank} 會獲得更多好處。
|
||||
但在實際情況下,當你實作安全機制時,使用整合的 [Security utilities(下一章)](../security/index.md) 會獲得更多好處。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
## 一組路徑操作的依賴 { #dependencies-for-a-group-of-path-operations }
|
||||
|
||||
之後在閱讀如何組織較大的應用程式([較大型應用程式——多個檔案](../../tutorial/bigger-applications.md){.internal-link target=_blank})時,你會學到如何為一組路徑操作宣告一個共同的 `dependencies` 參數。
|
||||
之後在閱讀如何組織較大的應用程式([較大型應用程式——多個檔案](../../tutorial/bigger-applications.md))時,你會學到如何為一組路徑操作宣告一個共同的 `dependencies` 參數。
|
||||
|
||||
## 全域依賴 { #global-dependencies }
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ FastAPI 支援在完成後執行一些<dfn title="有時也稱為「結束程式
|
|||
|
||||
任何可用於下列裝飾器的函式:
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> 或
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) 或
|
||||
* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
|
||||
|
||||
都可以作為 **FastAPI** 的相依。
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ FastAPI 支援在完成後執行一些<dfn title="有時也稱為「結束程式
|
|||
|
||||
/// note | 技術細節
|
||||
|
||||
這能運作,多虧了 Python 的 <a href="https://docs.python.org/3/library/contextlib.html" class="external-link" target="_blank">Context Managers</a>。
|
||||
這能運作,多虧了 Python 的 [Context Managers](https://docs.python.org/3/library/contextlib.html)。
|
||||
|
||||
**FastAPI** 在內部使用它們來達成這點。
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ FastAPI 支援在完成後執行一些<dfn title="有時也稱為「結束程式
|
|||
|
||||
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
|
||||
|
||||
如果你想攔截例外並據此回傳自訂回應,請建立一個[自訂例外處理器](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}。
|
||||
如果你想攔截例外並據此回傳自訂回應,請建立一個[自訂例外處理器](../handling-errors.md#install-custom-exception-handlers)。
|
||||
|
||||
## 含 `yield` 與 `except` 的相依 { #dependencies-with-yield-and-except }
|
||||
|
||||
|
|
@ -233,14 +233,14 @@ participant operation as Path Operation
|
|||
|
||||
含 `yield` 的相依隨時間演進,以涵蓋不同的使用情境並修正一些問題。
|
||||
|
||||
如果你想了解在不同 FastAPI 版本中改了哪些內容,可以在進階指南中閱讀:[進階相依 — 含 `yield`、`HTTPException`、`except` 與背景任務的相依](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}。
|
||||
如果你想了解在不同 FastAPI 版本中改了哪些內容,可以在進階指南中閱讀:[進階相依 — 含 `yield`、`HTTPException`、`except` 與背景任務的相依](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks)。
|
||||
## 情境管理器 { #context-managers }
|
||||
|
||||
### 什麼是「情境管理器」 { #what-are-context-managers }
|
||||
|
||||
「情境管理器」是那些你可以在 `with` 陳述式中使用的 Python 物件。
|
||||
|
||||
例如,<a href="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files" class="external-link" target="_blank">你可以用 `with` 來讀取檔案</a>:
|
||||
例如,[你可以用 `with` 來讀取檔案](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files):
|
||||
|
||||
```Python
|
||||
with open("./somefile.txt") as f:
|
||||
|
|
@ -264,7 +264,7 @@ with open("./somefile.txt") as f:
|
|||
|
||||
///
|
||||
|
||||
在 Python 中,你可以透過<a href="https://docs.python.org/3/reference/datamodel.html#context-managers" class="external-link" target="_blank">建立一個擁有 `__enter__()` 與 `__exit__()` 兩個方法的類別</a>來建立情境管理器。
|
||||
在 Python 中,你可以透過[建立一個擁有 `__enter__()` 與 `__exit__()` 兩個方法的類別](https://docs.python.org/3/reference/datamodel.html#context-managers)來建立情境管理器。
|
||||
|
||||
你也可以在 **FastAPI** 的含 `yield` 相依中,於相依函式內使用 `with` 或 `async with` 陳述式來使用它們:
|
||||
|
||||
|
|
@ -274,8 +274,8 @@ with open("./somefile.txt") as f:
|
|||
|
||||
建立情境管理器的另一種方式是:
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> 或
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) 或
|
||||
* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
|
||||
|
||||
用它們裝飾一個只包含單一 `yield` 的函式。
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
在某些類型的應用程式中,你可能想為整個應用程式新增依賴。
|
||||
|
||||
類似於你可以在[路徑操作(path operation)的裝飾器中新增 `dependencies`](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 的方式,你也可以把它們加到 `FastAPI` 應用程式上。
|
||||
類似於你可以在[路徑操作(path operation)的裝飾器中新增 `dependencies`](dependencies-in-path-operation-decorators.md) 的方式,你也可以把它們加到 `FastAPI` 應用程式上。
|
||||
|
||||
在這種情況下,它們會套用到應用程式中的所有路徑操作:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
|
||||
|
||||
而且,在[將 `dependencies` 新增到路徑操作裝飾器](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} 那一節中的所有概念依然適用,只是這裡是套用到整個應用中的所有路徑操作。
|
||||
而且,在[將 `dependencies` 新增到路徑操作裝飾器](dependencies-in-path-operation-decorators.md) 那一節中的所有概念依然適用,只是這裡是套用到整個應用中的所有路徑操作。
|
||||
|
||||
## 路徑操作群組的依賴 { #dependencies-for-groups-of-path-operations }
|
||||
|
||||
之後,在閱讀如何組織更大的應用程式([更大的應用程式 - 多個檔案](../../tutorial/bigger-applications.md){.internal-link target=_blank})時,可能會有多個檔案,你將會學到如何為一組路徑操作宣告單一的 `dependencies` 參數。
|
||||
之後,在閱讀如何組織更大的應用程式([更大的應用程式 - 多個檔案](../../tutorial/bigger-applications.md))時,可能會有多個檔案,你將會學到如何為一組路徑操作宣告單一的 `dependencies` 參數。
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ FastAPI 在 0.95.0 版新增了對 `Annotated` 的支援(並開始建議使用
|
|||
|
||||
如果你使用較舊的版本,嘗試使用 `Annotated` 時會出現錯誤。
|
||||
|
||||
在使用 `Annotated` 之前,請先[升級 FastAPI 版本](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}到至少 0.95.1。
|
||||
在使用 `Annotated` 之前,請先[升級 FastAPI 版本](../../deployment/versions.md#upgrading-the-fastapi-versions)到至少 0.95.1。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ commons: Annotated[dict, Depends(common_parameters)]
|
|||
|
||||
/// note | 注意
|
||||
|
||||
如果你不熟悉,請參考文件中的 [Async: "In a hurry?"](../../async.md#in-a-hurry){.internal-link target=_blank} 一節,瞭解 `async` 與 `await`。
|
||||
如果你不熟悉,請參考文件中的 [Async: "In a hurry?"](../../async.md#in-a-hurry) 一節,瞭解 `async` 與 `await`。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
例如,它不接受 `datetime` 物件,因為那與 JSON 不相容。
|
||||
|
||||
因此,必須將 `datetime` 物件轉為一個以 <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO 格式</a> 表示資料的 `str`。
|
||||
因此,必須將 `datetime` 物件轉為一個以 [ISO 格式](https://en.wikipedia.org/wiki/ISO_8601) 表示資料的 `str`。
|
||||
|
||||
同樣地,這個資料庫不會接受 Pydantic 模型(帶有屬性的物件),只接受 `dict`。
|
||||
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
在此範例中,它會把 Pydantic 模型轉成 `dict`,並將 `datetime` 轉成 `str`。
|
||||
|
||||
呼叫後的結果可以用 Python 標準的 <a href="https://docs.python.org/3/library/json.html#json.dumps" class="external-link" target="_blank">`json.dumps()`</a> 進行編碼。
|
||||
呼叫後的結果可以用 Python 標準的 [`json.dumps()`](https://docs.python.org/3/library/json.html#json.dumps) 進行編碼。
|
||||
|
||||
它不會回傳一個包含 JSON 內容的大型 `str`(字串)。它會回傳 Python 標準的資料結構(例如 `dict`),其中的值與子值都與 JSON 相容。
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
* `datetime.timedelta`:
|
||||
* Python 的 `datetime.timedelta`。
|
||||
* 在請求與回應中會以總秒數的 `float` 表示。
|
||||
* Pydantic 也允許用「ISO 8601 time diff encoding」來表示,<a href="https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers" class="external-link" target="_blank">詳情見文件</a>。
|
||||
* Pydantic 也允許用「ISO 8601 time diff encoding」來表示,[詳情見文件](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers)。
|
||||
* `frozenset`:
|
||||
* 在請求與回應中與 `set` 相同處理:
|
||||
* 在請求中,會讀取一個 list,去除重複並轉為 `set`。
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
* `Decimal`:
|
||||
* 標準的 Python `Decimal`。
|
||||
* 在請求與回應中,與 `float` 的處理方式相同。
|
||||
* 你可以在此查閱所有可用的 Pydantic 資料型別:<a href="https://docs.pydantic.dev/latest/usage/types/types/" class="external-link" target="_blank">Pydantic 資料型別</a>。
|
||||
* 你可以在此查閱所有可用的 Pydantic 資料型別:[Pydantic 資料型別](https://docs.pydantic.dev/latest/usage/types/types/)。
|
||||
|
||||
## 範例 { #example }
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
切勿儲存使用者的明文密碼。務必只儲存可供驗證的「安全雜湊」。
|
||||
|
||||
若你還不清楚,稍後會在[安全性章節](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}學到什麼是「密碼雜湊」。
|
||||
若你還不清楚,稍後會在[安全性章節](security/simple-oauth2.md#password-hashing)學到什麼是「密碼雜湊」。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -162,11 +162,11 @@ UserInDB(
|
|||
|
||||
在 OpenAPI 中會以 `anyOf` 定義。
|
||||
|
||||
要達成這點,使用標準的 Python 型別提示 <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>:
|
||||
要達成這點,使用標準的 Python 型別提示 [`typing.Union`](https://docs.python.org/3/library/typing.html#typing.Union):
|
||||
|
||||
/// note
|
||||
|
||||
在定義 <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a> 時,請先放置「更具體」的型別,再放「較不具體」的型別。以下範例中,較具體的 `PlaneItem` 置於 `CarItem` 之前:`Union[PlaneItem, CarItem]`。
|
||||
在定義 [`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions) 時,請先放置「更具體」的型別,再放「較不具體」的型別。以下範例中,較具體的 `PlaneItem` 置於 `CarItem` 之前:`Union[PlaneItem, CarItem]`。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
|
||||
$ <font color="#4E9A06">fastapi</font> dev
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|||
|
||||
### 查看它 { #check-it }
|
||||
|
||||
在瀏覽器中打開 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
|
||||
在瀏覽器中打開 [http://127.0.0.1:8000](http://127.0.0.1:8000)。
|
||||
|
||||
你將看到如下的 JSON 回應:
|
||||
|
||||
|
|
@ -68,17 +68,17 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|||
|
||||
### 互動式 API 文件 { #interactive-api-docs }
|
||||
|
||||
現在,前往 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
現在,前往 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
你將看到自動的互動式 API 文件(由 <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> 提供):
|
||||
你將看到自動的互動式 API 文件(由 [Swagger UI](https://github.com/swagger-api/swagger-ui) 提供):
|
||||
|
||||

|
||||
|
||||
### 替代 API 文件 { #alternative-api-docs }
|
||||
|
||||
現在,前往 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
現在,前往 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc)。
|
||||
|
||||
你將看到另一種自動文件(由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> 提供):
|
||||
你將看到另一種自動文件(由 [ReDoc](https://github.com/Rebilly/ReDoc) 提供):
|
||||
|
||||

|
||||
|
||||
|
|
@ -92,7 +92,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|||
|
||||
#### API 「schema」 { #api-schema }
|
||||
|
||||
在這種情況下,<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> 是一個規範,它規定了如何定義 API 的 schema。
|
||||
在這種情況下,[OpenAPI](https://github.com/OAI/OpenAPI-Specification) 是一個規範,它規定了如何定義 API 的 schema。
|
||||
|
||||
這個 schema 定義包含了你的 API 路徑、可能接收的參數等內容。
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ OpenAPI 為你的 API 定義了 API 的 schema。而該 schema 會包含你的 A
|
|||
|
||||
如果你好奇原始的 OpenAPI schema 長什麼樣子,FastAPI 會自動生成一個包含所有 API 描述的 JSON(schema)。
|
||||
|
||||
你可以直接在 <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a> 查看它。
|
||||
你可以直接在 [http://127.0.0.1:8000/openapi.json](http://127.0.0.1:8000/openapi.json) 查看它。
|
||||
|
||||
它會顯示一個 JSON,類似於:
|
||||
|
||||
|
|
@ -143,9 +143,58 @@ OpenAPI schema 驅動了兩個互動式文件系統。
|
|||
|
||||
你也可以用它自動生成程式碼,讓用戶端與你的 API 通訊。例如前端、手機或物聯網(IoT)應用程式。
|
||||
|
||||
### 在 `pyproject.toml` 設定應用的 `entrypoint` { #configure-the-app-entrypoint-in-pyproject-toml }
|
||||
|
||||
你可以在 `pyproject.toml` 中設定你的應用位置,例如:
|
||||
|
||||
```toml
|
||||
[tool.fastapi]
|
||||
entrypoint = "main:app"
|
||||
```
|
||||
|
||||
這個 `entrypoint` 會告訴 `fastapi` 指令應該用下面的方式匯入 app:
|
||||
|
||||
```python
|
||||
from main import app
|
||||
```
|
||||
|
||||
如果你的程式碼結構像是:
|
||||
|
||||
```
|
||||
.
|
||||
├── backend
|
||||
│ ├── main.py
|
||||
│ ├── __init__.py
|
||||
```
|
||||
|
||||
那你應該把 `entrypoint` 設為:
|
||||
|
||||
```toml
|
||||
[tool.fastapi]
|
||||
entrypoint = "backend.main:app"
|
||||
```
|
||||
|
||||
這等同於:
|
||||
|
||||
```python
|
||||
from backend.main import app
|
||||
```
|
||||
|
||||
### 搭配路徑使用 `fastapi dev` { #fastapi-dev-with-path }
|
||||
|
||||
你也可以把檔案路徑傳給 `fastapi dev` 指令,它會自動猜測要使用的 FastAPI app 物件:
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
```
|
||||
|
||||
但這樣每次執行 `fastapi` 指令時都要記得傳入正確路徑。
|
||||
|
||||
此外,其他工具可能找不到它,例如 [VS Code 擴充套件](../editor-support.md) 或 [FastAPI Cloud](https://fastapicloud.com),因此建議在 `pyproject.toml` 中使用 `entrypoint`。
|
||||
|
||||
### 部署你的應用程式(可選) { #deploy-your-app-optional }
|
||||
|
||||
你可以選擇將你的 FastAPI 應用程式部署到 <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>,如果還沒有,去加入候補名單吧。🚀
|
||||
你可以選擇將你的 FastAPI 應用程式部署到 [FastAPI Cloud](https://fastapicloud.com),如果還沒有,去加入候補名單吧。🚀
|
||||
|
||||
如果你已經有 **FastAPI Cloud** 帳號(我們已從候補名單邀請你 😉),你可以用一個指令部署你的應用程式。
|
||||
|
||||
|
|
@ -191,7 +240,7 @@ Deploying to FastAPI Cloud...
|
|||
|
||||
`FastAPI` 是一個直接繼承自 `Starlette` 的類別。
|
||||
|
||||
你同樣可以透過 `FastAPI` 來使用 <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> 所有的功能。
|
||||
你同樣可以透過 `FastAPI` 來使用 [Starlette](https://www.starlette.dev/) 所有的功能。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -336,7 +385,7 @@ Python 中的 `@something` 語法被稱為「裝飾器」。
|
|||
|
||||
/// note
|
||||
|
||||
如果你不知道差別,請查看 [Async: *"In a hurry?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
|
||||
如果你不知道差別,請查看 [Async: *"In a hurry?"*](../async.md#in-a-hurry)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -352,11 +401,11 @@ Python 中的 `@something` 語法被稱為「裝飾器」。
|
|||
|
||||
### 第六步:部署 { #step-6-deploy-it }
|
||||
|
||||
用一行指令將你的應用程式部署到 **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>**:`fastapi deploy`。🎉
|
||||
用一行指令將你的應用程式部署到 **[FastAPI Cloud](https://fastapicloud.com)**:`fastapi deploy`。🎉
|
||||
|
||||
#### 關於 FastAPI Cloud { #about-fastapi-cloud }
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** 由 **FastAPI** 的作者與團隊打造。
|
||||
**[FastAPI Cloud](https://fastapicloud.com)** 由 **FastAPI** 的作者與團隊打造。
|
||||
|
||||
它讓你以最小的成本完成 API 的**建置**、**部署**與**存取**流程。
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@
|
|||
|
||||
## 安裝自訂例外處理器 { #install-custom-exception-handlers }
|
||||
|
||||
你可以使用 <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">Starlette 的相同例外工具</a> 來加入自訂例外處理器。
|
||||
你可以使用 [Starlette 的相同例外工具](https://www.starlette.dev/exceptions/) 來加入自訂例外處理器。
|
||||
|
||||
假設你有一個自訂例外 `UnicornException`,你(或你使用的函式庫)可能會 `raise` 它。
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
|
||||
$ <font color="#4E9A06">fastapi</font> dev
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ $ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid
|
|||
|
||||
第一步是安裝 FastAPI。
|
||||
|
||||
確保你建立一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},啟用它,然後**安裝 FastAPI**:
|
||||
確保你建立一個[虛擬環境](../virtual-environments.md),啟用它,然後**安裝 FastAPI**:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ $ pip install "fastapi[standard]"
|
|||
|
||||
/// note | 注意
|
||||
|
||||
當你使用 `pip install "fastapi[standard]"` 安裝時,會包含一些預設的可選標準依賴項,其中包括 `fastapi-cloud-cli`,它可以讓你部署到 <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>。
|
||||
當你使用 `pip install "fastapi[standard]"` 安裝時,會包含一些預設的可選標準依賴項,其中包括 `fastapi-cloud-cli`,它可以讓你部署到 [FastAPI Cloud](https://fastapicloud.com)。
|
||||
|
||||
如果你不想包含那些可選的依賴項,你可以改為安裝 `pip install fastapi`。
|
||||
|
||||
|
|
@ -84,6 +84,12 @@ $ pip install "fastapi[standard]"
|
|||
|
||||
///
|
||||
|
||||
/// tip
|
||||
|
||||
FastAPI 提供了 [VS Code 官方擴充功能](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode)(以及 Cursor),包含許多功能,例如路徑操作探索器、路徑操作搜尋、測試中的 CodeLens 導航(從測試跳到定義)、以及 FastAPI Cloud 的部署與日誌,全部可直接在你的編輯器中完成。
|
||||
|
||||
///
|
||||
|
||||
## 進階使用者指南 { #advanced-user-guide }
|
||||
|
||||
還有一個**進階使用者指南**你可以在讀完這個**教學 - 使用者指南**後再閱讀。
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
| `version` | `string` | API 的版本號。這是你自己的應用程式版本,不是 OpenAPI 的版本,例如 `2.5.0`。 |
|
||||
| `terms_of_service` | `str` | 指向 API 服務條款的 URL。若提供,必須是 URL。 |
|
||||
| `contact` | `dict` | 對外公開的 API 聯絡資訊。可包含多個欄位。<details><summary><code>contact</code> 欄位</summary><table><thead><tr><th>參數</th><th>型別</th><th>說明</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>聯絡人/組織的識別名稱。</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>指向聯絡資訊的 URL。必須是 URL 格式。</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>聯絡人/組織的電子郵件地址。必須是電子郵件格式。</td></tr></tbody></table></details> |
|
||||
| `license_info` | `dict` | 對外公開的 API 授權資訊。可包含多個欄位。<details><summary><code>license_info</code> 欄位</summary><table><thead><tr><th>參數</th><th>型別</th><th>說明</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>必填</strong>(若有設定 <code>license_info</code>)。API 使用的授權名稱。</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>API 的 <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> 授權表示式。<code>identifier</code> 欄位與 <code>url</code> 欄位互斥。<small>自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>API 所採用授權的 URL。必須是 URL 格式。</td></tr></tbody></table></details> |
|
||||
| `license_info` | `dict` | 對外公開的 API 授權資訊。可包含多個欄位。<details><summary><code>license_info</code> 欄位</summary><table><thead><tr><th>參數</th><th>型別</th><th>說明</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>必填</strong>(若有設定 <code>license_info</code>)。API 使用的授權名稱。</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>API 的 [SPDX](https://spdx.org/licenses/) 授權表示式。<code>identifier</code> 欄位與 <code>url</code> 欄位互斥。<small>自 OpenAPI 3.1.0、FastAPI 0.99.0 起可用。</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>API 所採用授權的 URL。必須是 URL 格式。</td></tr></tbody></table></details> |
|
||||
|
||||
你可以這樣設定它們:
|
||||
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
/// info | 資訊
|
||||
|
||||
在[路徑操作設定]中閱讀更多關於標籤的內容:[Path Operation Configuration](path-operation-configuration.md#tags){.internal-link target=_blank}。
|
||||
在 [Path Operation Configuration](path-operation-configuration.md#tags) 中閱讀更多關於標籤的內容。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
如果你有使用帶有 `yield` 的相依性,其釋放階段的程式碼會在中介軟體之後執行。
|
||||
|
||||
若有背景工作(在[背景工作](background-tasks.md){.internal-link target=_blank}一節會介紹,你稍後會看到),它們會在所有中介軟體之後執行。
|
||||
若有背景工作(在[背景工作](background-tasks.md)一節會介紹,你稍後會看到),它們會在所有中介軟體之後執行。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -35,9 +35,9 @@
|
|||
|
||||
/// tip
|
||||
|
||||
請記得,自訂的非標準標頭可以<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">使用 `X-` 前綴</a>。
|
||||
請記得,自訂的非標準標頭可以[使用 `X-` 前綴](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)。
|
||||
|
||||
但如果你有自訂標頭並希望瀏覽器端的用戶端能看到它們,你需要在 CORS 設定([CORS(Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank})中使用 <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">Starlette 的 CORS 文件</a>所記載的參數 `expose_headers` 將它們加入。
|
||||
但如果你有自訂標頭並希望瀏覽器端的用戶端能看到它們,你需要在 CORS 設定([CORS(跨來源資源共用)](cors.md))中使用 [Starlette 的 CORS 文件](https://www.starlette.dev/middleware/#corsmiddleware)所記載的參數 `expose_headers` 將它們加入。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
/// tip
|
||||
|
||||
這裡我們使用 <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> 而不是 `time.time()`,因為在這些用例中它可能更精確。🤓
|
||||
這裡我們使用 [`time.perf_counter()`](https://docs.python.org/3/library/time.html#time.perf_counter) 而不是 `time.time()`,因為在這些用例中它可能更精確。🤓
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -90,6 +90,6 @@ app.add_middleware(MiddlewareB)
|
|||
|
||||
## 其他中介軟體 { #other-middlewares }
|
||||
|
||||
你之後可以在[進階使用者指南:進階中介軟體](../advanced/middleware.md){.internal-link target=_blank}閱讀更多關於其他中介軟體的內容。
|
||||
你之後可以在[進階使用者指南:進階中介軟體](../advanced/middleware.md)閱讀更多關於其他中介軟體的內容。
|
||||
|
||||
下一節你將會讀到如何使用中介軟體處理 <abbr title="Cross-Origin Resource Sharing - 跨來源資源共用">CORS</abbr>。
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
由於描述常常較長、跨越多行,你可以在函式的 <dfn title="用於文件的多行字串,作為函式內的第一個運算式(不賦值給任何變數)">文件字串(docstring)</dfn> 中宣告「路徑操作」的描述,**FastAPI** 會從那裡讀取。
|
||||
|
||||
你可以在 docstring 中書寫 <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a>,它會被正確解析並顯示(會考慮 docstring 的縮排)。
|
||||
你可以在 docstring 中書寫 [Markdown](https://en.wikipedia.org/wiki/Markdown),它會被正確解析並顯示(會考慮 docstring 的縮排)。
|
||||
|
||||
{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ FastAPI 在 0.95.0 版加入並開始推薦使用 `Annotated`。
|
|||
|
||||
如果你使用更舊的版本,嘗試使用 `Annotated` 會出錯。
|
||||
|
||||
請確保在使用 `Annotated` 前,先[升級 FastAPI 版本](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}到至少 0.95.1。
|
||||
請確保在使用 `Annotated` 前,先[升級 FastAPI 版本](../deployment/versions.md#upgrading-the-fastapi-versions)到至少 0.95.1。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ Python 不會對這個 `*` 做任何事,但它會知道後續的所有參數
|
|||
|
||||
## 小結 { #recap }
|
||||
|
||||
使用 `Query`、`Path`(以及你尚未看到的其他類別)時,你可以像在[查詢參數與字串驗證](query-params-str-validations.md){.internal-link target=_blank}中一樣,宣告中繼資料與字串驗證。
|
||||
使用 `Query`、`Path`(以及你尚未看到的其他類別)時,你可以像在[查詢參數與字串驗證](query-params-str-validations.md)中一樣,宣告中繼資料與字串驗證。
|
||||
|
||||
你也可以宣告數值驗證:
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
路徑參數 `item_id` 的值會作為引數 `item_id` 傳入你的函式。
|
||||
|
||||
所以,如果你執行這個範例並前往 <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>,你會看到這樣的回應:
|
||||
所以,如果你執行這個範例並前往 [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo),你會看到這樣的回應:
|
||||
|
||||
```JSON
|
||||
{"item_id":"foo"}
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
## 資料 <dfn title="也稱為:序列化、解析、封送">轉換</dfn> { #data-conversion }
|
||||
|
||||
如果你執行這個範例並在瀏覽器開啟 <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>,你會看到這樣的回應:
|
||||
如果你執行這個範例並在瀏覽器開啟 [http://127.0.0.1:8000/items/3](http://127.0.0.1:8000/items/3),你會看到這樣的回應:
|
||||
|
||||
```JSON
|
||||
{"item_id":3}
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
## 資料驗證 { #data-validation }
|
||||
|
||||
但如果你在瀏覽器前往 <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>,你會看到漂亮的 HTTP 錯誤:
|
||||
但如果你在瀏覽器前往 [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo),你會看到漂亮的 HTTP 錯誤:
|
||||
|
||||
```JSON
|
||||
{
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
因為路徑參數 `item_id` 的值是 `"foo"`,它不是 `int`。
|
||||
|
||||
同樣的錯誤也會在你提供 `float` 而不是 `int` 時出現,例如:<a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
|
||||
同樣的錯誤也會在你提供 `float` 而不是 `int` 時出現,例如:[http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
|
||||
|
||||
/// check
|
||||
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
## 文件 { #documentation }
|
||||
|
||||
當你在瀏覽器開啟 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>,你會看到自動產生、可互動的 API 文件,例如:
|
||||
當你在瀏覽器開啟 [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs),你會看到自動產生、可互動的 API 文件,例如:
|
||||
|
||||
<img src="/img/tutorial/path-params/image01.png">
|
||||
|
||||
|
|
@ -92,9 +92,9 @@
|
|||
|
||||
## 基於標準的優勢與替代文件 { #standards-based-benefits-alternative-documentation }
|
||||
|
||||
而且因為產生的 schema 來自 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a> 標準,有很多相容的工具可用。
|
||||
而且因為產生的 schema 來自 [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md) 標準,有很多相容的工具可用。
|
||||
|
||||
因此,**FastAPI** 本身也提供另一種 API 文件(使用 ReDoc),你可以在 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> 存取:
|
||||
因此,**FastAPI** 本身也提供另一種 API 文件(使用 ReDoc),你可以在 [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) 存取:
|
||||
|
||||
<img src="/img/tutorial/path-params/image02.png">
|
||||
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
|
||||
## Pydantic { #pydantic }
|
||||
|
||||
所有資料驗證都由 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> 在底層處理,因此你能直接受惠。而且你可以放心使用。
|
||||
所有資料驗證都由 [Pydantic](https://docs.pydantic.dev/) 在底層處理,因此你能直接受惠。而且你可以放心使用。
|
||||
|
||||
你可以用相同的型別宣告搭配 `str`、`float`、`bool` 與許多更複雜的資料型別。
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ FastAPI 自 0.95.0 版起加入並開始推薦使用 `Annotated`。
|
|||
|
||||
如果你的版本較舊,嘗試使用 `Annotated` 會出錯。
|
||||
|
||||
請先至少 [升級 FastAPI 版本](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} 到 0.95.1 再使用 `Annotated`。
|
||||
請先至少 [升級 FastAPI 版本](../deployment/versions.md#upgrading-the-fastapi-versions) 到 0.95.1 再使用 `Annotated`。
|
||||
|
||||
///
|
||||
|
||||
## 在 `q` 參數的型別中使用 `Annotated` { #use-annotated-in-the-type-for-the-q-parameter }
|
||||
|
||||
還記得先前在 [Python 型別介紹](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank} 提到可以用 `Annotated` 為參數加入中繼資料嗎?
|
||||
還記得先前在 [Python 型別介紹](../python-types.md#type-hints-with-metadata-annotations) 提到可以用 `Annotated` 為參數加入中繼資料嗎?
|
||||
|
||||
現在就用在 FastAPI 上吧。🚀
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ q: str = Query(default="rick")
|
|||
|
||||
若不使用 `Annotated`、改用「(舊式)預設值」寫法,你在沒有 FastAPI 的「其他地方」呼叫該函式時,就得「記得」傳入正確參數,否則值會和預期不同(例如會得到 `QueryInfo` 或類似的東西,而不是 `str`)。你的編輯器不會提示,Python 執行該函式時也不會抱怨,只有在內部操作失敗時才會出錯。
|
||||
|
||||
因為 `Annotated` 可以有多個中繼資料註解,你甚至可以用同一個函式配合其他工具,例如 <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a>。🚀
|
||||
因為 `Annotated` 可以有多個中繼資料註解,你甚至可以用同一個函式配合其他工具,例如 [Typer](https://typer.tiangolo.com/)。🚀
|
||||
|
||||
## 加入更多驗證 { #add-more-validations }
|
||||
|
||||
|
|
@ -369,11 +369,11 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
|
|||
|
||||
這種情況下,你可以使用「自訂驗證函式」,它會在一般驗證之後套用(例如先確認值是 `str` 之後)。
|
||||
|
||||
你可以在 `Annotated` 中使用 <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">Pydantic 的 `AfterValidator`</a> 來達成。
|
||||
你可以在 `Annotated` 中使用 [Pydantic 的 `AfterValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) 來達成。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
Pydantic 也有 <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> 等等。🤓
|
||||
Pydantic 也有 [`BeforeValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator) 等等。🤓
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,6 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
|||
|
||||
/// tip | 提示
|
||||
|
||||
你也可以像在[路徑參數](path-params.md#predefined-values){.internal-link target=_blank}中一樣使用 `Enum`。
|
||||
你也可以像在[路徑參數](path-params.md#predefined-values)中一樣使用 `Enum`。
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
/// info
|
||||
|
||||
若要接收上傳的檔案,請先安裝 <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>。
|
||||
若要接收上傳的檔案,請先安裝 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},然後安裝,例如:
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md),然後安裝,例如:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
|
|
@ -63,8 +63,8 @@ $ pip install python-multipart
|
|||
* 檔案在記憶體中保存到某個大小上限,超過上限後會存到磁碟。
|
||||
* 因此適合處理大型檔案(例如圖片、影片、大型二進位檔等),而不會耗盡記憶體。
|
||||
* 你可以取得上傳檔案的中繼資料。
|
||||
* 它提供一個<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">類檔案</a>的 `async` 介面。
|
||||
* 它會提供實際的 Python <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> 物件,你可以直接傳給需要類檔案物件的其他函式或函式庫。
|
||||
* 它提供一個[file-like](https://docs.python.org/3/glossary.html#term-file-like-object) 的 `async` 介面。
|
||||
* 它會提供實際的 Python [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) 物件,你可以直接傳給需要類檔案物件的其他函式或函式庫。
|
||||
|
||||
### `UploadFile` { #uploadfile }
|
||||
|
||||
|
|
@ -72,13 +72,13 @@ $ pip install python-multipart
|
|||
|
||||
* `filename`:一個 `str`,為上傳的原始檔名(例如 `myimage.jpg`)。
|
||||
* `content_type`:一個 `str`,為內容類型(MIME type / media type)(例如 `image/jpeg`)。
|
||||
* `file`:一個 <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a>(<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">類檔案</a>物件)。這是真正的 Python 檔案物件,你可以直接傳給期待「類檔案」物件的其他函式或函式庫。
|
||||
* `file`:一個 [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile)(一個[file-like](https://docs.python.org/3/glossary.html#term-file-like-object) 物件)。這是真正的 Python 檔案物件,你可以直接傳給期待「類檔案」物件的其他函式或函式庫。
|
||||
|
||||
`UploadFile` 有以下 `async` 方法。它們底層會呼叫對應的檔案方法(使用內部的 `SpooledTemporaryFile`)。
|
||||
|
||||
* `write(data)`:將 `data`(`str` 或 `bytes`)寫入檔案。
|
||||
* `read(size)`:讀取檔案的 `size`(`int`)個位元組/字元。
|
||||
* `seek(offset)`:移動到檔案中的位元組位置 `offset`(`int`)。
|
||||
* `write(data)`:將 `data` (`str` 或 `bytes`) 寫入檔案。
|
||||
* `read(size)`:讀取檔案的 `size` (`int`) 個位元組/字元。
|
||||
* `seek(offset)`:移動到檔案中的位元組位置 `offset` (`int`)。
|
||||
* 例如,`await myfile.seek(0)` 會移到檔案開頭。
|
||||
* 當你已經執行過 `await myfile.read()`,之後需要再次讀取內容時特別有用。
|
||||
* `close()`:關閉檔案。
|
||||
|
|
@ -121,7 +121,7 @@ HTML 表單(`<form></form>`)送到伺服器的資料通常使用一種「特
|
|||
|
||||
但當表單包含檔案時,會使用 `multipart/form-data` 編碼。若你使用 `File`,**FastAPI** 會知道要從請求本文的正確部分取得檔案。
|
||||
|
||||
若想進一步了解這些編碼與表單欄位,請參考 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla 開發者網路">MDN</abbr> Web Docs 的 <code>POST</code></a>。
|
||||
若想進一步了解這些編碼與表單欄位,請參考 [<abbr title="Mozilla Developer Network - Mozilla 開發者網路">MDN</abbr> web docs 的 `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
/// info | 說明
|
||||
|
||||
要使用表單,首先安裝 <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>。
|
||||
要使用表單,首先安裝 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
請先建立[虛擬環境](../virtual-environments.md){.internal-link target=_blank}、啟用後再安裝,例如:
|
||||
請先建立[虛擬環境](../virtual-environments.md)、啟用後再安裝,例如:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
/// info
|
||||
|
||||
要接收上傳的檔案與/或表單資料,請先安裝 <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>。
|
||||
要接收上傳的檔案與/或表單資料,請先安裝 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
請先建立並啟用一個 [虛擬環境](../virtual-environments.md){.internal-link target=_blank},然後再安裝,例如:
|
||||
請先建立並啟用一個 [虛擬環境](../virtual-environments.md),然後再安裝,例如:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
/// info
|
||||
|
||||
要使用表單,請先安裝 <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>。
|
||||
要使用表單,請先安裝 [`python-multipart`](https://github.com/Kludex/python-multipart)。
|
||||
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},然後再安裝,例如:
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md),然後再安裝,例如:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
|
|
@ -56,7 +56,7 @@ HTML 表單(`<form></form>`)向伺服器傳送資料時,通常會使用一
|
|||
|
||||
但當表單包含檔案時,會使用 `multipart/form-data`。你會在下一章閱讀如何處理檔案。
|
||||
|
||||
若想進一步了解這些編碼與表單欄位,請參考 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla 開發者網路">MDN</abbr> 的 <code>POST</code> 網頁文件</a>。
|
||||
若想進一步了解這些編碼與表單欄位,請參考 [<abbr title="Mozilla Developer Network - Mozilla 開發者網路">MDN</abbr> web docs 的 `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ FastAPI 會使用這個回傳型別來:
|
|||
* 在 OpenAPI 的「路徑操作」中為回應新增 JSON Schema。
|
||||
* 這會被自動文件使用。
|
||||
* 也會被自動用戶端程式碼產生工具使用。
|
||||
* 使用 Pydantic 將回傳資料**序列化**為 JSON,而 Pydantic 是用 **Rust** 撰寫的,因此會 **更快很多**。
|
||||
|
||||
但更重要的是:
|
||||
|
||||
|
|
@ -73,9 +74,9 @@ FastAPI 會使用這個 `response_model` 來做所有的資料文件、驗證等
|
|||
|
||||
/// info | 說明
|
||||
|
||||
要使用 `EmailStr`,請先安裝 <a href="https://github.com/JoshData/python-email-validator" class="external-link" target="_blank">`email-validator`</a>。
|
||||
要使用 `EmailStr`,請先安裝 [`email-validator`](https://github.com/JoshData/python-email-validator)。
|
||||
|
||||
請先建立一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank}、啟用它,然後安裝,例如:
|
||||
請先建立一個[虛擬環境](../virtual-environments.md)、啟用它,然後安裝,例如:
|
||||
|
||||
```console
|
||||
$ pip install email-validator
|
||||
|
|
@ -181,7 +182,7 @@ FastAPI 在內部會搭配 Pydantic 做一些事情,來確保不會把類別
|
|||
|
||||
### 直接回傳 Response { #return-a-response-directly }
|
||||
|
||||
最常見的情況是[直接回傳 Response(在進階文件中稍後會解釋)](../advanced/response-directly.md){.internal-link target=_blank}。
|
||||
最常見的情況是[直接回傳 Response(在進階文件中稍後會解釋)](../advanced/response-directly.md)。
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
|
||||
|
||||
|
|
@ -257,7 +258,7 @@ FastAPI 在內部會搭配 Pydantic 做一些事情,來確保不會把類別
|
|||
* `response_model_exclude_defaults=True`
|
||||
* `response_model_exclude_none=True`
|
||||
|
||||
如 <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">Pydantic 文件</a>中對 `exclude_defaults` 與 `exclude_none` 的說明。
|
||||
如 [Pydantic 文件](https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict)中對 `exclude_defaults` 與 `exclude_none` 的說明。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
/// info | 資訊
|
||||
|
||||
`status_code` 也可以接收一個 `IntEnum`,例如 Python 的 <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a>。
|
||||
`status_code` 也可以接收一個 `IntEnum`,例如 Python 的 [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ FastAPI 知道這點,並會產生聲明「無回應本文」的 OpenAPI 文件
|
|||
|
||||
/// tip | 提示
|
||||
|
||||
想深入瞭解各狀態碼與其用途,請參考 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla 開發者網路">MDN</abbr> 關於 HTTP 狀態碼的文件</a>。
|
||||
想深入瞭解各狀態碼與其用途,請參考 [<abbr title="Mozilla Developer Network - Mozilla 開發者網路">MDN</abbr> 關於 HTTP 狀態碼的文件](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -98,4 +98,4 @@ FastAPI 知道這點,並會產生聲明「無回應本文」的 OpenAPI 文件
|
|||
|
||||
## 變更預設值 { #changing-the-default }
|
||||
|
||||
稍後在 [進階使用者指南](../advanced/response-change-status-code.md){.internal-link target=_blank} 中,你會看到如何回傳一個不同於此處所宣告預設值的狀態碼。
|
||||
稍後在 [進階使用者指南](../advanced/response-change-status-code.md) 中,你會看到如何回傳一個不同於此處所宣告預設值的狀態碼。
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
這些額外資訊會原封不動加入該模型輸出的 JSON Schema,並且會用在 API 文件裡。
|
||||
|
||||
你可以使用屬性 `model_config`(接收一個 `dict`),詳見 <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic 文件:Configuration</a>。
|
||||
你可以使用屬性 `model_config`(接收一個 `dict`),詳見 [Pydantic 文件:Configuration](https://docs.pydantic.dev/latest/api/config/)。
|
||||
|
||||
你可以將 `"json_schema_extra"` 設為一個 `dict`,其中包含你想在產生的 JSON Schema 中出現的任何額外資料,包括 `examples`。
|
||||
|
||||
|
|
@ -145,12 +145,12 @@ OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)新增了對 `examples` 的支援
|
|||
|
||||
OpenAPI 也在規範的其他部分新增了 `example` 與 `examples` 欄位:
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object" class="external-link" target="_blank">`Parameter Object`(規範)</a>,對應到 FastAPI 的:
|
||||
* [`Parameter Object`(規範)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object),對應到 FastAPI 的:
|
||||
* `Path()`
|
||||
* `Query()`
|
||||
* `Header()`
|
||||
* `Cookie()`
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object" class="external-link" target="_blank">`Request Body Object` 中的 `content` 欄位裡的 `Media Type Object`(規範)</a>,對應到 FastAPI 的:
|
||||
* [`Request Body Object` 中的 `content` 欄位裡的 `Media Type Object`(規範)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object),對應到 FastAPI 的:
|
||||
* `Body()`
|
||||
* `File()`
|
||||
* `Form()`
|
||||
|
|
@ -163,7 +163,7 @@ OpenAPI 也在規範的其他部分新增了 `example` 與 `examples` 欄位:
|
|||
|
||||
### JSON Schema 的 `examples` 欄位 { #json-schemas-examples-field }
|
||||
|
||||
後來 JSON Schema 在新版本規範中新增了 <a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a> 欄位。
|
||||
後來 JSON Schema 在新版本規範中新增了 [`examples`](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5) 欄位。
|
||||
|
||||
接著新的 OpenAPI 3.1.0 以最新版本(JSON Schema 2020-12)為基礎,該版本就包含這個新的 `examples` 欄位。
|
||||
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@
|
|||
|
||||
/// info
|
||||
|
||||
當你使用 `pip install "fastapi[standard]"` 指令安裝時,<a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> 套件會隨 FastAPI 自動安裝。
|
||||
當你使用 `pip install "fastapi[standard]"` 指令安裝時,[`python-multipart`](https://github.com/Kludex/python-multipart) 套件會隨 FastAPI 自動安裝。
|
||||
|
||||
不過若只執行 `pip install fastapi`,預設不會包含 `python-multipart`。
|
||||
|
||||
若要手動安裝,請先建立並啟用一個[虛擬環境](../../virtual-environments.md){.internal-link target=_blank},接著執行:
|
||||
若要手動安裝,請先建立並啟用一個[虛擬環境](../../virtual-environments.md),接著執行:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
|
|
@ -45,7 +45,7 @@ $ pip install python-multipart
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
|
@ -54,7 +54,7 @@ $ fastapi dev main.py
|
|||
|
||||
## 檢查 { #check-it }
|
||||
|
||||
開啟互動式文件:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
|
||||
開啟互動式文件:[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
你會看到類似這樣:
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ FastAPI 提供多層抽象的工具來實作這些安全機制。
|
|||
|
||||
由於使用了相對 URL,若你的 API 位於 `https://example.com/`,那它會指向 `https://example.com/token`;但若你的 API 位於 `https://example.com/api/v1/`,那它會指向 `https://example.com/api/v1/token`。
|
||||
|
||||
使用相對 URL 很重要,能確保你的應用在像是[在 Proxy 後方](../../advanced/behind-a-proxy.md){.internal-link target=_blank}這類進階情境中仍能正常運作。
|
||||
使用相對 URL 很重要,能確保你的應用在像是[在 Proxy 後方](../../advanced/behind-a-proxy.md)這類進階情境中仍能正常運作。
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
|
|||
|
||||
一週後,權杖會過期,使用者就不再被授權,需要再次登入以取得新的權杖。而如果使用者(或第三方)試圖修改權杖來改變有效期,你也能發現,因為簽名不會相符。
|
||||
|
||||
如果你想玩玩看 JWT 權杖並了解其運作,請參考 <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a>。
|
||||
如果你想玩玩看 JWT 權杖並了解其運作,請參考 [https://jwt.io](https://jwt.io/)。
|
||||
|
||||
## 安裝 `PyJWT` { #install-pyjwt }
|
||||
|
||||
我們需要安裝 `PyJWT` 才能在 Python 中產生與驗證 JWT 權杖。
|
||||
|
||||
請先建立並啟用一個[虛擬環境](../../virtual-environments.md){.internal-link target=_blank},然後安裝 `pyjwt`:
|
||||
請先建立並啟用一個[虛擬環境](../../virtual-environments.md),然後安裝 `pyjwt`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ $ pip install pyjwt
|
|||
|
||||
如果你打算使用像 RSA 或 ECDSA 這類的數位簽章演算法,應該安裝帶有加密函式庫相依的 `pyjwt[crypto]`。
|
||||
|
||||
更多內容可參考 <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT 安裝文件</a>。
|
||||
更多內容可參考 [PyJWT 安裝文件](https://pyjwt.readthedocs.io/en/latest/installation.html)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ pwdlib 是一個很棒的 Python 套件,用來處理密碼雜湊。
|
|||
|
||||
建議使用的演算法是「Argon2」。
|
||||
|
||||
請先建立並啟用一個[虛擬環境](../../virtual-environments.md){.internal-link target=_blank},然後以 Argon2 支援安裝 pwdlib:
|
||||
請先建立並啟用一個[虛擬環境](../../virtual-environments.md),然後以 Argon2 支援安裝 pwdlib:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ JWT 除了用來識別使用者並允許他直接對你的 API 執行操作外
|
|||
|
||||
## 試試看 { #check-it }
|
||||
|
||||
啟動伺服器並前往文件頁:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
|
||||
啟動伺服器並前往文件頁:[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
你會看到這樣的介面:
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ UserInDB(
|
|||
|
||||
/// info
|
||||
|
||||
想更完整地了解 `**user_dict`,請回到[**額外模型** 的文件](../extra-models.md#about-user-in-dict){.internal-link target=_blank}。
|
||||
想更完整地了解 `**user_dict`,請回到[**額外模型** 的文件](../extra-models.md#about-user-in-dict)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ UserInDB(
|
|||
|
||||
## 實際操作看看 { #see-it-in-action }
|
||||
|
||||
開啟互動式文件:<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
|
||||
開啟互動式文件:[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)。
|
||||
|
||||
### 驗證身分 { #authenticate }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
FastAPI 不強制你使用 SQL(關聯式)資料庫。你可以使用任何你想要的資料庫。
|
||||
|
||||
這裡我們會用 <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel</a> 作為範例。
|
||||
這裡我們會用 [SQLModel](https://sqlmodel.tiangolo.com/) 作為範例。
|
||||
|
||||
SQLModel 建立在 <a href="https://www.sqlalchemy.org/" class="external-link" target="_blank">SQLAlchemy</a> 與 Pydantic 之上。它由 FastAPI 的作者開發,非常適合需要使用 SQL 資料庫的 FastAPI 應用。
|
||||
SQLModel 建立在 [SQLAlchemy](https://www.sqlalchemy.org/) 與 Pydantic 之上。它由 FastAPI 的作者開發,非常適合需要使用 SQL 資料庫的 FastAPI 應用。
|
||||
|
||||
/// tip | 提示
|
||||
|
||||
|
|
@ -26,15 +26,15 @@ SQLModel 建立在 <a href="https://www.sqlalchemy.org/" class="external-link" t
|
|||
|
||||
/// tip | 提示
|
||||
|
||||
有一個包含 FastAPI 與 PostgreSQL 的官方專案腳手架,還有前端與更多工具:<a href="https://github.com/fastapi/full-stack-fastapi-template" class="external-link" target="_blank">https://github.com/fastapi/full-stack-fastapi-template</a>
|
||||
有一個包含 FastAPI 與 PostgreSQL 的官方專案腳手架,還有前端與更多工具:[https://github.com/fastapi/full-stack-fastapi-template](https://github.com/fastapi/full-stack-fastapi-template)
|
||||
|
||||
///
|
||||
|
||||
這是一份非常簡短的教學,如果你想更全面學習資料庫、SQL,或更進階的功能,請參考 <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel 文件</a>。
|
||||
這是一份非常簡短的教學,如果你想更全面學習資料庫、SQL,或更進階的功能,請參考 [SQLModel 文件](https://sqlmodel.tiangolo.com/)。
|
||||
|
||||
## 安裝 `SQLModel` { #install-sqlmodel }
|
||||
|
||||
首先,請先建立你的[虛擬環境](../virtual-environments.md){.internal-link target=_blank}、啟用它,然後安裝 `sqlmodel`:
|
||||
首先,請先建立你的[虛擬環境](../virtual-environments.md)、啟用它,然後安裝 `sqlmodel`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ $ pip install sqlmodel
|
|||
|
||||
* `Field(primary_key=True)` 告訴 SQLModel,`id` 是 SQL 資料庫中的「主鍵」。 (你可以在 SQLModel 文件中進一步了解 SQL 主鍵)
|
||||
|
||||
注意:我們在主鍵欄位使用 `int | None`,這樣在 Python 程式碼中我們可以「在沒有 `id` 的情況下建立物件」(`id=None`),假設資料庫在儲存時會「自動產生」。SQLModel 瞭解資料庫會提供 `id`,並且在資料庫綱要中「將該欄位定義為非空的 `INTEGER`」。詳情請見 <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">SQLModel 文件:主鍵</a>。
|
||||
注意:我們在主鍵欄位使用 `int | None`,這樣在 Python 程式碼中我們可以「在沒有 `id` 的情況下建立物件」(`id=None`),假設資料庫在儲存時會「自動產生」。SQLModel 瞭解資料庫會提供 `id`,並且在資料庫綱要中「將該欄位定義為非空的 `INTEGER`」。詳情請見 [SQLModel 文件:主鍵](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id)。
|
||||
|
||||
* `Field(index=True)` 告訴 SQLModel 應為此欄位建立「SQL 索引」,以便在用此欄位過濾讀取資料時更快查詢。
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ SQLModel 的 `engine`(底層實際上是 SQLAlchemy 的 `engine`)是用來
|
|||
|
||||
/// tip | 提示
|
||||
|
||||
SQLModel 之後會提供包裝 Alembic 的遷移工具,但目前你可以直接使用 <a href="https://alembic.sqlalchemy.org/en/latest/" class="external-link" target="_blank">Alembic</a>。
|
||||
SQLModel 之後會提供包裝 Alembic 的遷移工具,但目前你可以直接使用 [Alembic](https://alembic.sqlalchemy.org/en/latest/)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ SQLModel 之後會提供包裝 Alembic 的遷移工具,但目前你可以直
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
|
@ -337,7 +337,7 @@ $ fastapi dev main.py
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
|
@ -352,6 +352,6 @@ $ fastapi dev main.py
|
|||
|
||||
## 總結 { #recap }
|
||||
|
||||
你可以使用 <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel</a> 與 SQL 資料庫互動,並用「資料模型」與「資料表模型」讓程式碼更簡潔。
|
||||
你可以使用 [SQLModel](https://sqlmodel.tiangolo.com/) 與 SQL 資料庫互動,並用「資料模型」與「資料表模型」讓程式碼更簡潔。
|
||||
|
||||
你可以在 SQLModel 文件學到更多內容,這裡還有一份更長的 <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">使用 SQLModel 與 FastAPI 的教學</a>。🚀
|
||||
你可以在 SQLModel 文件學到更多內容,這裡還有一份更長的 [使用 SQLModel 與 FastAPI 的教學](https://sqlmodel.tiangolo.com/tutorial/fastapi/)。🚀
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
這與使用 `APIRouter` 不同,因為被掛載的應用是完全獨立的。主應用的 OpenAPI 與文件不會包含掛載應用的任何內容,等等。
|
||||
|
||||
你可以在[進階使用者指南](../advanced/index.md){.internal-link target=_blank}中閱讀更多相關內容。
|
||||
你可以在[進階使用者指南](../advanced/index.md)中閱讀更多相關內容。
|
||||
|
||||
## 細節 { #details }
|
||||
|
||||
|
|
@ -37,4 +37,4 @@
|
|||
|
||||
## 更多資訊 { #more-info }
|
||||
|
||||
如需更多細節與選項,請參考 <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Starlette 關於靜態檔案的文件</a>。
|
||||
如需更多細節與選項,請參考 [Starlette 關於靜態檔案的文件](https://www.starlette.dev/staticfiles/)。
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
# 測試 { #testing }
|
||||
|
||||
多虧了 <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a>,測試 **FastAPI** 應用既簡單又好用。
|
||||
多虧了 [Starlette](https://www.starlette.dev/testclient/),測試 **FastAPI** 應用既簡單又好用。
|
||||
|
||||
它是基於 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> 打造,而 HTTPX 的設計又參考了 Requests,所以用起來非常熟悉、直覺。
|
||||
它是基於 [HTTPX](https://www.python-httpx.org) 打造,而 HTTPX 的設計又參考了 Requests,所以用起來非常熟悉、直覺。
|
||||
|
||||
借助它,你可以直接用 <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a> 來測試 **FastAPI**。
|
||||
借助它,你可以直接用 [pytest](https://docs.pytest.org/) 來測試 **FastAPI**。
|
||||
|
||||
## 使用 `TestClient` { #using-testclient }
|
||||
|
||||
/// info
|
||||
|
||||
要使用 `TestClient`,請先安裝 <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a>。
|
||||
要使用 `TestClient`,請先安裝 [`httpx`](https://www.python-httpx.org)。
|
||||
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},然後安裝,例如:
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md),然後安裝,例如:
|
||||
|
||||
```console
|
||||
$ pip install httpx
|
||||
|
|
@ -52,7 +52,7 @@ $ pip install httpx
|
|||
|
||||
/// tip
|
||||
|
||||
如果你想在測試中呼叫其他 `async` 函式,而不只是對 FastAPI 應用發送請求(例如非同步的資料庫函式),請參考進階教學中的[非同步測試](../advanced/async-tests.md){.internal-link target=_blank}。
|
||||
如果你想在測試中呼叫其他 `async` 函式,而不只是對 FastAPI 應用發送請求(例如非同步的資料庫函式),請參考進階教學中的[非同步測試](../advanced/async-tests.md)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ $ pip install httpx
|
|||
|
||||
### **FastAPI** 應用檔案 { #fastapi-app-file }
|
||||
|
||||
假設你的檔案結構如[更大型的應用](bigger-applications.md){.internal-link target=_blank}所述:
|
||||
假設你的檔案結構如[更大型的應用](bigger-applications.md)所述:
|
||||
|
||||
```
|
||||
.
|
||||
|
|
@ -142,13 +142,13 @@ $ pip install httpx
|
|||
* 要傳遞標頭(headers),在 `headers` 參數中放一個 `dict`。
|
||||
* 對於 Cookie(cookies),在 `cookies` 參數中放一個 `dict`。
|
||||
|
||||
關於如何把資料傳給後端(使用 `httpx` 或 `TestClient`),更多資訊請參考 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX 文件</a>。
|
||||
關於如何把資料傳給後端(使用 `httpx` 或 `TestClient`),更多資訊請參考 [HTTPX 文件](https://www.python-httpx.org)。
|
||||
|
||||
/// info
|
||||
|
||||
請注意,`TestClient` 接收的是可轉為 JSON 的資料,而不是 Pydantic models。
|
||||
|
||||
如果你的測試裡有一個 Pydantic model,並想在測試時把它的資料送給應用,你可以使用[JSON 相容編碼器](encoder.md){.internal-link target=_blank}中介紹的 `jsonable_encoder`。
|
||||
如果你的測試裡有一個 Pydantic model,並想在測試時把它的資料送給應用,你可以使用[JSON 相容編碼器](encoder.md)中介紹的 `jsonable_encoder`。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ $ pip install httpx
|
|||
|
||||
接下來,你只需要安裝 `pytest`。
|
||||
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},然後安裝,例如:
|
||||
請先建立並啟用一個[虛擬環境](../virtual-environments.md),然後安裝,例如:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
這個頁面將教你如何使用**虛擬環境**以及了解它們的工作原理。
|
||||
|
||||
如果你計畫使用一個**可以為你管理一切的工具**(包括安裝 Python),試試 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>。
|
||||
如果你計畫使用一個**可以為你管理一切的工具**(包括安裝 Python),試試 [uv](https://github.com/astral-sh/uv)。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ $ python -m venv .venv
|
|||
|
||||
//// tab | `uv`
|
||||
|
||||
如果你安裝了 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>,你也可以使用它來建立一個虛擬環境。
|
||||
如果你安裝了 [`uv`](https://github.com/astral-sh/uv),你也可以使用它來建立一個虛擬環境。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ $ .venv\Scripts\Activate.ps1
|
|||
|
||||
//// tab | Windows Bash
|
||||
|
||||
或者,如果你在 Windows 上使用 Bash(例如 <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
|
||||
或者,如果你在 Windows 上使用 Bash(例如 [Git Bash](https://gitforwindows.org/)):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
|
|||
|
||||
/// tip
|
||||
|
||||
如果你使用 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> 來安裝內容,而不是 `pip`,那麼你就不需要升級 `pip`。😎
|
||||
如果你使用 [`uv`](https://github.com/astral-sh/uv) 來安裝內容,而不是 `pip`,那麼你就不需要升級 `pip`。😎
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -268,7 +268,7 @@ $ python -m ensurepip --upgrade
|
|||
|
||||
/// tip
|
||||
|
||||
如果你使用 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> 來建立虛擬環境,它會自動為你完成這個操作,你可以跳過這一步。😎
|
||||
如果你使用 [`uv`](https://github.com/astral-sh/uv) 來建立虛擬環境,它會自動為你完成這個操作,你可以跳過這一步。😎
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -340,7 +340,7 @@ $ pip install "fastapi[standard]"
|
|||
|
||||
//// tab | `uv`
|
||||
|
||||
如果你有 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
|
||||
如果你有 [`uv`](https://github.com/astral-sh/uv):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ $ pip install -r requirements.txt
|
|||
|
||||
//// tab | `uv`
|
||||
|
||||
如果你有 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
|
||||
如果你有 [`uv`](https://github.com/astral-sh/uv):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -416,8 +416,8 @@ Hello World
|
|||
|
||||
例如:
|
||||
|
||||
* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a>
|
||||
* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a>
|
||||
* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
|
||||
* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
|
||||
|
||||
/// tip
|
||||
|
||||
|
|
@ -455,7 +455,7 @@ $ deactivate
|
|||
|
||||
## 為什麼要使用虛擬環境 { #why-virtual-environments }
|
||||
|
||||
你需要安裝 <a href="https://www.python.org/" class="external-link" target="_blank">Python</a> 才能使用 FastAPI。
|
||||
你需要安裝 [Python](https://www.python.org/) 才能使用 FastAPI。
|
||||
|
||||
接下來,你需要**安裝** FastAPI 以及你想使用的其他**套件**。
|
||||
|
||||
|
|
@ -564,7 +564,7 @@ $ pip install "fastapi[standard]"
|
|||
|
||||
</div>
|
||||
|
||||
這會從 <a href="https://pypi.org/project/fastapi/" class="external-link" target="_blank">PyPI</a> 下載一個壓縮檔案,其中包含 FastAPI 的程式碼。
|
||||
這會從 [PyPI](https://pypi.org/project/fastapi/) 下載一個壓縮檔案,其中包含 FastAPI 的程式碼。
|
||||
|
||||
它還會**下載** FastAPI 所依賴的其他套件的檔案。
|
||||
|
||||
|
|
@ -627,7 +627,7 @@ $ .venv\Scripts\Activate.ps1
|
|||
|
||||
//// tab | Windows Bash
|
||||
|
||||
或者如果你在 Windows 上使用 Bash(例如 <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
|
||||
或者如果你在 Windows 上使用 Bash(例如 [Git Bash](https://gitforwindows.org/)):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -639,13 +639,13 @@ $ source .venv/Scripts/activate
|
|||
|
||||
////
|
||||
|
||||
這個命令會建立或修改一些[環境變數](environment-variables.md){.internal-link target=_blank},這些環境變數將在接下來的指令中可用。
|
||||
這個命令會建立或修改一些[環境變數](environment-variables.md),這些環境變數將在接下來的指令中可用。
|
||||
|
||||
其中之一是 `PATH` 變數。
|
||||
|
||||
/// tip
|
||||
|
||||
你可以在 [環境變數](environment-variables.md#path-environment-variable){.internal-link target=_blank} 部分了解更多關於 `PATH` 環境變數的內容。
|
||||
你可以在 [環境變數](environment-variables.md#path-environment-variable) 部分了解更多關於 `PATH` 環境變數的內容。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -819,7 +819,7 @@ Traceback (most recent call last):
|
|||
|
||||
</div>
|
||||
|
||||
但如果你停用虛擬環境並啟用 `prisoner-of-askaban` 的新虛擬環境,那麼當你執行 `python` 時,它會使用 `prisoner-of-askaban` 中虛擬環境的 Python。
|
||||
但如果你停用虛擬環境並啟用 `prisoner-of-azkaban` 的新虛擬環境,那麼當你執行 `python` 時,它會使用 `prisoner-of-azkaban` 中虛擬環境的 Python。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -846,7 +846,7 @@ I solemnly swear 🐺
|
|||
|
||||
有許多**替代方案**來管理虛擬環境、套件依賴(requirements)、專案。
|
||||
|
||||
當你準備好並想要使用一個工具來**管理整個專案**、套件依賴、虛擬環境等,建議你嘗試 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>。
|
||||
當你準備好並想要使用一個工具來**管理整個專案**、套件依賴、虛擬環境等,建議你嘗試 [uv](https://github.com/astral-sh/uv)。
|
||||
|
||||
`uv` 可以執行許多操作,它可以:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue