refactor(docker): update .dockerignore and Dockerfile for improved build process

This commit is contained in:
Davidson Gomes 2025-05-05 16:37:21 -03:00
parent eb2b58c312
commit 0e90c811f8
9 changed files with 57 additions and 45 deletions

View File

@ -38,7 +38,6 @@ docs/
# Development tools
tests/
.flake8
pyproject.toml
requirements-dev.txt
Makefile
@ -98,4 +97,4 @@ test_*
*_test.py
# Documentação
docs/
docs/

2
.env
View File

@ -46,3 +46,5 @@ ADMIN_INITIAL_PASSWORD="senhaforte123"
DEMO_EMAIL="demo@exemplo.com"
DEMO_PASSWORD="demo123"
DEMO_CLIENT_NAME="Cliente Demo"
# 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

View File

@ -1,27 +1,28 @@
FROM python:3.10-slim
# Define o diretório de trabalho
WORKDIR /app
# Define variáveis de ambiente
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONPATH=/app
# Instala as dependências do sistema
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
curl \
gnupg \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Copy project files
COPY . .
# Install dependencies
RUN pip install --no-cache-dir -e .
# Configuração para produção
ENV PORT=8000 \
HOST=0.0.0.0 \
DEBUG=false
@ -29,5 +30,4 @@ ENV PORT=8000 \
# Expose port
EXPOSE 8000
# Define o comando de inicialização
CMD alembic upgrade head && uvicorn src.main:app --host $HOST --port $PORT

View File

@ -10,11 +10,15 @@ from sqlalchemy.ext.asyncio import AsyncEngine
from alembic import context
from src.models.models import Base
from src.config.settings import settings
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# Sobrescreve a URL do banco de dados com a definida nas configurações
config.set_main_option("sqlalchemy.url", settings.POSTGRES_CONNECTION_STRING)
# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
@ -32,7 +36,8 @@ target_metadata = [Base.metadata]
# ... etc.
# Lista de tabelas a serem ignoradas na geração automática de migrações
exclude_tables = ['sessions', 'events', 'app_states', 'user_states']
exclude_tables = ["sessions", "events", "app_states", "user_states"]
def include_object(object, name, type_, reflected, compare_to):
"""
@ -78,11 +83,13 @@ def run_migrations_online() -> None:
connectable = context.config.attributes.get("connection", None)
if connectable is None:
connectable = create_async_engine(
context.config.get_main_option("sqlalchemy.url").replace("postgresql://", "postgresql+asyncpg://"),
poolclass=pool.NullPool,
future=True,
context.config.get_main_option("sqlalchemy.url").replace(
"postgresql://", "postgresql+asyncpg://"
),
poolclass=pool.NullPool,
future=True,
)
if isinstance(connectable, AsyncEngine):
asyncio.run(run_async_migrations(connectable))
else:
@ -94,6 +101,7 @@ async def run_async_migrations(connectable):
await connection.run_sync(do_run_migrations)
await connectable.dispose()
def do_run_migrations(connection):
context.configure(
connection=connection,
@ -104,4 +112,5 @@ def do_run_migrations(connection):
with context.begin_transaction():
context.run_migrations()
run_migrations_online()

View File

@ -136,7 +136,7 @@ async def websocket_chat(
@router.post(
"/",
"",
response_model=ChatResponse,
responses={
400: {"model": ErrorResponse},

View File

@ -36,6 +36,7 @@ app = FastAPI(
title=settings.API_TITLE,
description=settings.API_DESCRIPTION,
version=settings.API_VERSION,
redirect_slashes=False,
)
# CORS configuration

View File

@ -37,24 +37,24 @@ def _convert_uuid_to_str(obj):
def validate_sub_agents(db: Session, sub_agents: List[Union[uuid.UUID, str]]) -> bool:
"""Validate if all sub-agents exist"""
logger.info(f"Validando sub-agentes: {sub_agents}")
logger.info(f"Validating sub-agents: {sub_agents}")
if not sub_agents:
logger.warning("Lista de sub-agentes vazia")
logger.warning("Empty sub-agents list")
return False
for agent_id in sub_agents:
# Garantir que o ID esteja no formato correto
# Ensure the ID is in the correct format
agent_id_str = str(agent_id)
logger.info(f"Validando sub-agente com ID: {agent_id_str}")
logger.info(f"Validating sub-agent with ID: {agent_id_str}")
agent = get_agent(db, agent_id_str)
if not agent:
logger.warning(f"Sub-agente não encontrado: {agent_id_str}")
logger.warning(f"Sub-agent not found: {agent_id_str}")
return False
logger.info(f"Sub-agente válido: {agent.name} (ID: {agent_id_str})")
logger.info(f"Valid sub-agent: {agent.name} (ID: {agent_id_str})")
logger.info(f"Todos os {len(sub_agents)} sub-agentes são válidos")
logger.info(f"All {len(sub_agents)} sub-agents are valid")
return True
@ -147,29 +147,31 @@ async def create_agent(db: Session, agent: AgentCreate) -> Agent:
detail=f"Failed to process agent card: {str(e)}",
)
if not isinstance(agent.config, dict):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid configuration: must be an object with sub_agents",
)
# Additional sub-agent validation (for non-llm and non-a2a types)
elif agent.type != "llm":
if not isinstance(agent.config, dict):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid configuration: must be an object with sub_agents",
)
if "sub_agents" not in agent.config:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid configuration: sub_agents is required for sequential, parallel or loop agents",
)
if "sub_agents" not in agent.config:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid configuration: sub_agents is required for sequential, parallel or loop agents",
)
if not agent.config["sub_agents"]:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid configuration: sub_agents cannot be empty",
)
if not agent.config["sub_agents"]:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid configuration: sub_agents cannot be empty",
)
if not validate_sub_agents(db, agent.config["sub_agents"]):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="One or more sub-agents do not exist",
)
if not validate_sub_agents(db, agent.config["sub_agents"]):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="One or more sub-agents do not exist",
)
# Process the configuration before creating the agent
config = agent.config
@ -225,7 +227,7 @@ async def create_agent(db: Session, agent: AgentCreate) -> Agent:
# Generate automatic API key if not provided or empty
if not config.get("api_key") or config.get("api_key") == "":
logger.info(f"Generating automatic API key for new agent")
logger.info("Generating automatic API key for new agent")
config["api_key"] = generate_api_key()
agent.config = config

View File

@ -56,7 +56,7 @@ def send_verification_email(email: str, token: str) -> bool:
to_email = To(email)
subject = "Email Verification - Evo AI"
verification_link = f"{settings.APP_URL}/auth/verify-email/{token}"
verification_link = f"{settings.APP_URL}/api/v1/auth/verify-email/{token}"
html_content = _render_template(
"verification_email",

View File

@ -11,7 +11,6 @@ from src.services.agent_service import get_agents_by_client
import uuid
import logging
from datetime import datetime
logger = logging.getLogger(__name__)