通过GitHub学习FastAPI:从零到一部署的终极指南
引言:为何选择FastAPI与GitHub?
在现代Web开发领域,选择正确的技术栈是项目成功的关键。Python以其简洁的语法和强大的生态系统,一直是后端开发的热门选择。而在众多Python Web框架中,FastAPI 如同一颗冉冉升起的新星,凭借其无与伦比的性能和现代化的开发体验,迅速获得了全球开发者的青睐。
FastAPI的核心优势在于:
- 高性能:基于Starlette和Pydantic,其性能与NodeJS和Go不相上下。
- 开发迅速:得益于Python的类型提示,代码重复率极低,功能开发速度提升约200%至300%。
- 更少Bug:类型声明使得编辑器和静态检查工具能更早地发现错误。
- 智能好用:自动生成的交互式API文档(Swagger UI & ReDoc)是其一大杀手级特性。
- 标准化:完全兼容OpenAPI和JSON Schema等开放标准。
然而,仅仅会写代码是不够的。一个专业的开发者还需要掌握如何管理代码、与他人协作以及如何将应用部署到线上。这正是 GitHub 发挥作用的地方。GitHub不仅仅是一个代码托管平台,它提供了一整套围绕软件开发生命周期的工具,包括版本控制(Git)、项目管理、持续集成与持续部署(CI/CD)等。
本文将作为你的“终极指南”,带领你走完一段完整的旅程:从在本地计算机上创建第一个FastAPI应用开始,使用Git和GitHub进行专业的版本控制,构建一个功能完备的CRUD API,然后通过GitHub Actions实现自动化测试与集成,最终将你的应用免费部署到云端,让全世界都能访问。
准备好了吗?让我们开始这段激动人心的学习之旅!
第一章:准备工作:环境搭建与基础概念
在编写任何代码之前,我们需要一个干净、隔离的开发环境。
1.1 Python虚拟环境
为每个项目创建独立的虚拟环境是一个至关重要的好习惯,它可以避免不同项目间的依赖冲突。
打开你的终端(在Windows上是CMD或PowerShell,在macOS或Linux上是Terminal),然后执行以下步骤:
“`bash
1. 创建一个项目文件夹并进入
mkdir fastapiproject
cd fastapiproject
2. 创建一个名为’venv’的虚拟环境
在macOS/Linux上
python3 -m venv venv
在Windows上
python -m venv venv
3. 激活虚拟环境
在macOS/Linux上
source venv/bin/activate
在Windows上
.\venv\Scripts\activate
激活后,你的终端提示符前应该会有一个(venv)的标识
“`
1.2 安装Git并配置GitHub
如果你的电脑上还没有安装Git,请访问 Git官网 下载并安装。安装后,进行基本配置:
bash
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
同时,确保你已经注册了一个 GitHub 账号。
1.3 安装FastAPI和Uvicorn
在已激活的虚拟环境中,使用pip安装FastAPI。我们推荐安装fastapi[all]
,它会一并安装所有可选依赖,包括用于运行服务器的uvicorn
。
bash
pip install "fastapi[all]"
第二章:”Hello World”:你的第一个FastAPI应用
让我们从一个最简单的应用开始,感受FastAPI的魅力。
2.1 编写代码
在fastapiproject
文件夹中,创建一个名为main.py
的文件,并写入以下内容:
“`python
main.py
from fastapi import FastAPI
import uvicorn
1. 创建一个FastAPI实例
app = FastAPI()
2. 定义一个路径操作装饰器
@app.get(“/”)
3. 定义路径操作函数
async def root():
return {“message”: “Hello, FastAPI World!”}
这是一个可选部分,但对于直接运行此脚本很方便
if name == “main“:
uvicorn.run(app, host=”127.0.0.1”, port=8000)
“`
代码解析:
1. app = FastAPI()
:创建了一个FastAPI应用的核心实例。
2. @app.get("/")
:这是一个“装饰器”,它告诉FastAPI,下面这个函数root
将负责处理访问根路径/
的GET请求。
3. async def root()
:这是一个异步函数。FastAPI可以处理普通的def
函数和异步的async def
函数。使用async def
可以更好地处理高并发请求。函数返回一个字典,FastAPI会自动将其转换为JSON响应。
2.2 运行应用
在终端中(确保虚拟环境已激活),运行你的应用:
bash
uvicorn main:app --reload
main
: 指的是main.py
文件。app
: 指的是在main.py
中创建的app = FastAPI()
对象。--reload
: 这是一个开发时非常有用的选项,当你的代码文件发生改动时,服务器会自动重启。
你应该会看到类似以下的输出:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [12345]
INFO: Started server process [12347]
INFO: Waiting for application startup.
INFO: Application startup complete.
2.3 探索自动交互式文档
这是FastAPI最令人兴奋的功能之一。打开你的浏览器,访问两个URL:
- Swagger UI: http://127.0.0.1:8000/docs
- ReDoc: http://127.0.0.1:8000/redoc
你将看到一个功能完善、美观的API文档页面。它详细列出了你所有的API端点(目前只有一个/
),你可以直接在页面上进行“Try it out”操作,发送真实请求并查看响应。这一切都是自动生成的,无需你编写任何额外的代码!
第三章:Git与GitHub:版本控制的最佳实践
现在我们的应用已经可以运行了,是时候用Git来管理我们的代码了。
3.1 初始化Git仓库并进行首次提交
-
创建
.gitignore
文件:
在提交代码前,我们必须告诉Git哪些文件或文件夹是不需要被跟踪的,例如虚拟环境、Python缓存文件等。在项目根目录下创建.gitignore
文件,并添加以下内容:“`
.gitignore
Virtualenv
venv/
.venv/Python cache
pycache/
*.pycIDE / Editor specific
.vscode/
.idea/
“` -
初始化并提交:
“`bash
初始化本地仓库
git init
将所有(未被忽略的)文件添加到暂存区
git add .
提交更改,并附上有意义的提交信息
git commit -m “Initial commit: Create basic FastAPI app with ‘Hello World’ endpoint”
“`
3.2 连接到GitHub远程仓库
-
在GitHub上创建一个新的空仓库(不要勾选初始化
README
或.gitignore
)。假设仓库名为fastapi-learning-journey
。 -
复制GitHub提供的远程仓库URL(HTTPS或SSH格式)。
-
在本地终端中,将本地仓库与远程仓库关联起来,并推送代码:
“`bash
添加远程仓库地址,并命名为’origin’
git remote add origin https://github.com/your-username/fastapi-learning-journey.git
将main分支重命名(这是一个好习惯)
git branch -M main
将本地的main分支推送到远程的origin仓库
git push -u origin main
“`
现在刷新你的GitHub仓库页面,你会看到main.py
和.gitignore
文件已经成功上传了。你的代码已经安全地托管在云端。
第四章:构建一个简单的CRUD API
“Hello World”很有趣,但真实世界的应用需要处理数据。让我们构建一个管理“待办事项(Todo)”的CRUD(Create, Read, Update, Delete)API。
为了简化,我们将使用一个内存中的列表来模拟数据库。
4.1 使用Pydantic定义数据模型
Pydantic是FastAPI数据验证和序列化的核心。我们需要定义数据的“形状”。在main.py
中添加以下代码:
“`python
main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
import uvicorn
… (保留之前的app = FastAPI())
Pydantic 模型
class TodoBase(BaseModel):
title: str
description: Optional[str] = None
completed: bool = False
class TodoCreate(TodoBase):
pass
class Todo(TodoBase):
id: int
内存数据库
fake_todos_db = {
1: {“id”: 1, “title”: “学习 FastAPI”, “description”: “阅读官方文档”, “completed”: True},
2: {“id”: 2, “title”: “创建 GitHub 仓库”, “description”: “并将代码推送上去”, “completed”: True},
3: {“id”: 3, “title”: “部署应用”, “description”: “使用云服务进行部署”, “completed”: False},
}
… (保留之前的 @app.get(“/”) … )
“`
模型解析:
* TodoBase
: 定义了所有Todo项共有的基础字段。Optional[str] = None
表示description
是可选的。
* TodoCreate
: 创建Todo时,客户端需要提供的数据模型,它继承自TodoBase
。
* Todo
: 从数据库读取或返回给客户端的完整Todo模型,包含了id
。
4.2 实现CRUD端点
现在,我们在main.py
中添加处理CRUD操作的路径函数。
1. 创建 (Create)
python
@app.post("/todos/", response_model=Todo, status_code=201)
async def create_todo(todo: TodoCreate):
new_id = max(fake_todos_db.keys()) + 1
new_todo = Todo(id=new_id, **todo.dict())
fake_todos_db[new_id] = new_todo.dict()
return new_todo
* @app.post("/todos/")
: 接收对/todos/
的POST请求。
* response_model=Todo
: 强制响应体符合Todo
模型的结构。
* todo: TodoCreate
: FastAPI会自动解析请求体JSON,并用TodoCreate
模型进行验证。
* **todo.dict()
: 将Pydantic模型转换为字典,方便创建新的Todo
实例。
2. 读取所有 (Read All)
python
@app.get("/todos/", response_model=List[Todo])
async def read_todos():
return list(fake_todos_db.values())
* response_model=List[Todo]
: 响应将是一个包含多个Todo
对象的列表。
3. 读取单个 (Read One)
python
@app.get("/todos/{todo_id}", response_model=Todo)
async def read_todo(todo_id: int):
if todo_id not in fake_todos_db:
raise HTTPException(status_code=404, detail="Todo not found")
return fake_todos_db[todo_id]
* {todo_id}
: 路径参数。FastAPI会自动将URL中的值转换为int
类型。
* HTTPException
: FastAPI提供的标准方式来返回HTTP错误。
4. 更新 (Update)
python
@app.put("/todos/{todo_id}", response_model=Todo)
async def update_todo(todo_id: int, todo: TodoCreate):
if todo_id not in fake_todos_db:
raise HTTPException(status_code=404, detail="Todo not found")
updated_todo = Todo(id=todo_id, **todo.dict())
fake_todos_db[todo_id] = updated_todo.dict()
return updated_todo
5. 删除 (Delete)
python
@app.delete("/todos/{todo_id}", status_code=204)
async def delete_todo(todo_id: int):
if todo_id not in fake_todos_db:
raise HTTPException(status_code=404, detail="Todo not found")
del fake_todos_db[todo_id]
return # 对于204 No Content,不需要返回任何内容
现在,重启你的服务器(如果--reload
开启,它会自动重启),然后再次访问 http://127.0.0.1:8000/docs。你会看到所有新的CRUD端点都已列出,并且可以交互测试!
4.3 提交你的CRUD功能
你的API功能更加丰富了,这是一个重要的里程碑,应该作为一个单独的提交。
bash
git add main.py
git commit -m "Feat: Implement full CRUD functionality for todos"
git push origin main
第五章:使用GitHub Actions实现CI/CD
持续集成(CI)是指在代码推送到仓库时自动运行测试。这能确保新的改动没有破坏现有功能。
5.1 编写测试
首先,我们需要有可运行的测试。FastAPI让测试变得异常简单。
-
安装测试依赖
pytest
和httpx
(httpx
用于在测试中向API发送请求):
bash
pip install pytest httpx -
创建
test_main.py
文件:
“`python
# test_main.py
from fastapi.testclient import TestClient
from .main import appclient = TestClient(app)
def test_read_root():
response = client.get(“/”)
assert response.status_code == 200
assert response.json() == {“message”: “Hello, FastAPI World!”}def test_read_todos():
response = client.get(“/todos/”)
assert response.status_code == 200
# 假设我们知道初始有3个todos
assert len(response.json()) >= 3def test_read_one_todo():
response = client.get(“/todos/1”)
assert response.status_code == 200
assert response.json()[“title”] == “学习 FastAPI”def test_read_nonexistent_todo():
response = client.get(“/todos/999”)
assert response.status_code == 404
assert response.json() == {“detail”: “Todo not found”}
“` -
在本地运行测试:
bash
pytest
你应该会看到所有测试都通过了。
5.2 创建依赖文件 requirements.txt
为了让GitHub Actions(以及后续的部署平台)知道我们的项目需要哪些依赖,我们需要创建一个requirements.txt
文件。
bash
pip freeze > requirements.txt
这会将当前虚拟环境中所有已安装的包及其版本号输出到该文件中。
5.3 配置GitHub Actions工作流
- 在项目根目录下,创建
.github/workflows
文件夹。 -
在该文件夹中,创建一个
ci.yml
文件,并写入以下内容:“`yaml
.github/workflows/ci.yml
name: FastAPI CI
on:
push:
branches: [ “main” ] # 当main分支有push时触发
pull_request:
branches: [ “main” ] # 当有PR到main分支时触发jobs:
build-and-test:
runs-on: ubuntu-latest # 使用最新的Ubuntu虚拟机steps: - name: Checkout code uses: actions/checkout@v3 # 第一步:拉取代码 - name: Set up Python uses: actions/setup-python@v4 # 第二步:设置Python环境 with: python-version: '3.9' # 指定Python版本 - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt # 第三步:安装依赖 - name: Run tests with pytest run: | pytest # 第四步:运行测试
“`
5.4 提交并触发CI
现在,将我们新增的测试文件、依赖文件和工作流文件提交到GitHub。
bash
git add test_main.py requirements.txt .github/workflows/ci.yml
git commit -m "CI: Add pytest tests and GitHub Actions workflow"
git push origin main
推送后,进入你的GitHub仓库页面,点击”Actions”标签页。你会看到一个正在运行的工作流。点击进去,你可以实时看到每一步(拉取代码、安装依赖、运行测试)的执行情况。如果一切顺利,最终会显示一个绿色的对勾,表示CI通过!
第六章:部署到云端
最后一步,也是最激动人心的一步:将我们的应用部署到互联网上。我们将使用对开发者非常友好的平台 Render,它提供慷慨的免费套餐,并且与GitHub深度集成。
6.1 准备部署
部署到生产环境与本地开发有一些不同。生产服务器需要从外部访问,并且端口由平台动态分配。我们需要对启动命令做一些调整。
Render通过一个名为PORT
的环境变量来告诉你的应用应该监听哪个端口。同时,主机地址(host)需要设置为0.0.0.0
,以接受来自任意IP的连接。
我们的启动命令应该是:
uvicorn main:app --host 0.0.0.0 --port $PORT
6.2 在Render上进行部署
- 使用你的GitHub账号注册并登录 Render。
- 在Dashboard页面,点击 “New +” -> “Web Service”。
- 授权Render访问你的GitHub账户,并选择我们创建的
fastapi-learning-journey
仓库。 -
进入配置页面:
- Name: 给你的服务起个名字,例如
my-fastapi-todos
。这个名字会成为你URL的一部分。 - Region: 选择离你或你的用户最近的地区。
- Branch: 确保是
main
分支。 - Runtime: Render会自动检测到是Python项目。
- Build Command:
pip install -r requirements.txt
(这通常是默认值,确认即可)。 - Start Command: 这是最关键的一步!填入
uvicorn main:app --host 0.0.0.0 --port 10000
。Render会自动将$PORT
环境变量映射到内部的10000
端口。 - Instance Type: 选择 “Free” 免费套餐。
- Name: 给你的服务起个名字,例如
-
向下滚动,点击 “Create Web Service”。
Render现在会自动从你的GitHub仓库拉取代码,执行Build Command
安装依赖,然后执行Start Command
启动你的服务。你可以在日志中看到整个过程。
首次部署可能需要几分钟。当状态显示为 “Live” 时,部署就成功了!
6.3 访问你的线上应用
在Render的服务页面顶部,会提供一个公开的URL,格式通常是 https://your-service-name.onrender.com
。
点击这个URL,你应该能看到熟悉的 {"message": "Hello, FastAPI World!"}
。
更重要的是,你可以访问它的线上API文档: https://your-service-name.onrender.com/docs
。现在,你可以通过这个公开的URL,在世界任何一个角落与你的CRUD API进行交互!
Render还配置了自动部署。现在,每当你向main
分支推送新的提交,Render都会自动拉取最新代码,重新构建并部署你的应用,实现了完整的CI/CD闭环。
总结:你的旅程刚刚开始
恭喜你!你已经走完了一条完整的现代Web开发之路。回顾一下我们所取得的成就:
- 从零开始,在本地搭建了Python环境并创建了一个FastAPI应用。
- 掌握了Git和GitHub的基础,学会了如何进行版本控制和远程协作。
- 构建了一个功能完备的CRUD API,并理解了Pydantic模型的核心作用。
- 通过GitHub Actions建立了自动化测试流程,保证了代码质量。
- 成功将应用部署到云端,使其成为一个全球可访问的真实服务。
这不仅仅是学习了一个框架,更是学习了一套现代、高效、专业的软件开发工作流。以此为起点,你可以继续探索更广阔的世界:连接真实数据库(如PostgreSQL)、实现用户认证与授权(OAuth2)、使用WebSocket进行实时通信、将项目拆分为更复杂的结构(Routers)等等。
FastAPI和GitHub的结合为你提供了一个强大而灵活的平台。继续编码,不断学习,用技术去创造更多有价值的东西吧!你的开发者之旅,才刚刚开始。