Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import random | |
| import time | |
| import requests | |
| from flask import Flask, render_template, request, jsonify, send_from_directory | |
| from flask_cors import CORS | |
| from werkzeug.utils import secure_filename | |
| app = Flask(__name__) | |
| CORS(app) | |
| # Configuration | |
| app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB | |
| app.config['JSON_AS_ASCII'] = False | |
| app.config['UPLOAD_FOLDER'] = 'uploads' | |
| # Ensure upload folder exists | |
| os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |
| # API Key Configuration | |
| # In production, use environment variables: os.environ.get("SILICONFLOW_API_KEY") | |
| SILICONFLOW_API_KEY = os.environ.get("SILICONFLOW_API_KEY", "sk-vimuseiptfbomzegyuvmebjzooncsqbyjtlddrfodzcdskgi") | |
| SILICONFLOW_API_URL = "https://api.siliconflow.cn/v1/chat/completions" | |
| # Global context to store uploaded data or latest traffic state | |
| traffic_context = {} | |
| # Mock Data Generator | |
| def generate_traffic_data(): | |
| """Generate mock traffic data for the dashboard (Chinese).""" | |
| districts = ["市中心", "北区", "科技园", "港口区", "西区"] | |
| data = { | |
| "timestamp": time.strftime("%H:%M:%S"), | |
| "congestion_index": round(random.uniform(1.0, 9.9), 1), | |
| "avg_speed": round(random.uniform(15, 60), 1), | |
| "active_incidents": random.randint(0, 5), | |
| "district_status": [] | |
| } | |
| for district in districts: | |
| status_map = { | |
| "Smooth": "畅通", | |
| "Moderate": "缓行", | |
| "Congested": "拥堵", | |
| "Heavy Congestion": "严重拥堵" | |
| } | |
| raw_status = random.choice(list(status_map.keys())) | |
| data["district_status"].append({ | |
| "name": district, | |
| "flow": random.randint(500, 3000), # vehicles per hour | |
| "status": raw_status, | |
| "status_cn": status_map[raw_status] | |
| }) | |
| # Update global context | |
| global traffic_context | |
| traffic_context = data | |
| return data | |
| def index(): | |
| return render_template('index.html') | |
| def get_traffic_data(): | |
| return jsonify(generate_traffic_data()) | |
| def upload_file(): | |
| if 'file' not in request.files: | |
| return jsonify({"error": "没有文件部分"}), 400 | |
| file = request.files['file'] | |
| if file.filename == '': | |
| return jsonify({"error": "未选择文件"}), 400 | |
| if file: | |
| filename = secure_filename(file.filename) | |
| filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
| try: | |
| file.save(filepath) | |
| except Exception as e: | |
| return jsonify({"error": f"保存文件失败: {str(e)}"}), 500 | |
| # Simple processing logic | |
| msg = f"文件 {filename} 上传成功。" | |
| if filename.lower().endswith('.json'): | |
| try: | |
| with open(filepath, 'r', encoding='utf-8') as f: | |
| data = json.load(f) | |
| # Try to merge into context if structure matches | |
| if 'congestion_index' in data: | |
| global traffic_context | |
| traffic_context.update(data) | |
| msg += " 交通数据已更新。" | |
| except Exception as e: | |
| msg += f" 但解析JSON失败: {str(e)}" | |
| return jsonify({"message": msg, "filename": filename}) | |
| def chat(): | |
| data = request.json | |
| user_message = data.get('message', '') | |
| # Use global context if available, else client provided context | |
| context_data = traffic_context if traffic_context else data.get('context', {}) | |
| if not user_message: | |
| return jsonify({"error": "No message provided"}), 400 | |
| # System Prompt with Context (Chinese) | |
| system_prompt = f"""你是一个名为'Urban Flow'的智慧城市交通管理AI专家。 | |
| 当前交通状况: | |
| - 拥堵指数: {context_data.get('congestion_index', 'N/A')} | |
| - 平均车速: {context_data.get('avg_speed', 'N/A')} km/h | |
| - 活跃事件: {context_data.get('active_incidents', 'N/A')} | |
| 你的角色是分析交通状况,提出信号优化策略和出行建议。 | |
| 请保持专业、简洁,并用数据说话。使用Markdown格式回复。 | |
| 如果被问及'优化信号灯',请提出具体的调整建议(例如:'建议将市中心主干道的绿灯时间延长15秒')。 | |
| """ | |
| payload = { | |
| "model": "Qwen/Qwen2.5-7B-Instruct", | |
| "messages": [ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_message} | |
| ], | |
| "temperature": 0.7, | |
| "max_tokens": 512 | |
| } | |
| headers = { | |
| "Authorization": f"Bearer {SILICONFLOW_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| try: | |
| # Mock Mode Fallback logic (Network resilience) | |
| try: | |
| response = requests.post(SILICONFLOW_API_URL, json=payload, headers=headers, timeout=5) | |
| response.raise_for_status() | |
| ai_response = response.json()['choices'][0]['message']['content'] | |
| except Exception as e: | |
| print(f"API Error: {e}. Switching to Mock Mode.") | |
| # Fallback Mock Response | |
| time.sleep(1) # Simulate delay | |
| ai_response = f"""**[模拟模式已激活]** 网络连接不可用。 | |
| 根据当前拥堵指数 **{context_data.get('congestion_index', 'N/A')}**,我的分析如下: | |
| 1. **信号优化**: 建议延长 **市中心** 区域绿灯时长 20%。 | |
| 2. **路线建议**: 建议重型货车绕行外环路。 | |
| 3. **事件响应**: 派遣无人机巡查西区路口。 | |
| *注意: 请检查网络连接和API密钥以获取实时AI分析。*""" | |
| return jsonify({"response": ai_response}) | |
| except Exception as e: | |
| return jsonify({"error": str(e)}), 500 | |
| def request_entity_too_large(error): | |
| return jsonify({"error": "文件太大,超过限制 (16MB)"}), 413 | |
| def page_not_found(e): | |
| return jsonify({"error": "未找到该资源 (404)"}), 404 | |
| def internal_server_error(e): | |
| return jsonify({"error": "服务器内部错误 (500)"}), 500 | |
| if __name__ == '__main__': | |
| app.run(host='0.0.0.0', port=7860, debug=True) | |