diff --git a/Makefile b/Makefile index d056654f9..f62ecb411 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ port ?= 7860 env ?= .env open_browser ?= true path = src/backend/base/langflow/frontend +workers ?= 1 codespell: @poetry install --with spelling @@ -144,10 +145,10 @@ backend: @-kill -9 $(lsof -t -i:7860) ifdef login @echo "Running backend autologin is $(login)"; - LANGFLOW_AUTO_LOGIN=$(login) poetry run uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload --env-file .env --loop asyncio + LANGFLOW_AUTO_LOGIN=$(login) poetry run uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload --env-file .env --loop asyncio --workers $(workers) else @echo "Running backend respecting the .env file"; - poetry run uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload --env-file .env --loop asyncio + poetry run uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload --env-file .env --loop asyncio --workers $(workers) endif build_and_run: diff --git a/poetry.lock b/poetry.lock index 146cd5d66..e0978b558 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4365,7 +4365,7 @@ rich = "^13.7.0" sqlmodel = "^0.0.18" typer = "^0.12.0" uncurl = "^0.0.11" -uvicorn = "^0.29.0" +uvicorn = "^0.30.0" websockets = "*" [package.extras] @@ -6834,17 +6834,17 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-settings" -version = "2.2.1" +version = "2.3.0" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.2.1-py3-none-any.whl", hash = "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"}, - {file = "pydantic_settings-2.2.1.tar.gz", hash = "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed"}, + {file = "pydantic_settings-2.3.0-py3-none-any.whl", hash = "sha256:26eeed27370a9c5e3f64e4a7d6602573cbedf05ed940f1d5b11c3f178427af7a"}, + {file = "pydantic_settings-2.3.0.tar.gz", hash = "sha256:78db28855a71503cfe47f39500a1dece523c640afd5280edb5c5c9c9cfa534c9"}, ] [package.dependencies] -pydantic = ">=2.3.0" +pydantic = ">=2.7.0" python-dotenv = ">=0.21.0" [package.extras] @@ -9230,13 +9230,13 @@ files = [ [[package]] name = "uvicorn" -version = "0.29.0" +version = "0.30.1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, - {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, + {file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"}, + {file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"}, ] [package.dependencies] diff --git a/src/backend/base/langflow/components/models/OpenAIModel.py b/src/backend/base/langflow/components/models/OpenAIModel.py index ced22c331..0aedce495 100644 --- a/src/backend/base/langflow/components/models/OpenAIModel.py +++ b/src/backend/base/langflow/components/models/OpenAIModel.py @@ -78,7 +78,7 @@ class OpenAIModelComponent(LCModelComponent): self, input_value: Text, openai_api_key: str, - temperature: Optional[float] = 0.1, + temperature: float = 0.1, model_name: str = "gpt-4o", max_tokens: Optional[int] = 256, model_kwargs: NestedDict = {}, diff --git a/src/backend/base/langflow/services/database/factory.py b/src/backend/base/langflow/services/database/factory.py index 7f7a142b5..f9c269f12 100644 --- a/src/backend/base/langflow/services/database/factory.py +++ b/src/backend/base/langflow/services/database/factory.py @@ -15,4 +15,4 @@ class DatabaseServiceFactory(ServiceFactory): # Here you would have logic to create and configure a DatabaseService if not settings_service.settings.database_url: raise ValueError("No database URL provided") - return DatabaseService(settings_service.settings.database_url) + return DatabaseService(settings_service) diff --git a/src/backend/base/langflow/services/database/service.py b/src/backend/base/langflow/services/database/service.py index 674c6c645..cf3795610 100644 --- a/src/backend/base/langflow/services/database/service.py +++ b/src/backend/base/langflow/services/database/service.py @@ -21,12 +21,17 @@ from langflow.services.utils import teardown_superuser if TYPE_CHECKING: from sqlalchemy.engine import Engine + from langflow.services.settings.service import SettingsService + class DatabaseService(Service): name = "database_service" - def __init__(self, database_url: str): - self.database_url = database_url + def __init__(self, settings_service: "SettingsService"): + self.settings_service = settings_service + if settings_service.settings.database_url is None: + raise ValueError("No database URL provided") + self.database_url: str = settings_service.settings.database_url # This file is in langflow.services.database.manager.py # the ini is in langflow langflow_dir = Path(__file__).parent.parent.parent @@ -41,7 +46,12 @@ class DatabaseService(Service): connect_args = {"check_same_thread": False} else: connect_args = {} - return create_engine(self.database_url, connect_args=connect_args) + return create_engine( + self.database_url, + connect_args=connect_args, + pool_size=self.settings_service.settings.pool_size, + max_overflow=self.settings_service.settings.max_overflow, + ) def __enter__(self): self._session = Session(self.engine) @@ -267,3 +277,4 @@ class DatabaseService(Service): logger.error(f"Error tearing down database: {exc}") self.engine.dispose() + self.engine.dispose() diff --git a/src/backend/base/langflow/services/settings/base.py b/src/backend/base/langflow/services/settings/base.py index 0f9d0d029..4f50cb756 100644 --- a/src/backend/base/langflow/services/settings/base.py +++ b/src/backend/base/langflow/services/settings/base.py @@ -67,6 +67,11 @@ class Settings(BaseSettings): dev: bool = False database_url: Optional[str] = None + """Database URL for Langflow. If not provided, Langflow will use a SQLite database.""" + pool_size: int = 10 + """The number of connections to keep open in the connection pool. If not provided, the default is 10.""" + max_overflow: int = 10 + """The number of connections to allow that can be opened beyond the pool size. If not provided, the default is 10.""" cache_type: str = "async" remove_api_keys: bool = False components_path: List[str] = [] diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 55aee39bf..324dccc72 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -2214,17 +2214,17 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-settings" -version = "2.2.1" +version = "2.3.0" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.2.1-py3-none-any.whl", hash = "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"}, - {file = "pydantic_settings-2.2.1.tar.gz", hash = "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed"}, + {file = "pydantic_settings-2.3.0-py3-none-any.whl", hash = "sha256:26eeed27370a9c5e3f64e4a7d6602573cbedf05ed940f1d5b11c3f178427af7a"}, + {file = "pydantic_settings-2.3.0.tar.gz", hash = "sha256:78db28855a71503cfe47f39500a1dece523c640afd5280edb5c5c9c9cfa534c9"}, ] [package.dependencies] -pydantic = ">=2.3.0" +pydantic = ">=2.7.0" python-dotenv = ">=0.21.0" [package.extras] @@ -2890,13 +2890,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.29.0" +version = "0.30.1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, - {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, + {file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"}, + {file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"}, ] [package.dependencies] @@ -3265,4 +3265,4 @@ local = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "1dc0dd442df5d174ea85c859208f5cfea9d4785c7b7a93f2c6bf8c92e93d8cad" +content-hash = "48a7355a7096e763b75315d0704bed8f4d8134a33553e62bc305a686b9e72803" diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 3dc50f617..3d80fe194 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -28,7 +28,7 @@ langflow-base = "langflow.__main__:main" python = ">=3.10,<3.13" fastapi = "^0.111.0" httpx = "*" -uvicorn = "^0.29.0" +uvicorn = "^0.30.0" gunicorn = "^22.0.0" langchain = "~0.2.0" langchainhub = "~0.1.15"