1
1
forked from wangqifan/calc
calc/backend/app/api/routes.py

148 lines
5.8 KiB
Python
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.

from fastapi import APIRouter, HTTPException
from ..models.schemas import PriceRequest, PriceComparison, InstanceSearchRequest, InstanceSearchRequestV2
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 ..services.aws.pricing_v2 import search_instances_v2
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("/search-instances-v2")
async def search_instances_v2_api(request: InstanceSearchRequestV2):
"""
第二套搜索API - 通过MySQL数据库搜索符合条件的AWS实例
"""
try:
# 调用服务层函数
instances = await search_instances_v2(
region=request.region,
cpu_cores=request.cpu_cores,
memory_gb=request.memory_gb,
disk_gb=request.disk_gb,
operating_system=request.operating_system
)
return 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))