Skip to content

Commit

Permalink
Merge branch 'main' into cloud-issue-369/-enhancement-logs-are-not-fe…
Browse files Browse the repository at this point in the history
…tched-2
  • Loading branch information
bekossy committed Jul 15, 2024
2 parents a2067c9 + 7357d2d commit 6016e1b
Show file tree
Hide file tree
Showing 17 changed files with 731 additions and 506 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
```bash
docker ps
docker exec -it {backend-container-id} bash
cd /app/agenta_backend/migrations/mongo_to_postgres
python3 migration.py
```
Migration steps are detailed here:
https://docs.agenta.ai/self-host/migration/migration-to-postgres
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
services:
reverse-proxy:
image: traefik:v2.10
command: --api.dashboard=true --api.insecure=true --providers.docker --entrypoints.web.address=:80
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- agenta-network
restart: always

backend:
build: ./agenta-backend
environment:
- MONGODB_URI=mongodb://username:password@mongo:27017
- POSTGRES_URI=postgresql+asyncpg://username:password@postgres:5432/agenta_oss
- REDIS_URL=redis://redis:6379/0
- ENVIRONMENT=development
- DATABASE_MODE=v2
- MIGRATION_SRC_MONGO_DB_NAME=v2
- BARE_DOMAIN_NAME=localhost
- DOMAIN_NAME=http://localhost
- FEATURE_FLAG=oss
- AGENTA_TEMPLATE_REPO=agentaai/templates_v2
- POSTHOG_API_KEY=phc_hmVSxIjTW1REBHXgj2aw4HW9X6CXb6FzerBgP9XenC7
- CELERY_BROKER_URL=amqp://guest@rabbitmq//
- CELERY_RESULT_BACKEND=redis://redis:6379/0
- TEMPLATES_BASE_URL=https://llm-app-json.s3.eu-central-1.amazonaws.com
- REGISTRY_REPO_NAME=agentaai
- DOCKER_HUB_URL=https://hub.docker.com/v2/repositories
volumes:
- ./agenta-backend/agenta_backend:/app/agenta_backend
- ./agenta-backend/tests:/app/tests
- /var/run/docker.sock:/var/run/docker.sock
- ./agenta-backend/db:/db
labels:
- "traefik.http.routers.backend.rule=PathPrefix(`/api/`)"
- "traefik.http.routers.backend.entrypoints=web"
- "traefik.http.middlewares.backend-strip.stripprefix.prefixes=/api"
- "traefik.http.middlewares.backend-strip.stripprefix.forceslash=true"
- "traefik.http.routers.backend.middlewares=backend-strip"
- "traefik.http.services.backend.loadbalancer.server.port=8000"
- "traefik.http.routers.backend.service=backend"
networks:
- agenta-network
extra_hosts:
- "host.docker.internal:host-gateway"
command:
[
"uvicorn",
"agenta_backend.main:app",
"--host",
"0.0.0.0",
"--port",
"8000",
"--reload",
"--log-level",
"info",
"--root-path",
"/api",
]
depends_on:
mongo:
condition: service_healthy
postgres:
condition: service_healthy
restart: always

agenta-web:
build:
context: ./agenta-web
dockerfile: dev.Dockerfile
volumes:
- ./agenta-web/src:/app/src
- ./agenta-web/public:/app/public
- .nextjs_cache:/app/.next
ports:
- "3000:3000"
networks:
- agenta-network
labels:
- "traefik.http.routers.agenta-web.rule=PathPrefix(`/`)"
- "traefik.http.routers.agenta-web.entrypoints=web"
- "traefik.http.services.agenta-web.loadbalancer.server.port=3000"
environment:
- NEXT_PUBLIC_POSTHOG_API_KEY=phc_hmVSxIjTW1REBHXgj2aw4HW9X6CXb6FzerBgP9XenC7
restart: always

