calc/backend/app/api/routes.py

127 lines
5.0 KiB
Python
Raw Normal View History

2025-04-02 16:57:05 +08:00
from fastapi import APIRouter, HTTPException
from ..models.schemas import PriceRequest, PriceComparison, InstanceSearchRequest
from ..core.config import AWS_REGION_NAMES, AZURE_REGION_NAMES, ALIYUN_REGION_NAMES
from ..core.instance_data import get_instance_info
from ..services import calculate_price
from typing import Dict, List, Any
router = APIRouter(prefix="/api")
@router.get("/regions")
async def get_regions(platform: str = "aws"):
"""获取指定平台的区域列表"""
result = []
if platform == "aws":
for key in AWS_REGION_NAMES.keys():
result.append({'code': key, 'name': AWS_REGION_NAMES[key]})
elif platform == "azure":
for key in AZURE_REGION_NAMES.keys():
result.append({'code': key, 'name': AZURE_REGION_NAMES[key]})
elif platform == "aliyun":
for key in ALIYUN_REGION_NAMES.keys():
result.append({'code': key, 'name': ALIYUN_REGION_NAMES[key]})
else:
raise HTTPException(status_code=400, detail=f"不支持的平台: {platform}")
return result
@router.get("/instance-types")
async def get_instance_types(platform: str = "aws"):
"""获取指定平台的实例类型"""
try:
return get_instance_info(platform)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
@router.post("/search-instances")
async def search_instances(request: InstanceSearchRequest):
"""搜索符合条件的实例类型"""
try:
# 验证必填参数
if request.cpu_cores is None:
raise HTTPException(status_code=400, detail="cpu_cores是必填参数")
if request.memory_gb is None:
raise HTTPException(status_code=400, detail="memory_gb是必填参数")
if request.disk_gb is None:
raise HTTPException(status_code=400, detail="disk_gb是必填参数")
if request.region is None:
raise HTTPException(status_code=400, detail="region是必填参数")
# 获取实例信息
try:
instance_info = get_instance_info(request.platform)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
matching_instances = []
# 遍历所有实例类型
for instance_type, info in instance_info.items():
try:
# 检查是否满足CPU要求严格匹配
if request.cpu_cores and info['cpu'] != request.cpu_cores:
continue
# 检查是否满足内存要求(严格匹配)
if request.memory_gb and info['memory'] != request.memory_gb:
continue
# 计算价格
price_info = await calculate_price(
platform=request.platform,
instance_type=instance_type,
region=request.region,
disk_gb=request.disk_gb,
operating_system=request.operating_system
)
# 添加到匹配列表
matching_instances.append({
"instance_type": instance_type,
"description": info['description'],
"cpu": info['cpu'],
"memory": info['memory'],
"disk_gb": request.disk_gb,
"hourly_price": price_info['hourly_price'],
"monthly_price": price_info['monthly_price'],
"disk_monthly_price": price_info['disk_monthly_price'],
"total_monthly_price": price_info['total_monthly_price']
})
except Exception as e:
print(f"计算价格时出错: {str(e)}")
# 按总价格排序
matching_instances.sort(key=lambda x: x['total_monthly_price'])
return matching_instances
except Exception as e:
print(f"搜索实例时出错: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.post("/compare-prices")
async def compare_prices(comparison: PriceComparison):
"""比较不同配置的价格"""
try:
results = []
for config in comparison.configurations:
# 根据请求中的平台参数调用对应的价格计算服务
# 这里假设需要扩展PriceRequest模型添加platform字段
# 暂时默认为AWS
platform = getattr(config, 'platform', 'aws')
price = await calculate_price(
platform=platform,
instance_type=config.instance_type,
region=config.region,
operating_system=config.operating_system,
disk_gb=config.disk_gb if hasattr(config, 'disk_gb') else 0
)
results.append({
"configuration": config.dict(),
"price": price
})
return results
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))