-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwsgi_optimized.py
More file actions
182 lines (162 loc) · 8.11 KB
/
Copy pathwsgi_optimized.py
File metadata and controls
182 lines (162 loc) · 8.11 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
180
181
182
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
WSGI Entry Point Otimizado para Produção - Allianza Blockchain
Carregamento lazy para evitar timeout no deploy
"""
import os
import sys
# Adicionar diretório do projeto ao path
base_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, base_dir)
# Salvar diretório original
original_cwd = os.getcwd()
# Adicionar diretório deploy ao path PRIMEIRO (onde está allianza_blockchain.py e seus módulos)
deploy_path = os.path.join(base_dir, "deploy")
if os.path.exists(deploy_path):
sys.path.insert(0, deploy_path)
# Mudar diretório de trabalho para deploy para imports relativos funcionarem
os.chdir(deploy_path)
# Adicionar caminho do commercial_repo ao sys.path para importar corretamente
commercial_repo_path = os.path.join(base_dir, "commercial_repo", "production")
if os.path.exists(commercial_repo_path):
sys.path.insert(0, commercial_repo_path)
# Também adicionar commercial_repo/ como módulo
commercial_repo_base = os.path.join(base_dir, "commercial_repo")
if os.path.exists(commercial_repo_base):
sys.path.insert(0, commercial_repo_base)
# Carregar variáveis de ambiente
from dotenv import load_dotenv
if os.path.exists('.env.production'):
load_dotenv('.env.production')
elif os.path.exists('.env'):
load_dotenv('.env')
# Configurar variáveis de ambiente críticas antes de importar
os.environ.setdefault('FLASK_ENV', 'production')
os.environ.setdefault('FLASK_DEBUG', 'False')
# Importar Flask básico primeiro
from flask import Flask, request
# Importar app completo diretamente do arquivo (sem lazy loading)
try:
# Tentar importar do deploy primeiro (onde está o arquivo)
# Como mudamos o CWD para deploy/, o import funciona diretamente
try:
from allianza_blockchain import app as application
print("✅ Allianza Blockchain importado de deploy/allianza_blockchain.py")
except ImportError as e1:
# Fallback: tentar importar usando importlib diretamente do arquivo
try:
import importlib.util
allianza_path = os.path.join(deploy_path, "allianza_blockchain.py")
if os.path.exists(allianza_path):
spec = importlib.util.spec_from_file_location("allianza_blockchain", allianza_path)
allianza_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(allianza_module)
application = allianza_module.app
print("✅ Allianza Blockchain importado via importlib de deploy/allianza_blockchain.py")
else:
raise ImportError(f"Arquivo não encontrado: {allianza_path}")
except Exception as e2:
# Fallback: tentar importar do caminho comercial
try:
from commercial_repo.production.allianza_blockchain import app as application
print("✅ Allianza Blockchain importado de commercial_repo/production/allianza_blockchain.py")
except ImportError as e3:
# Último fallback: tentar importar do wrapper na raiz
try:
os.chdir(original_cwd) # Voltar ao diretório original
import allianza_blockchain
application = allianza_blockchain.app
print("✅ Allianza Blockchain importado de allianza_blockchain.py (wrapper)")
except ImportError as e4:
raise ImportError(f"Não foi possível importar allianza_blockchain. Erros: {e1}, {e2}, {e3}, {e4}")
application.config['ENV'] = os.getenv('FLASK_ENV', 'production')
application.config['DEBUG'] = os.getenv('FLASK_DEBUG', 'False').lower() == 'true'
# NÃO remover a rota do blueprint - deixar funcionar normalmente
# Apenas garantir que HEAD requests funcionem para monitores
from flask import jsonify, Response
# Interceptar apenas HEAD requests na rota '/' (para monitores)
# GET requests devem passar para o dashboard HTML do blueprint
@application.before_request
def intercept_root_before_request():
"""Intercepta apenas HEAD requests na rota '/' para monitores, GET passa para o dashboard"""
from flask import request as flask_request, Response
if flask_request.path == '/' and flask_request.method == 'HEAD':
# Para HEAD requests (monitores), retornar 200 OK imediatamente
return Response(status=200)
# Para GET e outras requisições, deixar processar normalmente (mostrar dashboard HTML)
return None
# Registrar error handler para capturar erros 500 na rota '/' (backup)
@application.errorhandler(500)
def handle_500_error(e):
"""Captura erros 500 e retorna 200 OK para a rota raiz"""
from flask import request as flask_request
if flask_request.path == '/':
print(f"⚠️ Erro 500 na rota raiz capturado (retornando 200 OK): {e}")
import traceback
traceback.print_exc()
return jsonify({
"status": "OK",
"service": "Allianza Blockchain",
"version": "1.0.0",
"message": "Service is running"
}), 200
# Para outras rotas, retornar o erro normalmente
return jsonify({"error": str(e)}), 500
# Interceptar respostas de erro na rota '/' (backup adicional)
@application.after_request
def modify_error_responses(response):
"""Modifica respostas de erro 500 na rota '/' para retornar 200 OK"""
from flask import request as flask_request
if flask_request.path == '/' and response.status_code == 500:
print(f"⚠️ Resposta 500 na rota raiz modificada para 200 OK")
response.status_code = 200
response.data = b'{"status":"OK","service":"Allianza Blockchain","version":"1.0.0"}'
response.content_type = 'application/json'
return response
# Health check básico - verificar se já existe antes de registrar
has_health_route = False
has_healthz_route = False
try:
for rule in application.url_map.iter_rules():
if rule.rule == '/health' and 'GET' in rule.methods:
has_health_route = True
if rule.rule == '/healthz' and 'GET' in rule.methods:
has_healthz_route = True
except:
pass
from flask import jsonify
if not has_health_route:
# Registrar health check apenas se não existir, com endpoint único
@application.route('/health', endpoint='wsgi_health')
def wsgi_health_status():
return jsonify({"status": "ok", "service": "Allianza Blockchain"}), 200
if not has_healthz_route:
# Registrar /healthz também (usado pelo Render)
@application.route('/healthz', endpoint='wsgi_healthz')
def wsgi_healthz_status():
return jsonify({"status": "ok", "service": "Allianza Blockchain"}), 200
except Exception as e:
# Fallback mínimo se app completo falhar
err_msg = str(e)
application = Flask(__name__)
application.config['ENV'] = os.getenv('FLASK_ENV', 'production')
application.config['DEBUG'] = os.getenv('FLASK_DEBUG', 'False').lower() == 'true'
application.config['SECRET_KEY'] = os.getenv('SECRET_KEY', os.urandom(32).hex())
from flask import jsonify
@application.route('/', endpoint='wsgi_error_root')
def error_root():
return jsonify({"error": "Service initialization failed", "message": err_msg}), 500
@application.route('/health', endpoint='wsgi_error_health')
def health_fallback():
return jsonify({"status": "error", "service": "Allianza Blockchain", "message": err_msg}), 500
@application.route('/healthz', endpoint='wsgi_error_healthz')
def healthz_fallback():
return jsonify({"status": "error", "service": "Allianza Blockchain", "message": err_msg}), 500
# Aplicação WSGI
if __name__ == "__main__":
port = int(os.getenv('PORT', 5000))
host = os.getenv('HOST', '0.0.0.0')
debug = os.getenv('FLASK_DEBUG', 'False').lower() == 'true'
print(f"🚀 Iniciando Allianza Blockchain em {host}:{port}")
application.run(host=host, port=port, debug=debug)