-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
179 lines (156 loc) · 6.41 KB
/
main.py
File metadata and controls
179 lines (156 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
from flask import Flask, render_template, jsonify, send_from_directory
import pandas as pd
from utils.data_fetcher import (
get_bitcoin_data,
fetch_bitcoin_price,
fetch_etf_data,
fetch_onchain_metrics
)
from utils.visualizations import (
create_price_chart,
create_metric_chart,
create_etf_comparison
)
from utils.sitemap import generate_sitemap, write_sitemap
from utils.predictions import analyze_market_trends, generate_predictions # Fixed import path
import logging
import os
import json
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = Flask(__name__)
# Add sum function to Jinja context
app.jinja_env.globals.update(sum=sum)
# Flag to track if sitemap has been generated
_sitemap_generated = False
def get_routes():
"""Get all routes with metadata for sitemap"""
return [
{'path': '/', 'changefreq': 'always', 'priority': '1.0'},
{'path': '/correlation', 'changefreq': 'daily', 'priority': '0.8'},
{'path': '/liquidity', 'changefreq': 'daily', 'priority': '0.8'},
{'path': '/predictions', 'changefreq': 'daily', 'priority': '0.8'},
{'path': '/education', 'changefreq': 'weekly', 'priority': '0.7'},
{'path': '/cost-analysis', 'changefreq': 'weekly', 'priority': '0.7'}, #Added cost analysis route
{'path': '/risk-metrics', 'changefreq': 'weekly', 'priority': '0.7'} #Added risk metrics route
]
@app.before_request
def init_sitemap():
"""Generate sitemap.xml before first request"""
global _sitemap_generated
if not _sitemap_generated:
try:
base_url = 'https://bitcoin-etf-analytics.replit.app'
routes = get_routes()
sitemap_content = generate_sitemap(base_url, routes)
write_sitemap(sitemap_content)
logger.info("Sitemap generated successfully")
_sitemap_generated = True
except Exception as e:
logger.error(f"Error generating sitemap: {str(e)}")
@app.route('/sitemap.xml')
def serve_sitemap():
"""Serve the sitemap.xml file"""
return send_from_directory('.', 'sitemap.xml')
@app.route('/')
def index():
"""Main dashboard page"""
try:
btc_data = get_bitcoin_data()
if not btc_data:
logger.error("Failed to fetch Bitcoin data")
return render_template('index.html', error="Unable to fetch Bitcoin data")
historical_data = fetch_bitcoin_price()
price_chart = create_price_chart(historical_data) if not historical_data.empty else None
if not price_chart:
logger.warning("No historical price data available")
etf_data = fetch_etf_data()
etf_chart = create_etf_comparison(etf_data) if etf_data else None
if not etf_chart:
logger.warning("No ETF data available")
metrics_data = fetch_onchain_metrics()
active_addresses_chart = None
hash_rate_chart = None
if not metrics_data.empty:
active_addresses_chart = create_metric_chart(metrics_data, 'active_addresses', '#1f77b4')
hash_rate_chart = create_metric_chart(metrics_data, 'hash_rate', '#2ca02c')
else:
logger.warning("No metrics data available")
return render_template('index.html',
btc_data=btc_data,
price_chart=price_chart,
etf_chart=etf_chart,
active_addresses_chart=active_addresses_chart,
hash_rate_chart=hash_rate_chart
)
except Exception as e:
logger.error(f"Error rendering dashboard: {str(e)}", exc_info=True)
return render_template('index.html', error=f"An error occurred: {str(e)}")
@app.route('/correlation')
def correlation():
"""Correlation analysis page"""
try:
historical_data = fetch_bitcoin_price()
etf_data = fetch_etf_data()
return render_template('correlation.html',
price_chart=create_price_chart(historical_data) if not historical_data.empty else None,
etf_chart=create_etf_comparison(etf_data) if etf_data else None
)
except Exception as e:
logger.error(f"Error in correlation analysis: {str(e)}", exc_info=True)
return render_template('correlation.html', error=str(e))
@app.route('/liquidity')
def liquidity():
"""Liquidity analysis page"""
try:
etf_data = fetch_etf_data()
logger.info(f"Fetched ETF data: {etf_data}") # Add logging
if not etf_data:
return render_template('liquidity.html', error="Unable to fetch ETF data")
return render_template('liquidity.html', etf_data=etf_data)
except Exception as e:
logger.error(f"Error in liquidity analysis: {str(e)}", exc_info=True)
return render_template('liquidity.html', error=str(e))
@app.route('/predictions')
def predictions():
"""AI predictions page"""
try:
historical_data = fetch_bitcoin_price()
metrics_data = fetch_onchain_metrics()
if not historical_data.empty and not metrics_data.empty:
# Generate market analysis
analysis = json.loads(analyze_market_trends(historical_data, metrics_data))
predictions = generate_predictions()
return render_template('predictions.html',
historical_data=historical_data,
metrics_data=metrics_data,
analysis=analysis,
predictions=predictions
)
else:
logger.warning("Missing data for predictions")
return render_template('predictions.html', error="Unable to fetch required data")
except Exception as e:
logger.error(f"Error in predictions: {str(e)}", exc_info=True)
return render_template('predictions.html', error=str(e))
@app.route('/education')
def education():
"""Educational content page"""
return render_template('education.html')
@app.route('/cost-analysis')
def cost_analysis():
"""Cost analysis page"""
# Placeholder for charts - needs actual chart generation logic
cost_chart = "Cost Analysis Chart Placeholder"
return render_template('cost_analysis.html', cost_chart=cost_chart)
@app.route('/risk-metrics')
def risk_metrics():
"""Risk metrics and alerts page"""
return render_template('risk_metrics.html')
@app.route('/health')
def health_check():
"""Simple health check endpoint"""
return jsonify({"status": "healthy"})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)