front_ponto_eletronico/app.py

160 lines
5.7 KiB
Python

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 <JWT>'"
}
},
"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()
app.run(debug=True, host="0.0.0.0")