From e8ff4b80f895c3b7fafdd795b6cd87c50ac42b72 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Tue, 29 Apr 2025 21:01:52 +0800 Subject: [PATCH] update --- Dockerfile | 15 ++- README.md | 51 +++++++- cryptoai/api/__init__.py | 7 +- .../api/__pycache__/__init__.cpython-313.pyc | Bin 223 -> 223 bytes cryptoai/routes/fastapi_app.py | 110 ++++++++++++++++++ cryptoai/routes/routes.py | 19 +++ docker-compose.yml | 43 ++++--- requirements.txt | 3 + run_api.py | 19 +++ 9 files changed, 249 insertions(+), 18 deletions(-) create mode 100644 cryptoai/routes/fastapi_app.py create mode 100644 cryptoai/routes/routes.py create mode 100644 run_api.py diff --git a/Dockerfile b/Dockerfile index cbecfc8..f392b8d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,6 +50,15 @@ ENV PYTHONPATH=/app # 创建数据和日志目录 RUN mkdir -p /app/cryptoai/data /app/cryptoai/logs -# 设置入口点 -ENTRYPOINT [] -CMD ["python", "run.py"] \ No newline at end of file +# 复制API启动脚本 +COPY run_api.py ./ + +# 暴露API端口 +EXPOSE 8000 + +# 启动命令行(使用CMD,方便docker-compose覆盖) +CMD ["python", "run.py"] + +# API服务启动方式: +# docker run -p 8000:8000 -e "COMMAND=api" your-image-name +# 或者在docker-compose.yml中设置command: python run_api.py \ No newline at end of file diff --git a/README.md b/README.md index 19453ae..f12f385 100644 --- a/README.md +++ b/README.md @@ -126,4 +126,53 @@ docker run cryptoai --run-once --agent crypto ## 数据库配置 -项目使用SQLAlchemy ORM连接MySQL数据库,用于存储分析结果。默认连接到远程MySQL服务器,可以通过环境变量或配置文件自定义连接信息。 \ No newline at end of file +项目使用SQLAlchemy ORM连接MySQL数据库,用于存储分析结果。默认连接到远程MySQL服务器,可以通过环境变量或配置文件自定义连接信息。 + +## API服务 + +项目现已集成FastAPI框架,提供了HTTP API接口,方便前端系统调用。 + +### 启动API服务 + +```bash +# 安装依赖 +pip install -r requirements.txt + +# 启动API服务 +python run_api.py +``` + +API服务默认运行在 `http://0.0.0.0:8000`,可以通过环境变量自定义主机和端口: + +```bash +API_HOST=127.0.0.1 API_PORT=8080 python run_api.py +``` + +### API文档 + +启动服务后,可以通过以下URL访问API文档: + +- Swagger UI: `http://localhost:8000/docs` +- ReDoc: `http://localhost:8000/redoc` + +### 主要API接口 + +- `GET /` - API信息 +- `GET /health` - 健康检查 +- `POST /api/analyze` - 分析加密货币市场趋势 +- `GET /api/token-usage` - 获取DeepSeek API的token使用统计 +- `POST /api/export-usage` - 导出token使用统计 + +### API调用示例 + +使用curl调用分析接口: + +```bash +curl -X POST "http://localhost:8000/api/analyze" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "分析比特币最近的市场趋势", + "symbol": "BTC", + "task_type": "市场分析" + }' +``` \ No newline at end of file diff --git a/cryptoai/api/__init__.py b/cryptoai/api/__init__.py index 203bca8..f651fd6 100644 --- a/cryptoai/api/__init__.py +++ b/cryptoai/api/__init__.py @@ -1,4 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -"""API模块,提供与外部API交互的功能。""" \ No newline at end of file +"""API模块,提供与外部API交互的功能。""" + +# from cryptoai.api.deepseek_api import DeepSeekAPI +# from cryptoai.api.binance_api import BinanceAPI +# from cryptoai.api.okx_api import OKXAPI +# from cryptoai.api.alltick_api import AlltickAPI \ No newline at end of file diff --git a/cryptoai/api/__pycache__/__init__.cpython-313.pyc b/cryptoai/api/__pycache__/__init__.cpython-313.pyc index a212f51372767b6171acb2534b6659ebe5f3f2b8..80ce14c506acd8ac6ccd4e14d6052a422268debc 100644 GIT binary patch delta 22 ccmcc5c%PB)GcPX}0}wPH5XjJEoXB?(07(7@I{*Lx delta 22 ccmcc5c%PB)GcPX}0}%XO&YO|OFp=*f08N+%)c^nh diff --git a/cryptoai/routes/fastapi_app.py b/cryptoai/routes/fastapi_app.py new file mode 100644 index 0000000..62f50ca --- /dev/null +++ b/cryptoai/routes/fastapi_app.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +FastAPI应用程序入口 +为CryptoAI系统提供web API接口层 +""" + +import os +import logging +import uvicorn +from fastapi import FastAPI, Request +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse +import time +from typing import Dict, Any + +from cryptoai.routes.routes import router as api_router + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + handlers=[ + logging.FileHandler("api_server.log"), + logging.StreamHandler() + ] +) +logger = logging.getLogger("fastapi") + +# 创建FastAPI应用 +app = FastAPI( + title="CryptoAI API", + description="加密货币AI分析系统API接口", + version="0.1.0" +) + +# 添加CORS中间件 +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # 可以设置为特定域名,如["http://localhost:3000"] + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# 添加API路由 +app.include_router(api_router) + +# 请求计时中间件 +@app.middleware("http") +async def add_process_time_header(request: Request, call_next): + start_time = time.time() + response = await call_next(request) + process_time = time.time() - start_time + response.headers["X-Process-Time"] = str(process_time) + return response + +# 根路由 +@app.get("/", tags=["信息"]) +async def root() -> Dict[str, Any]: + """ + API根路径,提供API基本信息 + """ + return { + "name": "CryptoAI API", + "version": "0.1.0", + "description": "加密货币AI分析系统API接口", + "documentation": "/docs", + "status": "running" + } + +# 健康检查 +@app.get("/health", tags=["信息"]) +async def health_check() -> Dict[str, Any]: + """ + API健康检查接口 + """ + return { + "status": "healthy", + "timestamp": time.time() + } + +# 异常处理 +@app.exception_handler(Exception) +async def global_exception_handler(request: Request, exc: Exception): + logger.error(f"全局异常: {str(exc)}", exc_info=True) + return JSONResponse( + status_code=500, + content={"detail": f"服务器内部错误: {str(exc)}"} + ) + +def start(): + """ + 启动FastAPI服务器 + """ + # 获取环境变量或使用默认值 + host = os.environ.get("API_HOST", "127.0.0.1") + port = int(os.environ.get("API_PORT", 8000)) + + # 启动服务器 + uvicorn.run( + "cryptoai.routes.fastapi_app:app", + host=host, + port=port, + reload=False # 生产环境设为False + ) + +if __name__ == "__main__": + start() \ No newline at end of file diff --git a/cryptoai/routes/routes.py b/cryptoai/routes/routes.py new file mode 100644 index 0000000..124a0cb --- /dev/null +++ b/cryptoai/routes/routes.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +API路由模块,为前端提供REST API接口 +""" + +import os +from fastapi import APIRouter, Depends, HTTPException, status, Body +from typing import Dict, Any, List, Optional +from pydantic import BaseModel +import json +import logging + +from cryptoai.api.deepseek_api import DeepSeekAPI +from cryptoai.utils.config_loader import ConfigLoader + +# 创建路由 +router = APIRouter(prefix="/api", tags=["加密AI接口"]) \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index bbe6490..bb49c44 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,20 +2,37 @@ version: '3.8' services: cryptoai: - build: - context: . - dockerfile: Dockerfile + build: . container_name: cryptoai - image: cryptoai:0.0.6 - restart: unless-stopped + image: cryptoai:0.0.7 + restart: always volumes: - # 挂载配置文件 - - ./cryptoai/config/config.yaml:/app/cryptoai/config/config.yaml - # 持久化数据和日志 - - cryptoai_data:/app/cryptoai/data - - cryptoai_logs:/app/logs + - ./cryptoai/data:/app/cryptoai/data + - ./cryptoai/logs:/app/cryptoai/logs + environment: + - TZ=Asia/Shanghai command: python run.py + networks: + - app-network -volumes: - cryptoai_data: - cryptoai_logs: \ No newline at end of file + cryptoai-api: + build: . + container_name: cryptoai-api + image: cryptoai-api:0.0.1 + restart: always + ports: + - "8000:8000" + volumes: + - ./cryptoai/data:/app/cryptoai/data + - ./cryptoai/logs:/app/cryptoai/logs + environment: + - TZ=Asia/Shanghai + - API_HOST=0.0.0.0 + - API_PORT=8000 + command: python run_api.py + networks: + - app-network + +networks: + app-network: + driver: bridge \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 5eaa603..36bbf07 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,9 @@ requests==2.31.0 schedule==1.2.0 scikit-learn==1.3.2 pyyaml==6.0.1 +fastapi==0.110.0 +uvicorn==0.27.1 +python-dotenv==1.0.0 # # 日志相关 # logging==0.4.9.6 # # 数据处理相关 diff --git a/run_api.py b/run_api.py new file mode 100644 index 0000000..8b5de08 --- /dev/null +++ b/run_api.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +CryptoAI API 服务启动脚本 +""" + +import os +import sys + +# 添加项目根目录到Python路径 +current_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(current_dir) + +from cryptoai.routes.fastapi_app import start + +if __name__ == "__main__": + print("启动 CryptoAI API 服务...") + start() \ No newline at end of file