import os from flask import Flask, jsonify from flasgger import Swagger from flask_migrate import Migrate from flask_cors import CORS from pymysql import OperationalError from sqlalchemy import text from extensions import db, jwt from routes.auth import auth_bp from routes.user import user_bp from routes.permissions import permission_bp from routes.dinamic_table import dinamic_table_bp from routes.contact import contact_bp from routes.address import address_bp from routes.licenses import license_bp from routes.user_service_roles import user_service_role_bp from seeds.run_seed import run_all_seeds from datetime import timedelta from routes.service import service_bp from routes.service_roles import service_role_bp from routes.cameras import camera_bp from routes.ambiente import ambiente_bp from routes.service_instance import service_instance_bp from routes.reports import employee_bp from routes.shift import shift_bp from routes.time_schedules import time_schedule_bp from routes.holiday import holiday_bp from routes.company import company_bp from routes.record import record_bp import logging from dotenv import load_dotenv from werkzeug.exceptions import BadRequest # Carregar variáveis de ambiente do arquivo .env load_dotenv() def create_app(): app = Flask(__name__) @app.errorhandler(BadRequest) def handle_bad_request(error): # Verificar se o erro é específico para duplicação de campos error_message = error.description or "Requisição inválida." if "duplicate" in error_message.lower(): error_message = "Parece que você tentou inserir um valor duplicado. Por favor, verifique e tente novamente." return jsonify({"error": error_message}), 400 # Certifique-se de configurar os logs no Flask corretamente app.logger.setLevel(logging.DEBUG) # Defina o formato do log para o app Flask handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) app.logger.addHandler(handler) # Defina o caminho absoluto para o banco de dados dentro da pasta "instance" instance_path = os.path.join(app.instance_path) os.makedirs(instance_path, exist_ok=True) # Configurações do Flask # Configurações do Flask app.config.update( SQLALCHEMY_DATABASE_URI=os.getenv('DATABASE_URL', 'sqlite:///default.db'), # URL do banco de dados SQLALCHEMY_TRACK_MODIFICATIONS=False, # Desativa notificações de alterações JWT_SECRET_KEY=os.getenv('JWT_SECRET_KEY', 'fallback-secret-key'), # Chave secreta para JWT JWT_ACCESS_TOKEN_EXPIRES=timedelta( # Tempo de expiração do token de acesso minutes=int(os.getenv('JWT_ACCESS_TOKEN_EXPIRES', 30)) # Valor padrão: 30 minutos ), JWT_REFRESH_TOKEN_EXPIRES=timedelta( # Tempo de expiração do token de refresh days=int(os.getenv('JWT_REFRESH_TOKEN_EXPIRES', 30)) # Valor padrão: 30 dias ), ) app.config['DEBUG'] = True # Ativa o modo de depuração app.logger.setLevel(logging.DEBUG) # Configuração do Swagger com Bearer Token SWAGGER_TEMPLATE = { "swagger": "2.0", "info": { "title": "API com Autenticação JWT", "description": "API com autenticação JWT usando Bearer Token", "version": "1.0.0" }, "securityDefinitions": { "bearerAuth": { "type": "apiKey", "name": "Authorization", "in": "header", "description": "JWT Authorization header using the Bearer scheme. Exemplo: 'Authorization: Bearer '" } }, "security": [{"bearerAuth": []}], } # Inicializar extensões db.init_app(app) jwt.init_app(app) CORS(app) # Inicializar Migrate Migrate(app, db) # Inicializar Swagger Swagger(app, template=SWAGGER_TEMPLATE) # Registrar Blueprints app.register_blueprint(auth_bp) app.register_blueprint(user_bp) app.register_blueprint(contact_bp) app.register_blueprint(address_bp) app.register_blueprint(permission_bp) app.register_blueprint(dinamic_table_bp) app.register_blueprint(license_bp) app.register_blueprint(service_bp) app.register_blueprint(service_role_bp) app.register_blueprint(user_service_role_bp) app.register_blueprint(camera_bp) app.register_blueprint(ambiente_bp) app.register_blueprint(service_instance_bp) app.register_blueprint(employee_bp) app.register_blueprint(shift_bp) app.register_blueprint(time_schedule_bp) app.register_blueprint(record_bp) app.register_blueprint(holiday_bp) app.register_blueprint(company_bp) # Testa a conexão com o banco de dados with app.app_context(): try: # Use text() para fazer a string SQL executável with db.engine.connect() as connection: result = connection.execute(text("SELECT 1")) app.logger.info("Conexão ao banco de dados bem-sucedida: %s", result.scalar()) except OperationalError as e: app.logger.error("Erro ao conectar ao banco de dados:") app.logger.error(str(e)) raise e return app def get_database_type(uri): """Extrai o tipo de banco de dados da URI.""" return uri.split(":")[0] if __name__ == "__main__": app = create_app() with app.app_context(): db.create_all() # Cria as tabelas run_all_seeds() # Executa os seeds app.run(debug=True, host="0.0.0.0")