基于 FastAPI 和 GitHub 的 Web API 开发实战

基于 FastAPI 和 GitHub 的 Web API 开发实战

在当今的软件开发领域,Web API 已经成为不同系统、服务和应用程序之间进行通信和数据交换的基石。构建高效、可靠且易于维护的 API 对于任何成功的项目都至关重要。本文将深入探讨如何利用 FastAPI 这个现代、高性能的 Python Web 框架,结合 GitHub 进行版本控制和协作,来开发一个实用的 Web API。我们将涵盖从项目初始化、API 设计、代码实现、测试、部署到持续集成的全过程,并提供详细的代码示例和最佳实践。

1. FastAPI 简介:为什么选择 FastAPI?

FastAPI 是一个基于 Python 3.6+ 类型提示的现代、快速(高性能)的 Web 框架,用于构建 API。它具有以下显著优点:

  • 速度快:FastAPI 基于 Starlette 和 Pydantic,性能非常出色,可与 NodeJS 和 Go 相媲美。
  • 易于学习和使用:FastAPI 的设计注重简单性和直观性,学习曲线平缓,开发效率高。
  • 自动生成文档:FastAPI 能够自动生成交互式 API 文档(Swagger UI 和 ReDoc),方便 API 的测试和调试。
  • 类型检查和验证:FastAPI 利用 Python 类型提示进行数据验证和转换,减少错误并提高代码质量。
  • 异步支持:FastAPI 原生支持异步请求处理,能够处理大量并发连接。
  • 依赖注入系统:FastAPI 提供了强大的依赖注入系统,使代码更易于测试和维护。
  • 广泛的生态系统:FastAPI 可以轻松集成各种数据库、ORM、安全工具和其他第三方库。

2. 项目准备:环境搭建与 GitHub 集成

2.1 环境搭建

首先,确保你的系统已安装 Python 3.6+ 和 pip。然后,创建一个新的项目目录,并使用虚拟环境隔离项目依赖:

bash
mkdir my_fastapi_project
cd my_fastapi_project
python3 -m venv venv
source venv/bin/activate # Linux/macOS
venv\Scripts\activate # Windows

接下来,安装 FastAPI 和 Uvicorn(一个 ASGI 服务器):

bash
pip install fastapi uvicorn

2.2 GitHub 集成

  1. 创建 GitHub 仓库:在 GitHub 上创建一个新的仓库,用于存储你的项目代码。
  2. 初始化本地 Git 仓库:在项目目录下,初始化一个 Git 仓库:

    bash
    git init

    3. 关联远程仓库:将本地仓库与 GitHub 上的远程仓库关联:

    bash
    git remote add origin <your_github_repo_url>

    4. 创建 .gitignore 文件:创建一个 .gitignore 文件,排除不需要提交到版本控制的文件和目录,例如:

    venv/
    __pycache__/
    .env

    5. 提交初始代码:将项目初始文件提交到 GitHub 仓库:

    bash
    git add .
    git commit -m "Initial commit"
    git push -u origin main

3. API 设计:定义端点和数据模型

在开始编写代码之前,良好的 API 设计至关重要。我们需要明确 API 的功能、端点、请求方法、请求参数和响应数据。

假设我们要构建一个简单的图书管理 API,包含以下功能:

  • 获取所有图书
  • 获取指定 ID 的图书
  • 添加一本新书
  • 更新一本现有图书
  • 删除一本图书

根据这些功能,我们可以设计如下 API 端点:

端点 请求方法 描述
/books/ GET 获取所有图书
/books/{book_id} GET 获取指定 ID 的图书
/books/ POST 添加一本新书
/books/{book_id} PUT 更新一本现有图书
/books/{book_id} DELETE 删除一本图书

接下来,我们需要定义数据模型。使用 Pydantic 可以轻松定义数据模型,并进行数据验证:

```python

models.py

from pydantic import BaseModel
from typing import Optional

class Book(BaseModel):
id: int
title: str
author: str
description: Optional[str] = None
publication_year: int
```

4. 代码实现:构建 FastAPI 应用

4.1 创建主文件

创建一个名为 main.py 的文件,作为 FastAPI 应用的主文件:

```python

main.py

from fastapi import FastAPI, HTTPException
from typing import List
from models import Book # 导入我们定义的模型

app = FastAPI()

模拟数据库

books_db = [
Book(id=1, title="The Hitchhiker's Guide to the Galaxy", author="Douglas Adams", publication_year=1979),
Book(id=2, title="Pride and Prejudice", author="Jane Austen", publication_year=1813),
]

@app.get("/books/", response_model=List[Book])
async def get_all_books():
return books_db

@app.get("/books/{book_id}", response_model=Book)
async def get_book(book_id: int):
for book in books_db:
if book.id == book_id:
return book
raise HTTPException(status_code=404, detail="Book not found")

@app.post("/books/", response_model=Book)
async def create_book(book: Book):
books_db.append(book)
return book

@app.put("/books/{book_id}", response_model=Book)
async def update_book(book_id: int, updated_book: Book):
for i, book in enumerate(books_db):
if book.id == book_id:
books_db[i] = updated_book
return updated_book
raise HTTPException(status_code=404, detail="Book not found")

@app.delete("/books/{book_id}")
async def delete_book(book_id: int):
for i, book in enumerate(books_db):
if book.id == book_id:
del books_db[i]
return {"message": "Book deleted"}
raise HTTPException(status_code=404, detail="Book not found")
```

