Files
capitalism-eats-the-world/app/routes/main.py

312 lines
8.9 KiB
Python

"""
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/<simulation_id>')
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