Unstract Backend 完全指南:Django + Celery 后端服务的本地搭建、异步队列与 API 契约管理
【免费下载链接】unstractLLM-Driven Extraction of Unstructured Data — Built for API Deployments & ETL Pipeline Workflows项目地址: https://gitcode.com/GitHub_Trending/un/unstract
本文基于 Unstract 仓库的 backend/README.md 展开,系统讲解该 Django/DRF 后端服务的依赖环境搭建、环境变量配置、默认账号认证体系、基于 Celery + RabbitMQ 的异步执行架构(队列、autoscaling、监控面板)、Postgres 直连操作,以及 API 部署 OpenAPI 契约的生成与漂移检查机制。读完后可独立完成后端本地启动、Worker 拉起、凭据定制和 spec 重新生成。
一、定位与核心依赖
Unstract 后端由 Django 与 Django REST Framework 编写,负责构建和调度围绕非结构化数据的 ETL 流水线。仓库中 backend/pyproject.toml 明确其项目描述为 "Unstract backend built with Django to build and schedule ETL pipelines around unstructured data",要求 Python>=3.12,<3.13,核心依赖包括django==4.2.30、djangorestframework==3.17.1、celery[amqp]>=5.3.4、django-celery-beat==2.5.0、django-redis==5.4.0、drf-spectacular==0.30.0等,并内嵌引用了unstract-core、unstract-connectors、unstract-tool-registry等本仓库内的可编辑(editable)本地包。
后端运行依赖三个外部基础设施,README 明确列出:
- Postgres— 主数据库;
- Redis— 缓存、日志与状态跟踪(如执行状态 tracker、限流锁);
- RabbitMQ— Celery 消息 Broker。
从 backend/sample.env 可以看到三者的连接变量约定:
# Postgres DB envs DB_HOST='unstract-db' DB_USER='unstract_dev' DB_PASSWORD='unstract_pass' DB_NAME='unstract_db' DB_PORT=5432 DB_SCHEMA="unstract" # Redis REDIS_HOST="unstract-redis" REDIS_PORT=6379 REDIS_PASSWORD="" REDIS_USER=default # Celery Configuration # Used by celery and to connect to queue to push logs CELERY_BROKER_BASE_URL="amqp://unstract-rabbitmq:5672//" CELERY_BROKER_USER=admin CELERY_BROKER_PASS=password二、本地安装与启动
2.1 创建虚拟环境(基于 UV)
所有命令假设已在backend/目录内激活venv,并假定已安装 UV:
# Create venv and install dependencies uv venv source .venv/bin/activate # On Windows: .venv\Scripts\activate uv sync2.2 依赖安装分组
backend/pyproject.toml 通过[dependency-groups]声明了三组依赖,可精确安装:
# Install dependencies uv sync # Install specific dev dependency group(pytest、poethepoet、debugpy 等) uv sync --group dev # Install production dependencies only(gunicorn、OpenTelemetry 等) uv sync --group deploy从 pyproject.toml 的分组定义看,dev组包含pytest、poethepoet、debugpy、inotify(文件监听)以及本地unstract-*包;test组单独声明了pytest-django与jsonschema(注释说明 schema 测试直接 import jsonschema,显式声明可避免传递依赖变化导致测试静默跳过);deploy组包含gunicorn~=23.0与 OpenTelemetry 发行包。此外[tool.uv.constraint-dependencies]将numpy<2.0.0、pandas<2.2.0作为约束,以解决 Python 3.12 与 Numpy 2.0 的兼容问题。
2.3 脚本与命令执行
UV 支持直接运行服务目录内的脚本:
uv run sample_script.py2.4 配置 .env 并启动服务器
按计划,启动 Django 服务器前需确保 Postgres/Redis/RabbitMQ 已就绪(本地或 docker compose 方式)。将sample.env复制为.env并按需修改,本地直连的典型取值如下(README 原文示例):
DJANGO_SETTINGS_MODULE='backend.settings.dev' DB_HOST='localhost' DB_USER='unstract_dev' DB_PASSWORD='unstract_pass' DB_NAME='unstract_db' DB_PORT=5432其中DJANGO_SETTINGS_MODULE指向 backend/backend/settings/dev.py,该模块在 base.py 基础上开启DEBUG = True并追加localhost:3000、frontend.unstract.localhost等 CORS 来源,适合本地联调。
随后应用迁移并启动开发服务器:
# 若修改过模型,先生成迁移 uv run manage.py makemigrations # 应用迁移并启动服务 uv run manage.py migrate uv run manage.py runserver localhost:8000服务启动后运行在 8000 端口(http://localhost:8000)。
补充:生产容器内不走
runserver,而是通过 backend/entrypoint.sh 以 Gunicorn 启动(--worker-class gthread,GUNICORN_WORKERS/GUNICORN_THREADS环境变量可调)。脚本注释解释了一个关键调参逻辑:Gunicorn 线程数必须大于并发浏览器标签数,因为每个打开的 Socket.IO WebSocket 会独占一个线程直至关闭;线程池惰性创建,因此高上限在空闲时零成本。
三、认证体系:默认凭据与修改规范
3.1 默认账号
首次部署的默认登录凭据为:用户名unstract,密码unstract。这一默认值来自 backend/backend/settings/base.py 中的DEFAULT_AUTH_USERNAME = os.environ.get("DEFAULT_AUTH_USERNAME", "unstract"),即环境变量未设置时回退到unstract。
3.2 初始化自定义凭据
如需修改默认用户名/密码:
- 打开由 backend/sample.env 复制生成的
/backend/.env; - 将
DEFAULT_AUTH_USERNAME与DEFAULT_AUTH_PASSWORD更新为强且唯一的凭据; - 保存并重启服务使变更生效。
sample.env中对应位置(默认留空,空值即回退默认凭据):
# Default user auth credentials DEFAULT_AUTH_USERNAME= DEFAULT_AUTH_PASSWORD=3.3 初始化之后更新凭据
首次部署后更新方式相同:修改/backend/.env中DEFAULT_AUTH_USERNAME=your_new_username、DEFAULT_AUTH_PASSWORD=your_new_password,保存后重启backend服务,之后即可用新凭据登录。
3.4 重要注意事项
DEFAULT_AUTH_USERNAME不得与任何 Django superuser 或 admin 账号的username相同,保持二者分离以确保安全、避免冲突;- 使用强且唯一的凭据保护系统;
- 认证系统会以
/backend/.env中指定的值校验凭据。
从源码结构看,MOCK_USER等内部常量直接引用settings.DEFAULT_AUTH_USERNAME(见 backend/account_v2/constants.py),说明该变量同时参与内部用户模拟逻辑,改动时需注意其影响面。
四、异步执行:Celery 队列、Worker 与监控
项目使用 Celery 处理异步执行:任务经多个队列分发、由 Worker 消费。README 强调ETL、TASK 与 API Deployment 任务均由这些异步 Worker 处理,日志管理同样依赖 Celery。
4.1 队列一览
| Queue Name | 说明 | 承载任务 |
|---|---|---|
celery | 默认队列,处理未指定队列的通用任务 | Webhook 通知、Pipeline(ETL、Tasks)执行 |
celery_periodic_logs | 将日志持久化到数据库的队列 | — |
celery_log_task_queue | 向 WebSocket 客户端推送日志的队列 | — |
celery_api_deployments | 管理 API 部署任务的队列 | — |
从 backend/backend/celery_config.py 可以印证并补充更多细节:
- 结果后端:Celery 结果直接写入 Postgres,
result_backend为db+postgresql://.../{CELERY_BACKEND_DB_NAME}(CELERY_BACKEND_DB_NAME可选,默认回退到DB_NAME,见sample.env注释); - 序列化:任务与结果统一 JSON(
task_serializer = "json"),并开启result_extended = True; - 调度器:
beat_scheduler = "django_celery_beat.schedulers:DatabaseScheduler",周期任务存库管理; task_acks_late = True:任务确认延后到执行完成,降低 Worker 崩溃时任务丢失的风险;- HA 模式:当
RABBITMQ_HA_ENABLED=true时,配置在 import 期将celery、celery_api_deployments、celery_periodic_logs、celery_log_task_queue、dashboard_metric_events五个队列声明为x-queue-type: quorum(quorum 队列),并将 QoS 语义改为 per-consumer prefetch,因为 quorum 队列不支持 channel 级全局 QoS。
4.2 启动执行 Worker
celery -A backend worker --loglevel=info -Q <queue_name>4.3 Worker 自动伸缩(Autoscaling)
celery -A backend worker --loglevel=info -Q <queue_name> --autoscale=<max_workers>,<min_workers>Celery 支持按负载动态调整 Worker 进程数,README 给出的取值建议:
- max_workers:与 CPU 资源和所需并发度相关。
- CPU 密集型任务:设为接近或略高于 CPU 核心数;
- I/O 密集型任务:可设更高,通常为 CPU 核心数的 2–3 倍;
- min_workers:始终常驻的最少 Worker 进程数。
实战佐证:backend/pyproject.toml 的
[tool.poe.tasks]中内置了 dashboard metrics Worker 的启动任务celery -A backend worker --loglevel=info -Q dashboard_metric_events --autoscale 4,1,即"最大 4、常驻 1"的伸缩配置,可直接照抄到自己的队列上。
4.4 Worker 监控:Flower
前提:当前环境已安装 flower 包。启动命令:
celery -A backend flowerFlower 默认监听 5555 端口,浏览器访问即可获得友好的 Web 界面,用于监控和管理 Celery 任务。pyproject.toml 中同样提供了等价任务poe flower(celery -A backend flower --port=5555),另有poe beat启动 Celery Beat 调度器、poe worker-metrics启动 metrics Worker。
4.5 Broker 监控:RabbitMQ 管理台
RabbitMQ 自带 Web 管理界面:
- 访问
http://localhost:15672; - 默认凭据:
admin/password; - 可通过环境变量
RABBITMQ_DEFAULT_USER、RABBITMQ_DEFAULT_PASS配置(README 指出其定义于 docker 侧的 essentials 环境文件)。
五、连接 Postgres
连接 docker compose 中运行的 Postgres 的完整步骤:
- 进入 postgres 容器的 shell:
docker compose exec -it db bash- 以指定用户连接数据库:
psql -d unstract_db -U unstract_dev- 在该 shell 中直接执行 PSQL 命令即可。
六、API 文档:OpenAPI 契约的提交与漂移检查
API 部署端点的 OpenAPI 规范提交在 specs/docstudio-oss.json,它是已发布客户端及其生成 SDK 的构建契约,运行时并不提供该文件。规则是:任何路由、serializer 或 schema 注解变更,必须在同一个 PR中重新生成:
uv run python manage.py generate_docstudio_spec # 重写已提交的 spec uv run python manage.py generate_docstudio_spec --check # 只检查不落盘,存在漂移则报错该命令的实现位于 backend/api_v2/management/commands/generate_docstudio_spec.py,源码揭示了若干工程质量细节:
- 生成基于
api_v2.deployment_spec_urls这份专用 URL 配置(drf-spectacular的SchemaGenerator),只覆盖 API 部署面; - 若 spectacular 报告了任何解析 error/warning(即存在"猜测"的 schema),命令直接失败——宁可失败也不发布一份描述不出真实行为的契约;
- 生成的路径必须全部位于公共挂载前缀
/deployment/之下,若检测到API_DEPLOYMENT_PATH_PREFIX改变了挂载点而污染了产物,会拒绝生成; - 产物使用
sort_keys的规范化 JSON 输出,使"字节级一致"成为可用的漂移信号;--check模式下磁盘文件与重新渲染结果不一致即报out of date,并提示下游unstract-python-client与unstract-cli需要联动发 PR。
配套的漂移测试见 backend/api_v2/tests/test_docstudio_spec.py,它与命令共享同一渲染函数,避免"校验用的副本"与"生成产物"不一致。
README 同时索引了两份端点级文档:Account(account/api_doc.md)与 FileManagement。
七、连接器:Google Drive
Google Drive 连接器基于 PyDrive2 库实现,且仅支持 OAuth 2.0 认证。配置步骤:按 Google OAuth 文档完成客户端凭据申请,然后在backend/.env中填入:
GOOGLE_OAUTH2_KEY="<client-id>" GOOGLE_OAUTH2_SECRET="<client-secret>"这两个变量在 backend/sample.env 中对应GOOGLE_OAUTH2_KEY=与GOOGLE_OAUTH2_SECRET=(默认空)。此外sample.env还预留了 SharePoint 的 Azure AD OAuth 变量(AZUREAD_TENANT_OAUTH2_KEY/SECRET),配合social-auth-app-django实现第三方授权。
八、Tool Registry
工具的添加与维护机制在 unstract/tool-registry/README.md 中有专门说明。后端通过TOOL_REGISTRY_CONFIG_PATH(sample.env中默认/data/tool_registry_config)指定工具注册目录,TOOL_REGISTRY_STORAGE_CREDENTIALS指定其存储后端(示例为 local)。
九、附录(Archived / EXPERIMENTAL)
以下内容在 README 中标记为归档实验性内容。
9.1 访问 Admin 站点
- 首次使用时创建 superuser,按屏幕提示操作:
python manage.py createsuperuser- 在
<app>/admin.py中注册模型,例如:
from django.contrib import admin from .models import Prompt admin.site.register(Prompt)- 确保服务器运行后访问
/admin端点。
注意:这与 3.4 节的安全约束呼应——admin/superuser 账号与
DEFAULT_AUTH_USERNAME应保持分离。
9.2 运行单元测试
单元测试基于 pytest 与 pytest-django:
pytest pytest prompt # 运行名为 prompt 的 app测试按 app 组织,例如prompt/tests/test_urls.py。
注意:运行测试不需要 Django 服务器在线,但数据库必须在运行。从 backend/pyproject.toml 的[tool.pytest.ini_options]可见,默认addopts = "--no-migrations"(跳过迁移回放、直接从模型建表,避免 xdist 每个 Worker 重放一遍迁移历史);python_files同时匹配test_*.py、*_test.py、*_tests.py、tests.py;并定义了integration(需要真实 Postgres/Redis 基础设施)与critical_path(path_id)(配合tests/critical_paths.yaml声明关键路径覆盖)两个 marker。测试环境变量由 backend/conftest.py 通过 python-dotenv 直接加载test.env(仓库提供 backend/sample.test.env)。
十、快速核对清单
| 事项 | 命令 / 入口 |
|---|---|
| 安装依赖 | uv sync(可选--group dev/--group deploy) |
| 数据库迁移 | uv run manage.py migrate |
| 启动开发服务器 | uv run manage.py runserver localhost:8000 |
| 启动指定队列 Worker | celery -A backend worker --loglevel=info -Q <queue_name> |
| Flower 监控 | celery -A backend flower(端口 5555) |
| RabbitMQ 管理台 | http://localhost:15672(admin / password) |
| 重新生成 OpenAPI 契约 | uv run python manage.py generate_docstudio_spec [--check] |
| 进入 Postgres | docker compose exec -it db bash→psql -d unstract_db -U unstract_dev |
以上内容与 backend/README.md 保持一致,并以仓库内 backend/pyproject.toml、backend/sample.env、backend/backend/celery_config.py、backend/entrypoint.sh 及 backend/api_v2/management/commands/generate_docstudio_spec.py 的源码实现作为佐证。适用前提:Python 3.12、UV 工具链,以及 Postgres/Redis/RabbitMQ 三项依赖可用(本地进程或 docker compose 服务名均可)。
【免费下载链接】unstractLLM-Driven Extraction of Unstructured Data — Built for API Deployments & ETL Pipeline Workflows项目地址: https://gitcode.com/GitHub_Trending/un/unstract
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考