Spaces:
Running
Running
| # main.py — AKIRA V21 ULTIMATE (Janeiro 2025) | |
| """ | |
| Entry point Flask API para Akira IA V21 | |
| - Multi-API com fallback (6 provedores) | |
| - Suporte a .env para secrets | |
| - Otimizado para Hugging Face Spaces | |
| """ | |
| import os | |
| import sys | |
| # === CORREÇÃO: Garante que os imports funcionam (local e produção) === | |
| PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) | |
| if PROJECT_ROOT not in sys.path: | |
| sys.path.insert(0, PROJECT_ROOT) | |
| # Carregar variáveis de ambiente (.env) o mais cedo possível | |
| try: | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| except ImportError: | |
| pass | |
| from flask import Flask, jsonify | |
| from loguru import logger | |
| import datetime | |
| # === LOGS === | |
| logger.remove() | |
| logger.add( | |
| sys.stderr, | |
| format="<green>{time:HH:mm:ss}</green> | <level>{level}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan> -> <level>{message}</level>", | |
| colorize=True, | |
| backtrace=True, | |
| diagnose=True, | |
| level="INFO" | |
| ) | |
| # === FLASK APP === | |
| app = Flask(__name__) | |
| # Make app available for Gunicorn | |
| application = app | |
| # === ROTAS BASICAS === | |
| def index(): | |
| """Pagina inicial com status dinamico""" | |
| try: | |
| from modules import config | |
| apis_configuradas = [] | |
| if getattr(config, "MISTRAL_API_KEY", None): apis_configuradas.append("Mistral") | |
| if getattr(config, "GEMINI_API_KEY", None): apis_configuradas.append("Gemini") | |
| if getattr(config, "GROQ_API_KEY", None): apis_configuradas.append("Groq") | |
| if getattr(config, "COHERE_API_KEY", None): apis_configuradas.append("Cohere") | |
| if getattr(config, "TOGETHER_API_KEY", None): apis_configuradas.append("Together") | |
| if getattr(config, "OPENROUTER_API_KEY", None): apis_configuradas.append("OpenRouter") | |
| apis_texto = ", ".join(apis_configuradas) if apis_configuradas else "Nenhuma (Verifique os Secrets)" | |
| except Exception: | |
| apis_texto = "Erro ao ler configuracoes" | |
| return f''' | |
| <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; text-align: center; margin: 50px; background: #0a0a0a; color: #00ff41; padding: 40px; border: 2px solid #00ff41; border-radius: 10px; box-shadow: 0 0 20px rgba(0,255,65,0.2);"> | |
| <h1 style="text-shadow: 0 0 10px #00ff41;">AKIRA V21 ULTIMATE ONLINE!</h1> | |
| <p style="color: #fff;"><strong>Multi-API System — Core Infrastructure V21</strong></p> | |
| <p><strong>APIs Ativas:</strong> <span style="color: #fff;">{apis_texto}</span></p> | |
| <p><strong>Status:</strong> <span style="background: #00ff41; color: #000; padding: 2px 8px; border-radius: 4px; font-weight: bold;">OPERACIONAL</span></p> | |
| <hr style="border-color: #333; margin: 25px 0;"> | |
| <p style="font-size: 0.8em; color: #888;"><em>Luanda, Angola — Softedge Isaac N. Quarenta softwares</em></p> | |
| </div> | |
| ''', 200 | |
| def health(): | |
| """Health check para Docker/HF Spaces""" | |
| return "OK", 200 | |
| def status(): | |
| """Status detalhado das APIs dinâmico""" | |
| try: | |
| from modules import config | |
| status_info = { | |
| "timestamp": datetime.datetime.now().isoformat(), | |
| "versao": "V21 ULTIMATE", | |
| "uptime_status": "OK", | |
| "apis_disponiveis": [], | |
| } | |
| providers = { | |
| "mistral": "MISTRAL_API_KEY", | |
| "gemini": "GEMINI_API_KEY", | |
| "groq": "GROQ_API_KEY", | |
| "cohere": "COHERE_API_KEY", | |
| "together": "TOGETHER_API_KEY", | |
| "openrouter": "OPENROUTER_API_KEY" | |
| } | |
| for name, key in providers.items(): | |
| if getattr(config, key, None): | |
| status_info["apis_disponiveis"].append(name) | |
| return jsonify(status_info), 200 | |
| except Exception as e: | |
| return jsonify({"error": str(e), "status": "parcial"}), 500 | |
| # === INTEGRAÇÃO DA API === | |
| akira_api = None | |
| api_disponivel = False | |
| try: | |
| # Tenta importar a API | |
| from modules.api import AkiraAPI, get_blueprint | |
| import modules.config as config | |
| # API_AVAILABLE está em config.py | |
| API_AVAILABLE = getattr(config, 'API_AVAILABLE', {}) | |
| if API_AVAILABLE or True: # Always try if imports succeeded | |
| logger.info("Modulos importados com sucesso") | |
| if hasattr(config, 'validate_config'): | |
| config.validate_config() | |
| logger.info("Config validada") | |
| akira_api = AkiraAPI() | |
| app.register_blueprint(get_blueprint(), url_prefix="/api") | |
| logger.success("API V21 integrada -> /api/akira") | |
| apis_ok = [] | |
| if config.MISTRAL_API_KEY: | |
| apis_ok.append("Mistral") | |
| if config.GEMINI_API_KEY: | |
| apis_ok.append("Gemini") | |
| if config.GROQ_API_KEY: | |
| apis_ok.append("Groq") | |
| if config.COHERE_API_KEY: | |
| apis_ok.append("Cohere") | |
| if config.TOGETHER_API_KEY: | |
| apis_ok.append("Together") | |
| # HF não está sendo usado mais | |
| if apis_ok: | |
| logger.info(f"APIs: {', '.join(apis_ok)}") | |
| else: | |
| logger.warning("NENHUMA API CONFIGURADA!") | |
| api_disponivel = True | |
| else: | |
| logger.warning("API nao disponivel (erro de import)") | |
| except ImportError as e: | |
| logger.critical(f"ERRO DE IMPORTACAO: {e}") | |
| import traceback | |
| logger.critical(traceback.format_exc()) | |
| except Exception as e: | |
| logger.critical(f"FALHA: {e}") | |
| import traceback | |
| logger.critical(traceback.format_exc()) | |
| # === SERVIÇO DE BACKUP AUTOMÁTICO PARA HF BUCKETS === | |
| def periodic_hf_sync_checkpoint(): | |
| """ | |
| Roda um processo nativo em background que faz backup seguro | |
| do SQLite para a pasta cloud_sync a cada 2 horas, evitando | |
| qualquer interferência do SQLite WAL na hora de sincronizar p/ HF. | |
| """ | |
| import time | |
| import threading | |
| def _run_checkpoint(): | |
| try: | |
| from modules.database import Database | |
| import modules.config as config | |
| db = Database(getattr(config, 'DB_PATH', 'akira.db')) | |
| while True: | |
| # Dorme por 2 horas (7200 segundos) | |
| time.sleep(7200) | |
| db.fazer_checkpoint_hf_sync() | |
| except Exception as e: | |
| logger.error(f"Erro no scheduler de backup HF Sync: {e}") | |
| thread = threading.Thread(target=_run_checkpoint, daemon=True) | |
| thread.start() | |
| logger.info("⏱️ Background Job: Checkpoint HF Sync agendado p/ cada 2 horas.") | |
| # Inicia o serviço | |
| if api_disponivel: | |
| periodic_hf_sync_checkpoint() | |
| # === INICIO DO SERVIDOR === | |
| if __name__ == "__main__": | |
| logger.info("=" * 60) | |
| logger.info("AKIRA V21 ULTIMATE — SISTEMA MULTI-API") | |
| logger.info("=" * 60) | |
| host = os.getenv("API_HOST", "0.0.0.0") | |
| port = int(os.getenv("API_PORT", "7860")) | |
| logger.info(f"Servidor: http://{host}:{port}") | |
| logger.info("Endpoints: /, /health, /status, /api/akira") | |
| logger.info("=" * 60) | |
| if os.getenv("PRODUCTION", "false").lower() == "true": | |
| logger.info("Modo: PRODUCAO (Gunicorn)") | |
| else: | |
| logger.info("Modo: DESENVOLVIMENTO") | |
| app.run(host=host, port=port, debug=False, use_reloader=False) | |