mongo:
image: mongo:5.0
environment:
MONGO_INITDB_ROOT_USERNAME: username
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongodb_data:/data/db
ports:
- "27017:27017"
networks:
- agenta-network
healthcheck:
test: ["CMD", "mongo", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 10s
retries: 20
restart: always

mongo_express:
image: mongo-express:0.54.0
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: username
ME_CONFIG_MONGODB_ADMINPASSWORD: password
ME_CONFIG_MONGODB_SERVER: mongo
ports:
- "8081:8081"
networks:
- agenta-network
depends_on:
mongo:
condition: service_healthy
restart: always

redis:
image: redis:latest
networks:
- agenta-network
volumes:
- redis_data:/data
restart: always

rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672"
- "15672:15672"
volumes:
- ./rabbitmq_data:/var/lib/rabbitmq
environment:
RABBITMQ_DEFAULT_USER: "guest"
RABBITMQ_DEFAULT_PASS: "guest"
networks:
- agenta-network

celery_worker:
build: ./agenta-backend
command: >
watchmedo auto-restart --directory=./agenta_backend --pattern=*.py --recursive -- celery -A agenta_backend.main.celery_app worker --concurrency=1 --loglevel=INFO
environment:
- POSTGRES_URI=postgresql+asyncpg://username:password@postgres:5432/agenta_oss
- MONGODB_URI=mongodb://username:password@mongo:27017
- REDIS_URL=redis://redis:6379/0
- CELERY_BROKER_URL=amqp://guest@rabbitmq//
- CELERY_RESULT_BACKEND=redis://redis:6379/0
- FEATURE_FLAG=oss
volumes:
- ./agenta-backend/agenta_backend:/app/agenta_backend
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- mongo
- postgres
- rabbitmq
- redis
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- agenta-network

postgres:
image: postgres:16.2
container_name: postgres
restart: always
environment:
POSTGRES_USER: username
POSTGRES_PASSWORD: password
POSTGRES_DB: agenta_oss
ports:
- "5432:5432"
networks:
- agenta-network
volumes:
- postgresdb-data:/var/lib/postgresql/data/
- ./docker-assets/postgres/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5

pgadmin:
image: dpage/pgadmin4
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: "[email protected]"
PGADMIN_DEFAULT_PASSWORD: "password"
PGADMIN_SERVER_HOST: "postgres"
PGADMIN_SERVER_PORT: 5432
PGADMIN_SERVER_USER: "username"
PGADMIN_SERVER_PASSWORD: "password"
PGADMIN_SERVER_DB: agenta_oss
ports:
- "5050:80"
networks:
- agenta-network
volumes:
- pgadmin-data:/var/lib/pgadmin
depends_on:
postgres:
condition: service_healthy

networks:
agenta-network:
name: agenta-network

volumes:
mongodb_data:
redis_data:
nextjs_cache:
postgresdb-data:
pgadmin-data:
13 changes: 9 additions & 4 deletions agenta-backend/agenta_backend/models/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,17 @@ async def human_evaluation_db_to_pydantic(
variant_name = (
evaluation_variant.variant.variant_name
if isinstance(evaluation_variant.variant_id, uuid.UUID)
else str(evaluation_variant.variant.variant_id)
else str(evaluation_variant.variant_id)
)
variants_names.append(str(variant_name))
variants_ids.append(str(evaluation_variant.variant.id))
revisions.append(str(evaluation_variant.variant_revision.revision))
variants_revision_ids.append(str(evaluation_variant.variant_revision.id))
variants_ids.append(str(evaluation_variant.variant_id))
variant_revision = (
str(evaluation_variant.variant_revision.revision)
if isinstance(evaluation_variant.variant_revision_id, uuid.UUID)
else " None"
)
revisions.append(variant_revision)
variants_revision_ids.append(str(evaluation_variant.variant_revision_id))

return HumanEvaluation(
id=str(evaluation_db.id),
Expand Down
17 changes: 15 additions & 2 deletions agenta-backend/agenta_backend/routers/container_router.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import uuid
import logging

from typing import List, Optional, Union
Expand Down Expand Up @@ -163,11 +164,23 @@ async def construct_app_container_url(

if base_id:
object_db = await db_manager.fetch_base_by_id(base_id)
elif variant_id:
elif variant_id and variant_id != "None":
# NOTE: Backward Compatibility
# ---------------------------
# When a user creates a human evaluation with a variant and later deletes the variant,
# the human evaluation page becomes inaccessible due to the backend raising a
# "'NoneType' object has no attribute 'variant_id'" error. To suppress this error,
# we will return the string "None" as the ID of the variant.
# This change ensures that users can still view their evaluations; however,
# they will no longer be able to access a deployment URL for the deleted variant.
# Therefore, we ensure that variant_id is not "None".
object_db = await db_manager.fetch_app_variant_by_id(variant_id)
else:
# NOTE: required for backward compatibility
object_db = None

# Check app access
if isCloudEE():
if isCloudEE() and object_db is not None:
has_permission = await check_action_access(
user_uid=request.state.user_id,
object=object_db,
Expand Down
56 changes: 43 additions & 13 deletions agenta-backend/agenta_backend/services/db_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1973,7 +1973,11 @@ async def list_human_evaluations(app_id: str):
"""

async with db_engine.get_session() as session:
base_query = select(HumanEvaluationDB).filter_by(app_id=uuid.UUID(app_id))
base_query = (
select(HumanEvaluationDB)
.filter_by(app_id=uuid.UUID(app_id))
.filter(HumanEvaluationDB.testset_id.isnot(None))
)
if isCloudEE():
query = base_query.options(
joinedload(HumanEvaluationDB.user.of_type(UserDB)).load_only(UserDB.id, UserDB.username), # type: ignore
Expand Down Expand Up @@ -2737,24 +2741,50 @@ async def fetch_evaluations_by_resource(resource_type: str, resource_ids: List[s

async with db_engine.get_session() as session:
if resource_type == "variant":
query = select(EvaluationDB).filter(EvaluationDB.variant_id.in_(ids))
elif resource_type == "testset":
query = select(EvaluationDB).filter(EvaluationDB.testset_id.in_(ids))
elif resource_type == "evaluator_config":
result_evaluations = await session.execute(
select(EvaluationDB)
.filter(EvaluationDB.variant_id.in_(ids))
.options(load_only(EvaluationDB.id)) # type: ignore
)
result_human_evaluations = await session.execute(
select(HumanEvaluationDB)
.join(HumanEvaluationVariantDB)
.filter(HumanEvaluationVariantDB.variant_id.in_(ids))
.options(load_only(HumanEvaluationDB.id)) # type: ignore
)
res_evaluations = result_evaluations.scalars().all()
res_human_evaluations = result_human_evaluations.scalars().all()
return res_evaluations + res_human_evaluations

if resource_type == "testset":
result_evaluations = await session.execute(
select(EvaluationDB)
.filter(EvaluationDB.testset_id.in_(ids))
.options(load_only(EvaluationDB.id)) # type: ignore
)
result_human_evaluations = await session.execute(
select(HumanEvaluationDB)
.filter(HumanEvaluationDB.testset_id.in_(ids))
.options(load_only(HumanEvaluationDB.id)) # type: ignore
)
res_evaluations = result_evaluations.scalars().all()
res_human_evaluations = result_human_evaluations.scalars().all()
return res_evaluations + res_human_evaluations

if resource_type == "evaluator_config":
query = (
select(EvaluationDB)
.join(EvaluationDB.evaluator_configs)
.filter(EvaluationEvaluatorConfigDB.evaluator_config_id.in_(ids))
)
else:
raise HTTPException(
status_code=400,
detail=f"resource_type {resource_type} is not supported",
)
result = await session.execute(query)
res = result.scalars().all()
return res

result = await session.execute(query)
res = result.scalars().all()
return res
raise HTTPException(
status_code=400,
detail=f"resource_type {resource_type} is not supported",
)


async def delete_evaluations(evaluation_ids: List[str]) -> None:
Expand Down
2 changes: 1 addition & 1 deletion agenta-backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "agenta_backend"
version = "0.19.1"
version = "0.19.4"
description = ""
authors = ["Mahmoud Mabrouk <[email protected]>"]
readme = "README.md"
Expand Down
Loading

0 comments on commit 6016e1b

Please sign in to comment.