# evai-api **Repository Path**: lmh110/evai ## Basic Information - **Project Name**: evai-api - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-18 - **Last Updated**: 2026-05-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # evai-api 一个基于 `aiohttp` 的轻量服务框架:核心启动在 `main.py`,业务接口以插件形式(`plugins/*.py`)“插拔式”注册,便于后续扩展新模块。 ## 目录结构 - `main.py`:服务入口(加载 `.env`、初始化日志、加载插件、启动 aiohttp) - `plugins/`:插件(每个插件提供 `register(app)` 注册路由) - `agents/`:Agno Agent 封装(用于图片意图分析、关键词扩展等) - `cos_utils.py`:腾讯云 COS 上传工具(放大接口会用到) - `.env`:本地配置(不会提交,已在 `.gitignore` 忽略) - `.env.example`:配置模板 ## 快速启动 1) 复制配置并填写必要密钥: ```powershell copy .env.example .env ``` 2) 编辑 `.env`,至少需要: - `EVAI_PLUGIN_MODULES`:启用哪些插件 - `REPLICATE_API_TOKEN`:使用放大接口时必填 3) 启动服务: ```powershell python .\main.py ``` 健康检查: ```bash curl http://127.0.0.1:8188/health ``` ## 插件与接口 通过 `.env` 的 `EVAI_PLUGIN_MODULES` 启用插件(逗号分隔),例如: ```ini EVAI_PLUGIN_MODULES=plugins.upscale,plugins.image_intent,plugins.keyword_expansion ``` 如果你觉得写在一行不方便,可以把插件列表放到单独文件里(支持多行与 `#` 注释): 1) 复制示例文件: ```powershell copy .\plugin_modules.example.txt .\plugin_modules.txt ``` 2) 在 `.env` 配置: ```ini EVAI_PLUGIN_MODULES_FILE=plugin_modules.txt ``` 说明:服务会先读取 `EVAI_PLUGIN_MODULES_FILE`,再叠加 `EVAI_PLUGIN_MODULES`,并自动去重。 ## 简单防护(签名 + 限流) 如果前端需要直连本服务,建议: - Nginx 对 `/evai-api/` 做限流(例如:单 IP 每分钟不超过 10 次) - 前端每次请求都带签名头,服务端校验 `timestamp + nonce + HMAC-SHA256`,防止被简单抓包重放 ### 签名头 请求头(必填): - `X-EVAI-Timestamp`:秒级时间戳 - `X-EVAI-Nonce`:随机字符串(建议 UUID) - `X-EVAI-Signature`:HMAC-SHA256 签名(默认 hex;也支持 base64) - `X-EVAI-Signature-Format`:`hex`(默认)或 `base64` 服务端密钥(`.env`): - `EVAI_SIGNING_SECRET`:HMAC 密钥 - `EVAI_SIGNATURE_MAX_SKEW_SECONDS`:允许的时钟偏差(默认 60 秒) 签名串(按此顺序拼接,每项用 `\\n` 分隔): `timestamp + nonce + METHOD + path_with_query + sha256(body)` 说明: - `path_with_query` 建议用浏览器请求的原始路径(例如 `/evai-api/image/prompt/transform?x=1`) - body 为空时 `sha256(body)` 也需要计算(空字节的 sha256) ### 1) 图片放大(Replicate Real-ESRGAN) 插件:`plugins/upscale.py`(实现:`plugins/upscale_service.py`) 接口:`POST /replicate/esrgan` 请求 JSON: ```json { "image_url": "https://example.com/a.png", "scale": 2, "face_enhance": false } ``` 兼容字段:也支持 `image` / `url` 作为 `image_url` 的别名。 curl 示例: ```bash curl -X POST http://127.0.0.1:8188/replicate/esrgan \ -H "Content-Type: application/json" \ -d "{\"image_url\":\"https://example.com/a.png\",\"scale\":2,\"face_enhance\":false}" ``` ### 2) 图片意图分析(Agno Image Intent) 插件:`plugins/image_intent.py` 接口: - `GET /image/intent/options`:返回支持的类型/语言 - `POST /image/intent/analyze`:分析图片 请求 JSON: ```json { "image": "https://example.com/a.png", "analysis_type": "识别物体", "language": "中文", "question": "" } ``` 说明: - `analysis_type="自定义问题"` 且 `question` 为空时,会自动使用默认问题:`请描述这张图片的内容和风格` ### 3) 关键词扩展(Agno Expansion Word) 插件:`plugins/keyword_expansion.py` 接口:`POST /keywords/process` 请求 JSON: ```json { "keywords": "橘猫, 溪流, 夏日午后, 阳光, 鱼", "language": "中文", "seed": 0 } ``` ## 并发与性能(≈10 并发建议) 本项目的接口会调用第三方 SDK/HTTP/LLM(阻塞操作),已统一通过 `asyncio.to_thread` 放入线程池,避免阻塞事件循环;同时每个接口有并发上限(Semaphore)以防止过载。 建议在 `.env` 中配置: - `EVAI_THREADPOOL_WORKERS=32`:线程池大小(影响 `to_thread` 的吞吐) - `EVAI_BACKLOG=128`:TCP backlog - `EVAI_UPSCALE_CONCURRENCY=10` - `EVAI_IMAGE_INTENT_CONCURRENCY=10` - `EVAI_KEYWORD_CONCURRENCY=10` - `EVAI_IMAGE_CONNECT_TIMEOUT=30` / `EVAI_IMAGE_READ_TIMEOUT=300`:下载用户图片超时(图片意图分析) 并发超过上限时不会直接 429,而是会在服务端排队等待;排队太久可能导致客户端超时。 ## 网络与代理(可选) 如果需要通过代理访问外网(例如 Replicate),可在 `.env` 设置: ```ini HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 ``` ## 新增插件(扩展模块) 1) 新建 `plugins/xxx.py`,实现: ```python def register(app: web.Application) -> None: app.router.add_post("/your/path", handler) ``` 2) 在 `.env` 的 `EVAI_PLUGIN_MODULES` 中加入 `plugins.xxx`,重启服务即可生效。