{"id":108,"date":"2026-06-14T09:51:58","date_gmt":"2026-06-14T01:51:58","guid":{"rendered":"https:\/\/www.52runoob.com\/?p=108"},"modified":"2026-06-14T09:51:58","modified_gmt":"2026-06-14T01:51:58","slug":"fastapi-%e6%95%99%e7%a8%8b","status":"publish","type":"post","link":"https:\/\/www.52runoob.com\/index.php\/2026\/06\/14\/fastapi-%e6%95%99%e7%a8%8b\/","title":{"rendered":"FastAPI \u6559\u7a0b"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\u8fd9\u662f\u4e00\u4efd\u9762\u5411\u73b0\u4ee3 Python \u5f00\u53d1\u8005\u7684 <strong>FastAPI \u6838\u5fc3\u6559\u7a0b<\/strong>\u3002FastAPI \u662f\u76ee\u524d Python \u751f\u6001\u4e2d\u6784\u5efa API \u6700\u5feb\u3001\u6700\u73b0\u4ee3\u7684\u6846\u67b6\uff0c\u4ee5\u5176<strong>\u81ea\u52a8\u6587\u6863\u751f\u6210<\/strong>\u3001<strong>\u7c7b\u578b\u63d0\u793a\u9a71\u52a8\u7684\u6570\u636e\u9a8c\u8bc1<\/strong>\u548c<strong>\u5f3a\u5927\u7684\u4f9d\u8d56\u6ce8\u5165\u7cfb\u7edf<\/strong>\u8457\u79f0\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u672c\u6559\u7a0b\u5c06\u4ece\u96f6\u5f00\u59cb\uff0c\u5e26\u4f60\u5feb\u901f\u638c\u63e1 FastAPI \u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5e76\u7ed9\u51fa\u7b26\u5408\u751f\u4ea7\u6807\u51c6\u7684\u5de5\u7a0b\u5316\u5b9e\u8df5\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udce6 \u4e00\u3001\u73af\u5883\u51c6\u5907\u4e0e\u5b89\u88c5<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>\u8981\u6c42<\/strong>\uff1aPython 3.9+\uff08\u63a8\u8350 3.10+\uff09<\/p>\n<\/blockquote>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\"># \u5b89\u88c5 FastAPI \u548c ASGI \u670d\u52a1\u5668 Uvicorn\npip install fastapi uvicorn[standard]\n\n# \u63a8\u8350\u540c\u65f6\u5b89\u88c5\u5f00\u53d1\u5de5\u5177\npip install pydantic[email] python-multipart httpx<\/code><\/pre><\/div><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\ude80 \u4e8c\u3001\u7b2c\u4e00\u4e2a API\uff1a3 \u5206\u949f\u8dd1\u8d77\u6765<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u521b\u5efa\u6587\u4ef6 <code>main.py<\/code>\uff1a<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><span>9<\/span><span>10<\/span><span>11<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">from fastapi import FastAPI\n\napp = FastAPI(title=&quot;\u6211\u7684\u7b2c\u4e00\u4e2a FastAPI \u5e94\u7528&quot;, version=&quot;1.0.0&quot;)\n\n@app.get(&quot;\/&quot;)\ndef read_root():\n    return {&quot;message&quot;: &quot;Hello FastAPI!&quot;}\n\n@app.get(&quot;\/items\/{item_id}&quot;)\ndef get_item(item_id: int, q: str | None = None):\n    return {&quot;item_id&quot;: item_id, &quot;query&quot;: q}<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u542f\u52a8\u670d\u52a1\uff1a<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">uvicorn main:app --reload<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83c\udf10 \u8bbf\u95ee\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>API \u6839\u8def\u5f84\uff1a<code>http:\/\/127.0.0.1:8000<\/code><\/li>\n\n\n\n<li><strong>\u4ea4\u4e92\u5f0f\u6587\u6863 (Swagger UI)<\/strong>\uff1a<code>http:\/\/127.0.0.1:8000\/docs<\/code> \u2b50<\/li>\n\n\n\n<li>ReDoc \u6587\u6863\uff1a<code>http:\/\/127.0.0.1:8000\/redoc<\/code><\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udca1 <code>--reload<\/code> \u4f1a\u5728\u4ee3\u7801\u4fee\u6539\u65f6\u81ea\u52a8\u91cd\u542f\u670d\u52a1\u5668\uff0c\u5f00\u53d1\u65f6\u5fc5\u52a0\u3002<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83e\uddf1 \u4e09\u3001\u6838\u5fc3\u6982\u5ff5\uff1a\u53c2\u6570\u3001\u8bf7\u6c42\u4f53\u4e0e\u54cd\u5e94\u6a21\u578b<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">1. \u8def\u5f84\u53c2\u6570 &amp; \u67e5\u8be2\u53c2\u6570<\/h4>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">@app.get(&quot;\/users\/{user_id}&quot;)\ndef get_user(user_id: int, include_posts: bool = False):\n    # user_id \u6765\u81ea\u8def\u5f84\uff0cinclude_posts \u6765\u81ea\u67e5\u8be2\u53c2\u6570 (?include_posts=true)\n    return {&quot;user_id&quot;: user_id, &quot;include_posts&quot;: include_posts}<\/code><\/pre><\/div><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">2. \u8bf7\u6c42\u4f53 (Request Body) \u4e0e Pydantic \u9a8c\u8bc1<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">FastAPI \u4f7f\u7528 <strong>Pydantic<\/strong> \u6a21\u578b\u81ea\u52a8\u89e3\u6790\u3001\u9a8c\u8bc1 JSON \u8bf7\u6c42\u4f53\u3002<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><span>9<\/span><span>10<\/span><span>11<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">from pydantic import BaseModel, Field, EmailStr\n\nclass UserCreate(BaseModel):\n    username: str = Field(..., min_length=3, max_length=50)\n    email: EmailStr\n    age: int = Field(..., ge=18, le=120)  # ge: &gt;=, le: &lt;=\n\n@app.post(&quot;\/users\/&quot;)\ndef create_user(user: UserCreate):\n    # \u5982\u679c\u8bf7\u6c42\u4f53\u4e0d\u7b26\u5408 UserCreate \u5b9a\u4e49\uff0cFastAPI \u4f1a\u81ea\u52a8\u8fd4\u56de 422 \u9519\u8bef\n    return {&quot;msg&quot;: f&quot;\u7528\u6237 {user.username} \u521b\u5efa\u6210\u529f&quot;, &quot;user&quot;: user.model_dump()}<\/code><\/pre><\/div><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">3. \u54cd\u5e94\u6a21\u578b (Response Model)<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u63a7\u5236 API \u8fd4\u56de\u7684\u6570\u636e\u7ed3\u6784\uff0c\u81ea\u52a8\u8fc7\u6ee4\u5185\u90e8\u5b57\u6bb5\uff08\u5982\u5bc6\u7801\uff09\uff0c\u5e76\u751f\u6210 OpenAPI \u54cd\u5e94 Schema\u3002<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><span>9<\/span><span>10<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">class UserOut(BaseModel):\n    id: int\n    username: str\n    email: EmailStr\n\n@app.post(&quot;\/users\/&quot;, response_model=UserOut)\ndef create_user_v2(user: UserCreate):\n    # \u6a21\u62df\u4fdd\u5b58\u5230\u6570\u636e\u5e93\u540e\u8fd4\u56de\n    return {&quot;id&quot;: 1, &quot;username&quot;: user.username, &quot;email&quot;: user.email, &quot;password&quot;: &quot;hashed&quot;}\n    # \u26a0\ufe0f \u6ce8\u610f\uff1apassword \u5b57\u6bb5\u4f1a\u88ab response_model \u81ea\u52a8\u8fc7\u6ee4\uff0c\u4e0d\u4f1a\u8fd4\u56de\u7ed9\u5ba2\u6237\u7aef<\/code><\/pre><\/div><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd17 \u56db\u3001\u4f9d\u8d56\u6ce8\u5165 (Dependency Injection)\uff1aFastAPI \u7684\u7075\u9b42<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Depends()<\/code> \u8ba9\u4ee3\u7801\u9ad8\u5ea6\u590d\u7528\u3001\u6613\u4e8e\u6d4b\u8bd5\u3002\u5e38\u7528\u4e8e\uff1a\u6570\u636e\u5e93\u8fde\u63a5\u3001\u5206\u9875\u53c2\u6570\u3001\u6743\u9650\u6821\u9a8c\u3001\u65e5\u5fd7\u8bb0\u5f55\u7b49\u3002<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><span>9<\/span><span>10<\/span><span>11<\/span><span>12<\/span><span>13<\/span><span>14<\/span><span>15<\/span><span>16<\/span><span>17<\/span><span>18<\/span><span>19<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">from fastapi import Depends, HTTPException, status\n\n# 1. \u5b9a\u4e49\u53ef\u590d\u7528\u7684\u4f9d\u8d56\u51fd\u6570\ndef pagination(skip: int = 0, limit: int = 100):\n    return {&quot;skip&quot;: skip, &quot;limit&quot;: limit}\n\ndef get_current_user(token: str = Depends(oauth2_scheme)):\n    if token != &quot;valid_token&quot;:\n        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=&quot;\u65e0\u6548\u4ee4\u724c&quot;)\n    return {&quot;username&quot;: &quot;admin&quot;}\n\n# 2. \u5728\u8def\u7531\u4e2d\u4f7f\u7528\n@app.get(&quot;\/items\/&quot;, dependencies=[Depends(pagination)])\ndef list_items(page: dict = Depends(pagination)):\n    return {&quot;items&quot;: [&quot;item1&quot;, &quot;item2&quot;], &quot;page_info&quot;: page}\n\n@app.get(&quot;\/me&quot;)\ndef read_me(current_user: dict = Depends(get_current_user)):\n    return current_user<\/code><\/pre><\/div><\/div>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udca1 \u4f9d\u8d56\u53ef\u4ee5\u5d4c\u5957\uff0cFastAPI \u4f1a\u81ea\u52a8\u89e3\u6790\u8c03\u7528\u987a\u5e8f\u3002\u652f\u6301\u540c\u6b65\u548c\u5f02\u6b65 (<code>async def<\/code>)\u3002<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc1 \u4e94\u3001\u5de5\u7a0b\u5316\u9879\u76ee\u7ed3\u6784\uff08\u751f\u4ea7\u63a8\u8350\uff09<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0d\u8981\u628a\u6240\u6709\u4ee3\u7801\u585e\u8fdb <code>main.py<\/code>\u3002\u63a8\u8350\u7ed3\u6784\uff1a<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><span>9<\/span><span>10<\/span><span>11<\/span><span>12<\/span><span>13<\/span><span>14<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">my_api\/\n\u251c\u2500\u2500 app\/\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u251c\u2500\u2500 main.py          # FastAPI \u5b9e\u4f8b\u3001\u8def\u7531\u6302\u8f7d\u3001\u751f\u547d\u5468\u671f\u4e8b\u4ef6\n\u2502   \u251c\u2500\u2500 config.py        # \u73af\u5883\u53d8\u91cf\u914d\u7f6e (pydantic-settings)\n\u2502   \u251c\u2500\u2500 dependencies.py  # \u5168\u5c40\u4f9d\u8d56 (DB Session, Auth \u7b49)\n\u2502   \u251c\u2500\u2500 models\/          # Pydantic Schemas (\u8bf7\u6c42\/\u54cd\u5e94\u6a21\u578b)\n\u2502   \u251c\u2500\u2500 routers\/         # \u4e1a\u52a1\u8def\u7531\u62c6\u5206\n\u2502   \u2502   \u251c\u2500\u2500 users.py\n\u2502   \u2502   \u2514\u2500\u2500 items.py\n\u2502   \u2514\u2500\u2500 services\/        # \u4e1a\u52a1\u903b\u8f91\u5c42 (\u4e0e\u8def\u7531\u89e3\u8026)\n\u251c\u2500\u2500 tests\/               # \u5355\u5143\u6d4b\u8bd5 &amp; \u96c6\u6210\u6d4b\u8bd5\n\u251c\u2500\u2500 .env                 # \u73af\u5883\u53d8\u91cf\n\u2514\u2500\u2500 pyproject.toml       # \u4f9d\u8d56\u7ba1\u7406 (\u63a8\u8350 uv\/poetry)<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><code>app\/main.py<\/code> \u793a\u4f8b<\/strong>\uff1a<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><span>9<\/span><span>10<\/span><span>11<\/span><span>12<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">from fastapi import FastAPI\nfrom app.routers import users, items\n\napp = FastAPI()\n\n# \u6302\u8f7d\u5b50\u8def\u7531\napp.include_router(users.router, prefix=&quot;\/users&quot;, tags=[&quot;\u7528\u6237\u7ba1\u7406&quot;])\napp.include_router(items.router, prefix=&quot;\/items&quot;, tags=[&quot;\u5546\u54c1\u7ba1\u7406&quot;])\n\n@app.get(&quot;\/health&quot;)\ndef health_check():\n    return {&quot;status&quot;: &quot;ok&quot;}<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u8def\u7531\u62c6\u5206\u793a\u4f8b <code>app\/routers\/users.py<\/code><\/strong>\uff1a<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">from fastapi import APIRouter, Depends\nfrom app.models.users import UserCreate, UserOut\n\nrouter = APIRouter()\n\n@router.post(&quot;\/&quot;, response_model=UserOut)\ndef create_user(user: UserCreate):\n    return {&quot;id&quot;: 1, **user.model_dump()}<\/code><\/pre><\/div><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83e\uddea \u516d\u3001\u6d4b\u8bd5\u4e0e\u90e8\u7f72<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">1. \u81ea\u52a8\u5316\u6d4b\u8bd5 (\u4f7f\u7528 <code>httpx<\/code> + <code>pytest<\/code>)<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">FastAPI \u5b98\u65b9\u63a8\u8350\u7528 <code>TestClient<\/code> \u8fdb\u884c\u96c6\u6210\u6d4b\u8bd5\uff1a<\/p>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><span>7<\/span><span>8<\/span><span>9<\/span><span>10<\/span><span>11<\/span><span>12<\/span><span>13<\/span><span>14<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\"># tests\/test_users.py\nfrom fastapi.testclient import TestClient\nfrom app.main import app\n\nclient = TestClient(app)\n\ndef test_create_user():\n    response = client.post(&quot;\/users\/&quot;, json={\n        &quot;username&quot;: &quot;testuser&quot;,\n        &quot;email&quot;: &quot;test@example.com&quot;,\n        &quot;age&quot;: 25\n    })\n    assert response.status_code == 200\n    assert response.json()[&quot;username&quot;] == &quot;testuser&quot;<\/code><\/pre><\/div><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">2. \u751f\u4ea7\u90e8\u7f72<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5f00\u53d1<\/strong>\uff1a<code>uvicorn main:app --reload<\/code><\/li>\n\n\n\n<li><strong>\u751f\u4ea7<\/strong>\uff1a\u4f7f\u7528 <code>Gunicorn<\/code> + <code>Uvicorn Workers<\/code> \u7ba1\u7406\u8fdb\u7a0b<\/li>\n<\/ul>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">  gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000<\/code><\/pre><\/div><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Docker \u793a\u4f8b<\/strong>\uff1a<\/li>\n<\/ul>\n\n\n\n<div class=\"chp-code-block chp-theme-github-dark chp-wrap-on\" data-chp-language=\"plaintext\" data-chp-line-start=\"1\" data-chp-highlight=\"\"><div class=\"chp-toolbar\"><div class=\"chp-toolbar-left\"><span class=\"chp-dots\"><span><\/span><span><\/span><span><\/span><\/span><span class=\"chp-language-label\">\u7eaf\u6587\u672c<\/span><\/div><div class=\"chp-toolbar-right\"><button type=\"button\" class=\"chp-copy-btn\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><svg class=\"chp-icon-copy\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"\/><\/svg><svg class=\"chp-icon-check\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" aria-hidden=\"true\" style=\"display:none;\"><path fill=\"currentColor\" d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"\/><\/svg><span class=\"chp-copy-text\">\u590d\u5236<\/span><\/button><\/div><\/div><div class=\"chp-code-wrapper\"><div class=\"chp-line-numbers\" aria-hidden=\"true\"><span>1<\/span><span>2<\/span><span>3<\/span><span>4<\/span><span>5<\/span><span>6<\/span><\/div><pre class=\"chp-pre\" style=\"font-size:14px;\"><code class=\"language-plaintext\">  FROM python:3.11-slim\n  WORKDIR \/app\n  COPY requirements.txt .\n  RUN pip install --no-cache-dir -r requirements.txt\n  COPY . .\n  CMD [&quot;uvicorn&quot;, &quot;app.main:app&quot;, &quot;--host&quot;, &quot;0.0.0.0&quot;, &quot;--port&quot;, &quot;8000&quot;]<\/code><\/pre><\/div><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\uddfa\ufe0f \u4e03\u3001\u8fdb\u9636\u5b66\u4e60\u8def\u7ebf<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u638c\u63e1\u57fa\u7840\u540e\uff0c\u5efa\u8bae\u6309\u4ee5\u4e0b\u987a\u5e8f\u6df1\u5165\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6570\u636e\u5e93\u96c6\u6210<\/strong>\uff1a<code>SQLAlchemy 2.0<\/code> + <code>Alembic<\/code> (\u8fc1\u79fb) \u6216\u76f4\u63a5\u4f7f\u7528 FastAPI \u4f5c\u8005\u63a8\u8350\u7684 <code>SQLModel<\/code><\/li>\n\n\n\n<li><strong>\u8ba4\u8bc1\u6388\u6743<\/strong>\uff1a<code>OAuth2PasswordBearer<\/code> + JWT \u5b9e\u73b0\u767b\u5f55\/\u5237\u65b0\u4ee4\u724c<\/li>\n\n\n\n<li><strong>\u540e\u53f0\u4efb\u52a1<\/strong>\uff1a<code>BackgroundTasks<\/code> \u6216\u63a5\u5165 <code>Celery<\/code>\/<code>ARQ<\/code><\/li>\n\n\n\n<li><strong>\u4e2d\u95f4\u4ef6 &amp; \u751f\u547d\u5468\u671f<\/strong>\uff1aCORS\u3001\u8bf7\u6c42\u8017\u65f6\u7edf\u8ba1\u3001\u5168\u5c40\u5f02\u5e38\u5904\u7406 (<code>@app.exception_handler<\/code>)<\/li>\n\n\n\n<li><strong>\u6027\u80fd\u4f18\u5316<\/strong>\uff1a\u5f02\u6b65\u6570\u636e\u5e93\u9a71\u52a8 (<code>asyncpg<\/code>, <code>aiosqlite<\/code>)\u3001\u8fde\u63a5\u6c60\u914d\u7f6e\u3001\u7f13\u5b58 (<code>Redis<\/code>)<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcda \u5b98\u65b9\u8d44\u6e90<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud83d\udcd8 \u5b98\u65b9\u6587\u6863\uff08\u6781\u5176\u4f18\u79c0\uff0c\u5fc5\u8bfb\uff09\uff1ahttps:\/\/fastapi.tiangolo.com\/zh\/<\/li>\n\n\n\n<li>\ud83d\udc19 GitHub \u6e90\u7801\u4e0e\u793a\u4f8b\uff1ahttps:\/\/github.com\/tiangolo\/fastapi<\/li>\n\n\n\n<li>\ud83d\udd0d Pydantic V2 \u6587\u6863\uff1ahttps:\/\/docs.pydantic.dev\/latest\/<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u5982\u679c\u4f60\u5728\u642d\u5efa\u8fc7\u7a0b\u4e2d\u9047\u5230\u5177\u4f53\u95ee\u9898\uff08\u4f8b\u5982\uff1a<strong>\u5982\u4f55\u8fde\u63a5 PostgreSQL<\/strong>\u3001<strong>\u5982\u4f55\u5b9e\u73b0 JWT \u767b\u5f55<\/strong>\u3001<strong>\u5982\u4f55\u5904\u7406\u6587\u4ef6\u4e0a\u4f20<\/strong>\uff09\uff0c\u544a\u8bc9\u6211\u4f60\u7684\u573a\u666f\uff0c\u6211\u53ef\u4ee5\u63d0\u4f9b\u5b8c\u6574\u53ef\u8fd0\u884c\u7684\u4ee3\u7801\u7247\u6bb5\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u8fd9\u662f\u4e00\u4efd\u9762\u5411\u73b0\u4ee3 Python \u5f00\u53d1\u8005\u7684 Fast&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":["post-108","post","type-post","status-publish","format-standard","hentry","category-fastapi-"],"_links":{"self":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/comments?post=108"}],"version-history":[{"count":1,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/108\/revisions"}],"predecessor-version":[{"id":109,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/108\/revisions\/109"}],"wp:attachment":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/media?parent=108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/categories?post=108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/tags?post=108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}