Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions docs/zh-hant/docs/advanced/json-base64-bytes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 使用 Base64 表示位元組的 JSON { #json-with-bytes-as-base64 }

如果你的應用需要收發 JSON 資料,但其中需要包含二進位資料,你可以將它以 base64 編碼。

## Base64 與檔案 { #base64-vs-files }

請先考慮是否能用 [請求檔案](../tutorial/request-files.md) 來上傳二進位資料,並用 [自訂回應 - FileResponse](./custom-response.md#fileresponse--fileresponse-) 來傳送二進位資料,而不是把它們編碼進 JSON。

JSON 只能包含 UTF-8 編碼的字串,因此無法直接包含原始位元組。

Base64 可以把二進位資料編碼成字串,但為此會使用比原始二進位資料更多的字元,因此通常比直接使用檔案來得沒那麼有效率。

只有在確實必須把二進位資料包含在 JSON 裡,且無法改用檔案時,才使用 base64。

## Pydantic `bytes` { #pydantic-bytes }

你可以宣告含有 `bytes` 欄位的 Pydantic 模型,並在模型設定中使用 `val_json_bytes`,使其在驗證輸入的 JSON 資料時使用 base64;在驗證過程中,它會將 base64 字串解碼為位元組。

{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}

如果你查看 `/docs`,會看到欄位 `data` 需要 base64 編碼的位元組:

<div class="screenshot">
<img src="/img/tutorial/json-base64-bytes/image01.png">
</div>

你可以發送如下的請求:

```json
{
"description": "Some data",
"data": "aGVsbG8="
}
```

/// tip

`aGVsbG8=` 是 `hello` 的 base64 編碼。

///

接著 Pydantic 會將該 base64 字串解碼,並在模型的 `data` 欄位中提供原始位元組。

你會收到類似以下的回應:

```json
{
"description": "Some data",
"content": "hello"
}
```

## Pydantic `bytes` 用於輸出資料 { #pydantic-bytes-for-output-data }

你也可以在模型設定中搭配 `ser_json_bytes` 使用 `bytes` 欄位來處理輸出資料;當產生 JSON 回應時,Pydantic 會將位元組以 base64 進行序列化。

{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}

## Pydantic `bytes` 用於輸入與輸出資料 { #pydantic-bytes-for-input-and-output-data }

當然,你也可以使用同一個以 base64 設定的模型,同時處理輸入(以 `val_json_bytes` 驗證)與輸出(以 `ser_json_bytes` 序列化)的 JSON 資料。

{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}
117 changes: 117 additions & 0 deletions docs/zh-hant/docs/advanced/stream-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# 串流資料 { #stream-data }

如果你要串流可用 JSON 結構化的資料,應該[串流 JSON Lines](../tutorial/stream-json-lines.md)。

但如果你想串流純二進位資料或字串,以下是做法。

/// info

已在 FastAPI 0.134.0 新增。

///

## 使用情境 { #use-cases }

當你想串流純字串時可以用這個機制,例如直接轉發來自 AI LLM 服務的輸出。

你也可以用它來串流大型二進位檔案,邊讀邊將每個區塊(chunk)串流出去,而不必一次把整個檔案載入記憶體。

你也可以用同樣方式串流視訊或音訊,甚至可以在處理的同時即時產生並傳送。

## 使用 `yield` 的 `StreamingResponse` { #a-streamingresponse-with-yield }

如果在你的路徑操作函式中宣告 `response_class=StreamingResponse`,就可以用 `yield` 逐一送出每個資料區塊。

{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}

FastAPI 會如實將每個資料區塊交給 `StreamingResponse`,不會嘗試將其轉換為 JSON 或其他格式。

### 非 async 路徑操作函式 { #non-async-path-operation-functions }

你也可以使用一般的 `def` 函式(沒有 `async`),並以相同方式使用 `yield`。

{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *}

### 不需要型別註解 { #no-annotation }

對於串流二進位資料,其實不需要宣告回傳型別註解。

由於 FastAPI 不會試圖用 Pydantic 將資料轉成 JSON,或以其他方式序列化,在這種情況下,型別註解僅供編輯器與工具使用,FastAPI 並不會用到它。

{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}

這也意味著使用 `StreamingResponse` 時,你擁有自由與責任,需依需求自行產生並編碼要傳送的位元組資料,與型別註解無關。 🤓

### 串流位元組 { #stream-bytes }

一個主要用例是串流 `bytes` 而非字串,當然可以這麼做。

{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *}

## 自訂 `PNGStreamingResponse` { #a-custom-pngstreamingresponse }

在上述範例中,雖然串流了資料位元組,但回應沒有 `Content-Type` 標頭,因此用戶端不知道接收到的是哪種資料型別。

你可以建立 `StreamingResponse` 的自訂子類別,將 `Content-Type` 標頭設定為你要串流的資料型別。

例如,你可以建立 `PNGStreamingResponse`,透過 `media_type` 屬性把 `Content-Type` 設為 `image/png`:

{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}

接著在路徑操作函式中用 `response_class=PNGStreamingResponse` 使用這個新類別:

{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}

### 模擬檔案 { #simulate-a-file }

此範例中我們用 `io.BytesIO` 模擬檔案。它是只存在於記憶體中的類檔案物件,但提供相同的介面。

例如,我們可以像讀取一般檔案一樣,透過迭代來消耗其內容。

{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *}

/// note | 技術細節

另外兩個變數 `image_base64` 與 `binary_image`,分別是先將影像以 Base64 編碼,接著轉成位元組,最後再傳給 `io.BytesIO`。

這只是為了讓範例能放在同一個檔案中,方便你直接複製並執行。 🥚

///

使用 `with` 區塊可確保在產生器函式(包含 `yield` 的函式)完成後關閉該類檔案物件,也就是在送完回應之後。

在這個範例中因為是存在記憶體的假檔案(`io.BytesIO`),影響不大;但若是實際檔案,務必在處理完成後關閉檔案。

### 檔案與 Async { #files-and-async }

多數情況下,類檔案物件預設不相容於 async/await。

例如,它們沒有 `await file.read()`,也不支援 `async for chunk in file`。

而且在許多情況下,讀取它們會是阻塞操作(可能阻塞事件迴圈),因為資料是從磁碟或網路讀取。

/// info

上面的範例其實是例外,因為 `io.BytesIO` 物件已在記憶體中,讀取不會阻塞任何東西。

但在多數情況下,讀取檔案或類檔案物件會造成阻塞。

///

為了避免阻塞事件迴圈,你可以將路徑操作函式宣告為一般的 `def`(而非 `async def`),這樣 FastAPI 會在 threadpool worker 上執行它,避免阻塞主事件迴圈。

{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}

/// tip

如果你需要在 async 函式內呼叫阻塞程式碼,或在阻塞函式中呼叫 async 函式,你可以使用 [Asyncer](https://asyncer.tiangolo.com),它是 FastAPI 的姊妹函式庫。

///

### `yield from` { #yield-from }

當你在迭代某個物件(如類檔案物件),並對每個項目使用 `yield` 時,也可以用 `yield from` 直接逐項產出,省略 `for` 迴圈。

這不是 FastAPI 特有的功能,而是 Python 語法;不過這招很實用。 😎

{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *}
88 changes: 88 additions & 0 deletions docs/zh-hant/docs/advanced/strict-content-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# 嚴格的 Content-Type 檢查 { #strict-content-type-checking }

預設情況下,FastAPI 會對 JSON 請求主體使用嚴格的 `Content-Type` 標頭檢查。也就是說,JSON 請求必須包含有效的 `Content-Type` 標頭(例如 `application/json`),請求主體(body)才能被解析為 JSON。

## CSRF 風險 { #csrf-risk }

這個預設行為在某個非常特定的情境下,能對一類跨站請求偽造(CSRF, Cross-Site Request Forgery)攻擊提供保護。

這類攻擊利用了瀏覽器在以下情況下允許腳本發送請求而不進行任何 CORS 預檢(preflight)檢查的事實:

- 沒有 `Content-Type` 標頭(例如以 `fetch()` 並使用 `Blob` 作為 body)
- 且沒有送出任何身分驗證憑證

這種攻擊主要與以下情境相關:

- 應用在本機(例如 `localhost`)或內部網路中執行
- 並且應用沒有任何身分驗證,假設同一個網路中的任何請求都可被信任

## 攻擊範例 { #example-attack }

假設你打造了一個在本機執行 AI 代理(AI agent)的方法。

它提供一個 API:

```
http://localhost:8000/v1/agents/multivac
```

同時也有一個前端:

```
http://localhost:8000
```

/// tip | 提示

請注意兩者的主機(host)相同。

///

接著你可以透過前端讓 AI 代理代你執行動作。

由於它在本機執行、而非公開的網際網路上,你決定不設定任何身分驗證,只信任對本機網路的存取。

然後你的某位使用者可能安裝並在本機執行它。

接著他可能打開一個惡意網站,例如:

```
https://evilhackers.example.com
```

該惡意網站會使用 `fetch()` 並以 `Blob` 作為 body,向本機的 API 發送請求:

```
http://localhost:8000/v1/agents/multivac
```

即使惡意網站與本機應用的主機不同,瀏覽器也不會觸發 CORS 預檢請求,因為:

- 它在未經任何身分驗證的情況下執行,不需要送出任何憑證。
- 由於缺少 `Content-Type` 標頭,瀏覽器認為它並未傳送 JSON。

接著,惡意網站就能讓本機的 AI 代理替使用者向前老闆發飆傳訊... 或做更糟的事。😅

## 公開的網際網路 { #open-internet }

如果你的應用部署在公開的網際網路上,你不會「信任網路」而允許任何人在未經身分驗證的情況下發送具權限的請求。

攻擊者可以直接執行腳本向你的 API 發送請求,無需透過瀏覽器互動,因此你多半已經對任何具權限的端點做了防護。

在這種情況下,這種攻擊/風險不適用於你。

此風險與攻擊主要與應用只在本機或內部網路上執行,且「僅依賴此為保護」的情境相關。

## 允許沒有 Content-Type 的請求 { #allowing-requests-without-content-type }

若你需要支援未送出 `Content-Type` 標頭的客戶端,可以將 `strict_content_type=False` 以停用嚴格檢查:

{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *}

啟用此設定後,缺少 `Content-Type` 標頭的請求會將其主體解析為 JSON,這與舊版 FastAPI 的行為相同。

/// info | 資訊

此行為與設定新增於 FastAPI 0.132.0。

///
23 changes: 23 additions & 0 deletions docs/zh-hant/docs/editor-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 編輯器支援 { #editor-support }

官方的 [FastAPI 擴充套件](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) 透過支援路徑操作(path operation)探索、導覽,以及 FastAPI Cloud 部署與即時日誌串流,強化你的 FastAPI 開發流程。

想了解更多關於此擴充套件的細節,請參考其 [GitHub 儲存庫](https://github.com/fastapi/fastapi-vscode) 中的 README。

## 安裝與設定 { #setup-and-installation }

**FastAPI 擴充套件** 同時提供給 [VS Code](https://code.visualstudio.com/) 與 [Cursor](https://www.cursor.com/)。你可以在各編輯器的擴充套件面板中直接安裝:搜尋「FastAPI」,並選擇由 **FastAPI Labs** 發佈的擴充套件。此擴充套件同樣可在瀏覽器版編輯器(如 [vscode.dev](https://vscode.dev) 與 [github.dev](https://github.dev))中使用。

### 應用程式探索 { #application-discovery }

預設情況下,擴充套件會自動在你的工作區中,掃描會實例化 `FastAPI()` 的檔案,以發現 FastAPI 應用程式。若自動偵測無法因應你的專案結構,你可以在 `pyproject.toml` 的 `[tool.fastapi]` 中,或在 VS Code 設定的 `fastapi.entryPoint` 中,使用模組標記法(例如 `myapp.main:app`)指定入口點。

## 功能 { #features }

- **Path Operation Explorer** - 顯示應用程式中所有 <dfn title="路由、端點">*路徑操作*</dfn> 的側邊欄樹狀檢視。點擊即可跳至任一路由或 router 定義。
- **Route Search** - 使用 <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>(macOS:<kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>)依路徑、方法或名稱進行搜尋。
- **CodeLens Navigation** - 在測試用 client 呼叫(例如 `client.get('/items')`)上方提供可點連結,一鍵跳至對應的路徑操作,讓你在測試與實作間快速切換。
- **Deploy to FastAPI Cloud** - 一鍵將你的應用程式部署到 [FastAPI Cloud](https://fastapicloud.com/)。
- **Stream Application Logs** - 從部署於 FastAPI Cloud 的應用程式即時串流日誌,並支援層級篩選與文字搜尋。

若你想熟悉此擴充套件的功能,可開啟命令面板(<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>;macOS:<kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>),選擇 "Welcome: Open walkthrough...",然後挑選 "Get started with FastAPI" walkthrough。
Loading
Loading