#!/usr/bin/env python3 """ MeetSpot 精简版 API 测试脚本 ============================= 测试精简后的 API 接口是否正常工作,并输出性能数据。 使用方法: python test_minimal_api.py """ import sys import os import time import json from pathlib import Path # 添加项目根目录到路径 project_root = Path(__file__).resolve().parent sys.path.insert(0, str(project_root)) def test_import(): """测试模块导入""" print("📦 测试模块导入...") try: from app.config_simple import config from app.tool.meetspot_recommender import CafeRecommender print(" ✅ 核心模块导入成功") return True except Exception as e: print(f" ❌ 导入失败: {e}") return False def test_tmap_config(): """测试腾讯地图配置""" print("\n🗺️ 测试腾讯地图配置...") try: from app.config_simple import config if not config or not config.tmap: print(" ⚠️ 配置未加载(使用环境变量)") return True api_key = config.tmap.api_key if api_key and len(api_key) > 10: print(f" ✅ API Key 已配置: {api_key[:10]}...") else: print(" ⚠️ API Key 未配置(可从环境变量 TMAP_API_KEY 获取)") return True except Exception as e: print(f" ❌ 配置测试失败: {e}") return False def test_geocoding(): """测试地理编码""" print("\n📍 测试地理编码...") try: import asyncio from app.tool.meetspot_recommender import CafeRecommender async def test(): recommender = CafeRecommender() result = await recommender._geocode("北京大学") if result and result.get("location"): print(f" ✅ 地理编码成功: {result['location']}") print(f" 📌 地址: {result.get('formatted_address', 'N/A')}") return True else: print(" ⚠️ 地理编码失败(可能 API Key 未配置)") return False return asyncio.run(test()) except Exception as e: print(f" ❌ 测试失败: {e}") return False def test_poi_search(): """测试 POI 搜索""" print("\n🏪 测试 POI 搜索...") try: import asyncio from app.tool.meetspot_recommender import CafeRecommender async def test(): recommender = CafeRecommender() pois = await recommender._search_pois("116.4074,39.9042", "咖啡馆", radius=1000) if pois and len(pois) > 0: print(f" ✅ POI 搜索成功: 找到 {len(pois)} 个结果") for i, poi in enumerate(pois[:3]): print(f" {i+1}. {poi.get('name', 'N/A')}") return True else: print(" ⚠️ POI 搜索失败(可能 API Key 未配置)") return False return asyncio.run(test()) except Exception as e: print(f" ❌ 测试失败: {e}") return False def test_complete_recommendation(): """测试完整推荐流程""" print("\n🎯 测试完整推荐流程...") try: import asyncio from app.tool.meetspot_recommender import CafeRecommender async def test(): start_time = time.time() recommender = CafeRecommender() result = await recommender.run( locations=["北京大学", "清华大学", "中关村"], keywords="咖啡馆", user_requirements="环境安静" ) elapsed = time.time() - start_time if result and "HTML页面:" in result.output: print(f" ✅ 推荐成功(耗时: {elapsed:.2f}秒)") print(f" 📄 输出: {result.output[:80]}...") return True else: print(" ⚠️ 推荐失败(可能 API Key 未配置)") print(f" 错误信息: {result.output if result else 'None'}") return False return asyncio.run(test()) except Exception as e: print(f" ❌ 测试失败: {e}") import traceback traceback.print_exc() return False def test_minimal_api(): """测试精简版 API""" print("\n🚀 测试精简版 API...") try: sys.path.insert(0, str(project_root)) os.environ.setdefault("TMAP_API_KEY", "test_key_for_import") # 测试是否可以导入 import importlib.util spec = importlib.util.spec_from_file_location("api_minimal", project_root / "api_minimal.py") if spec and spec.loader: module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) print(" ✅ 精简版 API 导入成功") return True else: print(" ⚠️ 精简版 API 文件不存在") return False except Exception as e: print(f" ❌ 导入失败: {e}") return False def test_file_structure(): """测试文件结构""" print("\n📁 测试文件结构...") essential_files = [ "api_minimal.py", "api/tool/meetspot_recommender.py", "app/config_simple.py", "requirements.txt" ] all_exist = True for file_path in essential_files: full_path = project_root / file_path if full_path.exists(): size = full_path.stat().st_size print(f" ✅ {file_path:<40} {size:>6} bytes") else: print(f" ❌ {file_path:<40} 不存在") all_exist = False return all_exist def calculate_performance_score(results: dict) -> int: """计算性能分数""" score = 0 max_score = 100 # 模块导入(20分) if results.get('import', False): score += 20 # 配置测试(10分) if results.get('config', False): score += 10 # 文件结构(20分) if results.get('structure', False): score += 20 # 精简版 API(10分) if results.get('minimal_api', False): score += 10 # 地理编码(20分)- 可选(需要 API Key) if results.get('geocoding', False): score += 20 # POI 搜索(20分)- 可选(需要 API Key) if results.get('poi', False): score += 20 return min(score, max_score) def main(): """主测试函数""" print("=" * 70) print("MeetSpot 精简版 API 测试") print("=" * 70) # 检查文件是否存在 if not (project_root / "api_minimal.py").exists(): print("❌ 错误: api_minimal.py 不存在") print("请确保已运行精简脚本或手动创建") sys.exit(1) results = {} # 运行测试 results['import'] = test_import() results['config'] = test_tmap_config() results['structure'] = test_file_structure() results['minimal_api'] = test_minimal_api() results['geocoding'] = test_geocoding() results['poi'] = test_poi_search() results['complete'] = test_complete_recommendation() # 计算性能分数 score = calculate_performance_score(results) # 输出测试报告 print("\n" + "=" * 70) print("📊 测试报告") print("=" * 70) passed = sum(1 for v in results.values() if v) total = len(results) print(f"\n✅ 通过: {passed}/{total}") print(f"📈 性能分数: {score}/100") if score >= 80: print(f"\n🎉 优秀! 精简版 API 已准备就绪") elif score >= 60: print(f"\n✅ 良好! 基本功能正常,部分功能需要 API Key") else: print(f"\n⚠️ 需要改进! 请检查错误信息") # 输出建议 print(f"\n💡 建议:") if not results.get('geocoding') or not results.get('poi'): print(f" - 配置 TMAP_API_KEY 环境变量以启用完整功能") print(f" - export TMAP_API_KEY=your_key") if score >= 60: print(f" - 可以开始部署到云托管") print(f" - 使用 Dockerfile.minimal 构建镜像") print(f" - 配置 VPC 访问类型") print(f"\n🚀 下一步:") print(f" 1. 配置真实 API Key") print(f" 2. 部署到云托管") print(f" 3. 测试小程序调用") print(f" 4. 开发小程序前端") return score if __name__ == "__main__": try: score = main() sys.exit(0 if score >= 60 else 1) except KeyboardInterrupt: print("\n\n❌ 测试被中断") sys.exit(1) except Exception as e: print(f"\n\n❌ 测试失败: {e}") import traceback traceback.print_exc() sys.exit(1)