Files
UAV-CO2/项目交接文档.md
2026-04-20 09:43:21 +08:00

794 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GasFlux Web API 项目交接文档
> **文档版本**: 1.0
> **最后更新**: 2026年4月13日
> **项目路径**: `e:\code\CO2data\gasflux-develop\gasflux-develop-no-dockerV6`
---
## 1. 项目概述
### 1.1 项目简介
GasFlux 是一个专业的气体通量处理系统,用于处理无人机或飞行器采集的气体浓度数据,计算气体通量(如 CO₂、CH₄ 等)。该系统集成了完整的数据处理流程,包括数据预处理、背景校正、空间插值和报告生成。
### 1.2 核心功能
- **数据上传与处理**: 支持 Excel 文件 (.xlsx, .xls) 上传和异步处理
- **气体通量计算**: 支持 CO₂、CH₄ 等温室气体的通量计算
- **背景校正**: 集成 FastChrom 背景校正算法
- **空间插值**: 克里金 (Kriging) 插值算法
- **报告生成**: 自动生成 HTML 分析报告和数据导出
- **实时监控**: 任务状态实时查询和监控
- **RESTful API**: 完整的 Web API 接口
### 1.3 技术栈
- **后端框架**: Flask + Waitress WSGI 服务器
- **数据处理**: Pandas, NumPy, SciPy
- **空间分析**: scikit-gstat (地质统计学)
- **机器学习**: scikit-learn
- **可视化**: Matplotlib
- **数据库**: SQLite (任务状态持久化)
- **配置管理**: INI 文件 + 环境变量
---
## 2. 项目结构
```
gasflux-develop-no-dockerV6/
├── server_waitress.py # 生产服务器入口点 (★核心文件)
├── run_api.py # 开发环境 API 启动脚本
├── create_api_key.py # API 密钥管理工具
├── requirements.txt # Python 依赖列表
├── build_exe.bat/.sh # 可执行文件构建脚本
├── src/gasflux/ # 核心源代码
│ ├── app.py # Flask 应用主入口
│ ├── config_reader.py # INI 配置文件读取器
│ ├── processing.py # 数据处理算法
│ ├── processing_pipelines.py # 处理流程编排
│ ├── data_processor.py # 数据预处理
│ ├── background.py # 背景校正算法
│ ├── interpolation.py # 空间插值算法
│ ├── plotting.py # 可视化图表生成
│ ├── reporting.py # 报告生成
│ ├── gas.py # 气体属性计算
│ ├── ml.py # 机器学习模块
│ ├── db.py # 数据库管理
│ ├── auth.py # 认证与授权
│ ├── shared.py # 共享工具和常量
│ ├── janitor.py # 后台清理任务
│ ├── blueprints/ # Flask 蓝图 (API 端点)
│ │ ├── upload.py # 文件上传处理
│ │ ├── tasks.py # 任务管理
│ │ ├── task_pool.py # 任务池管理
│ │ ├── download.py # 文件下载
│ │ ├── reports.py # 报告查询
│ │ ├── health.py # 健康检查
│ │ ├── stats.py # 统计信息
│ │ ├── config.py # 配置信息
│ │ ├── web.py # Web 界面
│ │ └── api_keys.py # API 密钥管理
│ └── gasflux_config.yaml # 默认 YAML 配置文件
├── web_api_data/ # 数据存储目录
│ ├── uploads/ # 上传文件存储
│ └── outputs/ # 处理结果输出
└── docs/ # 文档目录
├── API_DOCUMENTATION.md # 完整 API 文档
├── WAITRESS_DEPLOYMENT.md # Waitress 部署指南
├── README.md # 项目说明
└── *.md # 其他文档
```
---
## 3. 核心组件详解
### 3.1 server_waitress.py (生产服务器入口)
**文件作用**: 使用 Waitress WSGI 服务器启动 GasFlux Web API 的生产环境入口点。
**关键特性**:
- 支持完整 GasFlux 处理功能
- 任务池管理和异步处理
- 实时任务状态监控
- 报告生成和文件下载
- 健康监控和统计信息
**启动方式**:
```bash
# 直接运行
python server_waitress.py
# 或使用 PyInstaller 打包
pyinstaller --onefile --name GasFluxAPI server_waitress.py
```
**启动后输出示例**:
```
Starting GasFlux Web API with Waitress...
✓ GasFlux app imported successfully
✓ Task pool management enabled
✓ All blueprints loaded: upload, tasks, task_pool, download, reports, health, stats, config, web
✓ Waitress WSGI server imported
Starting Waitress server on 0.0.0.0:5000
- Threads: 8
- Connection limit: 100
- Channel timeout: 300s
- Base URL: http://localhost:5000
```
**主要代码结构**:
```python
# 1. 环境设置
os.environ['MPLBACKEND'] = 'Agg' # 避免 GUI 依赖
sys.path.insert(0, str(project_root))
sys.path.insert(0, str(src_dir))
# 2. 配置加载
from src.gasflux.app import Config
host = Config.HOST
port = Config.PORT
threads = Config.THREADS
# 3. 启动 Waitress 服务器
from waitress import serve
serve(app, host=host, port=port, threads=threads, ...)
```
### 3.2 src/gasflux/app.py (Flask 应用核心)
**文件作用**: Flask 应用的主入口,定义了 Config 配置类和 API 统计收集器。
**核心类**:
#### Config 类
```python
class Config:
"""配置管理,从 INI 文件读取,支持环境变量覆盖"""
# 服务器配置
HOST = config_reader.host # 默认: 0.0.0.0
PORT = config_reader.port # 默认: 5000
DEBUG = config_reader.debug # 默认: false
BASE_URL = config_reader.base_url # 默认: http://localhost:5000
# 目录配置
UPLOAD_FOLDER = ... # 上传文件目录
OUTPUT_FOLDER = ... # 输出文件目录
# 性能配置
THREADS = config_reader.threads # 默认: 8
CONNECTION_LIMIT = config_reader.connection_limit # 默认: 100
CHANNEL_TIMEOUT = config_reader.channel_timeout # 默认: 300
# 任务清理配置
TASK_CLEANUP_INTERVAL = 3600 # 清理间隔(秒)
MAX_TASK_AGE = 86400 # 最大任务年龄
SUCCESSFUL_TASK_CLEANUP_AGE = 3600 # 成功任务清理时间
FAILED_TASK_CLEANUP_AGE = 604800 # 失败任务清理时间
```
#### APIStatsCollector 类
收集 API 统计信息,包括:
- 请求统计 (按方法、端点、状态码)
- 任务统计 (创建、完成、失败)
- 性能指标 (响应时间、错误率)
- 系统资源 (内存、磁盘使用)
### 3.3 src/gasflux/config_reader.py (配置读取器)
**文件作用**: 从 INI 文件读取配置,支持环境变量覆盖。
**配置文件优先级**:
1. 当前目录 `gasflux.ini`
2. 当前目录 `config.ini`
3. 项目根目录 `gasflux.ini`
**默认配置项** (gasflux.ini 示例):
```ini
[server]
host = 0.0.0.0
port = 5000
debug = false
base_url = http://localhost:5000
[paths]
uploads = ./web_api_data/uploads
outputs = ./web_api_data/outputs
[limits]
max_content_length = 104857600
[logging]
level = INFO
file = logs/gasflux_api.log
[performance]
threads = 8
connection_limit = 100
channel_timeout = 300
[cleanup]
task_cleanup_interval = 3600
max_task_age = 86400
successful_task_cleanup_age = 3600
failed_task_cleanup_age = 604800
[security]
admin_bootstrap_key = your_bootstrap_key_here
[database]
path = web_api_data/outputs/gasflux.db
```
---
## 4. API 端点一览
### 4.1 监控和健康检查
| 端点 | 方法 | 描述 |
|------|------|------|
| `/health` | GET | 健康状态检查 |
| `/stats` | GET | 系统统计信息 |
| `/stats/reset` | POST | 重置统计信息 |
| `/config` | GET | 配置信息 |
### 4.2 文件上传和任务管理
| 端点 | 方法 | 描述 |
|------|------|------|
| `/upload` | POST | 文件上传和处理 |
| `/task/<task_id>` | GET | 查询任务状态 |
| `/task/<task_id>` | PUT | 更新任务状态 |
| `/task/<task_id>` | DELETE | 删除任务 |
| `/tasks` | GET | 任务池列表 (分页) |
| `/tasks/stats` | GET | 任务池统计 |
| `/tasks/active` | GET | 活跃任务 |
| `/tasks/queue` | GET | 队列任务 |
### 4.3 报告和下载
| 端点 | 方法 | 描述 |
|------|------|------|
| `/reports` | GET | 分页查询报告 |
| `/download/<filename>` | GET | 下载文件 |
| `/` | GET | Web 管理界面 |
### 4.4 API 密钥管理
| 端点 | 方法 | 描述 |
|------|------|------|
| `/api_keys` | GET | 列出 API 密钥 |
| `/api_keys` | POST | 创建 API 密钥 |
| `/api_keys/<key>` | DELETE | 撤销 API 密钥 |
---
## 5. 数据流和业务流程
### 5.1 文件上传处理流程
```
1. 客户端上传文件
2. upload.py 验证文件类型和大小
3. 生成 UUID 任务 ID
4. 创建任务目录 (uploads/<task_id>/, outputs/<task_id>/)
5. 保存上传文件
6. 初始化任务状态 (SQLite 数据库)
7. 启动后台线程处理 (process_data_async)
8. 返回 202 Accepted包含 task_id
```
### 5.2 后台数据处理流程
```
process_data_async(task_id, data_path, config_path, output_dir)
1. 加载 YAML 配置文件
2. 数据预处理 (data_processor.py)
- 读取 Excel/CSV
- 数据验证 (列名、类型、范围)
- 单位转换
3. GasFlux 核心分析 (processing_pipelines.py)
- 背景校正 (background.py)
- 空间处理 (平面拟合、航段提取)
- 通量计算 (processing.py)
- 克里金插值 (interpolation.py)
4. 可视化生成 (plotting.py)
- 浓度分布图
- 风场图
- 插值结果图
5. 报告生成 (reporting.py)
- HTML 报告
- 输出变量 JSON
6. 更新任务状态为 completed
7. 客户端通过 /task/<id> 查询结果
```
---
## 6. 配置管理
### 6.1 INI 配置文件 (推荐)
创建 `gasflux.ini` 文件:
```ini
[server]
host = 0.0.0.0
port = 5000
[paths]
uploads = ./web_api_data/uploads
outputs = ./web_api_data/outputs
[performance]
threads = 8
connection_limit = 100
[security]
admin_bootstrap_key = your_secure_key_here
```
### 6.2 环境变量覆盖
| 环境变量 | 说明 | 默认值 |
|----------|------|--------|
| `GASFLUX_HOST` | 监听地址 | 0.0.0.0 |
| `GASFLUX_PORT` | 监听端口 | 5000 |
| `GASFLUX_LOG_LEVEL` | 日志级别 | INFO |
| `GASFLUX_THREADS` | 工作线程数 | 8 |
| `GASFLMAX_CONTENT_LENGTH` | 最大文件大小 | 104857600 (100MB) |
### 6.3 YAML 配置文件 (处理参数)
处理数据时使用的配置 `gasflux_config.yaml`:
```yaml
output_dir: ./output
required_cols:
latitude: [-90, 90]
longitude: [-180, 180]
height_ato: [0, 200]
windspeed: [0, 20]
temperature: [-50, 60]
pressure: [900, 1100]
gases:
ch4: [1.5, 10.0]
co2: [300, 500]
strategies:
background: "algorithm"
spatial: "curtain"
interpolation: "kriging"
sensor: "insitu"
algorithmic_baseline_settings:
# 背景校正算法参数
smooth_half_window: 50
num_std: 2
```
---
## 7. 部署指南
### 7.1 开发环境部署
```bash
# 1. 克隆仓库
cd gasflux-develop-no-dockerV6
# 2. 创建虚拟环境
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # Linux/macOS
# 3. 安装依赖
pip install -r requirements.txt
# 4. 启动开发服务器
python run_api.py
```
### 7.2 生产环境部署 (Waitress)
```bash
# 1. 安装 Waitress
pip install waitress
# 2. 启动生产服务器
python server_waitress.py
```
### 7.3 打包为可执行文件
**Windows**:
```cmd
build_exe.bat
```
**Linux/macOS**:
```bash
chmod +x build_exe.sh
./build_exe.sh
```
运行打包后的文件:
```bash
dist\GasFluxAPI.exe # Windows
./dist/GasFluxAPI # Linux/macOS
```
### 7.4 systemd 服务配置 (Linux)
```ini
# /etc/systemd/system/gasflux.service
[Unit]
Description=GasFlux Web API
After=network.target
[Service]
Type=simple
User=gasflux
WorkingDirectory=/opt/gasflux
ExecStart=/opt/gasflux/venv/bin/python server_waitress.py
Restart=always
RestartSec=5
Environment=GASFLUX_PORT=5000
Environment=GASFLUX_LOG_LEVEL=INFO
[Install]
WantedBy=multi-user.target
```
启用和启动服务:
```bash
sudo systemctl enable gasflux
sudo systemctl start gasflux
sudo systemctl status gasflux
```
---
## 8. 数据库和持久化
### 8.1 SQLite 数据库结构
**数据库文件**: `web_api_data/outputs/gasflux.db`
**表结构**:
```sql
-- 任务状态表
CREATE TABLE tasks (
task_id TEXT PRIMARY KEY,
status TEXT NOT NULL, -- pending, processing, completed, failed
message TEXT,
error TEXT,
results TEXT, -- JSON 格式
output_dir TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- API 密钥表
CREATE TABLE api_keys (
key_id TEXT PRIMARY KEY,
key_hash TEXT NOT NULL,
name TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_used_at TIMESTAMP,
revoked INTEGER DEFAULT 0
);
```
---
## 9. 维护和故障排除
### 9.1 日志查看
**日志文件位置**: `logs/gasflux_api.log`
**实时查看**:
```bash
tail -f logs/gasflux_api.log # Linux
Get-Content -Path logs/gasflux_api.log -Wait # PowerShell
```
**过滤特定任务**:
```bash
tail -f logs/gasflux_api.log | grep "task:abc123"
```
### 9.2 常见问题
#### 问题 1: 端口被占用
```bash
# Windows
netstat -ano | findstr :5000
taskkill /PID <PID> /F
# Linux
netstat -tulpn | grep :5000
kill -9 <PID>
```
#### 问题 2: 权限问题
```bash
# 确保目录可写
chmod -R 755 web_api_data/
chmod -R 755 logs/
```
#### 问题 3: 数据库锁定
```bash
# 如果 SQLite 数据库被锁定,检查是否有僵尸进程
lsof gasflux.db
# 重启服务解决
```
### 9.3 性能优化
**调整 Waitress 参数** (server_waitress.py):
```python
serve(
app,
host=host,
port=port,
threads=16, # 根据 CPU 核心数增加
connection_limit=200, # 增加连接限制
channel_timeout=600, # 延长超时时间
)
```
**数据库优化**:
```sql
-- 定期清理旧任务
DELETE FROM tasks
WHERE status = 'completed'
AND updated_at < datetime('now', '-7 days');
-- 重建索引
VACUUM;
```
### 9.4 备份策略
**需要备份的目录**:
```
web_api_data/uploads/ # 上传的原始数据
web_api_data/outputs/ # 处理结果
gasflux.ini # 配置文件
logs/ # 日志文件 (可选)
```
**自动备份脚本**:
```bash
#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d)
tar -czf "backup_$DATE.tar.gz" web_api_data/ gasflux.ini
# 上传到远程存储
rsync -avz "backup_$DATE.tar.gz" user@backup-server:/backups/
```
---
## 10. API 使用示例
### 10.1 Python 客户端示例
```python
import requests
import time
class GasFluxClient:
def __init__(self, base_url="http://localhost:5000"):
self.base_url = base_url.rstrip('/')
def upload_and_process(self, data_file, config_file=None, api_key=None):
"""上传文件并处理"""
files = {'file': open(data_file, 'rb')}
if config_file:
files['config'] = open(config_file, 'rb')
headers = {}
if api_key:
headers['X-API-Key'] = api_key
# 上传文件
response = requests.post(
f"{self.base_url}/upload",
files=files,
headers=headers
)
result = response.json()
task_id = result['data']['task_id']
# 轮询状态
while True:
status_resp = requests.get(f"{self.base_url}/task/{task_id}")
status = status_resp.json()['data']
print(f"Status: {status['status']} - {status.get('message', '')}")
if status['status'] == 'completed':
# 下载结果
for file_info in status['results']:
if 'download_url' in file_info:
download_url = f"{self.base_url}{file_info['download_url']}"
file_resp = requests.get(download_url)
with open(file_info['name'], 'wb') as f:
f.write(file_resp.content)
print(f"Downloaded: {file_info['name']}")
return status
elif status['status'] == 'failed':
raise Exception(f"Task failed: {status.get('error', 'Unknown error')}")
time.sleep(3)
# 使用示例
client = GasFluxClient()
client.upload_and_process('data.xlsx', 'config.yaml', api_key='your-api-key')
```
### 10.2 cURL 命令示例
```bash
# 1. 检查健康状态
curl http://localhost:5000/health
# 2. 上传文件
curl -X POST -F "file=@data.xlsx" -F "config=@config.yaml" \
-H "X-API-Key: your-api-key" \
http://localhost:5000/upload
# 3. 查询任务状态
curl http://localhost:5000/task/<task_id>
# 4. 下载结果文件
curl -O http://localhost:5000/download/<task_id>/report.html
```
---
## 11. 安全和认证
### 11.1 API 密钥管理
**创建 API 密钥**:
```bash
python create_api_key.py --name "Production Client"
```
**使用 API 密钥**:
```bash
curl -H "X-API-Key: your-api-key" http://localhost:5000/upload
```
### 11.2 Bootstrap Key
用于初始设置或管理员操作,在 `gasflux.ini` 中配置:
```ini
[security]
admin_bootstrap_key = your_secure_bootstrap_key
```
使用 Bootstrap Key:
```bash
curl -H "X-Admin-Bootstrap-Key: your_secure_bootstrap_key" \
http://localhost:5000/api_keys
```
---
## 12. 开发指南
### 12.1 添加新的蓝图
1. 创建蓝图文件 `src/gasflux/blueprints/new_feature.py`:
```python
from flask import Blueprint
from ..shared import _format_response
new_feature_bp = Blueprint('new_feature', __name__, url_prefix='/new-feature')
@new_feature_bp.route('', methods=['GET'])
def get_feature():
return _format_response(200, "Feature data", {"data": "value"})
```
2.`app.py` 中注册蓝图:
```python
from .blueprints.new_feature import new_feature_bp
app.register_blueprint(new_feature_bp)
```
### 12.2 代码规范
- 使用类型注解
- 添加文档字符串
- 使用 logger 而非 print
- 错误处理使用 try-except 块
- 性能敏感操作使用 `@log_performance` 装饰器
---
## 13. 联系和支持
### 13.1 相关文档
- `API_DOCUMENTATION.md` - 完整 API 接口文档
- `WAITRESS_DEPLOYMENT.md` - 生产部署指南
- `README.md` - 项目概述和使用说明
- `ENVIRONMENT_VARIABLES.md` - 环境变量配置
### 13.2 调试技巧
**启用 DEBUG 日志**:
```bash
set GASFLUX_LOG_LEVEL=DEBUG # Windows
export GASFLUX_LOG_LEVEL=DEBUG # Linux/macOS
python server_waitress.py
```
**数据库查询**:
```bash
sqlite3 web_api_data/outputs/gasflux.db
> SELECT * FROM tasks WHERE status = 'failed';
> SELECT COUNT(*), status FROM tasks GROUP BY status;
```
---
## 14. 附录
### 14.1 版本历史
| 版本 | 日期 | 说明 |
|------|------|------|
| 0.2.1 | 2026-01 | 初始版本 |
### 14.2 依赖版本
```
Flask>=2.0
waitress>=2.0
pandas>=2.0
numpy>=1.24
scipy>=1.10
scikit-gstat>=1.0
matplotlib>=3.7
pyyaml>=6.0
```
### 14.3 系统要求
- **Python**: 3.8+
- **内存**: 4GB+ (推荐 8GB+)
- **磁盘**: 1GB+ 可用空间
- **操作系统**: Windows 10/11, Linux, macOS
---
**文档结束**
*本文档由 AI 助手根据项目代码自动生成,如有疑问请参考源代码或联系开发团队。*