Files
FastapiAdmin/backend/pyproject.toml
T
zhangtao ce9401196a chore(deploy): 成品部署链路、依赖分组与运维基建
部署方式:服务器不再接收源码、不执行构建,改为本地构建成品后交付
- deploy-artifacts.sh:构建→备份→校验→原子替换,支持回滚、镜像/备份轮转、
  mysql 与 postgres 双变体镜像;后端以 docker save|ssh|docker load 交付
- 依赖分组:requirements/{base,storage}.txt + db/{mysql,postgres,sqlite}.txt,
  镜像按所选数据库只装对应驱动(MySQL 变体 565MB → 521MB)

编排与运行时加固
- compose:MySQL/Redis/backend 端口仅绑 127.0.0.1;密钥(SECRET_KEY、
  DATA_ENCRYPTION_KEY、DATA_ENCRYPTION_OLD_KEYS)、PROD_CORS_ORIGINS、
  FORWARDED_ALLOW_IPS、DEMO_ENABLE 一律由 docker/.env 注入
- Dockerfile:对齐依赖分组、以非 root(uid=1000) 运行;.dockerignore 排除全部真实 .env.*
- nginx:静态资源长缓存、隐藏文件拒绝、接口文档仅内网可访问、放行 ACME http-01 校验路径

工程基建
- 新增 CI:backend(uv sync + ruff + pytest)与 frontend(web type-check+vitest、app type-check)
- 新增 DEPLOYMENT.md 运维手册(部署/回滚/密钥轮换/每日巡检/证书/排查)
2026-10-04 04:26:03 +08:00

158 lines
5.3 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[project]
name = "backend"
version = "3.2.0"
description = "fastapiadmin后端工程"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"agno==2.5.8",
"aiofiles==24.1.0", # 文件操作
"alembic==1.18.4", # 数据库迁移
"apscheduler==3.11.0", # 定时任务
"bleach==6.4.0", # 过滤 HTML 标签
"click==8.1.7", # 命令行参数解析
"croniter==6.2.4", # cron 表达式校验
"fastapi==0.138.2", # fastapi 框架
"greenlet==3.5.2", # 协程核心依赖(SQLAlchemy 异步)
"httpx==0.28.1", # HTTP 客户端
"jinja2==3.1.6", # 模板引擎(代码生成 + 遗留模板)
"loguru==0.7.3", # 日志
"openpyxl==3.1.5", # Excel 文件处理
"psutil==7.2.2", # 系统信息
"py-ip2region==3.0.4", # IP 归属地离线查询(内置 xdb,无外网请求)
"pydantic-settings>=2.6.1,<3", # 配置设置
"pyjwt==2.13.0", # OAuth2
"python-multipart==0.0.32", # request.form() 对表单进行「解析」时安装
"redis==7.1.0", # redis 异步操作数据库
"rich==15.0.0", # 终端打印美化
"sqlalchemy==2.0.51", # 数据库ORM
"sqlglot[rs]==27.8.0", # sql 解析
"tinycss2==1.5.1", # bleach CSS 清洗依赖
"typer==0.26.7", # 命令行工具
"ua-parser==1.0.2", # 解析 User-Agent 获取 OS/浏览器
"uvicorn==0.49.0", # uvicorn web 框架
"websockets>=16.0,<17.0", # websocket 通信
"aiosqlite==0.22.1", # 内嵌知识库(app/modules/ai/chat)固定使用 sqlite,故列入核心
"openai==2.46.0",
"pydantic[email]>=2.12.5",
"cryptography==50.0.0", # Fernet 对称加密(存储源密码加密)
"paramiko==5.0.0", # SFTP 协议
"boto3==1.43.72", # S3 协议
"esdk-obs-python==3.26.6", # 华为云 OBS 协议
"alibabacloud-oss-v2==1.3.2", # 阿里云 OSS 协议
"cos-python-sdk-v5==1.9.44",
]
# 数据库驱动按需安装:uv sync --extra mysql / --extra postgres / --extra sqlite
# 默认(不指定 extra)只装核心依赖,启动时会提示缺少对应驱动
[project.optional-dependencies]
mysql = [
"aiomysql>=0.2.0", # 异步驱动(ASYNC_DB_URI)
"pymysql==1.2.0", # 同步驱动(DB_URI)
]
postgres = [
"asyncpg==0.31.0", # 异步驱动(ASYNC_DB_URI)
"psycopg[binary]==3.3.2", # 同步驱动(DB_URI,自带 libpq)
]
sqlite = [
"aiosqlite==0.22.1",
]
# 一个进程同时支持三种库(体积最大,适合本地开发)
all-db = [
"aiomysql>=0.2.0",
"pymysql==1.2.0",
"asyncpg==0.31.0",
"psycopg[binary]==3.3.2",
"aiosqlite==0.22.1",
]
[dependency-groups]
dev = [
"fakeredis>=2.21.0,<3", # 测试:内存 Redis,配合 TESTING
"pytest==9.0.2",
"pytest-asyncio>=0.24.0", # 异步测试支持
"ruff==0.14.13", # 代码检查/格式化
]
[tool.uv]
default-groups = ["dev"] # 本地 uv sync 含 dev;生产 pip -r requirements.txt 不含 pytest/ruff/fakeredis
[[tool.uv.index]]
name = "tuna"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
[tool.ruff]
line-length = 200
indent-width = 4
preview = false
fix = true
show-fixes = true
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
]
extend-include = ["*.pyw"]
[tool.ruff.lint]
select = [
"FAST",
"F",
"E",
"W",
"F",
"I",
"B",
"C4",
"UP",
]
ignore = [
"E501", # line too long, handled by black
"B008", # do not perform function calls in argument defaults
"C901", # too complex
"W191", # indentation contains tabs
"B904", # Within an `except` clause
"B010", # Do not call with a constant attribute value.
"B009", # Do not use getattr() with a constant attribute value.
"E712", # Avoid equality comparisons to `False`; use `not getattr(self.model, "is_deleted"):` for false checks
"W293", # blank line with whitespace
]
[tool.ruff.lint.per-file-ignores]
"tests/conftest.py" = ["E402"] # 先设置 TESTING/SQLite 环境再 import 应用
[tool.ruff.format]
docstring-code-format = true
preview = false
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"