""" Main Flask Routes Handles the primary web interface for the Markov economics simulation, including the main simulation page and basic navigation. """ from flask import Blueprint, render_template, request, jsonify from app.models import SimulationManager, SimulationParameters main_bp = Blueprint('main', __name__) # Import global simulation manager instance from app import simulation_manager @main_bp.route('/') def index(): """ Main simulation interface page. Returns: Rendered HTML template with simulation controls """ # Default parameters for display default_params = { 'r_rate': 0.05, # 5% capital return rate 'g_rate': 0.03, # 3% economic growth rate 'initial_capital': 1000.0, 'initial_consumption': 1000.0, 'num_agents': 100, 'iterations': 1000 } return render_template('simulation.html', default_params=default_params, title="Markov Economics - Capitalism Eats the World") @main_bp.route('/simulation') def simulation(): """ Alternative route to the main simulation page. Returns: Rendered HTML template with simulation controls """ return index() @main_bp.route('/about') def about(): """ Information page about the economic theory behind the simulation. Returns: Rendered HTML template with theoretical background """ return render_template('about.html', title="About - Markov Economics Theory") @main_bp.route('/results/') def results(simulation_id): """ Display results for a specific simulation. Args: simulation_id: Unique identifier for the simulation Returns: Rendered results template or 404 if simulation not found """ simulation = simulation_manager.get_simulation(simulation_id) if not simulation: return render_template('error.html', error_message=f"Simulation {simulation_id} not found", title="Simulation Not Found"), 404 # Get simulation summary data latest_snapshot = simulation.get_latest_snapshot() iterations, total_wealth, gini_coefficients = simulation.get_wealth_evolution() summary_data = { 'simulation_id': simulation_id, 'parameters': { 'r_rate': simulation.parameters.r_rate, 'g_rate': simulation.parameters.g_rate, 'num_agents': simulation.parameters.num_agents, 'iterations': simulation.parameters.iterations }, 'current_iteration': simulation.current_iteration, 'total_iterations': len(simulation.snapshots), 'latest_snapshot': latest_snapshot, 'has_data': len(simulation.snapshots) > 0 } return render_template('results.html', simulation_data=summary_data, title=f"Results - Simulation {simulation_id[:8]}") @main_bp.route('/test-simulation') def test_simulation(): """ Test endpoint to simulate a full simulation run and check distribution data flow. Returns: JSON response with complete simulation test results """ import time from app.models.economic_model import EconomicSimulation, SimulationParameters # Create test simulation with small parameters for quick testing test_params = SimulationParameters( r_rate=0.05, g_rate=0.03, initial_capital=1000, initial_consumption=1000, num_agents=20, iterations=10 ) test_sim = EconomicSimulation(test_params) # Simulate the full flow results = { 'simulation_created': True, 'steps_completed': 0, 'distribution_data': [], 'final_distribution': None, 'errors': [] } try: # Run simulation steps for i in range(10): snapshot = test_sim.step() results['steps_completed'] = i + 1 # Test distribution data generation at each step if i % 3 == 0: # Test every 3rd step like real simulation try: labels, counts = test_sim.get_wealth_histogram(5) distribution_data = { 'iteration': snapshot.iteration, 'labels': labels, 'counts': counts, 'total_agents': len(test_sim.agents) } results['distribution_data'].append(distribution_data) except Exception as e: results['errors'].append(f'Distribution generation error at step {i}: {str(e)}') # Get final distribution try: final_labels, final_counts = test_sim.get_wealth_histogram(8) results['final_distribution'] = { 'labels': final_labels, 'counts': final_counts, 'total_count': sum(final_counts) } except Exception as e: results['errors'].append(f'Final distribution error: {str(e)}') # Test API-style response format results['api_format_test'] = { 'distribution': { 'labels': final_labels, 'counts': final_counts, 'bins': 8 }, 'latest_snapshot': { 'iteration': test_sim.current_iteration, 'total_wealth': test_sim.snapshots[-1].total_wealth if test_sim.snapshots else 0, 'gini_coefficient': test_sim.snapshots[-1].gini_coefficient if test_sim.snapshots else 0 } } except Exception as e: results['errors'].append(f'General simulation error: {str(e)}') results['success'] = len(results['errors']) == 0 results['timestamp'] = time.time() return jsonify(results) @main_bp.route('/debug') def debug_info(): """ Debug endpoint to verify deployment and test functionality. Returns: JSON response with debug information """ import os from datetime import datetime from app.models.economic_model import EconomicSimulation, SimulationParameters # Test distribution functionality test_params = SimulationParameters( r_rate=0.05, g_rate=0.03, initial_capital=1000, initial_consumption=1000, num_agents=10, iterations=5 ) test_sim = EconomicSimulation(test_params) # Run a few steps for _ in range(5): test_sim.step() # Get distribution data labels, counts = test_sim.get_wealth_histogram(5) debug_data = { 'timestamp': datetime.now().isoformat(), 'environment': os.getenv('FLASK_ENV', 'unknown'), 'config': os.getenv('FLASK_CONFIG', 'unknown'), 'python_version': os.sys.version, 'distribution_test': { 'labels': labels, 'counts': counts, 'total_agents': len(test_sim.agents), 'snapshots': len(test_sim.snapshots) }, 'fixes_deployed': { 'fallback_polling': True, 'enhanced_socketio': True, 'production_debug': True, 'environment_fix': True }, 'version_info': 'v2.1-proxy-fixes' } return jsonify(debug_data) @main_bp.route('/health') def health_check(): """ Simple health check endpoint. Returns: JSON response indicating service status """ return jsonify({ 'status': 'healthy', 'service': 'markov-economics', 'active_simulations': len(simulation_manager.active_simulations), 'total_simulations': len(simulation_manager.simulations) }) @main_bp.route('/robots.txt') def robots_txt(): """ Serve the robots.txt file. Returns: robots.txt content """ from flask import current_app return current_app.send_static_file('robots.txt') @main_bp.route('/sitemap.xml') def sitemap_xml(): """ Serve the sitemap.xml file. Returns: sitemap.xml content """ from flask import current_app return current_app.send_static_file('sitemap.xml') @main_bp.errorhandler(404) def not_found_error(error): """ Handle 404 errors with custom template. Args: error: The error object Returns: Rendered error template """ return render_template('error.html', error_message="Page not found", title="Page Not Found"), 404 @main_bp.errorhandler(500) def internal_error(error): """ Handle 500 errors with custom template. Args: error: The error object Returns: Rendered error template """ return render_template('error.html', error_message="Internal server error occurred", title="Server Error"), 500