4.2 代码解析

  • 导入必要的模块FastAPI, HTTPException, List, Book
  • 创建 FastAPI 实例app = FastAPI()
  • 模拟数据库books_db 列表用于模拟存储图书数据。
  • 定义路由:使用 @app.get, @app.post, @app.put, @app.delete 装饰器定义不同的 HTTP 方法和路径。
  • 类型提示:使用 Python 类型提示指定请求参数和响应数据的类型。
  • 数据验证:FastAPI 会自动根据 Pydantic 模型进行数据验证。
  • 错误处理:使用 HTTPException 抛出 HTTP 错误。
  • 异步函数:使用 async def 定义异步函数,提高并发处理能力。
  • response_model: 指定响应数据的类型.

4.3 运行应用

使用 Uvicorn 运行 FastAPI 应用:

bash
uvicorn main:app --reload

--reload 选项会在代码修改后自动重启服务器,方便开发调试。

现在,你可以在浏览器中访问 http://127.0.0.1:8000/docs 查看自动生成的 API 文档(Swagger UI),并进行交互式测试。

5. 测试:确保 API 的质量

编写测试用例是确保 API 质量的重要环节。FastAPI 提供了便捷的测试工具,可以轻松编写单元测试和集成测试。

5.1 安装测试依赖

bash
pip install pytest httpx

5.2 编写测试用例

创建一个名为 test_main.py 的文件,编写测试用例:

```python

test_main.py

from fastapi.testclient import TestClient
from main import app
from models import Book

client = TestClient(app)

def test_get_all_books():
response = client.get("/books/")
assert response.status_code == 200
assert isinstance(response.json(), list)

def test_get_book():
response = client.get("/books/1")
assert response.status_code == 200
assert response.json()["title"] == "The Hitchhiker's Guide to the Galaxy"

def test_create_book():
new_book = Book(id=3, title="New Book", author="New Author", publication_year=2023)
response = client.post("/books/", json=new_book.dict())
assert response.status_code == 200
assert response.json()["title"] == "New Book"

def test_update_book():
updated_book = Book(id=1, title="Updated Title", author="Updated Author", publication_year=2024)
response = client.put("/books/1", json=updated_book.dict())
assert response.status_code == 200
assert response.json()["title"] == "Updated Title"

def test_delete_book():
response = client.delete("/books/2")
assert response.status_code == 200
assert response.json() == {"message": "Book deleted"}

def test_get_nonexistent_book():
response = client.get("/books/999")
assert response.status_code == 404
```

5.3 运行测试

使用 pytest 运行测试:

bash
pytest

pytest 会自动发现并运行 test_*.py 文件中的测试用例。

6. 部署:将 API 上线

将 FastAPI 应用部署到生产环境有多种方式,这里介绍一种常用的方式:使用 Docker 和 Docker Compose。

6.1 创建 Dockerfile

创建一个名为 Dockerfile 的文件,用于构建 Docker 镜像:

```dockerfile

Dockerfile

FROM python:3.9

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
```

6.2 创建 requirements.txt

创建一个 requirements.txt 文件,列出项目依赖:

fastapi==0.95.0 # 替换为你使用的版本号
uvicorn==0.21.1 # 替换为你使用的版本号
pydantic==1.10.7 # 替换为你使用的版本号

6.3 创建 docker-compose.yml (可选)

如果你需要使用 Docker Compose 管理多个服务,可以创建一个 docker-compose.yml 文件:

```yaml

docker-compose.yml

version: "3.9"
services:
web:
build: .
ports:
- "8000:80"
```

6.4 构建和运行 Docker 镜像

使用 Docker 构建镜像:

bash
docker build -t my-fastapi-app .

运行 Docker 容器:

bash
docker run -d -p 8000:80 my-fastapi-app

或者使用 Docker Compose:

bash
docker-compose up -d

现在,你的 FastAPI 应用已经在 Docker 容器中运行,可以通过 http://localhost:8000 访问。

7. 持续集成:自动化构建和测试

持续集成(CI)可以帮助你自动化构建、测试和部署流程,提高开发效率和代码质量。GitHub Actions 是 GitHub 提供的 CI/CD 服务,可以轻松集成到你的项目中。

7.1 创建 GitHub Actions 工作流

在项目根目录下创建一个名为 .github/workflows 的目录,然后在其中创建一个 YAML 文件,例如 ci.yml

