后端初始化结构
This commit is contained in:
22
web/ws/backend/.env.example
Normal file
22
web/ws/backend/.env.example
Normal file
@@ -0,0 +1,22 @@
|
||||
# 项目信息
|
||||
PROJECT_NAME=PBMDB API
|
||||
VERSION=1.0.0
|
||||
API_V1_STR=/api/v1
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL=postgresql://webws_admin:your_password_here@postgres:5432/webws_database
|
||||
|
||||
# 安全配置
|
||||
SECRET_KEY=your-secret-key-here-change-in-production-use-at-least-32-chars
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=10080
|
||||
|
||||
# CORS 配置
|
||||
ALLOWED_ORIGINS=https://amiap.hzau.edu.cn,http://localhost:3000
|
||||
|
||||
# 文件上传配置
|
||||
MAX_UPLOAD_SIZE=104857600
|
||||
UPLOAD_DIR=/app/uploads
|
||||
|
||||
# 分页配置
|
||||
DEFAULT_PAGE_SIZE=20
|
||||
MAX_PAGE_SIZE=100
|
||||
38
web/ws/backend/.gitignore
vendored
Normal file
38
web/ws/backend/.gitignore
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
venv/
|
||||
env/
|
||||
ENV/
|
||||
*.egg-info/
|
||||
dist/
|
||||
build/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# 环境变量
|
||||
.env
|
||||
|
||||
# 数据库
|
||||
*.db
|
||||
*.sqlite3
|
||||
|
||||
# 上传文件
|
||||
uploads/
|
||||
*.log
|
||||
|
||||
# 测试
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
|
||||
# Alembic
|
||||
alembic/versions/*.pyc
|
||||
314
web/ws/backend/CONTRIBUTING.md
Normal file
314
web/ws/backend/CONTRIBUTING.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# 开发指南
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 本地开发
|
||||
|
||||
```bash
|
||||
# 1. 进入后端目录
|
||||
cd /vol1/1000/docker_server/traefik/web/ws/backend
|
||||
|
||||
# 2. 使用启动脚本(自动创建虚拟环境、安装依赖)
|
||||
./start.sh
|
||||
|
||||
# 或者手动启动
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
访问:
|
||||
- API 文档: http://localhost:8000/docs
|
||||
- 健康检查: http://localhost:8000/health
|
||||
|
||||
### Docker 开发
|
||||
|
||||
```bash
|
||||
cd /vol1/1000/docker_server/traefik/web/ws
|
||||
|
||||
# 构建镜像
|
||||
docker compose build backend
|
||||
|
||||
# 启动服务
|
||||
docker compose up -d backend
|
||||
|
||||
# 查看日志
|
||||
docker compose logs -f backend
|
||||
|
||||
# 进入容器
|
||||
docker compose exec backend bash
|
||||
```
|
||||
|
||||
## 开发流程
|
||||
|
||||
### 1. 添加新的 API 端点
|
||||
|
||||
**示例:添加实验数据 API**
|
||||
|
||||
```bash
|
||||
# 1. 创建端点文件
|
||||
touch app/api/v1/endpoints/experiments.py
|
||||
```
|
||||
|
||||
```python
|
||||
# app/api/v1/endpoints/experiments.py
|
||||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/")
|
||||
async def get_experiments():
|
||||
"""获取实验列表"""
|
||||
return {"experiments": []}
|
||||
|
||||
@router.get("/{experiment_id}")
|
||||
async def get_experiment(experiment_id: str):
|
||||
"""获取实验详情"""
|
||||
return {"id": experiment_id}
|
||||
```
|
||||
|
||||
```python
|
||||
# 2. 在 app/api/v1/router.py 中注册
|
||||
from app.api.v1.endpoints import experiments
|
||||
|
||||
api_router.include_router(
|
||||
experiments.router,
|
||||
prefix="/experiments",
|
||||
tags=["experiments"]
|
||||
)
|
||||
```
|
||||
|
||||
### 2. 添加数据模型
|
||||
|
||||
```bash
|
||||
# 创建模型文件
|
||||
touch app/models/experiment.py
|
||||
```
|
||||
|
||||
```python
|
||||
# app/models/experiment.py
|
||||
from sqlalchemy import Column, String, Integer, DateTime
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class Experiment(Base):
|
||||
__tablename__ = "experiments"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String(200))
|
||||
description = Column(String(1000))
|
||||
created_at = Column(DateTime)
|
||||
```
|
||||
|
||||
### 3. 添加 Pydantic 模式
|
||||
|
||||
```bash
|
||||
# 创建模式文件
|
||||
touch app/schemas/experiment.py
|
||||
```
|
||||
|
||||
```python
|
||||
# app/schemas/experiment.py
|
||||
from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
class ExperimentBase(BaseModel):
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
|
||||
class ExperimentCreate(ExperimentBase):
|
||||
pass
|
||||
|
||||
class ExperimentResponse(ExperimentBase):
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
```
|
||||
|
||||
### 4. 添加业务逻辑
|
||||
|
||||
```bash
|
||||
# 创建服务文件
|
||||
touch app/services/experiment_service.py
|
||||
```
|
||||
|
||||
```python
|
||||
# app/services/experiment_service.py
|
||||
from sqlalchemy.orm import Session
|
||||
from app.models.experiment import Experiment
|
||||
from app.schemas.experiment import ExperimentCreate
|
||||
|
||||
async def create_experiment(db: Session, data: ExperimentCreate):
|
||||
"""创建实验"""
|
||||
experiment = Experiment(**data.dict())
|
||||
db.add(experiment)
|
||||
db.commit()
|
||||
db.refresh(experiment)
|
||||
return experiment
|
||||
```
|
||||
|
||||
## 代码规范
|
||||
|
||||
### Python 风格
|
||||
|
||||
- 遵循 PEP 8 规范
|
||||
- 使用类型提示
|
||||
- 函数添加文档字符串
|
||||
|
||||
```python
|
||||
async def get_strain_detail(strain_id: str) -> dict:
|
||||
"""
|
||||
获取菌种详情
|
||||
|
||||
Args:
|
||||
strain_id: 菌种 ID
|
||||
|
||||
Returns:
|
||||
dict: 菌种详细信息
|
||||
|
||||
Raises:
|
||||
HTTPException: 菌种不存在时
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
### 命名规范
|
||||
|
||||
- 文件名:`snake_case.py`
|
||||
- 类名:`PascalCase`
|
||||
- 函数名:`snake_case`
|
||||
- 常量:`UPPER_CASE`
|
||||
|
||||
### 目录组织
|
||||
|
||||
```
|
||||
app/
|
||||
├── api/v1/endpoints/ # 按功能模块组织
|
||||
│ ├── strains.py # 菌种相关
|
||||
│ ├── genes.py # 基因相关
|
||||
│ └── upload.py # 上传相关
|
||||
├── models/ # 数据库模型
|
||||
├── schemas/ # 数据验证模式
|
||||
└── services/ # 业务逻辑
|
||||
```
|
||||
|
||||
## 测试
|
||||
|
||||
### 单元测试
|
||||
|
||||
```bash
|
||||
# 安装测试依赖
|
||||
pip install pytest pytest-asyncio httpx
|
||||
|
||||
# 运行测试
|
||||
pytest
|
||||
```
|
||||
|
||||
### API 测试
|
||||
|
||||
```bash
|
||||
# 使用测试脚本
|
||||
./test_api.sh
|
||||
|
||||
# 或使用 curl
|
||||
curl http://localhost:8000/health
|
||||
```
|
||||
|
||||
## 数据库迁移
|
||||
|
||||
```bash
|
||||
# 安装 alembic
|
||||
pip install alembic
|
||||
|
||||
# 初始化
|
||||
alembic init alembic
|
||||
|
||||
# 创建迁移
|
||||
alembic revision --autogenerate -m "Add experiments table"
|
||||
|
||||
# 执行迁移
|
||||
alembic upgrade head
|
||||
|
||||
# 回滚
|
||||
alembic downgrade -1
|
||||
```
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 1. 日志输出
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@router.get("/debug")
|
||||
async def debug_endpoint():
|
||||
logger.info("Debug endpoint called")
|
||||
logger.debug(f"Data: {data}")
|
||||
return {"status": "ok"}
|
||||
```
|
||||
|
||||
### 2. 断点调试
|
||||
|
||||
```python
|
||||
# 使用 pdb
|
||||
import pdb; pdb.set_trace()
|
||||
|
||||
# 或使用 breakpoint()
|
||||
breakpoint()
|
||||
```
|
||||
|
||||
### 3. 查看 SQL 查询
|
||||
|
||||
```python
|
||||
# 在配置中启用 SQL 日志
|
||||
DATABASE_URL = "postgresql://...?echo=true"
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 导入错误?
|
||||
|
||||
确保在项目根目录运行,并使用正确的 Python 路径:
|
||||
|
||||
```bash
|
||||
export PYTHONPATH=/vol1/1000/docker_server/traefik/web/ws/backend:$PYTHONPATH
|
||||
```
|
||||
|
||||
### Q: 数据库连接失败?
|
||||
|
||||
检查 `.env` 文件中的 `DATABASE_URL` 配置。
|
||||
|
||||
### Q: CORS 错误?
|
||||
|
||||
在 `app/core/config.py` 中添加允许的源。
|
||||
|
||||
## 部署检查清单
|
||||
|
||||
- [ ] 修改生产环境 `SECRET_KEY`
|
||||
- [ ] 配置正确的 `DATABASE_URL`
|
||||
- [ ] 更新 `ALLOWED_ORIGINS`
|
||||
- [ ] 运行数据库迁移
|
||||
- [ ] 测试所有 API 端点
|
||||
- [ ] 配置日志记录
|
||||
- [ ] 设置监控和告警
|
||||
- [ ] 备份数据库
|
||||
|
||||
## 贡献流程
|
||||
|
||||
1. 创建功能分支
|
||||
2. 开发并测试
|
||||
3. 提交代码(commit message 规范)
|
||||
4. 提交 Pull Request
|
||||
5. Code Review
|
||||
6. 合并到主分支
|
||||
|
||||
## 联系方式
|
||||
|
||||
如有问题,请联系开发团队。
|
||||
33
web/ws/backend/Dockerfile
Normal file
33
web/ws/backend/Dockerfile
Normal file
@@ -0,0 +1,33 @@
|
||||
# FastAPI 后端 Dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装系统依赖
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
postgresql-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 复制依赖文件
|
||||
COPY requirements.txt .
|
||||
|
||||
# 安装 Python 依赖
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 复制应用代码
|
||||
COPY app/ ./app/
|
||||
|
||||
# 创建上传目录
|
||||
RUN mkdir -p /app/uploads
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8000
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
|
||||
|
||||
# 启动命令
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
297
web/ws/backend/README.md
Normal file
297
web/ws/backend/README.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# FastAPI 后端项目
|
||||
|
||||
PBMDB (Plant Beneficial Microbe Database) 农业有益微生物综合信息数据库后端 API 服务。
|
||||
|
||||
## 📁 项目结构
|
||||
|
||||
```
|
||||
backend/
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # FastAPI 应用入口
|
||||
│ ├── api/
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── v1/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── router.py # API 路由汇总
|
||||
│ │ └── endpoints/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── strains.py # 菌种资源 API
|
||||
│ │ ├── genomes.py # 基因组学数据 API
|
||||
│ │ ├── genes.py # 基因资源 API
|
||||
│ │ ├── upload.py # 数据汇交上传 API
|
||||
│ │ └── analysis.py # 智能分析 API
|
||||
│ ├── core/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── config.py # 应用配置
|
||||
│ │ └── security.py # 认证安全
|
||||
│ ├── models/ # SQLAlchemy 数据模型
|
||||
│ │ └── __init__.py
|
||||
│ ├── schemas/ # Pydantic 数据模式
|
||||
│ │ └── __init__.py
|
||||
│ └── services/ # 业务逻辑层
|
||||
│ └── __init__.py
|
||||
├── requirements.txt # Python 依赖
|
||||
├── Dockerfile # Docker 构建文件
|
||||
├── .env.example # 环境变量示例
|
||||
└── README.md # 本文件
|
||||
```
|
||||
|
||||
## 🚀 技术栈
|
||||
|
||||
- **FastAPI**: 现代、高性能 Python Web 框架
|
||||
- **Uvicorn**: ASGI 服务器
|
||||
- **SQLAlchemy**: ORM 数据库工具
|
||||
- **PostgreSQL**: 关系型数据库
|
||||
- **Pydantic**: 数据验证和设置管理
|
||||
|
||||
## 🎯 核心功能模块
|
||||
|
||||
### 1. 菌种资源 (`/api/v1/strains`)
|
||||
- 菌种列表查询(分类、搜索、分页)
|
||||
- 菌种详情展示
|
||||
- 菌种分类树
|
||||
|
||||
### 2. 基因组学数据 (`/api/v1/genomes`)
|
||||
- 基因组数据列表(基因组学/转录组学/其他组学)
|
||||
- 基因组详情
|
||||
- 物种分类树
|
||||
|
||||
### 3. 基因资源 (`/api/v1/genes`)
|
||||
- 基因列表查询(功能分类)
|
||||
- 基因详情
|
||||
- 功能基因分类
|
||||
|
||||
### 4. 数据汇交 (`/api/v1/upload`)
|
||||
- 基因组数据上传
|
||||
- 宏基因组数据上传
|
||||
- 原始测序数据上传
|
||||
- 上传口令验证
|
||||
- 上传状态查询
|
||||
|
||||
### 5. 智能分析 (`/api/v1/analysis`)
|
||||
- 智能问答(基于知识图谱)
|
||||
- 基因挖掘(序列比对)
|
||||
- 菌株评估
|
||||
- 知识图谱查询
|
||||
- 分析任务状态查询
|
||||
|
||||
## ⚙️ 环境配置
|
||||
|
||||
### 1. 创建环境变量文件
|
||||
|
||||
```bash
|
||||
cd /vol1/1000/docker_server/traefik/web/ws/backend
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
编辑 `.env` 文件:
|
||||
|
||||
```bash
|
||||
# 项目信息
|
||||
PROJECT_NAME=PBMDB API
|
||||
VERSION=1.0.0
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL=postgresql://webws_admin:your_password@postgres:5432/webws_database
|
||||
|
||||
# 安全配置
|
||||
SECRET_KEY=your-secret-key-here-change-in-production
|
||||
|
||||
# CORS 配置
|
||||
ALLOWED_ORIGINS=https://amiap.hzau.edu.cn,http://localhost:3000
|
||||
|
||||
# 文件上传配置
|
||||
MAX_UPLOAD_SIZE=104857600
|
||||
UPLOAD_DIR=/app/uploads
|
||||
```
|
||||
|
||||
## 🏃 本地开发
|
||||
|
||||
### 使用虚拟环境
|
||||
|
||||
```bash
|
||||
cd /vol1/1000/docker_server/traefik/web/ws/backend
|
||||
|
||||
# 创建虚拟环境
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 安装依赖
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 运行开发服务器
|
||||
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
访问:
|
||||
- API 文档: http://localhost:8000/docs
|
||||
- ReDoc 文档: http://localhost:8000/redoc
|
||||
- 健康检查: http://localhost:8000/health
|
||||
|
||||
## 🐳 Docker 部署
|
||||
|
||||
### 1. 更新 docker-compose.yml
|
||||
|
||||
在 `/vol1/1000/docker_server/traefik/web/ws/docker-compose.yml` 中添加后端服务:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
# ... 现有服务 ...
|
||||
|
||||
backend:
|
||||
build: ./backend
|
||||
container_name: webws-backend
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
|
||||
volumes:
|
||||
- ./backend/uploads:/app/uploads
|
||||
networks:
|
||||
- frontend
|
||||
depends_on:
|
||||
- postgres
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
||||
# HTTP 路由 - 重定向到 HTTPS
|
||||
- "traefik.http.routers.webws-api-http.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/ABM/api`)"
|
||||
- "traefik.http.routers.webws-api-http.entrypoints=web"
|
||||
- "traefik.http.routers.webws-api-http.priority=100"
|
||||
- "traefik.http.routers.webws-api-http.middlewares=redirect-to-https"
|
||||
|
||||
# HTTPS 路由
|
||||
- "traefik.http.routers.webws-api-https.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/ABM/api`)"
|
||||
- "traefik.http.routers.webws-api-https.entrypoints=websecure"
|
||||
- "traefik.http.routers.webws-api-https.priority=100"
|
||||
- "traefik.http.routers.webws-api-https.tls.certresolver=myresolver"
|
||||
|
||||
# StripPrefix 中间件(移除 /ABM/api 前缀)
|
||||
- "traefik.http.routers.webws-api-https.middlewares=api-stripprefix"
|
||||
- "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/ABM/api"
|
||||
|
||||
- "traefik.http.services.webws-api.loadbalancer.server.port=8000"
|
||||
```
|
||||
|
||||
### 2. 构建并启动
|
||||
|
||||
```bash
|
||||
cd /vol1/1000/docker_server/traefik/web/ws
|
||||
|
||||
# 构建镜像
|
||||
docker compose build backend
|
||||
|
||||
# 启动服务
|
||||
docker compose up -d backend
|
||||
|
||||
# 查看日志
|
||||
docker compose logs -f backend
|
||||
```
|
||||
|
||||
## 📡 API 访问地址
|
||||
|
||||
部署后,API 通过以下地址访问:
|
||||
|
||||
- **外部访问**: https://amiap.hzau.edu.cn/ABM/api/
|
||||
- **API 文档**: https://amiap.hzau.edu.cn/ABM/api/docs
|
||||
- **容器间访问**: http://webws-backend:8000/
|
||||
|
||||
## 🔧 路由说明
|
||||
|
||||
### URL 路径处理
|
||||
|
||||
由于使用了 Traefik `StripPrefix` 中间件,路径会自动处理:
|
||||
|
||||
**用户访问**: `https://amiap.hzau.edu.cn/ABM/api/strains/`
|
||||
**FastAPI 接收**: `/api/v1/strains/` (已移除 `/ABM/api`)
|
||||
|
||||
### 路由优先级
|
||||
|
||||
```
|
||||
Priority 100: /ABM/api/** → 后端 API 服务
|
||||
Priority 47: /ABM/** → Nginx 静态文件服务
|
||||
```
|
||||
|
||||
不会产生冲突,Traefik 优先匹配更高优先级和更具体的路径。
|
||||
|
||||
## 📊 数据库迁移
|
||||
|
||||
### 使用 Alembic
|
||||
|
||||
```bash
|
||||
# 进入容器
|
||||
docker compose exec backend bash
|
||||
|
||||
# 初始化迁移(首次)
|
||||
alembic init alembic
|
||||
|
||||
# 创建迁移
|
||||
alembic revision --autogenerate -m "Initial migration"
|
||||
|
||||
# 执行迁移
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
## 🧪 测试 API
|
||||
|
||||
### 使用 curl
|
||||
|
||||
```bash
|
||||
# 健康检查
|
||||
curl https://amiap.hzau.edu.cn/ABM/api/health
|
||||
|
||||
# 获取菌种列表
|
||||
curl https://amiap.hzau.edu.cn/ABM/api/api/v1/strains/
|
||||
|
||||
# 获取基因组数据
|
||||
curl https://amiap.hzau.edu.cn/ABM/api/api/v1/genomes/
|
||||
```
|
||||
|
||||
### 使用 Swagger UI
|
||||
|
||||
访问 https://amiap.hzau.edu.cn/ABM/api/docs 进行交互式测试。
|
||||
|
||||
## 📝 开发指南
|
||||
|
||||
### 添加新的 API 端点
|
||||
|
||||
1. 在 `app/api/v1/endpoints/` 下创建新文件
|
||||
2. 定义路由和处理函数
|
||||
3. 在 `app/api/v1/router.py` 中注册路由
|
||||
|
||||
### 添加数据模型
|
||||
|
||||
1. 在 `app/models/` 下创建 SQLAlchemy 模型
|
||||
2. 在 `app/schemas/` 下创建 Pydantic 模式
|
||||
3. 运行数据库迁移
|
||||
|
||||
### 添加业务逻辑
|
||||
|
||||
在 `app/services/` 下创建服务层代码,保持控制器简洁。
|
||||
|
||||
## 🔒 安全注意事项
|
||||
|
||||
1. **生产环境**必须修改 `SECRET_KEY`
|
||||
2. 使用环境变量管理敏感信息
|
||||
3. 启用 HTTPS(已配置)
|
||||
4. 实现完整的认证系统(待实现)
|
||||
5. 添加请求频率限制
|
||||
|
||||
## 🚀 性能优化
|
||||
|
||||
1. 使用数据库连接池
|
||||
2. 启用查询缓存(Redis)
|
||||
3. 异步文件处理
|
||||
4. 压缩响应数据
|
||||
5. CDN 加速静态资源
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [FastAPI 官方文档](https://fastapi.tiangolo.com/)
|
||||
- [Pydantic 文档](https://docs.pydantic.dev/)
|
||||
- [SQLAlchemy 文档](https://docs.sqlalchemy.org/)
|
||||
- [Uvicorn 文档](https://www.uvicorn.org/)
|
||||
|
||||
## 📞 联系方式
|
||||
|
||||
如有问题,请联系项目维护团队。
|
||||
0
web/ws/backend/app/__init__.py
Normal file
0
web/ws/backend/app/__init__.py
Normal file
0
web/ws/backend/app/api/__init__.py
Normal file
0
web/ws/backend/app/api/__init__.py
Normal file
0
web/ws/backend/app/api/v1/__init__.py
Normal file
0
web/ws/backend/app/api/v1/__init__.py
Normal file
0
web/ws/backend/app/api/v1/endpoints/__init__.py
Normal file
0
web/ws/backend/app/api/v1/endpoints/__init__.py
Normal file
112
web/ws/backend/app/api/v1/endpoints/analysis.py
Normal file
112
web/ws/backend/app/api/v1/endpoints/analysis.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""
|
||||
智能分析 API
|
||||
"""
|
||||
from typing import Optional
|
||||
from fastapi import APIRouter, BackgroundTasks, HTTPException
|
||||
from pydantic import BaseModel
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
class QuestionRequest(BaseModel):
|
||||
"""智能问答请求"""
|
||||
question: str
|
||||
context: Optional[str] = None
|
||||
|
||||
|
||||
class GeneMiningRequest(BaseModel):
|
||||
"""基因挖掘请求"""
|
||||
sequence: str
|
||||
algorithm: str = "blast"
|
||||
parameters: Optional[dict] = None
|
||||
|
||||
|
||||
class StrainEvaluationRequest(BaseModel):
|
||||
"""菌株评估请求"""
|
||||
strain_id: str
|
||||
evaluation_type: str # growth/resistance/etc
|
||||
|
||||
|
||||
@router.post("/qa")
|
||||
async def intelligent_qa(request: QuestionRequest):
|
||||
"""
|
||||
智能问答
|
||||
|
||||
基于知识图谱的智能问答系统
|
||||
"""
|
||||
# TODO: 集成 AI 模型进行问答
|
||||
return {
|
||||
"question": request.question,
|
||||
"answer": "This is a placeholder answer. AI integration pending.",
|
||||
"confidence": 0.0
|
||||
}
|
||||
|
||||
|
||||
@router.post("/gene-mining")
|
||||
async def gene_mining(
|
||||
background_tasks: BackgroundTasks,
|
||||
request: GeneMiningRequest
|
||||
):
|
||||
"""
|
||||
基因挖掘
|
||||
|
||||
通过序列比对等方法挖掘功能基因
|
||||
"""
|
||||
# TODO: 实现基因挖掘算法
|
||||
# background_tasks.add_task(run_gene_mining, request)
|
||||
|
||||
return {
|
||||
"status": "processing",
|
||||
"task_id": "task_123",
|
||||
"message": "Gene mining task started"
|
||||
}
|
||||
|
||||
|
||||
@router.post("/strain-evaluation")
|
||||
async def strain_evaluation(
|
||||
background_tasks: BackgroundTasks,
|
||||
request: StrainEvaluationRequest
|
||||
):
|
||||
"""
|
||||
菌株评估
|
||||
|
||||
评估菌株的各项指标和应用潜力
|
||||
"""
|
||||
# TODO: 实现菌株评估逻辑
|
||||
return {
|
||||
"status": "processing",
|
||||
"task_id": "task_456",
|
||||
"message": "Strain evaluation started"
|
||||
}
|
||||
|
||||
|
||||
@router.get("/knowledge-graph")
|
||||
async def get_knowledge_graph(
|
||||
entity: Optional[str] = None,
|
||||
relationship: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
知识图谱查询
|
||||
|
||||
查询微生物知识图谱
|
||||
"""
|
||||
# TODO: 实现知识图谱查询
|
||||
return {
|
||||
"nodes": [],
|
||||
"edges": [],
|
||||
"message": "Knowledge graph feature pending"
|
||||
}
|
||||
|
||||
|
||||
@router.get("/task/{task_id}")
|
||||
async def get_analysis_task_status(task_id: str):
|
||||
"""
|
||||
查询分析任务状态
|
||||
"""
|
||||
# TODO: 从数据库或缓存查询任务状态
|
||||
return {
|
||||
"task_id": task_id,
|
||||
"status": "completed",
|
||||
"progress": 100,
|
||||
"result": None
|
||||
}
|
||||
56
web/ws/backend/app/api/v1/endpoints/genes.py
Normal file
56
web/ws/backend/app/api/v1/endpoints/genes.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
基因资源 API
|
||||
"""
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Query, HTTPException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_genes(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
function_type: Optional[str] = None,
|
||||
search: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
获取基因列表
|
||||
|
||||
- **skip**: 跳过记录数
|
||||
- **limit**: 返回记录数
|
||||
- **function_type**: 功能类型 (抗逆/促生/杀虫/抗病/其他)
|
||||
- **search**: 搜索关键词
|
||||
"""
|
||||
# TODO: 实现数据库查询
|
||||
return {
|
||||
"total": 0,
|
||||
"items": [],
|
||||
"skip": skip,
|
||||
"limit": limit
|
||||
}
|
||||
|
||||
|
||||
@router.get("/{gene_id}")
|
||||
async def get_gene_detail(gene_id: str):
|
||||
"""
|
||||
获取基因详情
|
||||
"""
|
||||
# TODO: 从数据库查询基因详细信息
|
||||
raise HTTPException(status_code=404, detail="Gene not found")
|
||||
|
||||
|
||||
@router.get("/functions/categories")
|
||||
async def get_gene_functions():
|
||||
"""
|
||||
获取基因功能分类
|
||||
"""
|
||||
return {
|
||||
"categories": [
|
||||
{"id": 1, "name": "抗逆基因", "count": 0},
|
||||
{"id": 2, "name": "促生基因", "count": 0},
|
||||
{"id": 3, "name": "杀虫基因", "count": 0},
|
||||
{"id": 4, "name": "抗病基因", "count": 0},
|
||||
{"id": 5, "name": "其他功能基因", "count": 0},
|
||||
]
|
||||
}
|
||||
51
web/ws/backend/app/api/v1/endpoints/genomes.py
Normal file
51
web/ws/backend/app/api/v1/endpoints/genomes.py
Normal file
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
基因组学数据 API
|
||||
"""
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Query, HTTPException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_genomes(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
data_type: Optional[str] = None,
|
||||
species: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
获取基因组数据列表
|
||||
|
||||
- **skip**: 跳过记录数
|
||||
- **limit**: 返回记录数
|
||||
- **data_type**: 数据类型 (基因组学/转录组学/其他组学)
|
||||
- **species**: 物种名称
|
||||
"""
|
||||
# TODO: 实现数据库查询
|
||||
return {
|
||||
"total": 0,
|
||||
"items": [],
|
||||
"skip": skip,
|
||||
"limit": limit
|
||||
}
|
||||
|
||||
|
||||
@router.get("/{genome_id}")
|
||||
async def get_genome_detail(genome_id: str):
|
||||
"""
|
||||
获取基因组详情
|
||||
"""
|
||||
# TODO: 从数据库查询基因组详细信息
|
||||
raise HTTPException(status_code=404, detail="Genome not found")
|
||||
|
||||
|
||||
@router.get("/species/tree")
|
||||
async def get_species_tree():
|
||||
"""
|
||||
获取物种分类树
|
||||
"""
|
||||
# TODO: 返回物种分类树结构
|
||||
return {
|
||||
"tree": []
|
||||
}
|
||||
56
web/ws/backend/app/api/v1/endpoints/strains.py
Normal file
56
web/ws/backend/app/api/v1/endpoints/strains.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
菌种资源 API
|
||||
"""
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Query, HTTPException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_strains(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
category: Optional[str] = None,
|
||||
search: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
获取菌种列表
|
||||
|
||||
- **skip**: 跳过记录数
|
||||
- **limit**: 返回记录数
|
||||
- **category**: 菌种分类 (抗逆/促生/杀虫/抗病/食药用)
|
||||
- **search**: 搜索关键词
|
||||
"""
|
||||
# TODO: 实现数据库查询
|
||||
return {
|
||||
"total": 0,
|
||||
"items": [],
|
||||
"skip": skip,
|
||||
"limit": limit
|
||||
}
|
||||
|
||||
|
||||
@router.get("/{strain_id}")
|
||||
async def get_strain_detail(strain_id: str):
|
||||
"""
|
||||
获取菌种详情
|
||||
"""
|
||||
# TODO: 从数据库查询菌种详细信息
|
||||
raise HTTPException(status_code=404, detail="Strain not found")
|
||||
|
||||
|
||||
@router.get("/categories/tree")
|
||||
async def get_strain_categories():
|
||||
"""
|
||||
获取菌种分类树
|
||||
"""
|
||||
return {
|
||||
"categories": [
|
||||
{"id": 1, "name": "抗逆微生物", "count": 0},
|
||||
{"id": 2, "name": "促生微生物", "count": 0},
|
||||
{"id": 3, "name": "杀虫微生物", "count": 0},
|
||||
{"id": 4, "name": "抗病微生物", "count": 0},
|
||||
{"id": 5, "name": "食药用微生物", "count": 0},
|
||||
]
|
||||
}
|
||||
107
web/ws/backend/app/api/v1/endpoints/upload.py
Normal file
107
web/ws/backend/app/api/v1/endpoints/upload.py
Normal file
@@ -0,0 +1,107 @@
|
||||
"""
|
||||
数据汇交上传 API
|
||||
"""
|
||||
from typing import Optional
|
||||
from fastapi import APIRouter, UploadFile, File, Form, HTTPException, BackgroundTasks
|
||||
from app.core.security import verify_upload_key
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/verify-key")
|
||||
async def verify_key(key: str = Form(...)):
|
||||
"""
|
||||
验证上传口令
|
||||
"""
|
||||
is_valid = await verify_upload_key(key)
|
||||
if not is_valid:
|
||||
raise HTTPException(status_code=401, detail="Invalid upload key")
|
||||
return {"status": "success", "message": "Key verified"}
|
||||
|
||||
|
||||
@router.post("/genome")
|
||||
async def upload_genome_data(
|
||||
background_tasks: BackgroundTasks,
|
||||
project_id: str = Form(...),
|
||||
submitter_name: str = Form(...),
|
||||
submitter_email: str = Form(...),
|
||||
upload_key: str = Form(...),
|
||||
file: Optional[UploadFile] = File(None),
|
||||
):
|
||||
"""
|
||||
上传基因组数据
|
||||
|
||||
支持逐条提交和批量上传
|
||||
"""
|
||||
# 验证口令
|
||||
if not await verify_upload_key(upload_key):
|
||||
raise HTTPException(status_code=401, detail="Invalid upload key")
|
||||
|
||||
# TODO: 处理文件上传
|
||||
if file:
|
||||
# 异步保存文件
|
||||
filename = file.filename
|
||||
# background_tasks.add_task(save_file, file, filename)
|
||||
|
||||
# TODO: 保存到数据库
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "Data uploaded successfully",
|
||||
"project_id": project_id
|
||||
}
|
||||
|
||||
|
||||
@router.post("/metagenome")
|
||||
async def upload_metagenome_data(
|
||||
background_tasks: BackgroundTasks,
|
||||
project_id: str = Form(...),
|
||||
submitter_name: str = Form(...),
|
||||
upload_key: str = Form(...),
|
||||
file: Optional[UploadFile] = File(None),
|
||||
):
|
||||
"""
|
||||
上传宏基因组数据
|
||||
"""
|
||||
if not await verify_upload_key(upload_key):
|
||||
raise HTTPException(status_code=401, detail="Invalid upload key")
|
||||
|
||||
# TODO: 实现宏基因组数据上传逻辑
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "Metagenome data uploaded",
|
||||
"project_id": project_id
|
||||
}
|
||||
|
||||
|
||||
@router.post("/raw-data")
|
||||
async def upload_raw_data(
|
||||
background_tasks: BackgroundTasks,
|
||||
project_id: str = Form(...),
|
||||
upload_key: str = Form(...),
|
||||
file: UploadFile = File(...),
|
||||
):
|
||||
"""
|
||||
上传原始测序数据
|
||||
"""
|
||||
if not await verify_upload_key(upload_key):
|
||||
raise HTTPException(status_code=401, detail="Invalid upload key")
|
||||
|
||||
# TODO: 实现原始数据上传逻辑
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "Raw data uploaded",
|
||||
"filename": file.filename
|
||||
}
|
||||
|
||||
|
||||
@router.get("/status/{upload_id}")
|
||||
async def get_upload_status(upload_id: str):
|
||||
"""
|
||||
查询上传状态
|
||||
"""
|
||||
# TODO: 从数据库查询上传状态
|
||||
return {
|
||||
"upload_id": upload_id,
|
||||
"status": "processing",
|
||||
"progress": 50
|
||||
}
|
||||
14
web/ws/backend/app/api/v1/router.py
Normal file
14
web/ws/backend/app/api/v1/router.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
API v1 路由汇总
|
||||
"""
|
||||
from fastapi import APIRouter
|
||||
from app.api.v1.endpoints import strains, genomes, genes, upload, analysis
|
||||
|
||||
api_router = APIRouter()
|
||||
|
||||
# 注册各模块路由
|
||||
api_router.include_router(strains.router, prefix="/strains", tags=["strains"])
|
||||
api_router.include_router(genomes.router, prefix="/genomes", tags=["genomes"])
|
||||
api_router.include_router(genes.router, prefix="/genes", tags=["genes"])
|
||||
api_router.include_router(upload.router, prefix="/upload", tags=["upload"])
|
||||
api_router.include_router(analysis.router, prefix="/analysis", tags=["analysis"])
|
||||
0
web/ws/backend/app/core/__init__.py
Normal file
0
web/ws/backend/app/core/__init__.py
Normal file
43
web/ws/backend/app/core/config.py
Normal file
43
web/ws/backend/app/core/config.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
应用配置
|
||||
"""
|
||||
from typing import List
|
||||
from pydantic_settings import BaseSettings
|
||||
from pydantic import AnyHttpUrl
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""应用配置类"""
|
||||
|
||||
# 项目信息
|
||||
PROJECT_NAME: str = "PBMDB API"
|
||||
VERSION: str = "1.0.0"
|
||||
API_V1_STR: str = "/api/v1"
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL: str = "postgresql://webws_admin:password@postgres:5432/webws_database"
|
||||
|
||||
# CORS 配置
|
||||
ALLOWED_ORIGINS: List[str] = [
|
||||
"https://amiap.hzau.edu.cn",
|
||||
"http://localhost:3000", # 本地开发
|
||||
]
|
||||
|
||||
# 安全配置
|
||||
SECRET_KEY: str = "your-secret-key-here-change-in-production"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 7 # 7 days
|
||||
|
||||
# 文件上传配置
|
||||
MAX_UPLOAD_SIZE: int = 1024 * 1024 * 100 # 100MB
|
||||
UPLOAD_DIR: str = "/app/uploads"
|
||||
|
||||
# 分页配置
|
||||
DEFAULT_PAGE_SIZE: int = 20
|
||||
MAX_PAGE_SIZE: int = 100
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
case_sensitive = True
|
||||
|
||||
|
||||
settings = Settings()
|
||||
39
web/ws/backend/app/core/security.py
Normal file
39
web/ws/backend/app/core/security.py
Normal file
@@ -0,0 +1,39 @@
|
||||
"""
|
||||
安全认证模块
|
||||
"""
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional
|
||||
from fastapi import Depends, HTTPException, status
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
|
||||
|
||||
security = HTTPBearer()
|
||||
|
||||
|
||||
async def verify_token(
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security)
|
||||
) -> dict:
|
||||
"""
|
||||
验证 Token
|
||||
"""
|
||||
token = credentials.credentials
|
||||
# TODO: 实现 JWT token 验证逻辑
|
||||
return {"user_id": "example"}
|
||||
|
||||
|
||||
async def verify_upload_key(key: str) -> bool:
|
||||
"""
|
||||
验证上传口令
|
||||
用于数据汇交功能
|
||||
"""
|
||||
# TODO: 从数据库或配置中验证口令
|
||||
valid_keys = ["temp_key_123"] # 临时示例
|
||||
return key in valid_keys
|
||||
|
||||
|
||||
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
|
||||
"""
|
||||
创建访问令牌
|
||||
"""
|
||||
# TODO: 实现 JWT token 生成
|
||||
return "temporary_token"
|
||||
43
web/ws/backend/app/main.py
Normal file
43
web/ws/backend/app/main.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
FastAPI 应用入口
|
||||
"""
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from app.core.config import settings
|
||||
from app.api.v1.router import api_router
|
||||
|
||||
app = FastAPI(
|
||||
title=settings.PROJECT_NAME,
|
||||
version=settings.VERSION,
|
||||
description="PBMDB (Plant Beneficial Microbe Database) API",
|
||||
docs_url="/docs",
|
||||
redoc_url="/redoc",
|
||||
)
|
||||
|
||||
# CORS 配置
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=settings.ALLOWED_ORIGINS,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# 注册路由
|
||||
app.include_router(api_router, prefix="/api/v1")
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
"""健康检查端点"""
|
||||
return {
|
||||
"status": "ok",
|
||||
"message": "PBMDB API is running",
|
||||
"version": settings.VERSION
|
||||
}
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health_check():
|
||||
"""健康检查"""
|
||||
return {"status": "healthy"}
|
||||
0
web/ws/backend/app/models/__init__.py
Normal file
0
web/ws/backend/app/models/__init__.py
Normal file
0
web/ws/backend/app/schemas/__init__.py
Normal file
0
web/ws/backend/app/schemas/__init__.py
Normal file
0
web/ws/backend/app/services/__init__.py
Normal file
0
web/ws/backend/app/services/__init__.py
Normal file
22
web/ws/backend/manage.py
Normal file
22
web/ws/backend/manage.py
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.base')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
27
web/ws/backend/requirements.txt
Normal file
27
web/ws/backend/requirements.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
# FastAPI 核心
|
||||
fastapi>=0.104.0
|
||||
uvicorn[standard]>=0.24.0
|
||||
pydantic>=2.5.0
|
||||
pydantic-settings>=2.1.0
|
||||
|
||||
# 数据库
|
||||
sqlalchemy>=2.0.0
|
||||
asyncpg>=0.29.0
|
||||
alembic>=1.13.0
|
||||
|
||||
# 文件处理
|
||||
aiofiles>=23.2.0
|
||||
python-multipart>=0.0.6
|
||||
|
||||
# 认证
|
||||
python-jose[cryptography]>=3.3.0
|
||||
passlib[bcrypt]>=1.7.4
|
||||
|
||||
# 其他常用库
|
||||
python-dateutil>=2.8.2
|
||||
pytz>=2023.3
|
||||
|
||||
# 可选:AI/ML 相关(按需取消注释)
|
||||
# transformers>=4.35.0
|
||||
# torch>=2.1.0
|
||||
# scikit-learn>=1.3.0
|
||||
41
web/ws/backend/start.sh
Executable file
41
web/ws/backend/start.sh
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# FastAPI 开发服务器启动脚本
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "启动 FastAPI 开发服务器"
|
||||
echo "=========================================="
|
||||
|
||||
# 检查虚拟环境
|
||||
if [ ! -d "venv" ]; then
|
||||
echo "创建虚拟环境..."
|
||||
python3 -m venv venv
|
||||
fi
|
||||
|
||||
# 激活虚拟环境
|
||||
echo "激活虚拟环境..."
|
||||
source venv/bin/activate
|
||||
|
||||
# 安装依赖
|
||||
echo "安装依赖..."
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 检查环境变量
|
||||
if [ ! -f ".env" ]; then
|
||||
echo "警告: .env 文件不存在,复制 .env.example..."
|
||||
cp .env.example .env
|
||||
echo "请编辑 .env 文件配置数据库等信息"
|
||||
fi
|
||||
|
||||
# 启动服务器
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "启动服务器..."
|
||||
echo "=========================================="
|
||||
echo "API 文档: http://localhost:8000/docs"
|
||||
echo "健康检查: http://localhost:8000/health"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
35
web/ws/backend/test_api.sh
Executable file
35
web/ws/backend/test_api.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# FastAPI API 测试脚本
|
||||
|
||||
BASE_URL="https://amiap.hzau.edu.cn/ABM/api"
|
||||
|
||||
echo "=========================================="
|
||||
echo "测试 PBMDB FastAPI 接口"
|
||||
echo "=========================================="
|
||||
|
||||
echo -e "\n✓ 1. 健康检查..."
|
||||
curl -s "${BASE_URL}/health" | jq '.' || echo "Failed"
|
||||
|
||||
echo -e "\n✓ 2. 根路径..."
|
||||
curl -s "${BASE_URL}/" | jq '.' || echo "Failed"
|
||||
|
||||
echo -e "\n✓ 3. 获取菌种列表..."
|
||||
curl -s "${BASE_URL}/api/v1/strains/" | jq '.' || echo "Failed"
|
||||
|
||||
echo -e "\n✓ 4. 获取菌种分类..."
|
||||
curl -s "${BASE_URL}/api/v1/strains/categories/tree" | jq '.' || echo "Failed"
|
||||
|
||||
echo -e "\n✓ 5. 获取基因组列表..."
|
||||
curl -s "${BASE_URL}/api/v1/genomes/" | jq '.' || echo "Failed"
|
||||
|
||||
echo -e "\n✓ 6. 获取基因列表..."
|
||||
curl -s "${BASE_URL}/api/v1/genes/" | jq '.' || echo "Failed"
|
||||
|
||||
echo -e "\n✓ 7. 获取基因功能分类..."
|
||||
curl -s "${BASE_URL}/api/v1/genes/functions/categories" | jq '.' || echo "Failed"
|
||||
|
||||
echo -e "\n=========================================="
|
||||
echo "测试完成"
|
||||
echo "=========================================="
|
||||
echo "访问 API 文档: ${BASE_URL}/docs"
|
||||
echo "=========================================="
|
||||
Reference in New Issue
Block a user