AdCloud Server

面向开发者和 coding agent 的广告云埋点与广告推送后端。使用 FastAPI 开发,Python 依赖和虚拟环境统一由 uv 管理。

已实现 /v1 Gateway 路由、匿名身份签发、ID 映射图谱、可信身份 Stitch、稀疏画像及历史事件回溯。 画像可按部署设置选择关系库读取或 Cassandra 宽表投影;身份图谱保持关系库事务一致性。 广告业务目前仅有路由探测,尚未实现投放引擎。邮箱/手机号 OTP 和具体 OAuth 登录需要由调用方接入验证。

本地开发(无需安装数据库服务)

uv sync --locked
uv run python scripts/init_local_env.py
uv run uvicorn adcloud_server.main:app --reload --host 127.0.0.1 --port 8000

初始化脚本生成被 Git 忽略的 .env,权限 0600,包含本地开发所需随机 secret,不输出 secret 值,不覆盖已有文件。 SQLite 数据存放于 .data/,同样不提交。身份服务缺少 IDENTITY_SECRET 时返回 503,系统健康接口仍可用。 环境变量优先于 .env。生产 HTTPS 部署将 COOKIE_SECURE 设置为 true。

  • 系统健康检查:http://localhost:8000/health
  • API 文档:http://localhost:8000/docs
  • OpenAPI:http://localhost:8000/openapi.json

另一个终端可运行 uv run python scripts/demo_identity.py,演示匿名访问、埋点、临时画像、模拟验证后 Stitch 及继承结果。 演示脚本使用合成的已验证身份,不代替实际 OTP/OAuth 校验。

HTTP Gateway

HTTPS :443 (Nginx,终止 TLS)
  ├── /v1/events/*    → 事件接收、历史查询
  ├── /v1/users/*     → 稀疏用户画像
  ├── /v1/ads/*       → 广告业务模块(待实现)
  ├── /v1/identity/*  → 匿名 ID、解析、拼接与图谱
  └── /v1/...        → 后续业务模块
                         ↓
                  FastAPI 127.0.0.1:8000

各模块当前共用一个进程,独立注册在 api/v1/router.py 中;Nginx 为各域预留独立 upstream。 未知路由返回 404、不支持的方法返回 405。保留各模块 /health 探测以及旧系统 /health。 默认 CORS 允许 localhost:3000、5173、5174,启用 credentials;匿名写请求检查浏览器 Origin。

deploy/nginx.conf.example 放在 Nginx http {} 上下文,替换域名和证书路径后在部署环境执行 nginx -t。 精确匹配 /v1/events 防止 POST 被重定向为带尾斜杠路径,所有转发保留 /v1、业务前缀和查询参数。 配置未在本机部署或验证,未启动 443、未申请证书。API 文档仅通过内部地址访问。

Identity Resolution / Stitching

详见 身份图谱与存储配置,包含接口、合并策略、共享设备处理和 PostgreSQL / Cassandra 部署选择。

  • Cookie / token 只证明匿名设备持有,不能自行提交 verified=true 合并账户。
  • Stitch、图谱、画像读写和历史查询仅允许携带 SERVICE_TOKEN 的可信后端。
  • 匿名事件保留原始 ID,通过 alias 在合并后即时归入 Master ID。
  • PostgreSQL JSONB / SQLite JSON 省略空属性;Cassandra 可选宽表投影通过事务 outbox 同步和故障重试。
  • 图谱主库始终是关系库,不提供纯 Cassandra、HBase 或 Bigtable 图谱实现。

检查

uv run pytest
uv run ruff check .
uv run ruff format --check .

默认测试使用临时 SQLite 和可恢复的投影替身,不安装、不启动数据库服务。 PostgreSQL、Cassandra 联调入口默认跳过,等提供专用测试环境后使用:

uv sync --locked --extra postgres --extra cassandra
  • 设置 ADCLOUD_TEST_POSTGRES_URL 为专用测试 PostgreSQL 的 SQLAlchemy URL,然后运行 uv run --extra postgres pytest tests/test_postgres.py。
  • 设置 ADCLOUD_TEST_CASSANDRA_HOSTS、ADCLOUD_TEST_CASSANDRA_KEYSPACE 和可选的 PORT、USERNAME、PASSWORD、TLS、CA_FILE,同前缀环境变量配置;先在专用集群应用 deploy/cassandra.cql,再运行 uv run --extra cassandra pytest tests/test_cassandra.py。

联调测试使用独立随机租户,不自动创建 Cassandra 集群。PostgreSQL 测试会创建初始表并保留测试租户数据,需使用专用测试数据库。

Docker / CI/CD

Dockerfile 提供 test、runtime 两个目标;Gitea Actions 在 main 推送后构建、测试并部署到 runner 的 Docker daemon,默认映射宿主机 18080 到容器 8000。 详细配置、runner 要求、公网端口、持久化和回滚见 Docker 部署说明。

测试部署使用 compose.yml 编排 PostgreSQL、Cassandra、API 与画像 worker;CI 运行全部数据库集成测试,公网 API 默认 http://47.76.92.159:18080/docs。详见 Docker 部署文档。

事件字典与标准特征

已录入 33 个标准事件,涵盖访问与内容、电商交易、注册留资、广告和推送,支持客户事件别名、参数版本、草稿试算、不可变规则发布、停用和回滚。 默认接收端必须携带应用接入凭据及已发布事件版本;未注册或参数不符的事件不入库。 新增 adcloud-events worker 将事件按冻结的规则版本转成可去重的标准特征贡献;画像提供时间窗口和上限,身份缝合后自动汇总。 本地可运行 uv run adcloud-events,Cassandra 模式还需 uv run adcloud-profiles。 完整目录、API、配置和兼容说明见 事件注册表。 开发者控制台已加入事件字典页面;客户账号登录和角色授权尚未接入,目前使用应用范围管理凭据。

广告主控制台

新增独立 /v1/advertiser 注册登录、主子账户和项目 API。广告主身份与终端流量用户 identity 分离;详细接口、部署要求和首版边界见 广告主 API。广告主认证不依赖 IDENTITY_SECRET,应用启动会初始化共享数据库。

S
Description
AdCloud tracking and ad delivery server for developers and coding agents; Python/FastAPI with uv
Readme 274 KiB
Languages
Python 93.9%
Shell 5%
Dockerfile 0.8%
CQL 0.3%