From 2c0f4c9865fa3f9fde12015f356e3ec9432f1b75 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 13 Aug 2024 16:57:19 -0700 Subject: [PATCH 1/7] fix make prisma readable --- litellm/proxy/utils.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index d1d17d0ef5d..4df037fc349 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -14,6 +14,7 @@ from datetime import datetime, timedelta from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from functools import wraps +from pathlib import Path from typing import TYPE_CHECKING, Any, List, Literal, Optional, Tuple, Union import backoff @@ -815,6 +816,17 @@ class PrismaClient: org_list_transactons: dict = {} spend_log_transactions: List = [] + def ensure_prisma_has_writable_dirs(self, path: str | Path) -> None: + import stat + + for root, dirs, _ in os.walk(path): + for directory in dirs: + dir_path = os.path.join(root, directory) + os.makedirs(dir_path, exist_ok=True) + os.chmod( + dir_path, os.stat(dir_path).st_mode | stat.S_IWRITE | stat.S_IEXEC + ) + def __init__(self, database_url: str, proxy_logging_obj: ProxyLogging): verbose_proxy_logger.debug( "LiteLLM: DATABASE_URL Set in config, trying to 'pip install prisma'" @@ -846,6 +858,22 @@ class PrismaClient: # Now you can import the Prisma Client from prisma import Prisma # type: ignore verbose_proxy_logger.debug("Connecting Prisma Client to DB..") + import importlib.util + + # Get the location of the 'prisma' package + package_name = "prisma" + spec = importlib.util.find_spec(package_name) + print("spec = ", spec) # noqa + + if spec and spec.origin: + print("spec origin= ", spec.origin) # noqa + _base_prisma_package_dir = os.path.dirname(spec.origin) + print("base prisma package dir = ", _base_prisma_package_dir) # noqa + else: + raise ImportError(f"Package {package_name} not found.") + + # Use the package directory in your method call + self.ensure_prisma_has_writable_dirs(path=_base_prisma_package_dir) self.db = Prisma() # Client to connect to Prisma db verbose_proxy_logger.debug("Success - Connected Prisma Client to DB") From ab7758840b5af7c31a2acbcfda56251ce10c27d3 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 13 Aug 2024 18:38:10 -0700 Subject: [PATCH 2/7] skip prisma gen step --- litellm/proxy/utils.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 4df037fc349..4237a011b4f 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -844,17 +844,17 @@ class PrismaClient: dname = os.path.dirname(abspath) os.chdir(dname) - try: - subprocess.run(["prisma", "generate"]) - subprocess.run( - ["prisma", "db", "push", "--accept-data-loss"] - ) # this looks like a weird edge case when prisma just wont start on render. we need to have the --accept-data-loss - except Exception as e: - raise Exception( - f"Unable to run prisma commands. Run `pip install prisma` Got Exception: {(str(e))}" - ) - finally: - os.chdir(original_dir) + # try: + # subprocess.run(["prisma", "generate"]) + # subprocess.run( + # ["prisma", "db", "push", "--accept-data-loss"] + # ) # this looks like a weird edge case when prisma just wont start on render. we need to have the --accept-data-loss + # except Exception as e: + # raise Exception( + # f"Unable to run prisma commands. Run `pip install prisma` Got Exception: {(str(e))}" + # ) + # finally: + # os.chdir(original_dir) # Now you can import the Prisma Client from prisma import Prisma # type: ignore verbose_proxy_logger.debug("Connecting Prisma Client to DB..") From 2de276cb446df81b959e490bcebbd8b0a465f483 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 13 Aug 2024 18:40:00 -0700 Subject: [PATCH 3/7] temp set prisma pems --- set_prisma_permissions.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 set_prisma_permissions.py diff --git a/set_prisma_permissions.py b/set_prisma_permissions.py new file mode 100644 index 00000000000..0973b90b885 --- /dev/null +++ b/set_prisma_permissions.py @@ -0,0 +1,39 @@ +import os +import importlib +from pathlib import Path + + +# Get the location of the 'prisma' package +package_name = "prisma" +spec = importlib.util.find_spec(package_name) +print("spec = ", spec) # noqa + +if spec and spec.origin: + print("spec origin= ", spec.origin) # noqa + _base_prisma_package_dir = os.path.dirname(spec.origin) + print("base prisma package dir = ", _base_prisma_package_dir) # noqa +else: + raise ImportError(f"Package {package_name} not found.") + + +def ensure_prisma_has_writable_dirs(path: str | Path) -> None: + import stat + + for root, dirs, _ in os.walk(path): + for directory in dirs: + dir_path = os.path.join(root, directory) + os.makedirs(dir_path, exist_ok=True) + print("making dir for prisma = ", dir_path) + os.chmod(dir_path, os.stat(dir_path).st_mode | stat.S_IWRITE | stat.S_IEXEC) + + # make this file writable - prisma/schema.prisma + file_path = os.path.join(path, "schema.prisma") + print("making file for prisma = ", file_path) + # make entire directory writable + os.chmod(path, os.stat(path).st_mode | stat.S_IWRITE | stat.S_IEXEC) + + os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IWRITE | stat.S_IEXEC) + + +# Use the package directory in your method call +ensure_prisma_has_writable_dirs(path=_base_prisma_package_dir) From 353b470cbc084e098f74fef1ddb579aa69437c2a Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 13 Aug 2024 19:17:01 -0700 Subject: [PATCH 4/7] fix prisma issues --- litellm/proxy/utils.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 4237a011b4f..f16e604f661 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -14,7 +14,6 @@ from datetime import datetime, timedelta from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from functools import wraps -from pathlib import Path from typing import TYPE_CHECKING, Any, List, Literal, Optional, Tuple, Union import backoff @@ -816,17 +815,6 @@ class PrismaClient: org_list_transactons: dict = {} spend_log_transactions: List = [] - def ensure_prisma_has_writable_dirs(self, path: str | Path) -> None: - import stat - - for root, dirs, _ in os.walk(path): - for directory in dirs: - dir_path = os.path.join(root, directory) - os.makedirs(dir_path, exist_ok=True) - os.chmod( - dir_path, os.stat(dir_path).st_mode | stat.S_IWRITE | stat.S_IEXEC - ) - def __init__(self, database_url: str, proxy_logging_obj: ProxyLogging): verbose_proxy_logger.debug( "LiteLLM: DATABASE_URL Set in config, trying to 'pip install prisma'" @@ -858,22 +846,6 @@ class PrismaClient: # Now you can import the Prisma Client from prisma import Prisma # type: ignore verbose_proxy_logger.debug("Connecting Prisma Client to DB..") - import importlib.util - - # Get the location of the 'prisma' package - package_name = "prisma" - spec = importlib.util.find_spec(package_name) - print("spec = ", spec) # noqa - - if spec and spec.origin: - print("spec origin= ", spec.origin) # noqa - _base_prisma_package_dir = os.path.dirname(spec.origin) - print("base prisma package dir = ", _base_prisma_package_dir) # noqa - else: - raise ImportError(f"Package {package_name} not found.") - - # Use the package directory in your method call - self.ensure_prisma_has_writable_dirs(path=_base_prisma_package_dir) self.db = Prisma() # Client to connect to Prisma db verbose_proxy_logger.debug("Success - Connected Prisma Client to DB") From fef6f50e23231b5681910da5f40a2047bcf7fdba Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Tue, 13 Aug 2024 19:29:40 -0700 Subject: [PATCH 5/7] fic docker file to run in non root model --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index c8e9956b29d..bd840eaf54f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -62,6 +62,11 @@ COPY --from=builder /wheels/ /wheels/ RUN pip install *.whl /wheels/* --no-index --find-links=/wheels/ && rm -f *.whl && rm -rf /wheels # Generate prisma client +ENV PRISMA_BINARY_CACHE_DIR=/app/prisma +RUN mkdir -p /.cache +RUN chmod -R 777 /.cache +RUN pip install nodejs-bin +RUN pip install prisma RUN prisma generate RUN chmod +x entrypoint.sh From 6f06da7d46673d395b63c1b250ec8c34c74f0c39 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 14 Aug 2024 09:24:22 -0700 Subject: [PATCH 6/7] fix use normal prisma --- litellm/proxy/utils.py | 22 +++++++++++----------- set_prisma_permissions.py | 39 --------------------------------------- 2 files changed, 11 insertions(+), 50 deletions(-) delete mode 100644 set_prisma_permissions.py diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index f16e604f661..d1d17d0ef5d 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -832,17 +832,17 @@ class PrismaClient: dname = os.path.dirname(abspath) os.chdir(dname) - # try: - # subprocess.run(["prisma", "generate"]) - # subprocess.run( - # ["prisma", "db", "push", "--accept-data-loss"] - # ) # this looks like a weird edge case when prisma just wont start on render. we need to have the --accept-data-loss - # except Exception as e: - # raise Exception( - # f"Unable to run prisma commands. Run `pip install prisma` Got Exception: {(str(e))}" - # ) - # finally: - # os.chdir(original_dir) + try: + subprocess.run(["prisma", "generate"]) + subprocess.run( + ["prisma", "db", "push", "--accept-data-loss"] + ) # this looks like a weird edge case when prisma just wont start on render. we need to have the --accept-data-loss + except Exception as e: + raise Exception( + f"Unable to run prisma commands. Run `pip install prisma` Got Exception: {(str(e))}" + ) + finally: + os.chdir(original_dir) # Now you can import the Prisma Client from prisma import Prisma # type: ignore verbose_proxy_logger.debug("Connecting Prisma Client to DB..") diff --git a/set_prisma_permissions.py b/set_prisma_permissions.py deleted file mode 100644 index 0973b90b885..00000000000 --- a/set_prisma_permissions.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import importlib -from pathlib import Path - - -# Get the location of the 'prisma' package -package_name = "prisma" -spec = importlib.util.find_spec(package_name) -print("spec = ", spec) # noqa - -if spec and spec.origin: - print("spec origin= ", spec.origin) # noqa - _base_prisma_package_dir = os.path.dirname(spec.origin) - print("base prisma package dir = ", _base_prisma_package_dir) # noqa -else: - raise ImportError(f"Package {package_name} not found.") - - -def ensure_prisma_has_writable_dirs(path: str | Path) -> None: - import stat - - for root, dirs, _ in os.walk(path): - for directory in dirs: - dir_path = os.path.join(root, directory) - os.makedirs(dir_path, exist_ok=True) - print("making dir for prisma = ", dir_path) - os.chmod(dir_path, os.stat(dir_path).st_mode | stat.S_IWRITE | stat.S_IEXEC) - - # make this file writable - prisma/schema.prisma - file_path = os.path.join(path, "schema.prisma") - print("making file for prisma = ", file_path) - # make entire directory writable - os.chmod(path, os.stat(path).st_mode | stat.S_IWRITE | stat.S_IEXEC) - - os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IWRITE | stat.S_IEXEC) - - -# Use the package directory in your method call -ensure_prisma_has_writable_dirs(path=_base_prisma_package_dir) From 47afbfcbaa41b4de745b56777ff7d9dd952e7198 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 14 Aug 2024 09:26:47 -0700 Subject: [PATCH 7/7] allow running as non-root user --- Dockerfile.database | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile.database b/Dockerfile.database index 22084bab89c..c995939e5b9 100644 --- a/Dockerfile.database +++ b/Dockerfile.database @@ -62,6 +62,11 @@ RUN pip install PyJWT --no-cache-dir RUN chmod +x build_admin_ui.sh && ./build_admin_ui.sh # Generate prisma client +ENV PRISMA_BINARY_CACHE_DIR=/app/prisma +RUN mkdir -p /.cache +RUN chmod -R 777 /.cache +RUN pip install nodejs-bin +RUN pip install prisma RUN prisma generate RUN chmod +x entrypoint.sh