# 药店销售预测系统API文档 ## 目录 - [概述](#概述) - [API基础信息](#api基础信息) - [数据管理API](#数据管理api) - [获取所有产品列表](#获取所有产品列表) - [获取单个产品详情](#获取单个产品详情) - [获取产品销售数据](#获取产品销售数据) - [上传销售数据](#上传销售数据) - [模型训练API](#模型训练api) - [启动模型训练任务](#启动模型训练任务) - [查询训练任务状态](#查询训练任务状态) - [模型预测API](#模型预测api) - [使用模型预测](#使用模型预测) - [比较不同模型预测结果](#比较不同模型预测结果) - [模型管理API](#模型管理api) - [获取模型列表](#获取模型列表) - [获取模型详情](#获取模型详情) - [删除模型](#删除模型) - [导出模型](#导出模型) - [导入模型](#导入模型) - [API调用示例](#api调用示例) ## 概述 药店销售预测系统API提供了完整的RESTful接口,支持药店销售数据管理、模型训练、销售预测和模型管理等功能。API使用JSON格式进行数据交换,所有API响应都包含`status`字段,用于表示请求是否成功。 ## API基础信息 - **基础URL**: `http://localhost:5000/api` - **内容类型**: `application/json` - **认证方式**: 无认证(仅适用于测试环境) - **状态码**: - `200 OK`: 请求成功 - `400 Bad Request`: 请求参数错误 - `404 Not Found`: 资源不存在 - `500 Internal Server Error`: 服务器内部错误 ## 数据管理API ### 获取所有产品列表 获取系统中所有产品的ID和名称。 - **URL**: `/products` - **方法**: `GET` - **URL参数**: 无 **响应**: ```json { "status": "success", "data": [ { "product_id": "P001", "product_name": "布洛芬片" }, { "product_id": "P002", "product_name": "阿司匹林" } ] } ``` ### 获取单个产品详情 获取特定产品的详细信息。 - **URL**: `/products/{product_id}` - **方法**: `GET` - **URL参数**: - `product_id`: 产品ID,例如"P001" **响应**: ```json { "status": "success", "data": { "product_id": "P001", "product_name": "布洛芬片", "data_points": 365, "date_range": { "start": "2023-01-01", "end": "2023-12-31" } } } ``` ### 获取产品销售数据 获取指定产品在特定日期范围内的销售数据。 - **URL**: `/products/{product_id}/sales` - **方法**: `GET` - **URL参数**: - `product_id`: 产品ID,例如"P001" - **查询参数**: - `start_date`: 开始日期,格式为YYYY-MM-DD(可选) - `end_date`: 结束日期,格式为YYYY-MM-DD(可选) **响应**: ```json { "status": "success", "data": [ { "date": "2023-01-01", "product_id": "P001", "product_name": "布洛芬片", "sales": 120, "price": 15.5, "weekday": 6, "month": 1, "is_holiday": 1, "is_weekend": 1, "is_promotion": 0, "temperature": 5.2 }, { "date": "2023-01-02", "product_id": "P001", "product_name": "布洛芬片", "sales": 85, "price": 15.5, "weekday": 0, "month": 1, "is_holiday": 0, "is_weekend": 0, "is_promotion": 0, "temperature": 4.8 } ] } ``` ### 上传销售数据 上传新的销售数据文件。 - **URL**: `/data/upload` - **方法**: `POST` - **内容类型**: `multipart/form-data` - **参数**: - `file`: Excel文件(.xlsx),包含销售数据 **响应**: ```json { "status": "success", "message": "数据上传成功", "data": { "products": 5, "rows": 1825 } } ``` ## 模型训练API ### 启动模型训练任务 启动一个新的模型训练任务。 - **URL**: `/training` - **方法**: `POST` - **请求体**: ```json { "product_id": "P001", "model_type": "mlstm", "parameters": { "look_back": 14, "future_days": 7, "batch_size": 64, "epochs": 100, "learning_rate": 0.001 } } ``` - **参数说明**: - `product_id`: 产品ID - `model_type`: 模型类型,可选值:`mlstm`, `transformer`, `kan` - `parameters`: 训练参数(可选) - `look_back`: 回看天数,默认14 - `future_days`: 预测天数,默认7 - `batch_size`: 批大小,默认32 - `epochs`: 训练轮次,默认50 - `learning_rate`: 学习率,默认0.001 **响应**: ```json { "status": "success", "message": "模型训练任务已启动", "data": { "task_id": "550e8400-e29b-41d4-a716-446655440000" } } ``` ### 查询训练任务状态 查询特定训练任务的状态。 - **URL**: `/training/{task_id}` - **方法**: `GET` - **URL参数**: - `task_id`: 训练任务ID **响应**: ```json { "status": "success", "data": { "product_id": "P001", "model_type": "mlstm", "parameters": { "look_back": 14, "future_days": 7 }, "status": "completed", "created_at": "2023-06-15 14:30:25", "model_path": "models/P001_mlstm_model_v20230615_143025.pt", "metrics": { "MSE": 12.45, "RMSE": 3.52, "MAE": 2.85, "R2": 0.92, "MAPE": 5.67 }, "model_details_url": "/api/models?product_id=P001&model_type=mlstm" } } ``` - **可能的状态值**: - `pending`: 等待开始 - `running`: 正在训练 - `completed`: 训练完成 - `failed`: 训练失败 ## 模型预测API ### 使用模型预测 使用指定模型进行预测。 - **URL**: `/prediction` - **方法**: `POST` - **请求体**: ```json { "product_id": "P001", "model_type": "mlstm", "version": "20230615_143025", "future_days": 7, "include_visualization": true } ``` - **参数说明**: - `product_id`: 产品ID - `model_type`: 模型类型,可选值:`mlstm`, `transformer`, `kan` - `version`: 模型版本(可选,不指定则使用最新版本) - `future_days`: 预测天数(可选,默认为7) - `include_visualization`: 是否包含可视化结果(可选,默认为false) **响应**: ```json { "status": "success", "data": { "product_id": "P001", "product_name": "布洛芬片", "model_type": "mlstm", "predictions": [ { "date": "2023-07-01", "predicted_sales": 105.8 }, { "date": "2023-07-02", "predicted_sales": 98.3 }, { "date": "2023-07-03", "predicted_sales": 112.5 }, { "date": "2023-07-04", "predicted_sales": 120.1 }, { "date": "2023-07-05", "predicted_sales": 125.6 }, { "date": "2023-07-06", "predicted_sales": 118.9 }, { "date": "2023-07-07", "predicted_sales": 130.4 } ], "visualization": "base64_encoded_image_data" } } ``` ### 比较不同模型预测结果 比较不同模型的预测结果。 - **URL**: `/prediction/compare` - **方法**: `POST` - **请求体**: ```json { "product_id": "P001", "model_types": ["mlstm", "transformer", "kan"], "versions": ["20230615_143025", null, null], "include_visualization": true } ``` - **参数说明**: - `product_id`: 产品ID - `model_types`: 要比较的模型类型列表 - `versions`: 对应每个模型的版本列表(可选,不指定则使用最新版本) - `include_visualization`: 是否包含可视化结果(可选,默认为false) **响应**: ```json { "status": "success", "data": { "product_id": "P001", "product_name": "布洛芬片", "model_types": ["mlstm", "transformer", "kan"], "comparison": [ { "date": "2023-07-01", "mlstm_prediction": 105.8, "transformer_prediction": 108.2, "kan_prediction": 107.1 }, { "date": "2023-07-02", "mlstm_prediction": 98.3, "transformer_prediction": 101.5, "kan_prediction": 100.6 }, { "date": "2023-07-03", "mlstm_prediction": 112.5, "transformer_prediction": 115.8, "kan_prediction": 114.2 }, { "date": "2023-07-04", "mlstm_prediction": 120.1, "transformer_prediction": 122.4, "kan_prediction": 121.8 }, { "date": "2023-07-05", "mlstm_prediction": 125.6, "transformer_prediction": 127.3, "kan_prediction": 126.9 }, { "date": "2023-07-06", "mlstm_prediction": 118.9, "transformer_prediction": 121.2, "kan_prediction": 120.5 }, { "date": "2023-07-07", "mlstm_prediction": 130.4, "transformer_prediction": 132.8, "kan_prediction": 131.6 } ], "visualization": "base64_encoded_image_data" } } ``` ## 模型管理API ### 获取模型列表 获取系统中的模型列表,可按产品ID和模型类型筛选。 - **URL**: `/models` - **方法**: `GET` - **查询参数**: - `product_id`: 按产品ID筛选(可选) - `model_type`: 按模型类型筛选(可选) **响应**: ```json { "status": "success", "data": [ { "product_id": "P001", "model_type": "mlstm", "version": "20230615_143025", "file_path": "models/P001_mlstm_model_v20230615_143025.pt", "created_at": "2023-06-15 14:30:25", "file_size": "2.45 MB", "metrics": { "MSE": 12.45, "RMSE": 3.52, "MAE": 2.85, "R2": 0.92, "MAPE": 5.67 } }, { "product_id": "P001", "model_type": "transformer", "version": "20230615_150512", "file_path": "models/P001_transformer_model_v20230615_150512.pt", "created_at": "2023-06-15 15:05:12", "file_size": "3.12 MB", "metrics": { "MSE": 10.82, "RMSE": 3.29, "MAE": 2.73, "R2": 0.93, "MAPE": 5.21 } } ] } ``` ### 获取模型详情 获取特定模型的详细信息。 - **URL**: `/models/{model_id}` - **方法**: `GET` - **URL参数**: - `model_id`: 模型ID,格式为`{product_id}_{model_type}_v{version}`,例如`P001_mlstm_v20230615_143025` **响应**: ```json { "status": "success", "data": { "product_id": "P001", "model_type": "mlstm", "version": "20230615_143025", "created_at": "2023-06-15 14:30:25", "file_path": "models/P001_mlstm_model_v20230615_143025.pt", "file_size": "2.45 MB", "features": ["sales", "price", "weekday", "month", "is_holiday", "is_weekend", "is_promotion", "temperature"], "look_back": 14, "T": 7, "metrics": { "MSE": 12.45, "RMSE": 3.52, "MAE": 2.85, "R2": 0.92, "MAPE": 5.67 } } } ``` ### 删除模型 删除特定模型。 - **URL**: `/models/{model_id}` - **方法**: `DELETE` - **URL参数**: - `model_id`: 模型ID,格式为`{product_id}_{model_type}_v{version}`,例如`P001_mlstm_v20230615_143025` **响应**: ```json { "status": "success", "message": "模型已成功删除" } ``` ### 导出模型 导出特定模型文件。 - **URL**: `/models/{model_id}/export` - **方法**: `GET` - **URL参数**: - `model_id`: 模型ID,格式为`{product_id}_{model_type}_v{version}`,例如`P001_mlstm_v20230615_143025` **响应**: 直接下载模型文件 ### 导入模型 导入模型文件。 - **URL**: `/models/import` - **方法**: `POST` - **内容类型**: `multipart/form-data` - **参数**: - `file`: PyTorch模型文件(.pt) **响应**: ```json { "status": "success", "message": "模型已成功导入", "data": { "model_path": "models/P001_mlstm_model_v20230615_143025.pt" } } ``` ## API调用示例 以下是使用Python和requests库调用API的示例代码: ```python import requests import json import matplotlib.pyplot as plt import base64 from io import BytesIO # API基础URL API_BASE_URL = 'http://localhost:5000/api' # 获取所有产品 def get_products(): response = requests.get(f'{API_BASE_URL}/products') return response.json() # 训练模型 def train_model(product_id, model_type='mlstm'): data = { 'product_id': product_id, 'model_type': model_type, 'parameters': { 'look_back': 14, 'future_days': 7, 'epochs': 50 } } response = requests.post(f'{API_BASE_URL}/training', json=data) return response.json() # 查询训练状态 def check_training_status(task_id): response = requests.get(f'{API_BASE_URL}/training/{task_id}') return response.json() # 使用模型预测 def predict_sales(product_id, model_type='mlstm', include_visualization=True): data = { 'product_id': product_id, 'model_type': model_type, 'future_days': 7, 'include_visualization': include_visualization } response = requests.post(f'{API_BASE_URL}/prediction', json=data) result = response.json() # 如果包含可视化图表,显示它 if include_visualization and 'data' in result and 'visualization' in result['data']: img_data = base64.b64decode(result['data']['visualization']) img = plt.imread(BytesIO(img_data)) plt.figure(figsize=(12, 6)) plt.imshow(img) plt.axis('off') plt.show() return result # 比较不同模型 def compare_models(product_id, model_types=['mlstm', 'transformer', 'kan']): data = { 'product_id': product_id, 'model_types': model_types, 'include_visualization': True } response = requests.post(f'{API_BASE_URL}/prediction/compare', json=data) return response.json() # 调用示例 if __name__ == '__main__': # 获取所有产品 products = get_products() print(json.dumps(products, indent=2)) if products['status'] == 'success' and len(products['data']) > 0: # 选择第一个产品 product_id = products['data'][0]['product_id'] # 训练模型 training_result = train_model(product_id, 'mlstm') print(json.dumps(training_result, indent=2)) # 如果训练任务启动成功,检查状态 if training_result['status'] == 'success': task_id = training_result['data']['task_id'] # 这里实际使用时可以轮询检查状态 status = check_training_status(task_id) print(json.dumps(status, indent=2)) # 使用模型预测(实际使用时应等待训练完成) predictions = predict_sales(product_id) print(json.dumps(predictions, indent=2))