From 6e3a6ce8c3450577ecbe4228970957f43836ebe0 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 15 Aug 2023 16:33:47 -0300 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20set=20CONFIG?= =?UTF-8?q?=5FDIR=20to=20default=20value=20if=20not=20provided=20to=20impr?= =?UTF-8?q?ove=20functionality=20=E2=9C=A8=20feat(base.py):=20add=20suppor?= =?UTF-8?q?t=20for=20setting=20CONFIG=5FDIR=20to=20a=20cache=20directory?= =?UTF-8?q?=20if=20not=20provided=20to=20improve=20file=20management=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20set=20DATABASE=5FURL=20to=20defa?= =?UTF-8?q?ult=20value=20if=20not=20provided=20to=20improve=20functionalit?= =?UTF-8?q?y=20=E2=9C=A8=20feat(base.py):=20add=20support=20for=20setting?= =?UTF-8?q?=20DATABASE=5FURL=20to=20LANGFLOW=5FDATABASE=5FURL=20environmen?= =?UTF-8?q?t=20variable=20if=20not=20provided=20to=20improve=20configurabi?= =?UTF-8?q?lity=20=F0=9F=90=9B=20fix(base.py):=20raise=20ValueError=20if?= =?UTF-8?q?=20CONFIG=5FDIR=20is=20not=20set=20when=20using=20sqlite=20data?= =?UTF-8?q?base=20to=20improve=20error=20handling=20=E2=9C=A8=20feat(base.?= =?UTF-8?q?py):=20add=20support=20for=20copying=20existing=20sqlite=20data?= =?UTF-8?q?base=20to=20new=20location=20if=20CONFIG=5FDIR=20is=20set=20to?= =?UTF-8?q?=20improve=20migration=20process?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/services/settings/base.py | 103 ++++++++++++++++-- 1 file changed, 91 insertions(+), 12 deletions(-) diff --git a/src/backend/langflow/services/settings/base.py b/src/backend/langflow/services/settings/base.py index 1eb2793b3..e08e7a22f 100644 --- a/src/backend/langflow/services/settings/base.py +++ b/src/backend/langflow/services/settings/base.py @@ -1,6 +1,7 @@ import contextlib import json import os +from shutil import copy2 from typing import Optional, List from pathlib import Path @@ -29,26 +30,104 @@ class Settings(BaseSettings): OUTPUT_PARSERS: dict = {} CUSTOM_COMPONENTS: dict = {} + # Define the default LANGFLOW_DIR + CONFIG_DIR: Optional[str] = None + DEV: bool = False DATABASE_URL: Optional[str] = None CACHE: str = "InMemoryCache" REMOVE_API_KEYS: bool = False COMPONENTS_PATH: List[str] = [] - @validator("DATABASE_URL", pre=True) - def set_database_url(cls, value): + @validator("CONFIG_DIR", pre=True, allow_reuse=True) + def set_langflow_dir(cls, value): if not value: - logger.debug( - "No database_url provided, trying LANGFLOW_DATABASE_URL env variable" - ) - if langflow_database_url := os.getenv("LANGFLOW_DATABASE_URL"): - value = langflow_database_url - logger.debug("Using LANGFLOW_DATABASE_URL env variable.") - else: - logger.debug("No DATABASE_URL env variable, using sqlite database") - value = "sqlite:///./langflow.db" + import appdirs - return value + # Define the app name and author + app_name = "langflow" + app_author = "logspace" + + # Get the cache directory for the application + cache_dir = appdirs.user_cache_dir(app_name, app_author) + + # Create a .langflow directory inside the cache directory + value = Path(cache_dir) + value.mkdir(parents=True, exist_ok=True) + + if isinstance(value, str): + value = Path(value) + if not value.exists(): + value.mkdir(parents=True, exist_ok=True) + + return str(value) + + from typing import Any + import os + from pathlib import Path + from shutil import copy2 + from loguru import logger + from pydantic import validator + + class BaseSettings: + """ + Base settings class for Langflow service. + """ + + DEBUG: bool = False + TESTING: bool = False + CONFIG_DIR: str = "" + DATABASE_URL: str = "" + + @validator("DATABASE_URL", pre=True) + def set_database_url(cls, value, values): + """ + Validator to set the DATABASE_URL value. + + If no value is provided, it will try to get the LANGFLOW_DATABASE_URL environment variable. + If that is not set, it will use a sqlite database. + If a CONFIG_DIR is provided, it will use that directory to store the sqlite database. + If a sqlite database already exists in the current directory, it will be copied to the new location. + """ + if not value: + logger.debug( + "No database_url provided, trying LANGFLOW_DATABASE_URL env variable" + ) + if langflow_database_url := os.getenv("LANGFLOW_DATABASE_URL"): + value = langflow_database_url + logger.debug("Using LANGFLOW_DATABASE_URL env variable.") + else: + logger.debug("No DATABASE_URL env variable, using sqlite database") + # Originally, we used sqlite:///./langflow.db + # so we need to migrate to the new format + # if there is a database in that location + if not values["CONFIG_DIR"]: + raise ValueError( + "CONFIG_DIR not set, please set it or provide a DATABASE_URL" + ) + + new_path = f"{values['CONFIG_DIR']}/langflow.db" + if Path("./langflow.db").exists(): + if Path(new_path).exists(): + logger.debug( + f"Database already exists at {new_path}, using it" + ) + else: + try: + logger.debug( + "Copying existing database to new location" + ) + copy2("./langflow.db", new_path) + logger.debug(f"Copied existing database to {new_path}") + except Exception: + logger.error( + "Failed to copy database, using default path" + ) + new_path = "./langflow.db" + + value = f"sqlite:///{new_path}" + + return value @validator("COMPONENTS_PATH", pre=True) def set_components_path(cls, value): From 69d03f64b16c76f5137d16097a50663f6df795c6 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 15 Aug 2023 16:37:21 -0300 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=94=A7=20fix(base.py):=20remove=20red?= =?UTF-8?q?undant=20imports=20and=20nested=20class=20declaration=20?= =?UTF-8?q?=E2=9C=A8=20feat(base.py):=20add=20validation=20logic=20to=20se?= =?UTF-8?q?t=20the=20DATABASE=5FURL=20value=20based=20on=20environment=20v?= =?UTF-8?q?ariables=20and=20file=20paths?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/services/settings/base.py | 95 +++++++------------ 1 file changed, 32 insertions(+), 63 deletions(-) diff --git a/src/backend/langflow/services/settings/base.py b/src/backend/langflow/services/settings/base.py index e08e7a22f..c0fd0a0a1 100644 --- a/src/backend/langflow/services/settings/base.py +++ b/src/backend/langflow/services/settings/base.py @@ -62,72 +62,41 @@ class Settings(BaseSettings): return str(value) - from typing import Any - import os - from pathlib import Path - from shutil import copy2 - from loguru import logger - from pydantic import validator + @validator("DATABASE_URL", pre=True) + def set_database_url(cls, value, values): + if not value: + logger.debug( + "No database_url provided, trying LANGFLOW_DATABASE_URL env variable" + ) + if langflow_database_url := os.getenv("LANGFLOW_DATABASE_URL"): + value = langflow_database_url + logger.debug("Using LANGFLOW_DATABASE_URL env variable.") + else: + logger.debug("No DATABASE_URL env variable, using sqlite database") + # Originally, we used sqlite:///./langflow.db + # so we need to migrate to the new format + # if there is a database in that location + if not values["CONFIG_DIR"]: + raise ValueError( + "CONFIG_DIR not set, please set it or provide a DATABASE_URL" + ) - class BaseSettings: - """ - Base settings class for Langflow service. - """ + new_path = f"{values['CONFIG_DIR']}/langflow.db" + if Path("./langflow.db").exists(): + if Path(new_path).exists(): + logger.debug(f"Database already exists at {new_path}, using it") + else: + try: + logger.debug("Copying existing database to new location") + copy2("./langflow.db", new_path) + logger.debug(f"Copied existing database to {new_path}") + except Exception: + logger.error("Failed to copy database, using default path") + new_path = "./langflow.db" - DEBUG: bool = False - TESTING: bool = False - CONFIG_DIR: str = "" - DATABASE_URL: str = "" + value = f"sqlite:///{new_path}" - @validator("DATABASE_URL", pre=True) - def set_database_url(cls, value, values): - """ - Validator to set the DATABASE_URL value. - - If no value is provided, it will try to get the LANGFLOW_DATABASE_URL environment variable. - If that is not set, it will use a sqlite database. - If a CONFIG_DIR is provided, it will use that directory to store the sqlite database. - If a sqlite database already exists in the current directory, it will be copied to the new location. - """ - if not value: - logger.debug( - "No database_url provided, trying LANGFLOW_DATABASE_URL env variable" - ) - if langflow_database_url := os.getenv("LANGFLOW_DATABASE_URL"): - value = langflow_database_url - logger.debug("Using LANGFLOW_DATABASE_URL env variable.") - else: - logger.debug("No DATABASE_URL env variable, using sqlite database") - # Originally, we used sqlite:///./langflow.db - # so we need to migrate to the new format - # if there is a database in that location - if not values["CONFIG_DIR"]: - raise ValueError( - "CONFIG_DIR not set, please set it or provide a DATABASE_URL" - ) - - new_path = f"{values['CONFIG_DIR']}/langflow.db" - if Path("./langflow.db").exists(): - if Path(new_path).exists(): - logger.debug( - f"Database already exists at {new_path}, using it" - ) - else: - try: - logger.debug( - "Copying existing database to new location" - ) - copy2("./langflow.db", new_path) - logger.debug(f"Copied existing database to {new_path}") - except Exception: - logger.error( - "Failed to copy database, using default path" - ) - new_path = "./langflow.db" - - value = f"sqlite:///{new_path}" - - return value + return value @validator("COMPONENTS_PATH", pre=True) def set_components_path(cls, value): From 5e715af8755f13a5e2a6f976a285ab8cd6e9e08d Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 15 Aug 2023 16:46:53 -0300 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=94=A7=20fix(ApiModal/index.tsx):=20f?= =?UTF-8?q?ix=20formatting=20of=20codesArray=20to=20improve=20readability?= =?UTF-8?q?=20=F0=9F=94=A7=20fix(formModal/index.tsx):=20fix=20formatting?= =?UTF-8?q?=20of=20getWebSocketUrl=20function=20to=20improve=20readability?= =?UTF-8?q?=20=F0=9F=94=A7=20fix(vite.config.ts):=20fix=20formatting=20of?= =?UTF-8?q?=20comment=20to=20improve=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/modals/ApiModal/index.tsx | 8 +++++++- src/frontend/src/modals/formModal/index.tsx | 3 ++- src/frontend/vite.config.ts | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/modals/ApiModal/index.tsx b/src/frontend/src/modals/ApiModal/index.tsx index 8410ee7d4..5bd93df45 100644 --- a/src/frontend/src/modals/ApiModal/index.tsx +++ b/src/frontend/src/modals/ApiModal/index.tsx @@ -49,7 +49,13 @@ const ApiModal = forwardRef( const pythonCode = getPythonCode(flow, tweak.current, tabsState); const widgetCode = getWidgetCode(flow, tabsState); const tweaksCode = buildTweaks(flow); - const codesArray = [curl_code, pythonApiCode, pythonCode, widgetCode, pythonCode]; + const codesArray = [ + curl_code, + pythonApiCode, + pythonCode, + widgetCode, + pythonCode, + ]; const [tabs, setTabs] = useState(tabsArray(codesArray, 0)); function startState() { diff --git a/src/frontend/src/modals/formModal/index.tsx b/src/frontend/src/modals/formModal/index.tsx index 68137c0da..0e2f9b3c4 100644 --- a/src/frontend/src/modals/formModal/index.tsx +++ b/src/frontend/src/modals/formModal/index.tsx @@ -160,7 +160,8 @@ export default function FormModal({ } function getWebSocketUrl(chatId, isDevelopment = false) { - const isSecureProtocol = window.location.protocol === "https:" || window.location.port === "443"; + const isSecureProtocol = + window.location.protocol === "https:" || window.location.port === "443"; const webSocketProtocol = isSecureProtocol ? "wss" : "ws"; const host = isDevelopment ? "localhost:7860" : window.location.host; const chatEndpoint = `/api/v1/chat/${chatId}`; diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts index d477ce539..b513e36bb 100644 --- a/src/frontend/vite.config.ts +++ b/src/frontend/vite.config.ts @@ -6,7 +6,7 @@ const apiRoutes = ["^/api/v1/", "/health"]; // Use environment variable to determine the target. const target = process.env.VITE_PROXY_TARGET || "http://127.0.0.1:7860"; -// Use environment variable to determine the UI server port +// Use environment variable to determine the UI server port const port = process.env.VITE_PORT || 3000; const proxyTargets = apiRoutes.reduce((proxyObj, route) => {