From 617ad83eba5a05613b160ad0cc9e7c832a05ed39 Mon Sep 17 00:00:00 2001 From: Diwank Tomer Date: Wed, 28 Aug 2024 16:12:08 -0400 Subject: [PATCH] feat(gateway,agents-api): Add scalar for documentation Signed-off-by: Diwank Tomer --- .env.example | 6 ++- .../agents_api/dependencies/developer_id.py | 4 +- agents-api/agents_api/env.py | 39 ++++++++++++------- agents-api/agents_api/web.py | 25 +++++++++--- agents-api/docker-compose.yml | 23 +++++------ gateway/docker-compose.yml | 6 +-- gateway/traefik.yml.template | 2 +- llm-proxy/docker-compose.yml | 17 ++++---- scheduler/docker-compose.yml | 9 +++-- 9 files changed, 80 insertions(+), 51 deletions(-) diff --git a/.env.example b/.env.example index c2dce63e7..4e71dd340 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,6 @@ TEMPORAL_POSTGRES_PASSWORD= LITELLM_POSTGRES_PASSWORD= LITELLM_MASTER_KEY= LITELLM_REDIS_PASSWORD= -SKIP_CHECK_DEVELOPER_HEADERS=true EMBEDDING_SERVICE_BASE=http://text-embeddings-inference- # Use the 'gpu' profile to run on GPU # Memory Store @@ -16,7 +15,7 @@ EMBEDDING_SERVICE_BASE=http://text-embeddings-inference- # Use the 'gp # COZO_HOST=http://memory-store:9070 # COZO_PORT=9070 # COZO_ROCKSDB_DIR=cozo.db -# COZO_BACKUP_DIR=backup +# COZO_BACKUP_DIR=/backup # COZO_MNT_DIR=/data # Gateway @@ -28,6 +27,9 @@ EMBEDDING_SERVICE_BASE=http://text-embeddings-inference- # Use the 'gp # Agents API # --------- +# AGENTS_API_MULTI_TENANT_MODE=false +# AGENTS_API_HOSTNAME=localhost +# AGENTS_API_PREFIX="" # AGENTS_API_KEY_HEADER_NAME=Authorization # AGENTS_API_URL=http://agents-api:8080 # TRUNCATE_EMBED_TEXT=true diff --git a/agents-api/agents_api/dependencies/developer_id.py b/agents-api/agents_api/dependencies/developer_id.py index af4aa04de..46904131c 100644 --- a/agents-api/agents_api/dependencies/developer_id.py +++ b/agents-api/agents_api/dependencies/developer_id.py @@ -10,7 +10,7 @@ async def get_developer_id( - x_developer_id: Annotated[UUID | None, Header()] = None, + x_developer_id: Annotated[UUID | None, Header(include_in_schema=False)] = None, ) -> UUID: if skip_check_developer_headers: return x_developer_id or UUID("00000000-0000-0000-0000-000000000000") @@ -30,7 +30,7 @@ async def get_developer_id( async def get_developer_data( - x_developer_id: Annotated[UUID | None, Header()] = None, + x_developer_id: Annotated[UUID | None, Header(include_in_schema=False)] = None, ) -> Developer: if skip_check_developer_headers: x_developer_id = x_developer_id or UUID("00000000-0000-0000-0000-000000000000") diff --git a/agents-api/agents_api/env.py b/agents-api/agents_api/env.py index 64d9082ef..ec5d09abc 100644 --- a/agents-api/agents_api/env.py +++ b/agents-api/agents_api/env.py @@ -12,6 +12,12 @@ # Initialize the Env object for environment variable parsing. env: Any = Env() +# App +# --- +multi_tenant_mode: bool = env.bool("AGENTS_API_MULTI_TENANT_MODE", default=False) +hostname: str = env.str("AGENTS_API_HOSTNAME", default="localhost") +api_prefix: str = env.str("AGENTS_API_PREFIX", default="") + # Debug # ----- @@ -39,7 +45,7 @@ api_key_header_name: str = env.str("AGENTS_API_KEY_HEADER_NAME", default="X-Auth-Key") skip_check_developer_headers: bool = env.bool( - "SKIP_CHECK_DEVELOPER_HEADERS", default=False + "SKIP_CHECK_DEVELOPER_HEADERS", default=multi_tenant_mode ) @@ -57,7 +63,7 @@ embedding_model_id: str = env.str( "EMBEDDING_MODEL_ID", default="Alibaba-NLP/gte-large-en-v1.5" ) -truncate_embed_text: bool = env.bool("TRUNCATE_EMBED_TEXT", default=False) +truncate_embed_text: bool = env.bool("TRUNCATE_EMBED_TEXT", default=True) # Temporal @@ -73,6 +79,8 @@ # Consolidate environment variables environment: Dict[str, Any] = dict( debug=debug, + multi_tenant_mode=multi_tenant_mode, + skip_check_developer_headers=skip_check_developer_headers, cozo_host=cozo_host, cozo_auth=cozo_auth, sentry_dsn=sentry_dsn, @@ -80,7 +88,8 @@ temporal_task_queue=temporal_task_queue, api_key=api_key, api_key_header_name=api_key_header_name, - skip_check_developer_headers=skip_check_developer_headers, + hostname=hostname, + api_prefix=api_prefix, embedding_service_base=embedding_service_base, truncate_embed_text=truncate_embed_text, temporal_worker_url=temporal_worker_url, @@ -89,15 +98,15 @@ testing=testing, ) -if debug or testing: - # Print the loaded environment variables for debugging purposes. - print("Environment variables:") - pprint(environment) - print() - - # Yell if testing is enabled - print("@" * 80) - print( - f"@@@ Running in {'testing' if testing else 'debug'} mode. This should not be enabled in production. @@@" - ) - print("@" * 80) +# if debug or testing: +# Print the loaded environment variables for debugging purposes. +print("Environment variables:") +pprint(environment) +print() + +# Yell if testing is enabled +print("@" * 80) +print( + f"@@@ Running in {'testing' if testing else 'debug'} mode. This should not be enabled in production. @@@" +) +print("@" * 80) diff --git a/agents-api/agents_api/web.py b/agents-api/agents_api/web.py index fbb8d4af9..c28cabaaa 100644 --- a/agents-api/agents_api/web.py +++ b/agents-api/agents_api/web.py @@ -20,7 +20,7 @@ from .common.exceptions import BaseCommonException from .dependencies.auth import get_api_key -from .env import sentry_dsn +from .env import api_prefix, hostname, sentry_dsn from .exceptions import PromptTooBigError from .routers import ( agents, @@ -84,22 +84,37 @@ def register_exceptions(app: FastAPI) -> None: # Because some routes don't require auth # See: https://fastapi.tiangolo.com/tutorial/bigger-applications/ # -app: Any = FastAPI(docs_url="/swagger") +app: Any = FastAPI( + docs_url="/swagger", + openapi_prefix=api_prefix, + redoc_url=None, + title="Julep Agents API", + description="API for Julep Agents", + version="0.4.0", + terms_of_service="https://www.julep.ai/terms", + contact={ + "name": "Julep", + "url": "https://www.julep.ai", + "email": "team@julep.ai", + }, + root_path=api_prefix, +) # Create a new router for the docs -docs_router = APIRouter() +scalar_router = APIRouter() -@docs_router.get("/docs", include_in_schema=False) +@scalar_router.get("/docs", include_in_schema=False) async def scalar_html(): return get_scalar_api_reference( openapi_url=app.openapi_url[1:], # Remove leading '/' title=app.title, + servers=[{"url": f"http://{hostname}{api_prefix}"}], ) # Add the docs_router without dependencies -app.include_router(docs_router) +app.include_router(scalar_router) # Add other routers with the get_api_key dependency app.include_router(agents.router, dependencies=[Depends(get_api_key)]) diff --git a/agents-api/docker-compose.yml b/agents-api/docker-compose.yml index 2168a8f26..23aeb02c4 100644 --- a/agents-api/docker-compose.yml +++ b/agents-api/docker-compose.yml @@ -15,23 +15,25 @@ x--text-embeddings-inference: &text-embeddings-inference # Shared environment variables x-shared-environment: &shared-environment AGENTS_API_KEY: ${AGENTS_API_KEY} - LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY} - COZO_AUTH_TOKEN: ${COZO_AUTH_TOKEN} - SKIP_CHECK_DEVELOPER_HEADERS: ${SKIP_CHECK_DEVELOPER_HEADERS:-True} AGENTS_API_KEY_HEADER_NAME: ${AGENTS_API_KEY_HEADER_NAME:-Authorization} + AGENTS_API_HOSTNAME: ${AGENTS_API_HOSTNAME:-localhost} + AGENTS_API_PREFIX: ${AGENTS_API_PREFIX:-} AGENTS_API_URL: ${AGENTS_API_URL:-http://agents-api:8080} - TRUNCATE_EMBED_TEXT: ${TRUNCATE_EMBED_TEXT:-False} - WORKER_URL: ${WORKER_URL:-temporal:7233} + COZO_AUTH_TOKEN: ${COZO_AUTH_TOKEN} + COZO_HOST: ${COZO_HOST:-http://memory-store:9070} DEBUG: ${AGENTS_API_DEBUG:-False} - EMBEDDING_SERVICE_BASE: ${EMBEDDING_SERVICE_BASE:-http://text-embeddings-inference} EMBEDDING_MODEL_ID: ${EMBEDDING_MODEL_ID:-Alibaba-NLP/gte-large-en-v1.5} + EMBEDDING_SERVICE_BASE: ${EMBEDDING_SERVICE_BASE:-http://text-embeddings-inference} + LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY} LITELLM_URL: ${LITELLM_URL:-http://litellm:4000} - COZO_HOST: ${COZO_HOST:-http://memory-store:9070} + SKIP_CHECK_DEVELOPER_HEADERS: ${SKIP_CHECK_DEVELOPER_HEADERS:-True} SUMMARIZATION_MODEL_NAME: ${SUMMARIZATION_MODEL_NAME:-gpt-4-turbo} - TEMPORAL_WORKER_URL: ${TEMPORAL_WORKER_URL:-temporal:7233} - TEMPORAL_NAMESPACE: ${TEMPORAL_NAMESPACE:-default} TEMPORAL_ENDPOINT: ${TEMPORAL_ENDPOINT:-temporal:7233} + TEMPORAL_NAMESPACE: ${TEMPORAL_NAMESPACE:-default} TEMPORAL_TASK_QUEUE: ${TEMPORAL_TASK_QUEUE:-julep-task-queue} + TEMPORAL_WORKER_URL: ${TEMPORAL_WORKER_URL:-temporal:7233} + TRUNCATE_EMBED_TEXT: ${TRUNCATE_EMBED_TEXT:-True} + WORKER_URL: ${WORKER_URL:-temporal:7233} services: agents-api: @@ -121,8 +123,7 @@ services: dockerfile: Dockerfile.migration restart: "no" # Make sure to double quote this environment: - - COZO_HOST=${COZO_HOST:-http://cozo:9070} - - COZO_AUTH_TOKEN=${COZO_AUTH_TOKEN:-myauthkey} + <<: *shared-environment develop: watch: diff --git a/gateway/docker-compose.yml b/gateway/docker-compose.yml index 536905da3..84f466764 100644 --- a/gateway/docker-compose.yml +++ b/gateway/docker-compose.yml @@ -9,10 +9,10 @@ services: # - MODEL_API_URL=${MODEL_API_URL} # - MODEL_API_KEY=${MODEL_API_KEY} # - MODEL_API_KEY_HEADER_NAME=${MODEL_API_KEY_HEADER_NAME} - - AGENTS_API_URL=${AGENTS_API_URL} + - AGENTS_API_URL=${AGENTS_API_URL:-http://agents-api:8080} - AGENTS_API_KEY=${AGENTS_API_KEY} - - AGENTS_API_KEY_HEADER_NAME=${AGENTS_API_KEY_HEADER_NAME} - - TRAEFIK_LOG_LEVEL=${TRAEFIK_LOG_LEVEL} + - AGENTS_API_KEY_HEADER_NAME=${AGENTS_API_KEY_HEADER_NAME:-Authorization} + - TRAEFIK_LOG_LEVEL=${TRAEFIK_LOG_LEVEL:-INFO} container_name: gateway depends_on: agents-api: diff --git a/gateway/traefik.yml.template b/gateway/traefik.yml.template index 351e6604b..7423e3fde 100644 --- a/gateway/traefik.yml.template +++ b/gateway/traefik.yml.template @@ -32,7 +32,7 @@ http: agents-api-docs: entryPoints: - web - rule: Path(`/api/{path:docs|openapi.json}`) + rule: Path(`/api/{path:swagger|redoc|docs|scalar|openapi.json}`) middlewares: - agents-api-strip-prefix-api service: service-agents-api diff --git a/llm-proxy/docker-compose.yml b/llm-proxy/docker-compose.yml index 5b7f9d116..681ea4596 100644 --- a/llm-proxy/docker-compose.yml +++ b/llm-proxy/docker-compose.yml @@ -10,13 +10,13 @@ services: - "4000:4000" environment: - LITELLM_MASTER_KEY=${LITELLM_MASTER_KEY} - - LITELLM_POSTGRES_DB=${LITELLM_POSTGRES_DB} - - LITELLM_POSTGRES_USER=${LITELLM_POSTGRES_USER} + - LITELLM_POSTGRES_DB=${LITELLM_POSTGRES_DB:-litellm} + - LITELLM_POSTGRES_USER=${LITELLM_POSTGRES_USER:-llmproxy} - LITELLM_POSTGRES_PASSWORD=${LITELLM_POSTGRES_PASSWORD} - - LITELLM_REDIS_HOST=${LITELLM_REDIS_HOST} - - LITELLM_REDIS_PORT=${LITELLM_REDIS_PORT} + - LITELLM_REDIS_HOST=${LITELLM_REDIS_HOST:-litellm-redis} + - LITELLM_REDIS_PORT=${LITELLM_REDIS_PORT:-6379} - LITELLM_REDIS_PASSWORD=${LITELLM_REDIS_PASSWORD} - - LITELLM_DATABASE_URL=postgresql://${LITELLM_POSTGRES_USER}:${LITELLM_POSTGRES_PASSWORD}@litellm-db:5432/${LITELLM_POSTGRES_DB} + - LITELLM_DATABASE_URL=postgresql://${LITELLM_POSTGRES_USER:-llmproxy}:${LITELLM_POSTGRES_PASSWORD}@litellm-db:5432/${LITELLM_POSTGRES_DB:-litellm} - OPENAI_API_KEY=${OPENAI_API_KEY} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - GROQ_API_KEY=${GROQ_API_KEY} @@ -49,11 +49,12 @@ services: ports: - "15432:5432" environment: - - POSTGRES_DB=${LITELLM_POSTGRES_DB} - - POSTGRES_USER=${LITELLM_POSTGRES_USER} + - POSTGRES_DB=${LITELLM_POSTGRES_DB:-litellm} + - POSTGRES_USER=${LITELLM_POSTGRES_USER:-llmproxy} - POSTGRES_PASSWORD=${LITELLM_POSTGRES_PASSWORD} healthcheck: - test: [ "CMD-SHELL", "pg_isready -d ${LITELLM_POSTGRES_DB} -U ${LITELLM_POSTGRES_USER}" ] + test: [ "CMD-SHELL", "pg_isready -d ${LITELLM_POSTGRES_DB:-litellm} -U ${LITELLM_POSTGRES_USER:-llmproxy}" ] + interval: 1s timeout: 5s retries: 10 diff --git a/scheduler/docker-compose.yml b/scheduler/docker-compose.yml index 9d0dd5856..cbce5b909 100644 --- a/scheduler/docker-compose.yml +++ b/scheduler/docker-compose.yml @@ -8,7 +8,7 @@ services: - DB=postgres12 - DB_PORT=5432 - DB_HOST=temporal-db - - POSTGRES_USER=${TEMPORAL_POSTGRES_USER} + - POSTGRES_USER=${TEMPORAL_POSTGRES_USER:-temporal} - POSTGRES_PWD=${TEMPORAL_POSTGRES_PASSWORD} - POSTGRES_SEEDS=temporal-db - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml @@ -31,15 +31,16 @@ services: temporal-db: image: postgres:16 environment: - - POSTGRES_DB=${TEMPORAL_POSTGRES_DB} - - POSTGRES_USER=${TEMPORAL_POSTGRES_USER} + - POSTGRES_DB=${TEMPORAL_POSTGRES_DB:-temporal} + - POSTGRES_USER=${TEMPORAL_POSTGRES_USER:-temporal} - POSTGRES_PASSWORD=${TEMPORAL_POSTGRES_PASSWORD} ports: - 25432:5432 volumes: - temporal-db-data:/var/lib/postgresql/data healthcheck: - test: [ "CMD-SHELL", "pg_isready -d ${TEMPORAL_POSTGRES_DB} -U ${TEMPORAL_POSTGRES_USER}" ] + test: [ "CMD-SHELL", "pg_isready -d ${TEMPORAL_POSTGRES_DB:-temporal} -U ${TEMPORAL_POSTGRES_USER:-temporal}" ] + interval: 1s timeout: 5s retries: 10