python的FastAPI 框架入门教程:从零构建完整 API 项目(含 Jinja2 模板引擎使用)

作为一名开发者,我相信你一定遇到过这样的场景:1.需要快速开发一个 API,但不想写一堆复杂的样板代码。2.文档和代码总是不同步,维护起来苦不堪言。3.性能要求很高,但又不想学习太复杂的异步编程。4.在 Python 中写 API,总感觉缺少类型安全保障。这些困扰,在我们刚开始接触 Web 开发时都经历过。直到我遇到了 FastAPI------一个现代、高性能的 Python Web 框架,它彻底改变了我对 API 开发的认知。

前言

fastapi,一个用于构建 API 的现代、快速(高性能)的web框架。基于 Python 3.6+ 的类型提示系统,自动生成交互式 API 文档,性能接近 Node.js 和 Go,学习曲线却非常平缓。更重要的是,它完美地解决了上述所有痛点。它出现的比较晚,2018年底才发布在github上。广泛应用于当前各种前后端分离的项目开发,测试运维自动化以及微服务的场景中。

在这篇教程中,我将带你从零开始,一步步构建一个完整的 FastAPI 项目,包含 API 接口开发和 HTML 页面渲染(使用 Jinja2 模板引擎)。通过这个项目,你将掌握 FastAPI 的核心用法,并理解为什么它是当前 Python API 开发的最佳选择之一。


一、FastAPI 核心优势

在开始代码实现之前,让我先分享一下 FastAPI 最吸引我的几个特性:

1. 极速性能

FastAPI 基于 Starlette(异步 Web 框架)和 Pydantic(数据验证库),性能可以与 Node.js 和 Go 并肩。官方测试显示,它的性能是 Flask 的 10-100 倍。

2. 自动文档生成

编写代码时,FastAPI 会自动根据类型提示生成交互式 API 文档。你不需要单独维护文档,代码就是文档------这完全解决了文档同步问题。

3. 类型安全

通过 Python 类型提示,FastAPI 自动验证请求和响应数据,减少了 40% 的人为错误。你再也不用写一堆 if 语句来验证用户输入了。

4. 异步支持

原生支持 async/await 语法,处理数据库操作、HTTP 请求等异步任务时非常简单,性能也更好。

5. 生产就绪

FastAPI 不是玩具框架------它已经在 Uber、Netflix、Microsoft 等大公司的生产环境中得到了验证。


二、环境准备

环境配置往往是新手学习新技术时的第一个障碍。我刚开始学 FastAPI 时,也踩了不少坑。下面是我总结的最简单、最可靠的配置方法。

2.1 Python 版本检查

首先,确保你的 Python 版本是 3.6 或更高。打开终端(Windows 用 CMD 或 PowerShell,Mac/Linux 用 Terminal),输入:

bash 复制代码
python --version
# 或
python3 --version

技巧提示:我强烈建议使用 Python 3.7+,因为 FastAPI 的一些高级特性(如数据类)在 3.7 中更完善。

2.2 创建虚拟环境

为什么需要虚拟环境?想象一下:你同时在做两个项目,一个用 FastAPI 0.68,另一个用 0.95。如果没有虚拟环境,这两个版本的包会冲突,导致各种奇怪的问题。

bash 复制代码
# 使用 venv(Python 3.3+ 自带)
python -m venv fastapi-env

# 激活虚拟环境
# Windows
fastapi-env\Scripts\activate

# Mac/Linux
source fastapi-env/bin/activate

激活后,你的命令行提示符前会出现 (fastapi-env),表示已经在虚拟环境中了。

2.3 安装依赖

在虚拟环境中,安装必要的包:

bash 复制代码
pip install fastapi uvicorn jinja2

验证安装是否成功:

bash 复制代码
python -c "import fastapi; print(f'FastAPI 版本: {fastapi.__version__}')"

三、第一个 FastAPI 应用:Hello World

环境准备好了,让我们写第一个 API。我建议你跟着我一步步来,不要复制粘贴,亲手敲代码感受一下。

3.1 项目结构

创建一个新文件夹 fastapi-demo,然后在里面创建以下结构:

复制代码
fastapi-demo/
├── main.py          # 主应用文件
└── templates/       # 模板文件夹
    ├── index.html   # 首页模板
    ├── item_detail.html  # 商品详情页模板
    ├── base.html    # 基础布局模板
    └── error.html   # 错误页面模板

3.2 编写基础代码

打开 main.py,输入以下代码:

python 复制代码
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

app = FastAPI(title="产品展示系统", description="一个基于 FastAPI 的简单电商演示")

# 配置 Jinja2 模板引擎
templates = Jinja2Templates(directory="templates")

# 示例数据
ITEMS = [
    {"id": 1, "name": "无人机", "price": 2999},
    {"id": 2, "name": "智能手表", "price": 1599}
]

@app.get("/", response_class=HTMLResponse, name="首页")
async def read_root(request: Request):
    """根路径的 GET 请求处理函数,返回产品列表页面"""
    return templates.TemplateResponse("index.html", {"request": request, "items": ITEMS})

@app.get("/items/{item_id}", response_class=HTMLResponse, name="商品详情")
async def read_item(request: Request, item_id: int):
    """
    带路径参数的示例
    
    参数:
    - item_id: 路径参数,自动转换为 int 类型
    """
    item = next((i for i in ITEMS if i["id"] == item_id), None)
    if not item:
        return templates.TemplateResponse("error.html", {"request": request, "error": "商品不存在"})
    return templates.TemplateResponse("item_detail.html", {"request": request, "item": item})

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000, reload=True)

3.3 创建模板文件

templates 文件夹中创建以下模板文件:

