一个优雅的fastapi脚手架

一个优雅的fastapi脚手架

内容纲要

这是一个开箱即用的FastAPI脚手架,集成了ORM模型、JWT认证、日志系统、异常处理、路由注册、系统配置、调度任务等常用的模块。

FastAPI是一个用于构建API的现代、高性能的Python web框架,由于它只提供app核心,因此需要我们自己组织项目结构,通常得编写一些Web API项目必备的功能模块。对此,我在github上搜索相关的最佳实践,然而没有找到心仪的脚手架,所以决定封装一个FastAPI骨架项目。

设计思想

  • 层级结构清晰
  • 简洁优雅
  • 易于扩展
  • 开箱即用

项目结构

源码GitHub地址 -> kaxiluo/fastapi-skeleton

/kaxiluo/fastapi-skeleton/
|-- app
|   |-- commands                                ----- 放置一些命令行
|   |   `-- __init__.py
|   |-- exceptions                              ----- 自定义的异常类
|   |   |-- __init__.py
|   |   `-- exception.py
|   |-- http                                    ----- http目录
|   |   |-- api                                 ----- api控制器目录
|   |   |   |-- __init__.py
|   |   |   |-- auth.py                         ----- 登录认证api的控制器
|   |   |   |-- demo.py
|   |   |   `-- users.py
|   |   |-- middleware                          ----- 放置自定义中间件
|   |   |   `-- __init__.py
|   |   |-- __init__.py
|   |   `-- deps.py                             ----- 依赖
|   |-- jobs                                    ----- 调度任务
|   |   |-- __init__.py
|   |   `-- demo_job.py
|   |-- models                                  ----- 模型目录
|   |   |-- __init__.py
|   |   |-- base_model.py                       ----- 定义模型的基类
|   |   `-- user.py
|   |-- providers                               ----- 核心服务提供者
|   |   |-- __init__.py
|   |   |-- app_provider.py                     ----- 注册应用的全局事件、中间件等
|   |   |-- database.py                         ----- 数据库连接
|   |   |-- handle_exception.py                 ----- 异常处理器
|   |   |-- logging_provider.py                 ----- 集成loguru日志系统
|   |   `-- route_provider.py                   ----- 注册路由文件routes/*
|   |-- schemas                                 ----- 数据模型,负责请求和响应资源数据的定义和格式转换
|   |   |-- __init__.py
|   |   `-- user.py
|   |-- services                                ----- 服务层,业务逻辑层
|   |   |-- auth                                ----- 认证相关服务
|   |   |   |-- __init__.py
|   |   |   |-- grant.py                        ----- 认证核心类
|   |   |   |-- hashing.py
|   |   |   |-- jwt_helper.py
|   |   |   |-- oauth2_schema.py
|   |   |   `-- random_code_verifier.py
|   |   `-- __init__.py
|   |-- support                                 ----- 公共方法
|   |   |-- __init__.py
|   |   `-- helper.py
|   `-- __init__.py
|-- bootstrap                                   ----- 启动项
|   |-- __init__.py
|   |-- application.py                          ----- 创建app实例
|   `-- scheduler.py                            ----- 创建调度器实例
|-- config                                      ----- 配置目录
|   |-- auth.py                                 ----- 认证-JWT配置
|   |-- config.py                               ----- app配置
|   |-- database.py                             ----- 数据库配置
|   `-- logging.py                              ----- 日志配置
|-- database
|   `-- migrations                              ----- 初始化SQL
|       `-- 2022_09_07_create_users_table.sql
|-- routes                                      ----- 路由目录
|   |-- __init__.py
|   `-- api.py                                  ----- api路由
|-- storage
|   `-- logs                                    ----- 日志目录
|-- README.md
|-- main.py                                     ----- app/api启动入口
|-- requirements.txt
`-- scheduler.py                                ----- 调度任务启动入口

集成的模块

  • 日志系统

集成 loguru,一个优雅、简洁的日志库

  • 异常处理

定义认证异常类,注册 Exception Handler

  • 路由注册

路由集中注册,按模块划分为不同的文件,代码层次结构清晰

  • 系统配置

基于 pydantic.BaseSettings,使用 .env 文件设置环境变量。配置文件按功能模块划分,默认定义了app基础配置、数据库配置(mysql+redis)、日志配置、认证配置

  • 数据库 ORM模型

基于 peewee,一个轻量级的Python ORM框架

  • 中间件

默认注册了全局CORS中间件

  • JWT认证

默认提供了账号密码和手机号验证码两种认证方式。框架易于扩展新的认证方式。

测试登录认证请先执行初始化的SQL:fastapi-skeleton/database/migrations/*.sql

注:验证码的存储依赖redis

  • 调度任务

基于 APScheduler 调度任务框架

注:定时任务与api是分开启动的

运行

  1. 执行初始化SQL:/database/migrations/2022_09_07_create_users_table.sql

  2. API

uvicorn main:app --host 0.0.0.0 --port 8080
  1. 调度器
python scheduler.py 

关于部署部分,参见我的另一篇文章 fastapi部署

参考

FastAPI官方中文文档

FastAPI作者的全栈项目脚手架 full-stack-fastapi-postgresql

代码结构组织风格参考 Laravel框架

6条评论

    1. 老大,使用您的作品初步运行报错,能帮忙瞅一眼问题吗(Python版本 3.11)?:
      File “C:\Users\jeffr\Dev\Python\py-center\venv\Lib\site-packages\pydantic\main.py”, line 292, in __new__
      cls.__signature__ = ClassAttribute(‘__signature__’, generate_model_signature(cls.__init__, fields, config))
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File “C:\Users\jeffr\Dev\Python\py-center\venv\Lib\site-packages\pydantic\utils.py”, line 258, in generate_model_signature
      merged_params[param_name] = Parameter(
      ^^^^^^^^^^
      File “C:\Python311\Lib\inspect.py”, line 2715, in __init__
      raise ValueError(‘{!r} is not a valid parameter name’.format(name))
      ValueError: ‘not’ is not a valid parameter name

      Jeffrey Shou
  1. 大佬有微信吗? 想加您好友吗,方便交流。
    class Settings(BaseSettings):
    JWT_TTL: int = 60 * 24 * 8
    JWT_SECRET_KEY: str = “”
    JWT_ALGORITHM: str = ‘HS256’

    class Config:
    env_file = “.env”
    env_file_encoding = ‘utf-8’
    另外想问一下,Config的配置有什么作用的呢

    leslie

发表回复

您的电子邮箱地址不会被公开。