FastAPI入门:Python后端开发新手指南
开篇:FastAPI是什么?用来做什么?

如果你是编程零基础,可能对“后端”这个词还有些陌生。别担心,我们先从简单的例子说起!想象你正在使用一个手机App来查询天气情况,当你输入城市名称并点击搜索时,这个App会把你的请求发送到某个地方(也就是服务器),服务器收到请求后处理数据,再把结果返回给App展示出来。这个负责接收请求、处理数据、返回结果的部分就是后端。
FastAPI正是帮助开发者快速搭建后端服务的一种工具。它基于Python语言,简单易学但功能强大,特别适合像你这样的初学者开始学习。FastAPI的官方文档说它是“用于构建 API 的现代、快速(高性能)的框架”,换句话说,你可以用它轻松地写出能让别人调用的服务接口。比如,你想做一个可以记录待办事项的App,FastAPI可以帮助你写一个后端程序,让App能保存用户添加的任务并提供查看任务的功能。这听起来是不是很实用?那就让我们一起动手开始吧!
环境准备:安装FastAPI和相关工具

在开始编写代码之前,我们需要准备好开发环境。这一部分我们将一步步指导你完成必要的安装步骤。
安装Python
首先,你需要确保你的计算机上已经安装了Python。推荐使用 Python 3.7 或以上版本,因为FastAPI依赖一些较新的Python特性。要检查是否已安装Python,请打开终端(Mac/Linux)或命令提示符(Windows),然后输入以下命令:
python --version
如果你看到类似 Python 3.x.x 的输出,说明你已经安装了Python。如果没有安装,请访问 https://www.python.org/downloads/ 下载最新版本,并根据安装向导进行安装。
安装FastAPI
接下来,我们要安装FastAPI框架本身。FastAPI可以通过Python内置的包管理器 pip 来安装。在终端或命令行中输入以下命令:
pip install fastapi
执行完这条命令后,FastAPI就会被下载并安装到你的系统中。
安装Uvicorn(异步服务器)
为了运行FastAPI项目,我们需要一个支持异步请求的Web服务器。推荐使用 Uvicorn,它是一款专门为FastAPI设计的高性能服务器。同样通过pip来安装:
pip install uvicorn
验证安装
安装完成后,我们可以验证一下是否一切顺利。创建一个新的 .py 文件,例如 main.py,并在其中写入以下代码:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "欢迎来到FastAPI世界!"}
然后,在终端中运行以下命令启动服务器:
uvicorn main:app --reload
uvicorn是我们使用的服务器;main指的是文件名(即main.py);app是我们在代码中定义的FastAPI实例;--reload表示启用自动重载功能,方便开发时实时更新代码。
如果没有任何报错信息,说明安装成功!这时你可以打开浏览器并访问 http://127.0.0.1:8000,你会看到如下JSON格式的响应内容:
{"message": "欢迎来到FastAPI世界!"}
恭喜,你刚刚成功搭建了一个最基础的FastAPI应用!
其他推荐工具
虽然这些不是必须的,但我们建议你也安装一些常用的开发工具:
- Postman:这是一个强大的HTTP客户端,可以用于测试API接口。你可以通过 https://www.postman.com/downloads/ 下载适合自己系统的版本。
- VS Code 或 PyCharm:作为Python开发工具,它们对FastAPI有很好的支持,包括语法高亮、智能提示等功能。
现在,所有准备工作都已经完成了!我们已经成功设置了开发环境,接下来就可以进入核心概念的学习啦!
核心概念:理解关键术语与结构
在正式开始写代码之前,我们先来了解几个重要的概念:路由、接口函数以及 GET/POST 请求的区别。这些是FastAPI中最基本也是最重要的知识点。我们会用通俗的语言解释清楚,确保你理解这些术语的实际含义。
路由 (Route) 是什么?
想象一下你要去图书馆找一本书,你知道这本书在“三楼心理学书架”。这里,“三楼心理学书架”就像是图书管理员为你准备好的路线。在FastAPI中,**路由(Route)**就相当于一个“地址”,告诉服务器如何响应特定的请求。
举个例子:你在浏览网页时,输入的网址如 http://example.com/home 中的 /home 就是一个路由。FastAPI需要知道用户请求了哪个路由,从而决定应该返回哪一段内容。
示例:定义一个简单的路由
from fastapi import FastAPI
app = FastAPI()
@app.get("/greeting")
def greet_user():
return {"message": "你好呀!"}
在这个例子中,@app.get("/greeting") 表示当有人访问 /greeting 这个路由时,调用 greet_user() 函数,并返回 {"message": "你好呀!"}。
接口函数 (Endpoint Function) 是什么?
接口函数就是FastAPI接收到请求之后执行的具体操作。通常,它的作用是处理请求,并返回相应的数据。就像上面的例子一样,greet_user() 函数就是一个接口函数,它会在指定路由被访问时运行。
示例:带参数的接口函数
我们可以让接口函数接受一些额外的数据(例如用户名),让它更有用。下面是一个简单的例子:
@app.get("/hello/{name}")
def say_hello(name: str):
return {"message": f"你好,{name}!"}
在这段代码中,{name} 是一个路径参数,表示你可以将任意名字插入 URL 后面。比如,当你访问 /hello/Alice,FastAPI会自动将 name 设为 "Alice",最终返回的结果是:
{"message": "你好,Alice!"}
GET 和 POST 请求有什么区别?
在网络请求中,GET 和 POST 是最常见的两种方法。它们的主要区别在于用途不同。
✅ GET 请求:获取数据
GET 方法主要用于获取数据。比如,当你想读取一篇文章的内容或者查看商品列表,通常使用GET请求。
示例:
@app.get("/items")
def get_item(item_id: int):
return {"item_id": item_id, "status": "Item 已找到!"}
访问 /items?item_id=5,你会得到如下结果:
{"item_id": 5, "status": "Item 已找到!"}
注意这里的 item_id=5 是放在URL后面的查询参数中传递的。
📤 POST 请求:提交数据
POST 方法则用于发送或创建新数据。比如,当你注册账号、上传头像,或者提交表单时,通常使用POST方法。
示例:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class UserInput(BaseModel):
name: str
age: int
@app.post("/user")
def create_user(user: UserInput):
return {"message": f"{user.name} 今年 {user.age} 岁,已加入系统。"}
在 Postman 或其他 API 测试工具中,你可以向 /user 发送 POST 请求,并以 JSON 格式提交数据:
{
"name": "张三",
"age": 28
}
后端返回的内容是:
{"message": "张三 今年 28 岁,已加入系统。"}
总结:三个核心概念的对比
| 概念 | 作用 | 示例 |
|---|---|---|
| 路由(Route) | 决定请求的访问地址 | /greeting, /hello/{name} |
| 接口函数(Endpoint) | 处理请求逻辑并返回结果 | greet_user(), say_hello(name) |
| GET vs POST | GET 获取数据 / POST 提交新数据 | 使用 @app.get() 或 @app.post() |
掌握了这三个基础概念,你就具备了构建简单API的能力了!下一步,我们会动手实践,通过一个简单的项目加深理解。
实战项目:构建一个待办事项管理接口
现在我们来实战练习一下,用FastAPI实现一个简单的待办事项(To-Do List)管理接口。这个项目将会覆盖本篇文章前面介绍的所有知识点:定义路由、GET和POST请求以及接口函数的作用。我们将逐步讲解每一步怎么做,并展示完整的代码示例。
第一步:初始化FastAPI项目
创建一个新的Python文件,比如叫 todo_app.py。导入 FastAPI 框架,并初始化一个应用实例:
from fastapi import FastAPI
app = FastAPI()
这是我们的起点,非常简单!接下来,我们将逐步扩展这个程序,使它可以存储和返回用户的待办事项。
第二步:定义临时存储数据结构
因为还没有数据库的知识,所以我们就用一个 Python 列表来模拟存储待办事项的数据。我们在程序中定义一个全局变量 todos 来保存所有任务:
# 初始化一个待办事项列表
todos = [
{"id": 1, "title": "买菜", "completed": False},
{"id": 2, "title": "读书", "completed": True}
]
每个任务包含 id(唯一编号)、title(任务标题)、以及 completed(是否完成)。这部分我们只是用静态数据做演示,后续你可以替换成数据库查询。
第三步:创建接口:获取所有待办事项(GET)
接下来,我们定义一个接口来获取全部的待办事项。使用 @app.get() 方法绑定路由 /todos:
@app.get("/todos")
def get_todos():
return todos
运行这个程序后,访问 http://127.0.0.1:8000/todos,你应该能看到当前列表中的两个任务以 JSON 形式显示:
[
{"id": 1, "title": "买菜", "completed": false},
{"id": 2, "title": "读书", "completed": true}
]
注意:FastAPI 自动将 Python 字典转换成了标准的 JSON 格式返回给你。
第四步:创建接口:新增一个待办事项(POST)
现在我们要实现添加新任务的功能。使用 @app.post() 定义 /todos 路由的 POST 请求。为了让接口更规范,我们先定义一个 Pydantic 模型来描述输入数据结构:
from fastapi import FastAPI
from pydantic import BaseModel
class TodoCreate(BaseModel):
title: str
接着,修改我们的 POST 接口函数:
@app.post("/todos")
def add_todo(todo: TodoCreate):
new_id = max(t["id"] for t in todos) + 1 if todos else 1
new_todo = {
"id": new_id,
"title": todo.title,
"completed": False
}
todos.append(new_todo)
return new_todo
这个函数的作用是:
- 接收一个包含
title的输入数据(使用TodoCreate模型做校验)。 - 自动生成一个新的唯一ID。
- 把新任务添加进
todos列表。 - 返回新增任务的信息。
你可以通过 Postman 或类似的工具发起 POST 请求,发送如下 JSON 数据:
{
"title": "学习FastAPI"
}
后端响应将是:
{"id": 3, "title": "学习FastAPI", "completed": false}
并且刷新 /todos 页面时也能看到新增的任务。
第五步:创建接口:按ID获取单个任务(GET with ID)
我们现在加一个功能:用户可以传入任务ID查看详细信息。使用 @app.get("/{id}") 来匹配路径中的整数ID:
@app.get("/todos/{id}")
def get_todo(id: int):
for todo in todos:
if todo["id"] == id:
return todo
return {"error": "未找到对应任务"}
比如,访问 /todos/2 应该返回:
{"id": 2, "title": "读书", "completed": true}
而访问 /todos/999 则返回错误消息:
{"error": "未找到对应任务"}
完整代码回顾
以下是完整的 todo_app.py 代码整理版,包含了我们目前实现的所有功能:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# 初始化一个待办事项列表
todos = [
{"id": 1, "title": "买菜", "completed": False},
{"id": 2, "title": "读书", "completed": True}
]
# 获取所有待办事项
@app.get("/todos")
def get_todos():
return todos
# 新增待办事项
class TodoCreate(BaseModel):
title: str
@app.post("/todos")
def add_todo(todo: TodoCreate):
new_id = max(t["id"] for t in todos) + 1 if todos else 1
new_todo = {
"id": new_id,
"title": todo.title,
"completed": False
}
todos.append(new_todo)
return new_todo
# 按ID获取单个待办事项
@app.get("/todos/{id}")
def get_todo(id: int):
for todo in todos:
if todo["id"] == id:
return todo
return {"error": "未找到对应任务"}
运行方式还是老样子:
uvicorn todo_app:app --reload
成果展示
到这里,我们已经完成了一个功能完善的待办事项管理系统的核心模块,包括:
- 获取所有任务列表;
- 新增一个任务;
- 按ID获取任务详情。
你可以继续尝试扩展这个项目,比如添加更新任务状态、删除任务等API。不过没关系,我们后面还会深入学习这些内容。现在先把注意力集中在理解基础知识上,继续往下看!
常见问题解答
在刚开始学习 FastAPI 的过程中,很多新手都会遇到一些常见问题。下面是一些典型问题及解决方案,帮助你顺利避开这些“坑”。
Q1:为什么运行 uvicorn main:app --reload 时提示模块找不到?
这个问题通常发生在你没有正确安装FastAPI或者没有正确命名文件时。
✅ 解决方案:
- 确保你已经按照之前教程安装了FastAPI和uvicorn:
pip install fastapi uvicorn - 检查你的主文件名称是否是正确的。例如,如果你的代码写在
main.py中,那命令应该是:
如果你的文件是uvicorn main:app --reloadapp.py,那要改成:uvicorn app:app --reload
Q2:我访问 /docs 页面看不到自动生成的API文档怎么办?
FastAPI默认会生成交互式API文档(基于Swagger UI和Redoc),但如果你访问 http://127.0.0.1:8000/docs 却出现页面空白或错误,可能是你的路由设置有问题。
✅ 解决方案:
- 确保你没有手动删除了FastAPI提供的默认文档路由;
- 确保你的接口函数有明确的返回类型声明,这样文档才能正确解析;
- 如果仍然无法加载,可以尝试刷新页面,或者清除浏览器缓存。
Q3:为什么我的 POST 请求始终报错:“Unprocessable Entity”?
这是最常见的请求参数校验失败问题,意味着你发送的数据不符合预期结构。
✅ 解决方案:
- 检查你是否按照模型(BaseModel)的要求提供了所有必填字段;
- 确保数据类型匹配,例如不要把字符串类型的数字当成整数使用;
- 使用 Postman 或 curl 工具时,确认你发送的请求体格式是
application/json,否则FastAPI可能会无法识别你的输入。
Q4:如何在接口函数中调试并打印日志?
很多时候,你希望看看中间变量的值,或者跟踪程序运行流程。
✅ 解决方案:
- 在函数内部直接使用 Python 内置的
print()函数,例如:def my_endpoint(param): print(f"收到的参数是:{param}") return ... - 使用 logging 模块来记录更详细的日志信息(推荐长期项目中使用):
import logging logging.basicConfig(level=logging.INFO) def my_endpoint(param): logging.info(f"收到了参数 {param}")
Q5:为什么重启 uvicorn 后之前的测试数据又不见了?
在我们之前的项目中,我们使用了一个全局变量 todos 来保存数据。但每次重启服务器时,Python 会重新执行脚本,因此数据会被清空。
✅ 解决方案: 这个问题目前只需要理解即可,实际开发中会通过数据库存储持久化数据(例如 SQLite、MySQL)。我们将在后面的文章中深入探讨这个话题。
Q6:接口函数返回中文为什么会乱码?
有时你会发现浏览器显示的中文字符变成了一堆乱码,或者变成了 Unicode 编码形式。
✅ 解决方案:
- 确保你的 FastAPI 项目在响应时设置了正确的编码格式(UTF-8);
- FastAPI 默认已经使用 UTF-8 编码,但如果配合某些代理服务器或前端框架时出现问题,

评论 0