base.html(基础布局)
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}产品展示系统{% endblock %}</title>
    <style>
        body { 
            font-family: "Microsoft YaHei", Arial; 
            max-width: 800px; 
            margin: 0 auto;
            padding: 20px;
        }
        .item { 
            border: 1px solid #ddd; 
            padding: 15px; 
            margin: 10px 0;
            border-radius: 8px;
        }
        .item:hover {
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .price { color: #e74c3c; font-weight: bold; }
        .discount { color: #27ae60; font-size: 0.9em; }
        header h1 { color: #3498db; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
        footer { margin-top: 40px; text-align: center; color: #999; font-size: 0.9em; }
    </style>
</head>
<body>
    <header>
        <h1>产品展示系统</h1>
    </header>
    <main>{% block content %}{% endblock %}</main>
    <footer>© 2024 FastAPI 商城</footer>
</body>
</html>
index.html(首页)
html 复制代码
{% extends "base.html" %}

{% block title %}产品列表{% endblock %}

{% block content %}
<h2>所有商品</h2>
<div class="items">
    {% for item in items %}
    <div class="item">
        <h3>{{ item.name }}</h3>
        <p class="price">价格: ¥{{ item.price }}</p>
        <a href="/items/{{ item.id }}">查看详情</a>
    </div>
    {% endfor %}
</div>
{% endblock %}
item_detail.html(商品详情页)
html 复制代码
{% extends "base.html" %}

{% block title %}{{ item.name }} 详情{% endblock %}

{% block content %}
<div class="item-detail">
    <h2>{{ item.name }}</h2>
    <p class="price">价格: ¥{{ item.price }}</p>
    <p>产品ID: {{ item.id }}</p>
    
    {% if item.price > 2000 %}
    <p class="discount">🔥 高端产品</p>
    {% endif %}
</div>
{% endblock %}
error.html(错误页面)
html 复制代码
{% extends "base.html" %}

{% block title %}错误{% endblock %}

{% block content %}
<h2>错误信息</h2>
<p>{{ error }}</p>
{% endblock %}

3.4 启动项目

现在,你可以直接运行 main.py 文件来启动项目:

bash 复制代码
python main.py

解释

  • uvicorn.run(app, host="127.0.0.1", port=8000, reload=True):启动 FastAPI 应用
  • reload=True:开发模式,代码修改后自动重启服务器

四、项目测试与文档查看

启动服务后,访问以下 URL 进行测试:

4.1 访问页面

4.2 查看自动生成的 API 文档

FastAPI 自动生成了两种格式的 API 文档:

  1. 交互式 API 文档 (Swagger UI)

  2. ReDoc 文档


五、理解关键概念

现在,让我们深入理解 FastAPI 中的几个关键概念。

5.1 路由与路径参数

python 复制代码
@app.get("/items/{item_id}")
async def read_item(request: Request, item_id: int):
    ...
  • /items/{item_id}:路由定义,{item_id} 是路径参数
  • item_id: int:路径参数类型注解,FastAPI 会自动验证类型
  • 如果访问 /items/abc 这样的路径,FastAPI 会自动返回 422 错误

5.2 模板引擎与上下文传递

python 复制代码
return templates.TemplateResponse("index.html", {"request": request, "items": ITEMS})
  • request:必须包含的参数,因为 Jinja2 模板需要它
  • items:传递给模板的数据,在模板中可以通过 {``{ items }} 访问

5.3 响应类型注解

python 复制代码
@app.get("/", response_class=HTMLResponse)
  • response_class=HTMLResponse:指定返回类型为 HTML
  • 这样,FastAPI 会自动设置正确的 Content-Type 响应头

六、生产环境部署建议

当你的代码准备好部署到生产环境时,有以下几点建议:

6.1 使用多进程运行

bash 复制代码
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
  • --workers 4:根据 CPU 核心数设置工作进程数,一般是核心数的 2-4 倍

6.2 使用 Gunicorn 管理进程

bash 复制代码
pip install gunicorn
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app

6.3 使用 Nginx 反向代理

nginx 复制代码
server {
    listen 80;
    server_name your-domain.com;
    
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

七、项目扩展思路

现在你已经有了一个基础的项目,下面是一些扩展思路,可以让你的项目更加强大:

7.1 添加表单处理

python 复制代码
from fastapi import Form

@app.post("/items/create")
async def create_item(
    name: str = Form(...),
    price: float = Form(...)
):
    new_id = max(i["id"] for i in ITEMS) + 1
    ITEMS.append({"id": new_id, "name": name, "price": price})
    return {"message": "商品创建成功"}

7.2 添加静态文件服务

python 复制代码
from fastapi.staticfiles import StaticFiles

app.mount("/static", StaticFiles(directory="static"), name="static")

7.3 添加数据库连接

可以使用 SQLAlchemy 或 Tortoise ORM 与数据库交互。

7.4 添加身份验证

可以使用 OAuth2 或 JWT 进行身份验证。


八、学习资源推荐

官方文档

示例项目

视频教程


总结

通过本教程,详细你已经从零开始搭建了一个完整的 FastAPI 项目,并使用 Jinja2 模板引擎生成了美观的 HTML 页面。并学会了如何使用自动生成的 API 文档来调试和测试。

FastAPI 的强大之处在于它的简单性和高性能。你只需要专注于业务逻辑,剩下的事情 FastAPI 都会帮你处理。强烈建议你在实际项目中尝试使用 FastAPI,相信它会给你带来全新的开发体验。如果你在学习过程中遇到任何问题,或者有任何建议,欢迎在评论区与我交流!


项目资源

参考链接

https://blog.csdn.net/m0_46577795/article/details/155462743

https://www.cnblogs.com/banchengyanyu/p/18251156

相关推荐
a35354138216 小时前
设计模式-原型模式
开发语言·c++
Tinachen8816 小时前
YonBIP旗舰版本地开发环境搭建教程
java·开发语言·oracle·eclipse·前端框架
liulilittle16 小时前
libxdp: No bpffs found at /sys/fs/bpf
linux·运维·服务器·开发语言·c++
hqwest16 小时前
码上通QT实战07--主窗体消息栏设计
开发语言·qt·qt事件·主窗体·stackedwidget
hqwest16 小时前
码上通QT实战06--导航按钮事件
开发语言·qt·mousepressevent·qfont·qpainter·qlineargradient·setbrush
shughui17 小时前
实现Python多版本共存
开发语言·python·pip
BoBoZz1917 小时前
TextureCutQuadric 利用3D隐式函数(Quadrics)来生成2D纹理坐标
python·vtk·图形渲染·图形处理
dhdjjsjs17 小时前
Day58 PythonStudy
开发语言·python·机器学习
你真的可爱呀17 小时前
自定义颜色选择功能
开发语言·前端·javascript
mzhan01717 小时前
perl: redhat9, perl-interpreter.rpm 一个包分成很多个小包
开发语言·perl·redhat·rpm