diff --git a/.env.example b/.env.example index 0ccdcd6..b4aea24 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,54 @@ +#----------------------------------------------- +# Configurações do Servidor +#----------------------------------------------- +# Configurações do UVICORN +UVICORN_PORT=8005 +UVICORN_HOST=0.0.0.0 +UVICORN_RELOAD=true +UVICORN_WORKERS=1 + +# Domínios da Aplicação +API_DOMAIN=seu.dominio.com # Subdomínio para a API (ex: api.seudominio.com) +MANAGER_DOMAIN=manager.seu.dominio.com # Subdomínio para o Manager (ex: manager.seudominio.com) + # Debug e Logs DEBUG_MODE=false LOG_LEVEL=INFO -# Credenciais do Gerenciador -MANAGER_USER=admin -MANAGER_PASSWORD=impacteai2024 +#----------------------------------------------- +# Credenciais de Acesso +#----------------------------------------------- +# Credenciais do Painel Administrativo +MANAGER_USER=seu_usuario_admin # Username para acessar o painel admin +MANAGER_PASSWORD=sua_senha_segura # Senha para acessar o painel admin -# Configurações do Servidor -FASTAPI_PORT=8005 -STREAMLIT_PORT=8501 -HOST=0.0.0.0 +#----------------------------------------------- +# Configurações do Redis +#----------------------------------------------- +# Configurações Básicas +REDIS_HOST=redis-transcrevezap # Host do Redis (use redis-transcrevezap para docker-compose) +REDIS_PORT=6380 # Porta do Redis +REDIS_DB=0 # Número do banco de dados Redis + +# Autenticação Redis (opcional) +REDIS_USERNAME= # Deixe em branco se não usar autenticação +REDIS_PASSWORD= # Deixe em branco se não usar autenticação + +#----------------------------------------------- +# Configurações de Rede +#----------------------------------------------- +# Nome da Rede Docker Externa +NETWORK_NAME=sua_rede_externa # Nome da sua rede Docker externa + +#----------------------------------------------- +# Configurações do Traefik (se estiver usando) +#----------------------------------------------- +# Certificados SSL +SSL_RESOLVER=letsencryptresolver # Resolvedor SSL do Traefik +SSL_ENTRYPOINT=websecure # Entrypoint SSL do Traefik + +#----------------------------------------------- +# Portas da Aplicação +#----------------------------------------------- +API_PORT=8005 # Porta para a API FastAPI +MANAGER_PORT=8501 # Porta para o Streamlit Manager \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 60e0c84..99df28c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,41 +1,46 @@ -# Usar uma imagem oficial do Python como base +# Imagem base do Python 3.10-slim FROM python:3.10-slim -# Instalar dependências do sistema, incluindo redis-tools e tzdata para fuso horário +# Configuração básica de timezone +ENV TZ=America/Sao_Paulo + +# Instalação de dependências mínimas necessárias RUN apt-get update && apt-get install -y --no-install-recommends \ redis-tools \ tzdata \ - && apt-get clean && rm -rf /var/lib/apt/lists/* + dos2unix \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ + && echo $TZ > /etc/timezone -# Configurar o fuso horário -ENV TZ=America/Sao_Paulo -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone - -# Definir o diretório de trabalho +# Configuração do ambiente de trabalho WORKDIR /app -# Copiar o arquivo requirements.txt e instalar dependências +# Instalação das dependências Python COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Copiar todo o código da aplicação +# Copia dos arquivos da aplicação COPY . . -# Garantir que o diretório static existe -RUN mkdir -p /app/static +# Preparação do diretório de estáticos +RUN mkdir -p /app/static && \ + if [ -d "static" ]; then cp -r static/* /app/static/ 2>/dev/null || true; fi -# Copiar arquivos estáticos para o diretório apropriado -COPY static/ /app/static/ +# Configuração do script de inicialização +RUN chmod +x start.sh && \ + dos2unix start.sh && \ + apt-get purge -y dos2unix && \ + apt-get autoremove -y -# Garantir permissões de execução ao script inicial -COPY start.sh . -RUN chmod +x start.sh - -# Converter possíveis caracteres de retorno de carro do Windows -RUN apt-get update && apt-get install -y dos2unix && dos2unix start.sh && apt-get remove -y dos2unix && apt-get autoremove -y && apt-get clean - -# Expor as portas usadas pela aplicação +# Portas da aplicação EXPOSE 8005 8501 -# Definir o comando inicial +# Valores padrão para Redis +ENV REDIS_HOST=redis-transcrevezap \ + REDIS_PORT=6380 \ + REDIS_DB=0 + +# Comando de inicialização CMD ["/bin/bash", "/app/start.sh"] \ No newline at end of file diff --git a/config.py b/config.py index 9c5c2f3..735dda9 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,7 @@ import logging import redis import os +from utils import create_redis_client # Configuração de logging com cores e formatação melhorada class ColoredFormatter(logging.Formatter): @@ -30,12 +31,7 @@ logger.addHandler(handler) logger.setLevel(logging.INFO) # Conexão com o Redis -redis_client = redis.Redis( - host=os.getenv('REDIS_HOST', 'localhost'), - port=int(os.getenv('REDIS_PORT', 6380)), - db=int(os.getenv('REDIS_DB', '0')), - decode_responses=True -) +redis_client = create_redis_client() class Settings: """Classe para gerenciar configurações do sistema.""" diff --git a/docker-compose.yaml b/docker-compose.yaml index 1dea44f..f364215 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,6 +21,9 @@ services: - REDIS_HOST=redis-transcrevezap - REDIS_PORT=6380 # Porta personalizada para o Redis do TranscreveZAP - REDIS_DB=0 # Opcional: pode ser removida para usar o valor padrão + # Autenticação Redis (opcional - descomente se necessário, se estiver usando autenticação) + # - REDIS_USERNAME=${REDIS_USERNAME:-} # Nome do usuário definido no comando do Redis + # - REDIS_PASSWORD=${REDIS_PASSWORD:-} # Senha definida no comando do Redis (sem o '>') depends_on: - redis-transcrevezap deploy: @@ -49,7 +52,20 @@ services: redis-transcrevezap: image: redis:6 - command: redis-server --port 6380 --appendonly yes + # 1. Configuração SEM autenticação (padrão): + command: redis-server --port 6380 --appendonly yes + # 2. Configuração COM autenticação (descomente e ajuste se necessário): + # command: > + # redis-server + # --port 6380 + # --appendonly yes + # --user seuusuario on '>minhasenha' '~*' '+@all' + # # Explicação dos parâmetros: + # # --user seuusuario: nome do usuário + # # on: indica início da configuração do usuário + # # '>minhasenha': senha do usuário (mantenha o '>') + # # '~*': permite acesso a todas as chaves + # # '+@all': concede todas as permissões volumes: - redis_transcrevezap_data:/data networks: diff --git a/manager.py b/manager.py index 551ddd7..6054224 100644 --- a/manager.py +++ b/manager.py @@ -6,6 +6,7 @@ from storage import StorageHandler import plotly.express as px import os import redis +from utils import create_redis_client # 1. Primeiro: Configuração da página st.set_page_config( @@ -16,11 +17,7 @@ st.set_page_config( ) # 2. Depois: Inicialização do Redis -redis_client = redis.Redis( - host=os.getenv('REDIS_HOST', 'localhost'), - port=int(os.getenv('REDIS_PORT', 6380)), - decode_responses=True -) +redis_client = create_redis_client() # 3. Funções de sessão (atualizado para usar st.query_params) def init_session(): diff --git a/readme.md b/readme.md index 9988db0..98d1048 100644 --- a/readme.md +++ b/readme.md @@ -40,40 +40,70 @@ Antes de começar, certifique-se de ter os seguintes requisitos: version: "3.7" services: + # Serviço principal do TranscreveZAP tcaudio: image: impacteai/transcrevezap:latest build: context: . ports: - - 8005:8005 # Porta para FastAPI - - 8501:8501 # Porta para Streamlit + - "8005:8005" # API FastAPI - Use esta porta para configurar o webhook + - "8501:8501" # Interface Web Streamlit - Acesse o painel por esta porta environment: + # Configurações do Servidor - UVICORN_PORT=8005 - UVICORN_HOST=0.0.0.0 - UVICORN_RELOAD=true - UVICORN_WORKERS=1 - - API_DOMAIN=localhost + - API_DOMAIN=localhost # Para uso local mantenha localhost + + # Modo Debug e Logs - DEBUG_MODE=false - LOG_LEVEL=INFO + + # Credenciais do Painel Admin (ALTERE ESTAS CREDENCIAIS!) - MANAGER_USER=admin - MANAGER_PASSWORD=sua_senha_aqui - - REDIS_HOST=redis-transcrevezap - - REDIS_PORT=6380 # Porta personalizada para o Redis do TranscreveZAP - - REDIS_DB=0 # Opcional: pode ser removida para usar o valor padrão + + # Configurações do Redis + - REDIS_HOST=redis-transcrevezap # Nome do serviço Redis + - REDIS_PORT=6380 # Porta do Redis + - REDIS_DB=0 # Banco de dados Redis + + # Autenticação Redis (opcional - descomente se necessário) + # - REDIS_USERNAME=seu_usuario # Nome do usuário Redis + # - REDIS_PASSWORD=sua_senha # Senha do Redis depends_on: - redis-transcrevezap command: ./start.sh + # Serviço Redis para armazenamento de dados redis-transcrevezap: image: redis:6 + # Escolha UMA das configurações do Redis abaixo: + + # 1. Configuração simples SEM autenticação: command: redis-server --port 6380 --appendonly yes + + # 2. Configuração COM autenticação (descomente e ajuste se necessário): + # command: > + # redis-server + # --port 6380 + # --appendonly yes + # --user admin on '>sua_senha' '~*' '+@all' volumes: - - redis_transcrevezap_data:/data + - redis_transcrevezap_data:/data # Persistência dos dados +# Volumes para persistência volumes: redis_transcrevezap_data: driver: local +# Instruções de Uso: +# 1. Salve este arquivo como docker-compose.yml +# 2. Execute com: docker compose up -d +# 3. Acesse o painel em: http://localhost:8501 +# 4. Configure o webhook da Evolution API para: http://localhost:8005/transcreve-audios + ``` 2. Inicie os serviços: @@ -172,6 +202,9 @@ services: - REDIS_HOST=redis-transcrevezap - REDIS_PORT=6380 # Porta personalizada para o Redis do TranscreveZAP - REDIS_DB=0 # Opcional: pode ser removida para usar o valor padrão + # Autenticação Redis (opcional - descomente se necessário, se estiver usando autenticação) + # - REDIS_USERNAME=${REDIS_USERNAME:-} # Nome do usuário definido no comando do Redis + # - REDIS_PASSWORD=${REDIS_PASSWORD:-} # Senha definida no comando do Redis (sem o '>') depends_on: - redis-transcrevezap deploy: @@ -200,7 +233,20 @@ services: redis-transcrevezap: image: redis:6 - command: redis-server --port 6380 --appendonly yes + # 1. Configuração SEM autenticação (padrão): + command: redis-server --port 6380 --appendonly yes + # 2. Configuração COM autenticação (descomente e ajuste se necessário): + # command: > + # redis-server + # --port 6380 + # --appendonly yes + # --user seuusuario on '>minhasenha' '~*' '+@all' + # # Explicação dos parâmetros: + # # --user seuusuario: nome do usuário + # # on: indica início da configuração do usuário + # # '>minhasenha': senha do usuário (mantenha o '>') + # # '~*': permite acesso a todas as chaves + # # '+@all': concede todas as permissões volumes: - redis_transcrevezap_data:/data networks: diff --git a/start.sh b/start.sh index f80d91d..199ab42 100644 --- a/start.sh +++ b/start.sh @@ -1,22 +1,47 @@ #!/bin/bash -# Função para inicializar configurações no Redis se não existirem +# Função para construir o comando redis-cli com autenticação condicional +build_redis_cli_cmd() { + cmd="redis-cli -h ${REDIS_HOST:-localhost} -p ${REDIS_PORT:-6380}" + + if [ ! -z "$REDIS_USERNAME" ]; then + cmd="$cmd --user $REDIS_USERNAME" + fi + + if [ ! -z "$REDIS_PASSWORD" ]; then + cmd="$cmd -a $REDIS_PASSWORD" + fi + + if [ ! -z "$REDIS_DB" ]; then + cmd="$cmd -n $REDIS_DB" + fi + + echo "$cmd" +} + +# Função para inicializar configurações no Redis initialize_redis_config() { - redis-cli -h $REDIS_HOST -p $REDIS_PORT SET GROQ_API_KEY "sua_api_key_aqui" NX - redis-cli -h $REDIS_HOST -p $REDIS_PORT SET BUSINESS_MESSAGE "*Impacte AI* Premium Services" NX - redis-cli -h $REDIS_HOST -p $REDIS_PORT SET PROCESS_GROUP_MESSAGES "false" NX - redis-cli -h $REDIS_HOST -p $REDIS_PORT SET PROCESS_SELF_MESSAGES "true" NX - redis-cli -h $REDIS_HOST -p $REDIS_PORT SET API_DOMAIN "$API_DOMAIN" NX + redis_cmd=$(build_redis_cli_cmd) + + $redis_cmd SET GROQ_API_KEY "sua_api_key_aqui" NX + $redis_cmd SET BUSINESS_MESSAGE "*Impacte AI* Premium Services" NX + $redis_cmd SET PROCESS_GROUP_MESSAGES "false" NX + $redis_cmd SET PROCESS_SELF_MESSAGES "true" NX + $redis_cmd SET API_DOMAIN "$API_DOMAIN" NX } # Aguardar o Redis estar pronto echo "Aguardando o Redis ficar disponível..." -until redis-cli -h $REDIS_HOST -p $REDIS_PORT PING; do +redis_cmd=$(build_redis_cli_cmd) + +until $redis_cmd PING 2>/dev/null; do echo "Redis não está pronto - aguardando..." sleep 5 done -# Inicializar configurações no Redis (apenas se não existirem) +echo "Redis disponível!" + +# Inicializar configurações initialize_redis_config # Iniciar o FastAPI em background diff --git a/storage.py b/storage.py index 000b437..9486686 100644 --- a/storage.py +++ b/storage.py @@ -5,6 +5,7 @@ from datetime import datetime, timedelta import traceback import logging import redis +from utils import create_redis_client class StorageHandler: def __init__(self): @@ -20,12 +21,7 @@ class StorageHandler: self.logger.info("StorageHandler inicializado.") # Conexão com o Redis - self.redis = redis.Redis( - host=os.getenv('REDIS_HOST', 'localhost'), - port=int(os.getenv('REDIS_PORT', 6380)), - db=int(os.getenv('REDIS_DB', '0')), - decode_responses=True - ) + self.redis = create_redis_client() # Retenção de logs e backups self.log_retention_hours = int(os.getenv('LOG_RETENTION_HOURS', 48)) diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..246a6df --- /dev/null +++ b/utils.py @@ -0,0 +1,49 @@ +import os +import redis +import logging + +logger = logging.getLogger("TranscreveZAP") + +def get_redis_connection_params(): + """ + Retorna os parâmetros de conexão do Redis baseado nas variáveis de ambiente. + Retira parâmetros de autenticação se não estiverem configurados. + """ + params = { + 'host': os.getenv('REDIS_HOST', 'localhost'), + 'port': int(os.getenv('REDIS_PORT', 6380)), + 'db': int(os.getenv('REDIS_DB', '0')), + 'decode_responses': True + } + + # Adiciona credenciais apenas se estiverem configuradas + username = os.getenv('REDIS_USERNAME') + password = os.getenv('REDIS_PASSWORD') + + if username and username.strip(): + params['username'] = username + if password and password.strip(): + params['password'] = password + + return params + +def create_redis_client(): + """ + Cria e testa a conexão com o Redis. + Retorna o cliente Redis se bem sucedido. + """ + try: + params = get_redis_connection_params() + client = redis.Redis(**params) + client.ping() # Testa a conexão + logger.info("Conexão com Redis estabelecida com sucesso!") + return client + except redis.exceptions.AuthenticationError: + logger.error("Falha de autenticação no Redis. Verifique as credenciais.") + raise + except redis.exceptions.ConnectionError as e: + logger.error(f"Erro de conexão com Redis: {e}") + raise + except Exception as e: + logger.error(f"Erro ao configurar Redis: {e}") + raise \ No newline at end of file