```yaml

.github/workflows/ci.yml

name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: '3.9'

- name: Install dependencies
  run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt

- name: Run tests
  run: |
    pytest

```

7.2 工作流解析

  • name:工作流的名称。
  • on:触发工作流的事件,这里配置了在 main 分支上的 pushpull_request 事件。
  • jobs:定义工作流中的任务。
  • build:任务的名称。
  • runs-on:指定运行任务的操作系统。
  • steps:定义任务中的步骤。
    • uses: actions/checkout@v3:检出代码。
    • uses: actions/setup-python@v4:设置 Python 环境。
    • run: pip install -r requirements.txt:安装依赖。
    • run: pytest:运行测试。

7.3 提交工作流文件

.github/workflows/ci.yml 文件提交到 GitHub 仓库。

现在,每次你向 main 分支推送代码或创建 Pull Request 时,GitHub Actions 都会自动运行你的 CI 工作流,执行构建和测试。你可以在 GitHub 仓库的 "Actions" 标签页中查看工作流的运行状态和结果。

8. 进阶:数据库集成、身份验证和安全性

8.1 数据库集成

FastAPI 可以轻松集成各种数据库,例如 PostgreSQL、MySQL、SQLite 等。你可以使用 ORM(对象关系映射)工具,如 SQLAlchemy 或 Tortoise ORM,来简化数据库操作。

以下是使用 SQLAlchemy 和 PostgreSQL 的示例:

  1. 安装依赖

    bash
    pip install sqlalchemy asyncpg psycopg2-binary

    2. 创建数据库模型

    ```python

    models.py

    from sqlalchemy import create_engine, Column, Integer, String
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker

    DATABASE_URL = "postgresql://user:password@host:port/database"

    engine = create_engine(DATABASE_URL)
    SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

    Base = declarative_base()

    class BookDB(Base):
    tablename = "books"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True)
    author = Column(String)
    description = Column(String, nullable=True)
    publication_year = Column(Integer)
    

    ```
    3. 修改 API 端点

    ```python

    main.py

    from fastapi import Depends
    from sqlalchemy.orm import Session
    from models import BookDB, Book, SessionLocal, engine

    ... (其他代码)

    Base.metadata.create_all(bind=engine)

    def get_db():
    db = SessionLocal()
    try:
    yield db
    finally:
    db.close()

    @app.get("/books/", response_model=List[Book])
    async def get_all_books(db: Session = Depends(get_db)):
    books = db.query(BookDB).all()
    return books

    @app.get("/books/{book_id}", response_model=Book)
    async def get_book(book_id: int, db: Session = Depends(get_db)):
    book = db.query(BookDB).filter(BookDB.id == book_id).first()
    if book is None:
    raise HTTPException(status_code=404, detail="Book not found")
    return book

    @app.post("/books/", response_model=Book)
    async def create_book(book: Book, db: Session = Depends(get_db)):
    db_book = BookDB(**book.dict())
    db.add(db_book)
    db.commit()
    db.refresh(db_book)
    return db_book

    ...类似地修改 update 和 delete 端点

    ```

8.2 身份验证和安全性

保护你的 API 免受未经授权的访问至关重要。FastAPI 提供了多种身份验证和授权机制,例如:

  • API 密钥:简单的 API 密钥验证。
  • OAuth2:基于 OAuth2 的身份验证和授权,支持多种授权流程。
  • JWT:JSON Web Token,用于在客户端和服务器之间安全地传输用户信息。

你可以使用 FastAPI 的 fastapi.security 模块来实现这些机制。

8.3 安全性最佳实践

  • 使用 HTTPS:始终使用 HTTPS 加密 API 通信,防止数据泄露。
  • 输入验证:对所有用户输入进行严格验证,防止注入攻击。
  • 速率限制:限制 API 的请求速率,防止 DDoS 攻击。
  • CORS:配置跨域资源共享(CORS),控制哪些来源可以访问你的 API。
  • 安全头部:设置适当的安全头部,例如 X-Frame-OptionsX-XSS-Protection 等。
  • 定期更新依赖:及时更新 FastAPI 和其他依赖库,修复安全漏洞。
  • 最小权限原则:为 API 用户分配最小必要的权限。
  • 日志和监控:记录 API 的访问日志和错误日志,并设置监控系统,及时发现异常情况。

9. 总结

本文详细介绍了如何使用 FastAPI 和 GitHub 开发一个实用的 Web API。我们涵盖了从项目初始化、API 设计、代码实现、测试、部署到持续集成的全过程,并提供了详细的代码示例和最佳实践。

FastAPI 是一个强大而灵活的 Web 框架,能够帮助你快速构建高性能、易于维护的 API。结合 GitHub 的版本控制和协作功能,以及 GitHub Actions 的 CI/CD 服务,你可以实现高效的 API 开发流程。

希望本文能帮助你掌握 FastAPI 和 GitHub 在 Web API 开发中的应用,并构建出高质量的 API 服务。

THE END