From 7b000e6456ba9fe70b6c3adbe879ae34c86612c2 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Mon, 11 Mar 2024 17:18:18 +0530 Subject: [PATCH 1/5] chore: introduce more variables for different config chore: update workflow to run trigger workflow --- .github/workflows/main-release.yaml | 2 +- .gitignore | 1 + core/local_model.py | 4 +- core/tasks/celery_config.py | 5 +- core/tasks/tasks.py | 2 + services/backend/api_server/app/backend.py | 66 +++++++++++++++++----- 6 files changed, 62 insertions(+), 18 deletions(-) diff --git a/.github/workflows/main-release.yaml b/.github/workflows/main-release.yaml index 90c83ac..df14d5f 100644 --- a/.github/workflows/main-release.yaml +++ b/.github/workflows/main-release.yaml @@ -7,7 +7,7 @@ concurrency: on: push: branches: - - main + - chore/new-environment-variable-configuration jobs: build-and-push: diff --git a/.gitignore b/.gitignore index 290b078..11ba271 100644 --- a/.gitignore +++ b/.gitignore @@ -255,3 +255,4 @@ dist-ssr *.sln *.sw? +**/.vim/ diff --git a/core/local_model.py b/core/local_model.py index e00b52d..ac64783 100644 --- a/core/local_model.py +++ b/core/local_model.py @@ -28,12 +28,12 @@ QUERY_FORMAT = '{"query": "refined question"}' litellm_host = os.getenv("LITELLM_HOST", "localhost") - +litellm_api_key = os.getenv("LITELLM_MASTER_KEY") oai_client = OpenAI( base_url=f"http://{litellm_host}:8002/v1/", # base_url="http://localhost:1234/v1/", - api_key="abc", + api_key=litellm_api_key, ) model_name = "custom" diff --git a/core/tasks/celery_config.py b/core/tasks/celery_config.py index 2e8e6b1..2194759 100644 --- a/core/tasks/celery_config.py +++ b/core/tasks/celery_config.py @@ -2,6 +2,7 @@ import os CELERY_REDIS_HOST = os.getenv("REDIS_HOST", "localhost") -BROKER_URL = f"redis://{CELERY_REDIS_HOST}:6379/0" # Redis configuration -CELERY_RESULT_BACKEND = f"redis://{CELERY_REDIS_HOST}:6379/0" +CELERY_REDIS_PORT = os.getenv("REDIS_PORT", 6379) +BROKER_URL = f"redis://{CELERY_REDIS_HOST}:{CELERY_REDIS_PORT}/0" # Redis configuration +CELERY_RESULT_BACKEND = BROKER_URL CELERY_IMPORTS = ("core.tasks.tasks",) diff --git a/core/tasks/tasks.py b/core/tasks/tasks.py index 3bd6eba..831cf44 100644 --- a/core/tasks/tasks.py +++ b/core/tasks/tasks.py @@ -31,6 +31,8 @@ from openai import OpenAI from pymongo import MongoClient +from + litellm_host = os.getenv("LITELLM_HOST", "localhost") redis_host = os.getenv("REDIS_HOST", "localhost") mongodb_host = os.getenv("MONGODB_HOST", "localhost") diff --git a/services/backend/api_server/app/backend.py b/services/backend/api_server/app/backend.py index 9d67d55..afa3b5c 100644 --- a/services/backend/api_server/app/backend.py +++ b/services/backend/api_server/app/backend.py @@ -104,18 +104,16 @@ generate_thread_id, ) -litellm_host = os.getenv("LITELLM_HOST", "localhost") -redis_host = os.getenv("REDIS_HOST", "localhost") -mongodb_host = os.getenv("MONGODB_HOST", "localhost") - app = FastAPI() -origins = [ +default_origins = [ "http://localhost:3000", # Add the frontend host here "http://localhost", "https://docs.rubra.ai", ] +origins = os.getenv("CORS_ALLOWED_ORIGINS", default_origins) + app.add_middleware( CORSMiddleware, allow_origins=origins, @@ -124,17 +122,59 @@ allow_headers=["*"], # Allows all headers ) + +def _get_mongo_url(): + url = os.getenv("MONGODB_URL") + if url: + return url + + host = os.getenv("MONGODB_HOST", "localhost") + user = os.getenv("MONGODB_USER") + password = os.getenv("MONGODB_PASSWORD") + port = os.getenv("MONGODB_PORT", 27017) + if ( + not user or not password + ): # if any of these not passed, just return unauthenticated url + return f"mongodb://{host}:{port}" + + return f"mongodb://{user}:{password}@{host}:{port}" + + +def _get_litellm_proxy_url(): + host = os.getenv("LITELLM_HOST", "localhost") + port = os.getenv("LITELLM_PORT", 8002) + return f"http://{host}:{port}" + + +def _get_redis_url(): + url = os.getenv("REDIS_URL") + if url: + return url + + host = os.getenv("REDIS_HOST", "localhost") + user = os.getenv("REDIS_USER") + password = os.getenv("REDIS_PASSWORD") + port = os.getenv("REDIS_PORT", 6379) + + if not password: + return f"redis://{host}:{port}/0" + + return f"redis://{user}:{password}@{host}:{port}/0" + + # MongoDB Configurationget -MONGODB_URL = f"mongodb://{mongodb_host}:27017" -DATABASE_NAME = "rubra_db" -LITELLM_URL = f"http://{litellm_host}:8002" +MONGODB_URL = _get_mongo_url() +DATABASE_NAME = os.getenv("MONGODB_DATABASE", "rubra_db") +LITELLM_URL = _get_litellm_proxy_url() HEADERS = {"accept": "application/json", "Content-Type": "application/json"} # Initialize MongoDB client mongo_client = AsyncIOMotorClient(MONGODB_URL) database = mongo_client[DATABASE_NAME] -celery_app = Celery(broker=f"redis://{redis_host}:6379/0") +redis_url = _get_redis_url() + +celery_app = Celery(broker=redis_url) logging.basicConfig(level=logging.INFO) @@ -203,7 +243,7 @@ async def on_startup(): async def get_api_key_status(): try: redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) openai_key = await redis.get("OPENAI_API_KEY") anthropic_key = await redis.get("ANTHROPIC_API_KEY") @@ -226,7 +266,7 @@ async def get_api_key_status(): async def set_api_key_status(api_keys: ApiKeysUpdateModel): try: redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) logging.info("Setting API keys") @@ -752,7 +792,7 @@ async def list_messages( async def redis_subscriber(channel, timeout=1): logging.info(f"Connecting to Redis and subscribing to channel: {channel}") redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) pubsub = redis.pubsub() await pubsub.subscribe(channel) @@ -782,7 +822,7 @@ async def listen_for_task_status( pubsub = None try: redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) pubsub = redis.pubsub() await pubsub.subscribe(task_status_channel) From a9ac08bcc0148060d6c896fd9615138d50bea600 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Mon, 29 Apr 2024 16:27:51 +0530 Subject: [PATCH 2/5] try to build --- .github/workflows/main-release.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/main-release.yaml b/.github/workflows/main-release.yaml index df14d5f..1481ed8 100644 --- a/.github/workflows/main-release.yaml +++ b/.github/workflows/main-release.yaml @@ -6,8 +6,6 @@ concurrency: on: push: - branches: - - chore/new-environment-variable-configuration jobs: build-and-push: From 18177f49008311a1c865ce8f30b49ee39b0dd77f Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Mon, 29 Apr 2024 17:37:41 +0530 Subject: [PATCH 3/5] fix dockerfiles --- Makefile | 1 + services/backend/api_server/Dockerfile | 1 + services/backend/task_executor/Dockerfile | 1 + 3 files changed, 3 insertions(+) diff --git a/Makefile b/Makefile index d5ad67b..8bc2cb6 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ build_images: FULL_TAG=$(call get_full_tag,$$SERVICE); \ echo "Building Docker image $$FULL_TAG"; \ docker build -t $$FULL_TAG --build-context core=./core $$dir; \ + if [ $$? -ne 0 ]; then exit 1; fi; \ else \ if [ -d "$$dir" ]; then \ echo "Skipping $$dir, no Dockerfile found."; \ diff --git a/services/backend/api_server/Dockerfile b/services/backend/api_server/Dockerfile index 4a905e5..a9f5ee7 100644 --- a/services/backend/api_server/Dockerfile +++ b/services/backend/api_server/Dockerfile @@ -8,6 +8,7 @@ COPY . /app COPY --from=core ./ /app/core # Install any needed packages specified in requirements.txt +RUN apt-get update && apt-get install gcc g++ -y RUN pip install --no-cache-dir -r requirements.txt RUN spacy download en_core_web_sm RUN playwright install diff --git a/services/backend/task_executor/Dockerfile b/services/backend/task_executor/Dockerfile index 4844f47..eabb063 100644 --- a/services/backend/task_executor/Dockerfile +++ b/services/backend/task_executor/Dockerfile @@ -7,6 +7,7 @@ WORKDIR /app ADD requirements.txt /app/ # Install any needed packages specified in requirements.txt +RUN apt-get update && apt-get install gcc g++ -y RUN pip install --no-cache-dir -r requirements.txt RUN spacy download en_core_web_sm RUN playwright install From 4cc247a94520f63d4c3a5e73c2d584f5b2c31547 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Mon, 29 Apr 2024 17:41:18 +0530 Subject: [PATCH 4/5] fix mis-import --- core/tasks/tasks.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/tasks/tasks.py b/core/tasks/tasks.py index 831cf44..3bd6eba 100644 --- a/core/tasks/tasks.py +++ b/core/tasks/tasks.py @@ -31,8 +31,6 @@ from openai import OpenAI from pymongo import MongoClient -from - litellm_host = os.getenv("LITELLM_HOST", "localhost") redis_host = os.getenv("REDIS_HOST", "localhost") mongodb_host = os.getenv("MONGODB_HOST", "localhost") From 0fcbfbfff87055688ce2ce451807b68f905cc731 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Thu, 2 May 2024 10:28:33 +0530 Subject: [PATCH 5/5] common place to get all configurations --- core/common.py | 62 +++++++++++++++++++ core/tasks/celery_config.py | 6 +- core/tasks/tasks.py | 15 ++--- .../vector_db/milvus/custom_embeddigs.py | 2 +- 4 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 core/common.py diff --git a/core/common.py b/core/common.py new file mode 100644 index 0000000..9335c8f --- /dev/null +++ b/core/common.py @@ -0,0 +1,62 @@ +import os + +_mongo_url = "" +_redis_url = "" +_litellm_url = "" + + +def get_mongo_url(): + global _mongo_url + if _mongo_url: + return _mongo_url + + _mongo_url = os.getenv("MONGODB_URL") + if _mongo_url: + return _mongo_url + + host = os.getenv("MONGODB_HOST", "localhost") + user = os.getenv("MONGODB_USER") + password = os.getenv("MONGODB_PASSWORD") + port = os.getenv("MONGODB_PORT", 27017) + if ( + not user or not password + ): # if any of these not passed, just return unauthenticated url + _mongo_url = f"mongodb://{host}:{port}" + return _mongo_url + + _mongo_url = f"mongodb://{user}:{password}@{host}:{port}" + return _mongo_url + + +def get_litellm_proxy_url(): + global _litellm_url + if _litellm_url: + return _litellm_url + + host = os.getenv("LITELLM_HOST", "localhost") + port = os.getenv("LITELLM_PORT", 8002) + + _litellm_url = f"http://{host}:{port}" + return _litellm_url + + +def get_redis_url(): + global _redis_url + if _redis_url: + return _redis_url + + _redis_url = os.getenv("REDIS_URL") + if _redis_url: + return _redis_url + + host = os.getenv("REDIS_HOST", "localhost") + user = os.getenv("REDIS_USER") + password = os.getenv("REDIS_PASSWORD") + port = os.getenv("REDIS_PORT", 6379) + + if not password: + _redis_url = f"redis://{host}:{port}/0" + return _redis_url + + _redis_url = f"redis://{user}:{password}@{host}:{port}/0" + return _redis_url diff --git a/core/tasks/celery_config.py b/core/tasks/celery_config.py index 2194759..4597107 100644 --- a/core/tasks/celery_config.py +++ b/core/tasks/celery_config.py @@ -1,8 +1,6 @@ # Standard Library -import os +from core.common import get_redis_url -CELERY_REDIS_HOST = os.getenv("REDIS_HOST", "localhost") -CELERY_REDIS_PORT = os.getenv("REDIS_PORT", 6379) -BROKER_URL = f"redis://{CELERY_REDIS_HOST}:{CELERY_REDIS_PORT}/0" # Redis configuration +BROKER_URL = get_redis_url() CELERY_RESULT_BACKEND = BROKER_URL CELERY_IMPORTS = ("core.tasks.tasks",) diff --git a/core/tasks/tasks.py b/core/tasks/tasks.py index 3bd6eba..221c94e 100644 --- a/core/tasks/tasks.py +++ b/core/tasks/tasks.py @@ -31,17 +31,17 @@ from openai import OpenAI from pymongo import MongoClient +from core.common import get_redis_url, get_litellm_proxy_url, get_mongo_url + litellm_host = os.getenv("LITELLM_HOST", "localhost") -redis_host = os.getenv("REDIS_HOST", "localhost") -mongodb_host = os.getenv("MONGODB_HOST", "localhost") -redis_client = redis.Redis(host=redis_host, port=6379, db=0) -app = Celery("tasks", broker=f"redis://{redis_host}:6379/0") +redis_client = redis.Redis(get_redis_url()) +app = Celery("tasks", broker=get_redis_url()) app.config_from_object("core.tasks.celery_config") app.autodiscover_tasks(["core.tasks"]) # Explicitly discover tasks in 'app' package # MongoDB Configuration -MONGODB_URL = f"mongodb://{mongodb_host}:27017" +MONGODB_URL = get_mongo_url() DATABASE_NAME = "rubra_db" # Global MongoDB client @@ -51,7 +51,7 @@ @signals.worker_process_init.connect def setup_mongo_connection(*args, **kwargs): global mongo_client - mongo_client = MongoClient(f"mongodb://{mongodb_host}:27017") + mongo_client = MongoClient(MONGODB_URL) def create_assistant_message( @@ -216,7 +216,8 @@ def form_openai_tools(tools, assistant_id: str): def execute_chat_completion(assistant_id, thread_id, redis_channel, run_id): try: oai_client = OpenAI( - base_url=f"http://{litellm_host}:8002/v1/", + base_url=get_litellm_proxy_url(), + # FIXME: actual master key api_key="abc", # point to litellm server ) db = mongo_client[DATABASE_NAME] diff --git a/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py b/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py index 085f281..9a60413 100644 --- a/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py +++ b/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py @@ -8,7 +8,7 @@ from langchain.embeddings.base import Embeddings HOST = os.getenv("EMBEDDING_HOST", "localhost") -EMBEDDING_URL = f"http://{HOST}:8020/embed_multiple" +EMBEDDING_URL = os.getenv("EMBEDDING_URL", f"http://{HOST}:8020/embed_multiple") def embed_text(texts: List[str]) -> List[List[float]]: