From af98504e4afe0b45a53c14203ee760070d072608 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 24 Jun 2024 13:29:41 -0700 Subject: [PATCH 01/12] Fix Astra Component and Middleware (#2321) * chore: update linting workflows to include dev branch in merge_group * Update README.md Add 1.0 banner * Update README.md * chore: update package versions in pyproject.toml files * Refactor "created_at" column type for consistency and fix cancel middleware (#2316) * chore: update linting workflows to include dev branch in merge_group * Update README.md Add 1.0 banner * Update README.md * chore: update package versions in pyproject.toml files * refactor: update "created_at" column type to use the "sa" module for consistency * Update README.md Add 1.0 banner * chore: Remove unused import in ToolCallingAgent.py * fix: adapt RequestCancelledMiddleware to handle cancelled requests * chore: Remove unused import in test_helper_components.py * refactor: Declare queue variable with explicit type in RequestCancelledMiddleware --------- Co-authored-by: Rodrigo Nader * chore: Update AstraDB.py imports and method signature for search_documents * chore: Update package versions in pyproject.toml files * chore: Update run-name in release.yml for Langflow Release * fix: add call to _add_documents_to_vector_store in AstraDB component * chore: Fix missing parentheses in RequestCancelledMiddleware * chore: Update pydantic-settings and tenacity versions The commit updates the versions of the `pydantic-settings` and `tenacity` packages in the `poetry.lock` file. The `pydantic-settings` version is updated from 2.3.3 to 2.3.4, and the `tenacity` version is updated from 8.4.1 to 8.4.2. * Update README.md Add 1.0 banner --------- Co-authored-by: Rodrigo Nader --- README.md | 1 - poetry.lock | 53 ++++++++++++++++--------------- pyproject.toml | 2 +- src/backend/base/langflow/main.py | 2 +- src/backend/base/poetry.lock | 12 +++---- src/backend/base/pyproject.toml | 2 +- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index c4fcde4a2..6a15027aa 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,6 @@ Alternatively, click the **"Open in Cloud Shell"** button below to launch Google Use this template to deploy Langflow 1.0 on Railway: - [![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/JMXEWp?referralCode=MnPSdg) ## Deploy on Render diff --git a/poetry.lock b/poetry.lock index c07ae2e94..5ac1608a9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2579,13 +2579,13 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4 [[package]] name = "google-api-core" -version = "2.19.0" +version = "2.19.1" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google-api-core-2.19.0.tar.gz", hash = "sha256:cf1b7c2694047886d2af1128a03ae99e391108a08804f87cfd35970e49c9cd10"}, - {file = "google_api_core-2.19.0-py3-none-any.whl", hash = "sha256:8661eec4078c35428fd3f69a2c7ee29e342896b70f01d1a1cbcb334372dd6251"}, + {file = "google-api-core-2.19.1.tar.gz", hash = "sha256:f4695f1e3650b316a795108a76a1c416e6afb036199d1c1f1f110916df479ffd"}, + {file = "google_api_core-2.19.1-py3-none-any.whl", hash = "sha256:f12a9b8309b5e21d92483bbd47ce2c445861ec7d269ef6784ecc0ea8c1fa6125"}, ] [package.dependencies] @@ -2600,7 +2600,7 @@ grpcio-status = [ {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, ] proto-plus = ">=1.22.3,<2.0.0dev" -protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" requests = ">=2.18.0,<3.0.0.dev0" [package.extras] @@ -2936,18 +2936,18 @@ requests = "*" [[package]] name = "googleapis-common-protos" -version = "1.63.1" +version = "1.63.2" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.63.1.tar.gz", hash = "sha256:c6442f7a0a6b2a80369457d79e6672bb7dcbaab88e0848302497e3ec80780a6a"}, - {file = "googleapis_common_protos-1.63.1-py2.py3-none-any.whl", hash = "sha256:0e1c2cdfcbc354b76e4a211a35ea35d6926a835cba1377073c4861db904a1877"}, + {file = "googleapis-common-protos-1.63.2.tar.gz", hash = "sha256:27c5abdffc4911f28101e635de1533fb4cfd2c37fbaa9174587c799fac90aa87"}, + {file = "googleapis_common_protos-1.63.2-py2.py3-none-any.whl", hash = "sha256:27a2499c7e8aff199665b22741997e485eccc8645aa9176c7c988e6fae507945"}, ] [package.dependencies] grpcio = {version = ">=1.44.0,<2.0.0.dev0", optional = true, markers = "extra == \"grpc\""} -protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] @@ -3070,19 +3070,19 @@ typing-extensions = ">=4.7,<5" [[package]] name = "grpc-google-iam-v1" -version = "0.13.0" +version = "0.13.1" description = "IAM API client library" optional = false python-versions = ">=3.7" files = [ - {file = "grpc-google-iam-v1-0.13.0.tar.gz", hash = "sha256:fad318608b9e093258fbf12529180f400d1c44453698a33509cc6ecf005b294e"}, - {file = "grpc_google_iam_v1-0.13.0-py2.py3-none-any.whl", hash = "sha256:53902e2af7de8df8c1bd91373d9be55b0743ec267a7428ea638db3775becae89"}, + {file = "grpc-google-iam-v1-0.13.1.tar.gz", hash = "sha256:3ff4b2fd9d990965e410965253c0da6f66205d5a8291c4c31c6ebecca18a9001"}, + {file = "grpc_google_iam_v1-0.13.1-py2.py3-none-any.whl", hash = "sha256:c3e86151a981811f30d5e7330f271cee53e73bb87755e88cc3b6f0c7b5fe374e"}, ] [package.dependencies] googleapis-common-protos = {version = ">=1.56.0,<2.0.0dev", extras = ["grpc"]} grpcio = ">=1.44.0,<2.0.0dev" -protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0dev" [[package]] name = "grpcio" @@ -4442,7 +4442,7 @@ six = "*" [[package]] name = "langflow-base" -version = "0.0.76" +version = "0.0.78" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" @@ -7016,13 +7016,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-settings" -version = "2.3.3" +version = "2.3.4" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.3.3-py3-none-any.whl", hash = "sha256:e4ed62ad851670975ec11285141db888fd24947f9440bd4380d7d8788d4965de"}, - {file = "pydantic_settings-2.3.3.tar.gz", hash = "sha256:87fda838b64b5039b970cd47c3e8a1ee460ce136278ff672980af21516f6e6ce"}, + {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"}, + {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"}, ] [package.dependencies] @@ -8783,13 +8783,13 @@ files = [ [[package]] name = "tenacity" -version = "8.4.1" +version = "8.4.2" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.4.1-py3-none-any.whl", hash = "sha256:28522e692eda3e1b8f5e99c51464efcc0b9fc86933da92415168bc1c4e2308fa"}, - {file = "tenacity-8.4.1.tar.gz", hash = "sha256:54b1412b878ddf7e1f1577cd49527bad8cdef32421bd599beac0c6c3f10582fd"}, + {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"}, + {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"}, ] [package.extras] @@ -9541,13 +9541,13 @@ six = "*" [[package]] name = "unstructured" -version = "0.14.7" +version = "0.14.8" description = "A library that prepares raw documents for downstream ML tasks." optional = false python-versions = "<3.13,>=3.9.0" files = [ - {file = "unstructured-0.14.7-py3-none-any.whl", hash = "sha256:78e029eb2dd3dc792989af2133cb5472e6a17a501cf415cd8c095f1a88763738"}, - {file = "unstructured-0.14.7.tar.gz", hash = "sha256:219f6ae8a8c5a23e5e6944d3a78d1c7f162ee01e7c6034afe2e5052eef679918"}, + {file = "unstructured-0.14.8-py3-none-any.whl", hash = "sha256:eb97a0754d9f1a90134af45e4ee2e17f12aced57fda4f73ca4875090fef396a5"}, + {file = "unstructured-0.14.8.tar.gz", hash = "sha256:2a39fd2e92a986c45f9686b1115cce56a022d2600a1aae67b8e09eb0373d85b3"}, ] [package.dependencies] @@ -9576,7 +9576,7 @@ wrapt = "*" [package.extras] airtable = ["pyairtable"] -all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "pytesseract", "python-docx (>=1.1.2)", "python-oxmsg", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.35)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] +all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "pytesseract", "python-docx (>=1.1.2)", "python-oxmsg", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] astra = ["astrapy"] azure = ["adlfs", "fsspec"] azure-cognitive-search = ["azure-search-documents"] @@ -9605,9 +9605,10 @@ gitlab = ["python-gitlab"] google-drive = ["google-api-python-client"] hubspot = ["hubspot-api-client", "urllib3"] huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"] -image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "pytesseract", "unstructured-inference (==0.7.35)", "unstructured.pytesseract (>=0.3.12)"] +image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "pytesseract", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)"] jira = ["atlassian-python-api"] -local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "pytesseract", "python-docx (>=1.1.2)", "python-oxmsg", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.35)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] +kafka = ["confluent-kafka"] +local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "pytesseract", "python-docx (>=1.1.2)", "python-oxmsg", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] md = ["markdown"] mongodb = ["pymongo"] msg = ["python-oxmsg"] @@ -9619,7 +9620,7 @@ opensearch = ["opensearch-py"] org = ["pypandoc"] outlook = ["Office365-REST-Python-Client", "msal"] paddleocr = ["unstructured.paddleocr (==2.6.1.3)"] -pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "pytesseract", "unstructured-inference (==0.7.35)", "unstructured.pytesseract (>=0.3.12)"] +pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "pytesseract", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)"] pinecone = ["pinecone-client (>=3.7.1)"] postgres = ["psycopg2-binary"] ppt = ["python-pptx (<=0.6.23)"] diff --git a/pyproject.toml b/pyproject.toml index 5fc120287..98d00485b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.2" +version = "1.0.3" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/langflow/main.py b/src/backend/base/langflow/main.py index a8a165c95..085d72710 100644 --- a/src/backend/base/langflow/main.py +++ b/src/backend/base/langflow/main.py @@ -42,7 +42,7 @@ class RequestCancelledMiddleware(BaseHTTPMiddleware): async def message_poller(sentinel, handler_task, request): nonlocal queue while True: - message = await request.receive + message = await request.receive() if message["type"] == "http.disconnect": handler_task.cancel() return sentinel # Break the loop diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index a919a0251..379821ebf 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -2199,13 +2199,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-settings" -version = "2.3.3" +version = "2.3.4" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.3.3-py3-none-any.whl", hash = "sha256:e4ed62ad851670975ec11285141db888fd24947f9440bd4380d7d8788d4965de"}, - {file = "pydantic_settings-2.3.3.tar.gz", hash = "sha256:87fda838b64b5039b970cd47c3e8a1ee460ce136278ff672980af21516f6e6ce"}, + {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"}, + {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"}, ] [package.dependencies] @@ -2669,13 +2669,13 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "tenacity" -version = "8.4.1" +version = "8.4.2" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.4.1-py3-none-any.whl", hash = "sha256:28522e692eda3e1b8f5e99c51464efcc0b9fc86933da92415168bc1c4e2308fa"}, - {file = "tenacity-8.4.1.tar.gz", hash = "sha256:54b1412b878ddf7e1f1577cd49527bad8cdef32421bd599beac0c6c3f10582fd"}, + {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"}, + {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"}, ] [package.extras] diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 102097591..ee8072a05 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow-base" -version = "0.0.78" +version = "0.0.79" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ From fff4537b1e46f6c617e8bd1c14c1bb8d4148d581 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 25 Jun 2024 09:20:55 -0700 Subject: [PATCH 02/12] Fixes CLI and server (#2342) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: update linting workflows to include dev branch in merge_group * Update README.md Add 1.0 banner * Update README.md * chore: update package versions in pyproject.toml files * Refactor "created_at" column type for consistency and fix cancel middleware (#2316) * chore: update linting workflows to include dev branch in merge_group * Update README.md Add 1.0 banner * Update README.md * chore: update package versions in pyproject.toml files * refactor: update "created_at" column type to use the "sa" module for consistency * Update README.md Add 1.0 banner * chore: Remove unused import in ToolCallingAgent.py * fix: adapt RequestCancelledMiddleware to handle cancelled requests * chore: Remove unused import in test_helper_components.py * refactor: Declare queue variable with explicit type in RequestCancelledMiddleware --------- Co-authored-by: Rodrigo Nader * chore: Update AstraDB.py imports and method signature for search_documents * chore: Update package versions in pyproject.toml files * chore: Update run-name in release.yml for Langflow Release * fix: add call to _add_documents_to_vector_store in AstraDB component * chore: Fix missing parentheses in RequestCancelledMiddleware * chore: Update pydantic-settings and tenacity versions The commit updates the versions of the `pydantic-settings` and `tenacity` packages in the `poetry.lock` file. The `pydantic-settings` version is updated from 2.3.3 to 2.3.4, and the `tenacity` version is updated from 8.4.1 to 8.4.2. * Update README.md Add 1.0 banner * fix fetch data to work even with autologin true * format code * deactivate stop button until we have a better solution (#2337) * consistent auth error status code * [Fix] unhandled http errors in background tasks (#2326) * handle exceptions for background task * revert changes that is not related to this HTTP handler exception * Refactor model GoogleGenerativeAIModel (#2251) * refactor model GoogleGenerativeAIModel * adds model options --------- Co-authored-by: Gabriel Luiz Freitas Almeida * Fix .env values not being honored in CLI (#2336) * chore: Update launch.json to include environment file The launch.json file was updated to include the environment file path for the "run" command in the "Python: Flask" configuration. This change ensures that the necessary environment variables are loaded when running the backend base of Langflow frontend. The previous configuration had the environment variables set in the "env" field, but it has been removed as it is redundant with the new environment file inclusion. * chore: Update dotenv import and environment variable handling This commit updates the import statement for the `dotenv` module in the `__main__.py` file. It adds the `dotenv_values` function to the import statement to enable loading environment variables from a file. Additionally, it introduces a new section of code that maps environment variables to their corresponding variables and types, allowing for more flexible and dynamic configuration. The commit also updates the `run` function to update variables based on environment variables, if they are present. This change improves the handling of environment variables and enhances the configurability of the application. * deactivate stop button until we have a better solution (#2337) * consistent auth error status code * [Fix] unhandled http errors in background tasks (#2326) * handle exceptions for background task * revert changes that is not related to this HTTP handler exception * Refactor model GoogleGenerativeAIModel (#2251) * refactor model GoogleGenerativeAIModel * adds model options --------- Co-authored-by: Gabriel Luiz Freitas Almeida --------- Co-authored-by: ming luo Co-authored-by: Ítalo Johnny * Update GitHub Actions workflows and dependencies (#2341) * chore: Add GitHub Actions workflow for testing documentation build * Fix server start command in GitHub Actions workflows * chore: Bump langflow and langflow-base versions * chore: Update GitHub Actions workflow for docs_test * chore: Update typing import in __main__.py * Fix user authentication and authorization issues (#2343) --------- Co-authored-by: Rodrigo Nader Co-authored-by: anovazzi1 Co-authored-by: ming luo Co-authored-by: Ítalo Johnny --- .github/workflows/docs_test.yml | 47 +++ .github/workflows/python_test.yml | 2 +- .github/workflows/release.yml | 4 +- .vscode/launch.json | 10 +- poetry.lock | 344 +++++++++--------- pyproject.toml | 2 +- src/backend/base/langflow/__main__.py | 27 +- src/backend/base/langflow/api/v1/endpoints.py | 30 +- .../models/GoogleGenerativeAIModel.py | 65 ++-- src/backend/base/langflow/main.py | 39 +- .../base/langflow/services/auth/utils.py | 10 +- src/backend/base/poetry.lock | 11 +- src/backend/base/pyproject.toml | 2 +- src/frontend/src/App.tsx | 7 - .../components/menuBar/index.tsx | 5 +- src/frontend/src/contexts/authContext.tsx | 18 +- tests/test_user.py | 14 +- 17 files changed, 365 insertions(+), 272 deletions(-) create mode 100644 .github/workflows/docs_test.yml diff --git a/.github/workflows/docs_test.yml b/.github/workflows/docs_test.yml new file mode 100644 index 000000000..cc25b56f6 --- /dev/null +++ b/.github/workflows/docs_test.yml @@ -0,0 +1,47 @@ +name: Test Docs Build + +on: + pull_request: + paths: + - "docs/**" + merge_group: + types: [checks_requested] + +env: + NODE_VERSION: "21" + + +jobs: + test-docs-build: + name: Test Docs Build + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + id: setup-node + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Cache Node.js dependencies + uses: actions/cache@v4 + id: npm-cache + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('docs/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install Node.js dependencies + run: | + cd docs + npm install + if: ${{ steps.setup-node.outputs.cache-hit != 'true' }} + + - name: Build Docs + run: | + cd docs + npm run build diff --git a/.github/workflows/python_test.yml b/.github/workflows/python_test.yml index c3c320aad..4846f59fb 100644 --- a/.github/workflows/python_test.yml +++ b/.github/workflows/python_test.yml @@ -50,7 +50,7 @@ jobs: poetry run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only & SERVER_PID=$! # Wait for the server to start - timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) + timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) # Terminate the server kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) sleep 10 # give the server some time to terminate diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b6453075e..97e175cfd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,7 +62,7 @@ jobs: python -m langflow run --host 127.0.0.1 --port 7860 & SERVER_PID=$! # Wait for the server to start - timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) + timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) # Terminate the server kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) sleep 10 # give the server some time to terminate @@ -124,7 +124,7 @@ jobs: python -m langflow run --host 127.0.0.1 --port 7860 & SERVER_PID=$! # Wait for the server to start - timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) + timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) # Terminate the server kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) sleep 10 # give the server some time to terminate diff --git a/.vscode/launch.json b/.vscode/launch.json index a2a38dcba..eaaf23f33 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -34,14 +34,12 @@ "args": [ "run", "--path", - "${workspaceFolder}/src/backend/base/langflow/frontend" + "${workspaceFolder}/src/backend/base/langflow/frontend", + "--env-file", + "${workspaceFolder}/.env" ], "jinja": true, - "justMyCode": false, - "env": { - "LANGFLOW_LOG_LEVEL": "debug" - }, - "envFile": "${workspaceFolder}/.env" + "justMyCode": false }, { "name": "Python: Remote Attach", diff --git a/poetry.lock b/poetry.lock index 5ac1608a9..6773edcab 100644 --- a/poetry.lock +++ b/poetry.lock @@ -368,13 +368,13 @@ files = [ [[package]] name = "bce-python-sdk" -version = "0.9.14" +version = "0.9.17" description = "BCE SDK for python" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,<4,>=2.7" files = [ - {file = "bce_python_sdk-0.9.14-py3-none-any.whl", hash = "sha256:5704aa454151ee608b01ddda7531457433f9b4bb8afbd00706dd368f3b4339a1"}, - {file = "bce_python_sdk-0.9.14.tar.gz", hash = "sha256:7cbd182ec1e21034f10d3cdb812f3171d31908f1a783d6cf643039272942d8e8"}, + {file = "bce_python_sdk-0.9.17-py3-none-any.whl", hash = "sha256:6c5995d60edad3f6771b83ccd79197fc00d88081e3175ca8eecad8a29551ad75"}, + {file = "bce_python_sdk-0.9.17.tar.gz", hash = "sha256:aaece4c590b859ad6bc2d6a04b4a01308ac781ef1d539116b299ec50d62e1ca1"}, ] [package.dependencies] @@ -461,17 +461,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.131" +version = "1.34.132" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.131-py3-none-any.whl", hash = "sha256:05e388cb937e82be70bfd7eb0c84cf8011ff35cf582a593873ac21675268683b"}, - {file = "boto3-1.34.131.tar.gz", hash = "sha256:dab8f72a6c4e62b4fd70da09e08a6b2a65ea2115b27dd63737142005776ef216"}, + {file = "boto3-1.34.132-py3-none-any.whl", hash = "sha256:b5d1681a0d8bf255787c8b37f911d706672d5722c9ace5342cd283a3cdb04820"}, + {file = "boto3-1.34.132.tar.gz", hash = "sha256:3b2964060620f1bbe9574b5f8d3fb2a4e087faacfc6023c24154b184f1b16443"}, ] [package.dependencies] -botocore = ">=1.34.131,<1.35.0" +botocore = ">=1.34.132,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -480,13 +480,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.131" +version = "1.34.132" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.131-py3-none-any.whl", hash = "sha256:13b011d7b206ce00727dcee26548fa3b550db9046d5a0e90ac25a6e6c8fde6ef"}, - {file = "botocore-1.34.131.tar.gz", hash = "sha256:502ddafe1d627fcf1e4c007c86454e5dd011dba7c58bd8e8a5368a79f3e387dc"}, + {file = "botocore-1.34.132-py3-none-any.whl", hash = "sha256:06ef8b4bd3b3cb5a9b9a4273a543b257be3304030978ba51516b576a65156c39"}, + {file = "botocore-1.34.132.tar.gz", hash = "sha256:372a6cfce29e5de9bcf8c95af901d0bc3e27d8aa2295fadee295424f95f43f16"}, ] [package.dependencies] @@ -2562,13 +2562,13 @@ test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", [[package]] name = "google-ai-generativelanguage" -version = "0.6.4" +version = "0.6.5" description = "Google Ai Generativelanguage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-ai-generativelanguage-0.6.4.tar.gz", hash = "sha256:1750848c12af96cb24ae1c3dd05e4bfe24867dc4577009ed03e1042d8421e874"}, - {file = "google_ai_generativelanguage-0.6.4-py3-none-any.whl", hash = "sha256:730e471aa549797118fb1c88421ba1957741433ada575cf5dd08d3aebf903ab1"}, + {file = "google-ai-generativelanguage-0.6.5.tar.gz", hash = "sha256:c4089c277fa4e26722f76ab03ee3039f28be8bf1c9be282948b9583a154c6d79"}, + {file = "google_ai_generativelanguage-0.6.5-py3-none-any.whl", hash = "sha256:236875bb4a6d6ebdba2f12bd9d5e776100fd913402157a47b5e9fb80a13f25a7"}, ] [package.dependencies] @@ -2882,16 +2882,16 @@ testing = ["pytest"] [[package]] name = "google-generativeai" -version = "0.5.4" +version = "0.7.0" description = "Google Generative AI High level API client library and tools." optional = false python-versions = ">=3.9" files = [ - {file = "google_generativeai-0.5.4-py3-none-any.whl", hash = "sha256:036d63ee35e7c8aedceda4f81c390a5102808af09ff3a6e57e27ed0be0708f3c"}, + {file = "google_generativeai-0.7.0-py3-none-any.whl", hash = "sha256:7be4b634afeb8b6bebde1af7271e94d2af84d2d28b5988c7ed9921733c40fe63"}, ] [package.dependencies] -google-ai-generativelanguage = "0.6.4" +google-ai-generativelanguage = "0.6.5" google-api-core = "*" google-api-python-client = "*" google-auth = ">=2.15.0" @@ -3798,72 +3798,72 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jiter" -version = "0.4.2" +version = "0.5.0" description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" files = [ - {file = "jiter-0.4.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c2b003ff58d14f5e182b875acd5177b2367245c19a03be9a2230535d296f7550"}, - {file = "jiter-0.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b48c77c25f094707731cd5bad6b776046846b60a27ee20efc8fadfb10a89415f"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f50ad6b172bde4d45f4d4ea10c49282a337b8bb735afc99763dfa55ea84a743"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95f6001e86f525fbbc9706db2078dc22be078b0950de55b92d37041930f5f940"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16646ef23b62b007de80460d303ebb2d81e355dac9389c787cec87cdd7ffef2f"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b4e847c13b0bf1255c711a92330e7a8cb8b5cdd1e37d7db309627bcdd3367ff"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c536589be60e4c5f2b20fadc4db7e9f55d4c9df3551f29ddf1c4a18dcc9dd54"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3b2763996167830889a854b4ded30bb90897f9b76be78069c50c3ec4540950e"}, - {file = "jiter-0.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:675e8ab98c99495091af6b6e9bf2b6353bcf81f25ab6ce27d36127e315b4505d"}, - {file = "jiter-0.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e48e43d9d999aaf55f53406b8846ff8cbe3e47ee4b9dc37e5a10a65ce760809f"}, - {file = "jiter-0.4.2-cp310-none-win32.whl", hash = "sha256:881b6e67c50bc36acb3570eda693763c8cd77d590940e06fa6d325d0da52ec1b"}, - {file = "jiter-0.4.2-cp310-none-win_amd64.whl", hash = "sha256:bb8f7b43259efc6add0d721ade2953e064b24e2026d26d979bc09ec080844cef"}, - {file = "jiter-0.4.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:24ad336ac47f274fa83f6fbedcabff9d3387c80f67c66b992688e6a8ba2c47e9"}, - {file = "jiter-0.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fc392a220095730afe365ce1516f2f88bb085a2fd29ea191be9c6e3c71713d9a"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1fdc408de36c81460896de0176f2f7b9f3574dcd35693a0b2c00f4ca34c98e4"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c10ad76722ee6a8c820b0db06a793c08b7d679e5201b9563015bd1e06c959a09"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbb46d1e9c82bba87f0cbda38413e49448a7df35b1e55917124bff9f38974a23"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:194e28ef4b5f3b61408cb2ee6b6dcbcdb0c9063d01b92b01345b7605692849f5"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0a447533eccd62748a727e058efa10a8d7cf1de8ffe1a4d705ecb41dad9090"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5f7704d7260bbb88cca3453951af739589132b26e896a3144fa2dae2263716d7"}, - {file = "jiter-0.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:01427458bc9550f2eda09d425755330e7d0eb09adce099577433bebf05d28d59"}, - {file = "jiter-0.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:159b8416879c0053b17c352f70b67b749ef5b2924c6154318ecf71918aab0905"}, - {file = "jiter-0.4.2-cp311-none-win32.whl", hash = "sha256:f2445234acfb79048ce1a0d5d0e181abb9afd9e4a29d8d9988fe26cc5773a81a"}, - {file = "jiter-0.4.2-cp311-none-win_amd64.whl", hash = "sha256:e15a65f233b6b0e5ac10ddf3b97ceb18aa9ffba096259961641d78b4ee321bd5"}, - {file = "jiter-0.4.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d61d59521aea9745447ce50f74d39a16ef74ec9d6477d9350d77e75a3d774ad2"}, - {file = "jiter-0.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eef607dc0acc251923427808dbd017f1998ae3c1a0430a261527aa5cbb3a942"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af6bf39954646e374fc47429c656372ac731a6a26b644158a5a84bcdbed33a47"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f509d23606e476852ee46a2b65b5c4ad3905f17424d9cc19c1dffa1c94ba3c6"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59672774daa44ee140aada0c781c82bee4d9ac5e522966186cfb6b3c217d8a51"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24a0458efac5afeca254cf557b8a654e17013075a69905c78f88d557f129d871"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8860766d1c293e75c1bb4e25b74fa987e3adf199cac3f5f9e6e49c2bebf092f"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a109f3281b72bbf4921fe43db1005c004a38559ca0b6c4985add81777dfe0a44"}, - {file = "jiter-0.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:faa7e667454b77ad2f0ef87db39f4944de759617aadf210ea2b73f26bb24755f"}, - {file = "jiter-0.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3512f8b00cafb6780b427cb6282800d2bf8277161d9c917830661bd4ed1d3528"}, - {file = "jiter-0.4.2-cp312-none-win32.whl", hash = "sha256:853b35d508ee5b66d06630473c1c0b7bb5e29bf4785c9d2202437116c94f7e21"}, - {file = "jiter-0.4.2-cp312-none-win_amd64.whl", hash = "sha256:4a3a8197784278eb8b24cb02c45e1cad67c2ce5b5b758adfb19b87f74bbdff9c"}, - {file = "jiter-0.4.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ca2a4d750aed3154b89f2efb148609fc985fad8db739460797aaf9b478acedda"}, - {file = "jiter-0.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0e6c304b3cc6896256727e1fb8991c7179a345eca8224e201795e9cacf4683b0"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cc34ac708ae1750d077e490321761ec4b9a055b994cbdd1d6fbd37099e4aa7b"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c93383875ab8d2e4f760aaff335b4a12ff32d4f9cf49c4498d657734f611466"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce197ee044add576afca0955b42142dd0312639adb6ebadbdbe4277f2855614f"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a427716813ff65480ca5b5117cfa099f49b49cd38051f8609bd0d5493013ca0"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:479990218353356234669e70fac53e5eb6f739a10db25316171aede2c97d9364"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d35a91ec5ac74cf33234c431505299fa91c0a197c2dbafd47400aca7c69489d4"}, - {file = "jiter-0.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b27189847193708c94ad10ca0d891309342ae882725d2187cf5d2db02bde8d1b"}, - {file = "jiter-0.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:76c255308cd1093fb411a03756b7bb220e48d4a98c30cbc79ed448bf3978e27d"}, - {file = "jiter-0.4.2-cp38-none-win32.whl", hash = "sha256:bb77438060bad49cc251941e6701b31138365c8a0ddaf10cdded2fcc6dd30701"}, - {file = "jiter-0.4.2-cp38-none-win_amd64.whl", hash = "sha256:ce858af19f7ce0d4b51c9f6c0c9d08f1e9dcef1986c5875efd0674a7054292ca"}, - {file = "jiter-0.4.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:6128838a2f357b3921b2a3242d5dc002ae4255ecc8f9f05c20d56d7d2d79c5ad"}, - {file = "jiter-0.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f2420cebb9ba856cb57dcab1d2d8def949b464b0db09c22a4e4dbd52fff7b200"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5d13d8128e853b320e00bb18bd4bb8b136cc0936091dc87633648fc688eb705"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eba5d6e54f149c508ba88677f97d3dc7dd75e9980d234bbac8027ac6db0763a3"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0fad5d64af0bc0545237419bf4150d8de56f0bd217434bdd1a59730327252bef"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d179e7bca89cf5719bd761dd37a341ff0f98199ecaa9c14af09792e47e977cc"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36353caee9f103d8ee7bda077f6400505b0f370e27eabcab33a33d21de12a2a6"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dd146c25bce576ca5db64fc7eccb8862af00f1f0e30108796953f12a53660e4c"}, - {file = "jiter-0.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:14b7c08cadbcd703041c66dc30e24e17de2f340281cac0e69374223ecf153aa4"}, - {file = "jiter-0.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a90f1a8b3d29aea198f8ea2b01148276ced8056e5103f32525266b3d880e65c9"}, - {file = "jiter-0.4.2-cp39-none-win32.whl", hash = "sha256:25b174997c780337b61ae57b1723455eecae9a17a9659044fd3c3b369190063f"}, - {file = "jiter-0.4.2-cp39-none-win_amd64.whl", hash = "sha256:bef62cea18521c5b99368147040c7e560c55098a35c93456f110678a2d34189a"}, - {file = "jiter-0.4.2.tar.gz", hash = "sha256:29b9d44f23f0c05f46d482f4ebf03213ee290d77999525d0975a17f875bf1eea"}, + {file = "jiter-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b599f4e89b3def9a94091e6ee52e1d7ad7bc33e238ebb9c4c63f211d74822c3f"}, + {file = "jiter-0.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a063f71c4b06225543dddadbe09d203dc0c95ba352d8b85f1221173480a71d5"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc0d5b8b3dd12e91dd184b87273f864b363dfabc90ef29a1092d269f18c7e28"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c22541f0b672f4d741382a97c65609332a783501551445ab2df137ada01e019e"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63314832e302cc10d8dfbda0333a384bf4bcfce80d65fe99b0f3c0da8945a91a"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a25fbd8a5a58061e433d6fae6d5298777c0814a8bcefa1e5ecfff20c594bd749"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:503b2c27d87dfff5ab717a8200fbbcf4714516c9d85558048b1fc14d2de7d8dc"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d1f3d27cce923713933a844872d213d244e09b53ec99b7a7fdf73d543529d6d"}, + {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c95980207b3998f2c3b3098f357994d3fd7661121f30669ca7cb945f09510a87"}, + {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:afa66939d834b0ce063f57d9895e8036ffc41c4bd90e4a99631e5f261d9b518e"}, + {file = "jiter-0.5.0-cp310-none-win32.whl", hash = "sha256:f16ca8f10e62f25fd81d5310e852df6649af17824146ca74647a018424ddeccf"}, + {file = "jiter-0.5.0-cp310-none-win_amd64.whl", hash = "sha256:b2950e4798e82dd9176935ef6a55cf6a448b5c71515a556da3f6b811a7844f1e"}, + {file = "jiter-0.5.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4c8e1ed0ef31ad29cae5ea16b9e41529eb50a7fba70600008e9f8de6376d553"}, + {file = "jiter-0.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6f16e21276074a12d8421692515b3fd6d2ea9c94fd0734c39a12960a20e85f3"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5280e68e7740c8c128d3ae5ab63335ce6d1fb6603d3b809637b11713487af9e6"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:583c57fc30cc1fec360e66323aadd7fc3edeec01289bfafc35d3b9dcb29495e4"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26351cc14507bdf466b5f99aba3df3143a59da75799bf64a53a3ad3155ecded9"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829df14d656b3fb87e50ae8b48253a8851c707da9f30d45aacab2aa2ba2d614"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42a4bdcf7307b86cb863b2fb9bb55029b422d8f86276a50487982d99eed7c6e"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04d461ad0aebf696f8da13c99bc1b3e06f66ecf6cfd56254cc402f6385231c06"}, + {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6375923c5f19888c9226582a124b77b622f8fd0018b843c45eeb19d9701c403"}, + {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cec323a853c24fd0472517113768c92ae0be8f8c384ef4441d3632da8baa646"}, + {file = "jiter-0.5.0-cp311-none-win32.whl", hash = "sha256:aa1db0967130b5cab63dfe4d6ff547c88b2a394c3410db64744d491df7f069bb"}, + {file = "jiter-0.5.0-cp311-none-win_amd64.whl", hash = "sha256:aa9d2b85b2ed7dc7697597dcfaac66e63c1b3028652f751c81c65a9f220899ae"}, + {file = "jiter-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9f664e7351604f91dcdd557603c57fc0d551bc65cc0a732fdacbf73ad335049a"}, + {file = "jiter-0.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:044f2f1148b5248ad2c8c3afb43430dccf676c5a5834d2f5089a4e6c5bbd64df"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:702e3520384c88b6e270c55c772d4bd6d7b150608dcc94dea87ceba1b6391248"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:528d742dcde73fad9d63e8242c036ab4a84389a56e04efd854062b660f559544"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf80e5fe6ab582c82f0c3331df27a7e1565e2dcf06265afd5173d809cdbf9ba"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:44dfc9ddfb9b51a5626568ef4e55ada462b7328996294fe4d36de02fce42721f"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c451f7922992751a936b96c5f5b9bb9312243d9b754c34b33d0cb72c84669f4e"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:308fce789a2f093dca1ff91ac391f11a9f99c35369117ad5a5c6c4903e1b3e3a"}, + {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7f5ad4a7c6b0d90776fdefa294f662e8a86871e601309643de30bf94bb93a64e"}, + {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ea189db75f8eca08807d02ae27929e890c7d47599ce3d0a6a5d41f2419ecf338"}, + {file = "jiter-0.5.0-cp312-none-win32.whl", hash = "sha256:e3bbe3910c724b877846186c25fe3c802e105a2c1fc2b57d6688b9f8772026e4"}, + {file = "jiter-0.5.0-cp312-none-win_amd64.whl", hash = "sha256:a586832f70c3f1481732919215f36d41c59ca080fa27a65cf23d9490e75b2ef5"}, + {file = "jiter-0.5.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f04bc2fc50dc77be9d10f73fcc4e39346402ffe21726ff41028f36e179b587e6"}, + {file = "jiter-0.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6f433a4169ad22fcb550b11179bb2b4fd405de9b982601914ef448390b2954f3"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad4a6398c85d3a20067e6c69890ca01f68659da94d74c800298581724e426c7e"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6baa88334e7af3f4d7a5c66c3a63808e5efbc3698a1c57626541ddd22f8e4fbf"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ece0a115c05efca597c6d938f88c9357c843f8c245dbbb53361a1c01afd7148"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:335942557162ad372cc367ffaf93217117401bf930483b4b3ebdb1223dbddfa7"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649b0ee97a6e6da174bffcb3c8c051a5935d7d4f2f52ea1583b5b3e7822fbf14"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4be354c5de82157886ca7f5925dbda369b77344b4b4adf2723079715f823989"}, + {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5206144578831a6de278a38896864ded4ed96af66e1e63ec5dd7f4a1fce38a3a"}, + {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8120c60f8121ac3d6f072b97ef0e71770cc72b3c23084c72c4189428b1b1d3b6"}, + {file = "jiter-0.5.0-cp38-none-win32.whl", hash = "sha256:6f1223f88b6d76b519cb033a4d3687ca157c272ec5d6015c322fc5b3074d8a5e"}, + {file = "jiter-0.5.0-cp38-none-win_amd64.whl", hash = "sha256:c59614b225d9f434ea8fc0d0bec51ef5fa8c83679afedc0433905994fb36d631"}, + {file = "jiter-0.5.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0af3838cfb7e6afee3f00dc66fa24695199e20ba87df26e942820345b0afc566"}, + {file = "jiter-0.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:550b11d669600dbc342364fd4adbe987f14d0bbedaf06feb1b983383dcc4b961"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:489875bf1a0ffb3cb38a727b01e6673f0f2e395b2aad3c9387f94187cb214bbf"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b250ca2594f5599ca82ba7e68785a669b352156260c5362ea1b4e04a0f3e2389"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ea18e01f785c6667ca15407cd6dabbe029d77474d53595a189bdc813347218e"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:462a52be85b53cd9bffd94e2d788a09984274fe6cebb893d6287e1c296d50653"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92cc68b48d50fa472c79c93965e19bd48f40f207cb557a8346daa020d6ba973b"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c834133e59a8521bc87ebcad773608c6fa6ab5c7a022df24a45030826cf10bc"}, + {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab3a71ff31cf2d45cb216dc37af522d335211f3a972d2fe14ea99073de6cb104"}, + {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cccd3af9c48ac500c95e1bcbc498020c87e1781ff0345dd371462d67b76643eb"}, + {file = "jiter-0.5.0-cp39-none-win32.whl", hash = "sha256:368084d8d5c4fc40ff7c3cc513c4f73e02c85f6009217922d0823a48ee7adf61"}, + {file = "jiter-0.5.0-cp39-none-win_amd64.whl", hash = "sha256:ce03f7b4129eb72f1687fa11300fbf677b02990618428934662406d2a76742a1"}, + {file = "jiter-0.5.0.tar.gz", hash = "sha256:1d916ba875bcab5c5f7d927df998c4cb694d27dceddf3392e58beaf10563368a"}, ] [[package]] @@ -4278,40 +4278,40 @@ langchain-core = ">=0.2.7,<0.3.0" [[package]] name = "langchain-google-genai" -version = "1.0.6" +version = "1.0.7" description = "An integration package connecting Google's genai package and LangChain" optional = false python-versions = "<4.0,>=3.9" files = [ - {file = "langchain_google_genai-1.0.6-py3-none-any.whl", hash = "sha256:65188b3c2867efda78e09c29371499ab0d25c6a111b175365fdae2b5be1502e6"}, - {file = "langchain_google_genai-1.0.6.tar.gz", hash = "sha256:7c964117fa385c490b323ee50ab46907229823d3678b80bfacc8fa0a237fb0b9"}, + {file = "langchain_google_genai-1.0.7-py3-none-any.whl", hash = "sha256:8fc03a0b5f635d369d1eec25076921ea7a472a1cb96dbea8e8ff2c2cdce58650"}, + {file = "langchain_google_genai-1.0.7.tar.gz", hash = "sha256:6522da59720ad551867e278d63c053e0fb65fa4fa1d65382aacedca5293930fa"}, ] [package.dependencies] -google-generativeai = ">=0.5.2,<0.6.0" -langchain-core = ">=0.2.2,<0.3" +google-generativeai = ">=0.7.0,<0.8.0" +langchain-core = ">=0.2.9,<0.3" [package.extras] images = ["pillow (>=10.1.0,<11.0.0)"] [[package]] name = "langchain-google-vertexai" -version = "1.0.5" +version = "1.0.6" description = "An integration package connecting Google VertexAI and LangChain" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_google_vertexai-1.0.5-py3-none-any.whl", hash = "sha256:38f4a39bf35927d744d0883907c4d4a59eef059e9b36f28bb5c737c2aae6963b"}, - {file = "langchain_google_vertexai-1.0.5.tar.gz", hash = "sha256:50005dc12ff9d66bbbab9e1ab660574b1584eee3e7b5a647dc8a009a94f0c500"}, + {file = "langchain_google_vertexai-1.0.6-py3-none-any.whl", hash = "sha256:240a9be3ae749335ec9a495502ca8f2bff60a432b8400a21cbd93b415e4d166d"}, + {file = "langchain_google_vertexai-1.0.6.tar.gz", hash = "sha256:000c4cfd0dee73317e1752dfeec76a08c5bf24f7a134d79b9905a720ac886b11"}, ] [package.dependencies] -google-cloud-aiplatform = ">=1.47.0,<2.0.0" -google-cloud-storage = ">=2.14.0,<3.0.0" -langchain-core = ">=0.2.2,<0.3" +google-cloud-aiplatform = ">=1.56.0,<2.0.0" +google-cloud-storage = ">=2.17.0,<3.0.0" +langchain-core = ">=0.2.9,<0.3" [package.extras] -anthropic = ["anthropic[vertexai] (>=0.23.0,<1)"] +anthropic = ["anthropic[vertexai] (>=0.29.0,<1)"] [[package]] name = "langchain-groq" @@ -4442,7 +4442,7 @@ six = "*" [[package]] name = "langflow-base" -version = "0.0.78" +version = "0.0.80" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" @@ -4524,29 +4524,32 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.81" +version = "0.1.82" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.81-py3-none-any.whl", hash = "sha256:3251d823225eef23ee541980b9d9e506367eabbb7f985a086b5d09e8f78ba7e9"}, - {file = "langsmith-0.1.81.tar.gz", hash = "sha256:585ef3a2251380bd2843a664c9a28da4a7d28432e3ee8bcebf291ffb8e1f0af0"}, + {file = "langsmith-0.1.82-py3-none-any.whl", hash = "sha256:9b3653e7d316036b0c60bf0bc3e280662d660f485a4ebd8e5c9d84f9831ae79c"}, + {file = "langsmith-0.1.82.tar.gz", hash = "sha256:c02e2bbc488c10c13b52c69d271eb40bd38da078d37b6ae7ae04a18bd48140be"}, ] [package.dependencies] orjson = ">=3.9.14,<4.0.0" -pydantic = ">=1,<3" +pydantic = [ + {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, + {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, +] requests = ">=2,<3" [[package]] name = "litellm" -version = "1.40.25" +version = "1.40.26" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.40.25-py3-none-any.whl", hash = "sha256:94bff834ca92338223bed474fe614ab30a706681a596e1e38ea60fe8a574a7a8"}, - {file = "litellm-1.40.25.tar.gz", hash = "sha256:437d515274b8cc901d527fbf14ce46599700225f4e1dae2d19b46b446e402b08"}, + {file = "litellm-1.40.26-py3-none-any.whl", hash = "sha256:5daedec00a3a8e32f55b3099190ccd9d550177f6e516823002831e6620ae771c"}, + {file = "litellm-1.40.26.tar.gz", hash = "sha256:4dfd4ca3eb50a62600e60303c4975ba9fe7c52d07882d0d2b6bad2d474d88758"}, ] [package.dependencies] @@ -4590,13 +4593,13 @@ test = ["httpx (>=0.24.1)", "pytest (>=7.4.0)", "scipy (>=1.10)"] [[package]] name = "locust" -version = "2.29.0" +version = "2.29.1" description = "Developer-friendly load testing framework" optional = false python-versions = ">=3.9" files = [ - {file = "locust-2.29.0-py3-none-any.whl", hash = "sha256:aa9d94d3604ed9f2aab3248460d91e55d3de980a821dffdf8658b439b049d03f"}, - {file = "locust-2.29.0.tar.gz", hash = "sha256:649c99ce49d00720a3084c0109547035ad9021222835386599a8b545d31ebe51"}, + {file = "locust-2.29.1-py3-none-any.whl", hash = "sha256:8b15daab44cdf50eef1860a32bb30969423e3795247115e5a37446da3240c6d6"}, + {file = "locust-2.29.1.tar.gz", hash = "sha256:2e0628a59e2689a50cb4735a9a43709e30f2da7ed276c15d877c5325507f44b1"}, ] [package.dependencies] @@ -4615,6 +4618,7 @@ requests = [ {version = ">=2.32.2", markers = "python_version > \"3.11\""}, ] tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.11\""} Werkzeug = ">=2.0.0" [[package]] @@ -5321,38 +5325,38 @@ dill = ">=0.3.8" [[package]] name = "mypy" -version = "1.10.0" +version = "1.10.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] @@ -8093,13 +8097,13 @@ files = [ [[package]] name = "s3transfer" -version = "0.10.1" +version = "0.10.2" description = "An Amazon S3 Transfer Manager" optional = false -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "s3transfer-0.10.1-py3-none-any.whl", hash = "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"}, - {file = "s3transfer-0.10.1.tar.gz", hash = "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19"}, + {file = "s3transfer-0.10.2-py3-none-any.whl", hash = "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"}, + {file = "s3transfer-0.10.2.tar.gz", hash = "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6"}, ] [package.dependencies] @@ -8277,45 +8281,45 @@ tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc ( [[package]] name = "scipy" -version = "1.13.1" +version = "1.14.0" description = "Fundamental algorithms for scientific computing in Python" optional = true -python-versions = ">=3.9" +python-versions = ">=3.10" files = [ - {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, - {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, - {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, - {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, - {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, - {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, - {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, - {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, - {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, - {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, - {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"}, + {file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"}, + {file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"}, + {file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"}, + {file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"}, + {file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"}, + {file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"}, + {file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"}, ] [package.dependencies] -numpy = ">=1.22.4,<2.3" +numpy = ">=1.23.5,<2.3" [package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] -test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "sentence-transformers" @@ -8395,13 +8399,13 @@ tornado = ["tornado (>=5)"] [[package]] name = "setuptools" -version = "70.1.0" +version = "70.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.0-py3-none-any.whl", hash = "sha256:d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267"}, - {file = "setuptools-70.1.0.tar.gz", hash = "sha256:01a1e793faa5bd89abc851fa15d0a0db26f160890c7102cd8dce643e886b47f5"}, + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, ] [package.extras] @@ -9391,13 +9395,13 @@ urllib3 = ">=2" [[package]] name = "types-setuptools" -version = "70.0.0.20240524" +version = "70.1.0.20240625" description = "Typing stubs for setuptools" optional = false python-versions = ">=3.8" files = [ - {file = "types-setuptools-70.0.0.20240524.tar.gz", hash = "sha256:e31fee7b9d15ef53980526579ac6089b3ae51a005a281acf97178e90ac71aff6"}, - {file = "types_setuptools-70.0.0.20240524-py3-none-any.whl", hash = "sha256:8f5379b9948682d72a9ab531fbe52932e84c4f38deda570255f9bae3edd766bc"}, + {file = "types-setuptools-70.1.0.20240625.tar.gz", hash = "sha256:eb7175c9a304de4de9f4dfd0f299c754ac94cd9e30a262fbb5ff3047a0a6c517"}, + {file = "types_setuptools-70.1.0.20240625-py3-none-any.whl", hash = "sha256:181986729bdae9fa7efc7d37f1578361739e35dd6ec456d37de8e8f3bd2be1ef"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 98d00485b..8ffb4ccf5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.3" +version = "1.0.4" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/langflow/__main__.py b/src/backend/base/langflow/__main__.py index 730d31ea7..256b614c2 100644 --- a/src/backend/base/langflow/__main__.py +++ b/src/backend/base/langflow/__main__.py @@ -4,12 +4,12 @@ import sys import time import warnings from pathlib import Path -from typing import Optional +from typing import Any, Callable, Optional import click import httpx import typer -from dotenv import load_dotenv +from dotenv import dotenv_values, load_dotenv from multiprocess import Process, cpu_count # type: ignore from packaging import version as pkg_version from rich import box @@ -130,6 +130,29 @@ def run( if env_file: load_dotenv(env_file, override=True) + env_vars = dotenv_values(env_file) + + # Define a mapping of environment variables to their corresponding variables and types + env_var_mapping: dict[str, tuple[str, type | Callable[[Any], bool]]] = { + "LANGFLOW_HOST": ("host", str), + "LANGFLOW_PORT": ("port", int), + "LANGFLOW_WORKERS": ("workers", int), + "LANGFLOW_WORKER_TIMEOUT": ("timeout", int), + "LANGFLOW_COMPONENTS_PATH": ("components_path", Path), + "LANGFLOW_LOG_LEVEL": ("log_level", str), + "LANGFLOW_LOG_FILE": ("log_file", Path), + "LANGFLOW_LANGCHAIN_CACHE": ("cache", str), + "LANGFLOW_FRONTEND_PATH": ("path", str), + "LANGFLOW_OPEN_BROWSER": ("open_browser", lambda x: x.lower() == "true"), + "LANGFLOW_REMOVE_API_KEYS": ("remove_api_keys", lambda x: x.lower() == "true"), + "LANGFLOW_BACKEND_ONLY": ("backend_only", lambda x: x.lower() == "true"), + "LANGFLOW_STORE": ("store", lambda x: x.lower() == "true"), + } + + # Update variables based on environment variables + for env_var, (var_name, var_type) in env_var_mapping.items(): + if env_var in env_vars: + locals()[var_name] = var_type(env_vars[env_var]) update_settings( dev=dev, diff --git a/src/backend/base/langflow/api/v1/endpoints.py b/src/backend/base/langflow/api/v1/endpoints.py index e5c648d1f..d8b5e9da8 100644 --- a/src/backend/base/langflow/api/v1/endpoints.py +++ b/src/backend/base/langflow/api/v1/endpoints.py @@ -116,11 +116,29 @@ async def simple_run_flow( return RunResponse(outputs=task_result, session_id=session_id) except sa.exc.StatementError as exc: - # StatementError('(builtins.ValueError) badly formed hexadecimal UUID string') - if "badly formed hexadecimal UUID string" in str(exc): - logger.error(f"Flow ID {flow_id_str} is not a valid UUID") - # This means the Flow ID is not a valid UUID which means it can't find the flow - raise ValueError(str(exc)) from exc + raise ValueError(str(exc)) from exc + + +async def simple_run_flow_task( + flow: Flow, + input_request: SimplifiedAPIRequest, + stream: bool = False, + api_key_user: Optional[User] = None, +): + """ + Run a flow task as a BackgroundTask, therefore it should not throw exceptions. + """ + try: + result = await simple_run_flow( + flow=flow, + input_request=input_request, + stream=stream, + api_key_user=api_key_user, + ) + return result + + except Exception as exc: + logger.exception(f"Error running flow {flow.id} task: {exc}") @router.post("/run/{flow_id_or_name}", response_model=RunResponse, response_model_exclude_none=True) @@ -266,7 +284,7 @@ async def webhook_run_flow( ) logger.debug("Starting background task") background_tasks.add_task( # type: ignore - simple_run_flow, + simple_run_flow_task, flow=flow, input_request=input_request, ) diff --git a/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py b/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py index 377e307a9..d4e75e54b 100644 --- a/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py +++ b/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py @@ -3,44 +3,40 @@ from pydantic.v1 import SecretStr from langflow.base.constants import STREAM_INFO_TEXT from langflow.base.models.model import LCModelComponent from langflow.field_typing import LanguageModel -from langflow.io import BoolInput, DropdownInput, FloatInput, IntInput, MessageInput, Output, SecretStrInput, StrInput +from langflow.inputs import ( + BoolInput, + DropdownInput, + FloatInput, + IntInput, + MessageInput, + SecretStrInput, + StrInput, +) class GoogleGenerativeAIComponent(LCModelComponent): - display_name: str = "Google Generative AI" - description: str = "Generate text using Google Generative AI." + display_name = "Google Generative AI" + description = "Generate text using Google Generative AI." icon = "GoogleGenerativeAI" inputs = [ - SecretStrInput( - name="google_api_key", - display_name="Google API Key", - info="The Google API Key to use for the Google Generative AI.", + MessageInput(name="input_value", display_name="Input"), + IntInput( + name="max_output_tokens", + display_name="Max Output Tokens", + info="The maximum number of tokens to generate.", ), DropdownInput( name="model", display_name="Model", info="The name of the model to use.", - options=["gemini-1.5-pro", "gemini-1.5-flash"], + options=["gemini-1.5-pro", "gemini-1.5-flash", "gemini-1.0-pro", "gemini-1.0-pro-vision"], value="gemini-1.5-pro", ), - IntInput( - name="max_output_tokens", - display_name="Max Output Tokens", - info="The maximum number of tokens to generate.", - advanced=True, - ), - FloatInput( - name="temperature", - display_name="Temperature", - info="Run inference with this temperature. Must by in the closed interval [0.0, 1.0].", - value=0.1, - ), - IntInput( - name="top_k", - display_name="Top K", - info="Decode using top-k sampling: consider the set of top_k most probable tokens. Must be positive.", - advanced=True, + SecretStrInput( + name="google_api_key", + display_name="Google API Key", + info="The Google API Key to use for the Google Generative AI.", ), FloatInput( name="top_p", @@ -48,29 +44,26 @@ class GoogleGenerativeAIComponent(LCModelComponent): info="The maximum cumulative probability of tokens to consider when sampling.", advanced=True, ), + FloatInput(name="temperature", display_name="Temperature", value=0.1), + BoolInput(name="stream", display_name="Stream", info=STREAM_INFO_TEXT, advanced=True), IntInput( name="n", display_name="N", info="Number of chat completions to generate for each prompt. Note that the API may not return the full n completions if duplicates are generated.", advanced=True, ), - MessageInput( - name="input_value", - display_name="Input", - info="The input to the model.", - input_types=["Text", "Data", "Prompt"], - ), - BoolInput(name="stream", display_name="Stream", info=STREAM_INFO_TEXT, advanced=True), StrInput( name="system_message", display_name="System Message", info="System message to pass to the model.", advanced=True, ), - ] - outputs = [ - Output(display_name="Text", name="text_output", method="text_response"), - Output(display_name="Language Model", name="model_output", method="build_model"), + IntInput( + name="top_k", + display_name="Top K", + info="Decode using top-k sampling: consider the set of top_k most probable tokens. Must be positive.", + advanced=True, + ), ] def build_model(self) -> LanguageModel: diff --git a/src/backend/base/langflow/main.py b/src/backend/base/langflow/main.py index 085d72710..5eab2f331 100644 --- a/src/backend/base/langflow/main.py +++ b/src/backend/base/langflow/main.py @@ -37,28 +37,26 @@ class RequestCancelledMiddleware(BaseHTTPMiddleware): super().__init__(app) async def dispatch(self, request: Request, call_next): - queue: asyncio.Queue = asyncio.Queue() - - async def message_poller(sentinel, handler_task, request): - nonlocal queue - while True: - message = await request.receive() - if message["type"] == "http.disconnect": - handler_task.cancel() - return sentinel # Break the loop - - # Puts the message in the queue - await queue.put(message) - sentinel = object() - handler_task = asyncio.create_task(call_next(request)) - asyncio.create_task(message_poller(sentinel, handler_task, request)) - try: - response = await handler_task - return response - except asyncio.CancelledError: + async def cancel_handler(): + while True: + if await request.is_disconnected(): + return sentinel + await asyncio.sleep(0.1) + + handler_task = asyncio.create_task(call_next(request)) + cancel_task = asyncio.create_task(cancel_handler()) + + done, pending = await asyncio.wait([handler_task, cancel_task], return_when=asyncio.FIRST_COMPLETED) + + for task in pending: + task.cancel() + + if cancel_task in done: return Response("Request was cancelled", status_code=499) + else: + return await handler_task class JavaScriptMIMETypeMiddleware(BaseHTTPMiddleware): @@ -126,7 +124,8 @@ def create_app(): allow_headers=["*"], ) app.add_middleware(JavaScriptMIMETypeMiddleware) - app.add_middleware(RequestCancelledMiddleware) + # ! Deactivating this until we find a better solution + # app.add_middleware(RequestCancelledMiddleware) @app.middleware("http") async def flatten_query_string_lists(request: Request, call_next): diff --git a/src/backend/base/langflow/services/auth/utils.py b/src/backend/base/langflow/services/auth/utils.py index b0a35e474..4c2fdbfb4 100644 --- a/src/backend/base/langflow/services/auth/utils.py +++ b/src/backend/base/langflow/services/auth/utils.py @@ -164,15 +164,15 @@ async def get_current_user_for_websocket( def get_current_active_user(current_user: Annotated[User, Depends(get_current_user)]): if not current_user.is_active: - raise HTTPException(status_code=400, detail="Inactive user") + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive user") return current_user def get_current_active_superuser(current_user: Annotated[User, Depends(get_current_user)]) -> User: if not current_user.is_active: - raise HTTPException(status_code=401, detail="Inactive user") + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive user") if not current_user.is_superuser: - raise HTTPException(status_code=400, detail="The user doesn't have enough privileges") + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="The user doesn't have enough privileges") return current_user @@ -324,8 +324,8 @@ def authenticate_user(username: str, password: str, db: Session = Depends(get_se if not user.is_active: if not user.last_login_at: - raise HTTPException(status_code=400, detail="Waiting for approval") - raise HTTPException(status_code=400, detail="Inactive user") + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Waiting for approval") + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive user") return user if verify_password(password, user.password) else None diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 379821ebf..07d7472cf 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -1281,18 +1281,21 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langsmith" -version = "0.1.81" +version = "0.1.82" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.81-py3-none-any.whl", hash = "sha256:3251d823225eef23ee541980b9d9e506367eabbb7f985a086b5d09e8f78ba7e9"}, - {file = "langsmith-0.1.81.tar.gz", hash = "sha256:585ef3a2251380bd2843a664c9a28da4a7d28432e3ee8bcebf291ffb8e1f0af0"}, + {file = "langsmith-0.1.82-py3-none-any.whl", hash = "sha256:9b3653e7d316036b0c60bf0bc3e280662d660f485a4ebd8e5c9d84f9831ae79c"}, + {file = "langsmith-0.1.82.tar.gz", hash = "sha256:c02e2bbc488c10c13b52c69d271eb40bd38da078d37b6ae7ae04a18bd48140be"}, ] [package.dependencies] orjson = ">=3.9.14,<4.0.0" -pydantic = ">=1,<3" +pydantic = [ + {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, + {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, +] requests = ">=2,<3" [[package]] diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index ee8072a05..100bcbd2b 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow-base" -version = "0.0.79" +version = "0.0.80" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 1c8274e63..1a7178248 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -103,13 +103,6 @@ export default function App() { if (isAuthenticated) { try { await setupAxiosDefaults(); - - const res = await getGlobalVariables(); - setGlobalVariables(res); - - checkHasStore(); - fetchApiData(); - resolve(); } catch (error) { console.error("Failed to fetch data:", error); diff --git a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx index ba3b0e9ad..7376bfc4f 100644 --- a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx +++ b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx @@ -218,7 +218,8 @@ export const MenuBar = ({}: {}): JSX.Element => { />
{printByBuildStatus()}
- + */} )} diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index bd5c2d02c..cfdbdfb4f 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -1,9 +1,15 @@ import { createContext, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import Cookies from "universal-cookie"; -import { getLoggedUser, requestLogout } from "../controllers/API"; +import { + getGlobalVariables, + getLoggedUser, + requestLogout, +} from "../controllers/API"; import useAlertStore from "../stores/alertStore"; import { useFolderStore } from "../stores/foldersStore"; +import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVariables"; +import { useStoreStore } from "../stores/storeStore"; import { Users } from "../types/api"; import { AuthContextType } from "../types/contexts/auth"; @@ -45,6 +51,11 @@ export function AuthProvider({ children }): React.ReactElement { ); const getFoldersApi = useFolderStore((state) => state.getFoldersApi); + const setGlobalVariables = useGlobalVariablesStore( + (state) => state.setGlobalVariables, + ); + const checkHasStore = useStoreStore((state) => state.checkHasStore); + const fetchApiData = useStoreStore((state) => state.fetchApiData); useEffect(() => { const storedAccessToken = cookies.get("access_token_lf"); @@ -66,8 +77,11 @@ export function AuthProvider({ children }): React.ReactElement { setUserData(user); const isSuperUser = user!.is_superuser; setIsAdmin(isSuperUser); - getFoldersApi(true, true); + const res = await getGlobalVariables(); + setGlobalVariables(res); + checkHasStore(); + fetchApiData(); }) .catch((error) => { setLoading(false); diff --git a/tests/test_user.py b/tests/test_user.py index cd1cf9165..86d4b1865 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -75,15 +75,15 @@ def test_user_waiting_for_approval( def test_deactivated_user_cannot_login(client, deactivated_user): login_data = {"username": deactivated_user.username, "password": "testpassword"} response = client.post("/api/v1/login", data=login_data) - assert response.status_code == 400, response.json() - assert response.json()["detail"] == "Inactive user" + assert response.status_code == 401, response.json() + assert response.json()["detail"] == "Inactive user", response.text def test_deactivated_user_cannot_access(client, deactivated_user, logged_in_headers): # Assuming the headers for deactivated_user response = client.get("/api/v1/users", headers=logged_in_headers) - assert response.status_code == 400, response.json() - assert response.json()["detail"] == "The user doesn't have enough privileges" + assert response.status_code == 403, response.json() + assert response.json()["detail"] == "The user doesn't have enough privileges", response.text def test_data_consistency_after_update(client, active_user, logged_in_headers, super_user_headers): @@ -124,7 +124,7 @@ def test_inactive_user(client): login_data = {"username": "inactiveuser", "password": "testpassword"} response = client.post("/api/v1/login", data=login_data) - assert response.status_code == 400 + assert response.status_code == 401 assert response.json()["detail"] == "Inactive user" @@ -154,7 +154,7 @@ def test_read_all_users(client, super_user_headers): def test_normal_user_cant_read_all_users(client, logged_in_headers): response = client.get("/api/v1/users", headers=logged_in_headers) - assert response.status_code == 400, response.json() + assert response.status_code == 403, response.json() assert response.json() == {"detail": "The user doesn't have enough privileges"} @@ -228,5 +228,5 @@ def test_delete_user_wrong_id(client, test_user, super_user_headers): def test_normal_user_cant_delete_user(client, test_user, logged_in_headers): user_id = test_user["id"] response = client.delete(f"/api/v1/users/{user_id}", headers=logged_in_headers) - assert response.status_code == 400 + assert response.status_code == 403 assert response.json() == {"detail": "The user doesn't have enough privileges"} From c8d37c38b4c29b977b5cdf0e7c3269b5a278a347 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Mon, 24 Jun 2024 17:33:20 -0300 Subject: [PATCH 03/12] fix fetch data to work even with autologin true --- src/frontend/src/contexts/authContext.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index cfdbdfb4f..ab845963a 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -12,6 +12,8 @@ import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVa import { useStoreStore } from "../stores/storeStore"; import { Users } from "../types/api"; import { AuthContextType } from "../types/contexts/auth"; +import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVariables"; +import { useStoreStore } from "../stores/storeStore"; const initialValue: AuthContextType = { isAdmin: false, From f954295731d6f1621b495eb271a3725283ca4d4f Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Mon, 24 Jun 2024 17:34:03 -0300 Subject: [PATCH 04/12] format code --- src/frontend/src/contexts/authContext.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index ab845963a..50a0cf4e7 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -14,6 +14,8 @@ import { Users } from "../types/api"; import { AuthContextType } from "../types/contexts/auth"; import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVariables"; import { useStoreStore } from "../stores/storeStore"; +import { Users } from "../types/api"; +import { AuthContextType } from "../types/contexts/auth"; const initialValue: AuthContextType = { isAdmin: false, From 2fe2024a58511dbab17a340a317cb0b0f344bec0 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com> Date: Tue, 25 Jun 2024 13:21:44 -0300 Subject: [PATCH 05/12] Fix lint error version of tailwind css plugin (#2323) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⬆️ (package.json): update prettier-plugin-tailwindcss to version 0.6.5 ♻️ (package.json): reorder @types/lodash dependency for consistency Co-authored-by: Gabriel Luiz Freitas Almeida --- src/frontend/package-lock.json | 2 +- src/frontend/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index d6b9d3b74..811237487 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -102,7 +102,7 @@ "postcss": "^8.4.38", "prettier": "^3.3.2", "prettier-plugin-organize-imports": "^3.2.4", - "prettier-plugin-tailwindcss": "^0.6.4", + "prettier-plugin-tailwindcss": "^0.6.5", "simple-git-hooks": "^2.11.1", "tailwindcss": "^3.4.4", "tailwindcss-dotted-background": "^1.1.0", diff --git a/src/frontend/package.json b/src/frontend/package.json index a4b10db6c..219b5c7d4 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -113,18 +113,18 @@ "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", + "@types/lodash": "4.17.5", "@types/node": "^20.14.2", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/uuid": "^9.0.8", - "@types/lodash": "4.17.5", "@vitejs/plugin-react-swc": "^3.7.0", "autoprefixer": "^10.4.19", "eslint": "^9.5.0", "postcss": "^8.4.38", "prettier": "^3.3.2", "prettier-plugin-organize-imports": "^3.2.4", - "prettier-plugin-tailwindcss": "^0.6.4", + "prettier-plugin-tailwindcss": "^0.6.5", "simple-git-hooks": "^2.11.1", "tailwindcss": "^3.4.4", "tailwindcss-dotted-background": "^1.1.0", From 4077135ba7c302b7e2a50402a7cb911c1e56defc Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com> Date: Tue, 25 Jun 2024 13:23:11 -0300 Subject: [PATCH 06/12] Updating Tests and Fixing Related Bugs (#2319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 (tableNodeCellRender): fix templateValue check to use Object.keys ✨ (textAreaComponent): add Case component for conditional rendering ♻️ (editNodeModal): remove commented-out useEffect code ✅ (basicExamples.spec): update test selectors and increase timeout values ✅ (filterEdge.spec.ts): update test IDs to match new naming conventions ✅ (inputListComponent.spec.ts, intComponent.spec.ts): update test IDs and streamline test steps for consistency and clarity ✅ (keyPairListComponent.spec.ts): update test ID for model element ✅ (keyPairListComponent.spec.ts): add steps to test editing model options and saving changes * ✅ (tests): update end-to-end tests for chat input/output and modal components - Update test selectors for better accuracy - Add keyboard interaction in chatInputOutputUser.spec.ts - Improve file handling in chat image upload test - Refine prompt modal component tests for better validation - Enhance twoEdges.spec.ts with additional view controls * ♻️ (tests): refactor repeated click actions into reusable function in e2e tests * ✅ (tests): replace waitForTimeout with waitForSelector in end-to-end tests * ✅ (typescript_test.yml): add --debug flag to Playwright test command for better debugging * ✅ (typescript_test.yml): enable trace option in Playwright tests for better debugging * ✅ (typescript_test.yml): reduce Playwright test workers from 2 to 1 to improve stability ✅ (textInputOutput.spec.ts): add waitFor visibility checks to ensure elements are visible before interaction * ✅ (tests): update paths for test assets to correct locations ✅ (tests): add waitForSelector to ensure elements are loaded before interaction * ✅ (typescript_test.yml): increase Playwright workers from 1 to 2 to speed up tests ✅ (chatInputOutputUser.spec.ts): increase timeout for AI response to 100000ms ✅ (chatInputOutputUser.spec.ts): correct file path for image upload test ✅ (deleteComponentFlows.spec.ts): change waitFor to target last checkbox-component ✅ (store.spec.ts): increase timeout for share button to 100000ms * 🐛 (flows.py): ensure flow names are unique by appending a number if necessary * Apply Ruff formatting --------- Co-authored-by: Gabriel Luiz Freitas Almeida Co-authored-by: Cristhianzl --- .github/workflows/typescript_test.yml | 2 +- src/backend/base/langflow/api/v1/flows.py | 17 +++ .../components/tableNodeCellRender/index.tsx | 2 +- .../components/textAreaComponent/index.tsx | 68 ++++++---- .../src/modals/editNodeModal/index.tsx | 6 - .../tests/end-to-end/basicExamples.spec.ts | 30 ++-- .../tests/end-to-end/chatInputOutput.spec.ts | 2 +- .../end-to-end/chatInputOutputUser.spec.ts | 59 +++++--- .../end-to-end/codeAreaModalComponent.spec.ts | 12 +- .../end-to-end/deleteComponentFlows.spec.ts | 13 ++ .../tests/end-to-end/dragAndDrop.spec.ts | 2 +- .../tests/end-to-end/filterEdge.spec.ts | 91 ++++++++----- src/frontend/tests/end-to-end/folders.spec.ts | 2 +- .../tests/end-to-end/generalBugs.spec.ts | 5 + .../end-to-end/inputListComponent.spec.ts | 128 +++++++----------- .../tests/end-to-end/intComponent.spec.ts | 4 +- .../end-to-end/keyPairListComponent.spec.ts | 10 +- .../end-to-end/promptModalComponent.spec.ts | 27 +++- .../tests/end-to-end/saveComponents.spec.ts | 2 +- src/frontend/tests/end-to-end/store.spec.ts | 4 + .../end-to-end/textAreaModalComponent.spec.ts | 13 +- .../tests/end-to-end/textInputOutput.spec.ts | 50 ++++++- .../tests/end-to-end/toggleComponent.spec.ts | 12 +- .../tests/end-to-end/tweaks_test.spec.ts | 8 +- .../tests/end-to-end/twoEdges.spec.ts | 17 ++- .../tests/end-to-end/userSettings.spec.ts | 17 ++- 26 files changed, 381 insertions(+), 222 deletions(-) diff --git a/.github/workflows/typescript_test.yml b/.github/workflows/typescript_test.yml index be081bec6..8fd809020 100644 --- a/.github/workflows/typescript_test.yml +++ b/.github/workflows/typescript_test.yml @@ -88,7 +88,7 @@ jobs: - name: Run Playwright Tests run: | cd src/frontend - npx playwright test --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2 + npx playwright test --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2 - name: Upload blob report to GitHub Actions Artifacts if: always() diff --git a/src/backend/base/langflow/api/v1/flows.py b/src/backend/base/langflow/api/v1/flows.py index 800e2c088..d735a314b 100644 --- a/src/backend/base/langflow/api/v1/flows.py +++ b/src/backend/base/langflow/api/v1/flows.py @@ -209,6 +209,23 @@ def update_flow( webhook_component = get_webhook_component_in_flow(db_flow.data) db_flow.webhook = webhook_component is not None db_flow.updated_at = datetime.now(timezone.utc) + + # First check if the flow.name is unique + # there might be flows with name like: "MyFlow", "MyFlow (1)", "MyFlow (2)" + # so we need to check if the name is unique with `like` operator + # if we find a flow with the same name, we add a number to the end of the name + # based on the highest number found + flow_from_db = session.exec(select(Flow).where(Flow.id == flow_id, Flow.user_id == current_user.id)).first() + if flow_from_db: + flows = session.exec( + select(Flow).where(Flow.name.like(f"{flow.name} (%")).where(Flow.user_id == current_user.id) # type: ignore + ).all() + if flows: + numbers = [int(flow.name.split("(")[1].split(")")[0]) for flow in flows] + flow.name = f"{flow.name} ({max(numbers) + 1})" + else: + flow.name = f"{flow.name} (1)" + if db_flow.folder_id is None: default_folder = session.exec(select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME)).first() if default_folder: diff --git a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx index b55788134..d0c3d4e53 100644 --- a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx +++ b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx @@ -153,7 +153,7 @@ export default function TableNodeCellRender({ disabled={disabled} editNode={true} value={ - templateValue?.length === 0 || !templateValue + Object.keys(templateValue)?.length === 0 || !templateValue ? [{ "": "" }] : convertObjToArray(templateValue, templateData.type) } diff --git a/src/frontend/src/components/textAreaComponent/index.tsx b/src/frontend/src/components/textAreaComponent/index.tsx index ce42437d7..18a7f5b40 100644 --- a/src/frontend/src/components/textAreaComponent/index.tsx +++ b/src/frontend/src/components/textAreaComponent/index.tsx @@ -2,6 +2,7 @@ import { useEffect } from "react"; import { EDIT_TEXT_MODAL_TITLE } from "../../constants/constants"; import { TypeModal } from "../../constants/enums"; import GenericModal from "../../modals/genericModal"; +import { Case } from "../../shared/components/caseComponent"; import { TextAreaComponentType } from "../../types/components"; import IconComponent from "../genericIconComponent"; import { Button } from "../ui/button"; @@ -24,29 +25,31 @@ export default function TextAreaComponent({ return (
- { - onChange(event.target.value); - }} - /> -
- + { - onChange(value); - }} disabled={disabled} - > - {!editNode && ( + className={editNode ? "input-edit-node w-full" : "w-full"} + placeholder={"Type something..."} + onChange={(event) => { + onChange(event.target.value); + }} + /> + + { + onChange(value); + }} + disabled={disabled} + > + {!editNode ? ( +
- )} - -
+
+ ) : ( + + )} +
); diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx index cb6f82f59..f4a368fa6 100644 --- a/src/frontend/src/modals/editNodeModal/index.tsx +++ b/src/frontend/src/modals/editNodeModal/index.tsx @@ -65,12 +65,6 @@ const EditNodeModal = forwardRef( } }, [gridApi, open]); - // useEffect(() => { - // return () => { - // setOpenWDoubleClick(false); - // }; - // }, []); - return ( diff --git a/src/frontend/tests/end-to-end/basicExamples.spec.ts b/src/frontend/tests/end-to-end/basicExamples.spec.ts index e103fff30..c5f80c362 100644 --- a/src/frontend/tests/end-to-end/basicExamples.spec.ts +++ b/src/frontend/tests/end-to-end/basicExamples.spec.ts @@ -270,12 +270,12 @@ test("Blog Writer", async ({ page }) => { "https://www.natgeokids.com/uk/discover/animals/sea-life/turtle-facts/", ); await page - .getByTestId("input-list-input_urls-0") - .nth(1) + .getByTestId("input-list-input_urls-1") + .nth(0) .fill("https://www.originaldiving.com/blog/top-ten-turtle-facts"); await page - .getByTestId("textarea-input_value") + .getByTestId("popover-anchor-input-input_value") .nth(0) .fill( "Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.", @@ -284,7 +284,7 @@ test("Blog Writer", async ({ page }) => { await page.getByTestId("button_run_chat output").click(); await page.waitForTimeout(5000); await page.getByText("built successfully").last().click({ - timeout: 15000, + timeout: 30000, }); await page.getByText("Playground", { exact: true }).click(); @@ -403,17 +403,14 @@ test("Vector Store RAG", async ({ page }) => { await page.getByText("test_file.txt").isVisible(); await page.waitForTimeout(2000); - await page.getByTestId("button_run_astra db vector store").first().click(); - await page - .getByText("Astra DB Vector Store built successfully") - .last() - .click({ - timeout: 15000, - }); + await page.getByTestId("button_run_astra db").first().click(); + await page.getByText("built successfully").last().click({ + timeout: 30000, + }); await page.getByTestId("button_run_chat output").click(); await page.getByText("built successfully").last().click({ - timeout: 15000, + timeout: 30000, }); await page.getByText("Playground", { exact: true }).click(); @@ -427,15 +424,6 @@ test("Vector Store RAG", async ({ page }) => { .last() .isVisible(); - await page.getByText("Extracted Chunks", { exact: true }).last().click(); - - const inputChunksValues = await page.getByPlaceholder("Empty").inputValue(); - expect(inputChunksValues).toBe( - "this is a test file---this is a test file---this is a test file---this is a test file", - ); - - await page.getByTestId("icon-ExternalLink").last().click(); - await page.getByPlaceholder("Send a message...").last().isHidden(); await page.getByText("Memories", { exact: true }).last().click(); await page.getByText("Default Session").last().click(); diff --git a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts index e71178040..e1adf3d88 100644 --- a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts +++ b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts @@ -23,7 +23,7 @@ test("chat_io_teste", async ({ page }) => { } const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/ChatTest.json", + "tests/end-to-end/assets/ChatTest.json", "utf-8", ); diff --git a/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts b/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts index 4de3c49e5..524312bb3 100644 --- a/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts +++ b/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts @@ -48,14 +48,21 @@ test("user must interact with chat with Input/Output", async ({ page }) => { await page.getByPlaceholder("Send a message...").fill("Hello, how are you?"); await page.getByTestId("icon-LucideSend").click(); let valueUser = await page.getByTestId("sender_name_user").textContent(); + + await page.waitForSelector('[data-testid="sender_name_ai"]', { + timeout: 100000, + }); + let valueAI = await page.getByTestId("sender_name_ai").textContent(); expect(valueUser).toBe("User"); expect(valueAI).toBe("AI"); + await page.keyboard.press("Escape"); + await page .getByTestId("textarea-input_value") - .nth(1) + .nth(0) .fill( "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!", ); @@ -73,11 +80,11 @@ test("user must interact with chat with Input/Output", async ({ page }) => { await page.getByText("Save Changes", { exact: true }).click(); await page - .getByTestId("textarea-sender_name") + .getByTestId("popover-anchor-input-sender_name") .nth(1) .fill("TestSenderNameUser"); await page - .getByTestId("textarea-sender_name") + .getByTestId("popover-anchor-input-sender_name") .nth(0) .fill("TestSenderNameAI"); @@ -150,6 +157,10 @@ test("user must be able to see output inspection", async ({ page }) => { await page.waitForTimeout(5000); + await page.waitForSelector('[data-testid="icon-ScanEye"]', { + timeout: 30000, + }); + await page.getByTestId("icon-ScanEye").nth(4).click(); await page.getByText("Sender", { exact: true }).isVisible(); @@ -206,32 +217,46 @@ test("user must be able to send an image on chat", async ({ page }) => { await page.getByText("Playground", { exact: true }).click(); - const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/chain.png", - "utf-8", + // Read the image file as a binary string + const filePath = "tests/end-to-end/assets/chain.png"; + const fileContent = readFileSync(filePath, "base64"); + + // Create the DataTransfer and File objects within the browser context + const dataTransfer = await page.evaluateHandle( + ({ fileContent }) => { + const dt = new DataTransfer(); + const byteCharacters = atob(fileContent); + const byteNumbers = new Array(byteCharacters.length); + for (let i = 0; i < byteCharacters.length; i++) { + byteNumbers[i] = byteCharacters.charCodeAt(i); + } + const byteArray = new Uint8Array(byteNumbers); + const file = new File([byteArray], "chain.png", { type: "image/png" }); + dt.items.add(file); + return dt; + }, + { fileContent }, ); - // Create the DataTransfer and File - const dataTransfer = await page.evaluateHandle((data) => { - const dt = new DataTransfer(); - // Convert the buffer to a hex array - const file = new File([data], "chain.png", { - type: "application/json", - }); - dt.items.add(file); - return dt; - }, jsonContent); - + // Locate the target element const element = await page.getByPlaceholder("Send a message..."); + // Dispatch the drop event on the target element await element.dispatchEvent("drop", { dataTransfer }); + await page.waitForTimeout(4000); + await page.getByText("chain.png").isVisible(); await page.getByTestId("icon-LucideSend").click(); await page.waitForTimeout(2000); await page.getByText("chain.png").isVisible(); await page.getByText("Close", { exact: true }).click(); + + await page.waitForSelector('[data-testid="icon-ScanEye"]', { + timeout: 30000, + }); + await page.getByTestId("icon-ScanEye").nth(4).click(); await page.getByText("Restart").isHidden(); }); diff --git a/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts b/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts index 6d9ac2d02..044065d18 100644 --- a/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts +++ b/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts @@ -31,7 +31,7 @@ test("CodeAreaModalComponent", async ({ page }) => { await page.waitForTimeout(1000); await page - .getByTestId("experimentalPython Function") + .getByTestId("prototypesPython Function") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); await page.mouse.down(); @@ -65,19 +65,9 @@ class PythonFunctionComponent(CustomComponent): await page.locator("textarea").fill(wCode); await page.locator('//*[@id="checkAndSaveBtn"]').click(); await page.waitForTimeout(1000); - // expect( - // await page.getByText("invalid syntax (, line 1)").isVisible() - // ).toBeTruthy(); await page.locator("textarea").press("Control+a"); await page.locator("textarea").fill(wCode); await page.locator("textarea").fill(customComponentCode); await page.locator('//*[@id="checkAndSaveBtn"]').click(); await page.waitForTimeout(1000); - - // await page.getByTestId("code-button-modal").click(); - // const inputCodeValue = await page - // .locator('//*[@id="codeValue"]') - // .inputValue(); - - // expect(inputCodeValue).toContain("def python_function(text: str) -> str"); }); diff --git a/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts b/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts index 7992dcb6e..9099727b6 100644 --- a/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts +++ b/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts @@ -17,7 +17,14 @@ test("should delete a flow", async ({ page }) => { await page.waitForTimeout(5000); await page.getByText("My Collection").nth(0).click(); await page.getByText("Website Content QA").first().isVisible(); + + await page.getByLabel("checkbox-component").last().waitFor({ + state: "visible", + timeout: 30000, // Timeout of 30 seconds + }); + await page.getByLabel("checkbox-component").first().click(); + await page.getByTestId("icon-Trash2").click(); await page .getByText("Are you sure you want to delete the selected component?") @@ -36,6 +43,12 @@ test("should delete a component", async ({ page }) => { await page.getByText("My Collection").nth(0).click(); await page.getByText("Components").first().click(); await page.getByText("Basic RAG").first().isVisible(); + + await page.getByLabel("checkbox-component").last().waitFor({ + state: "visible", + timeout: 30000, // Timeout of 30 seconds + }); + await page.getByLabel("checkbox-component").first().click(); await page.getByTestId("icon-Trash2").click(); await page diff --git a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts index 03d11aaf7..ee1789d2d 100644 --- a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts +++ b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts @@ -26,7 +26,7 @@ test.describe("drag and drop test", () => { await page.locator("span").filter({ hasText: "My Collection" }).isVisible(); // Read your file into a buffer. const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/collection.json", + "tests/end-to-end/assets/collection.json", "utf-8", ); diff --git a/src/frontend/tests/end-to-end/filterEdge.spec.ts b/src/frontend/tests/end-to-end/filterEdge.spec.ts index a85f2c3e5..77bef251d 100644 --- a/src/frontend/tests/end-to-end/filterEdge.spec.ts +++ b/src/frontend/tests/end-to-end/filterEdge.spec.ts @@ -44,24 +44,40 @@ test("LLMChain - Tooltip", async ({ page }) => { ) .hover() .then(async () => { - await expect(page.getByTestId("tooltip-Chains").first()).toBeVisible(); await expect( - page.getByTestId("tooltip-Model Specs").first(), + page.getByTestId("available-output-chains").first(), ).toBeVisible(); await expect( - page.getByTestId("tooltip-Vector Search").first(), + page.getByTestId("available-output-textsplitters").first(), ).toBeVisible(); await expect( - page.getByTestId("tooltip-Text Splitters").first(), + page.getByTestId("available-output-retrievers").first(), ).toBeVisible(); await expect( - page.getByTestId("tooltip-Retrievers").first(), + page.getByTestId("available-output-prototypes").first(), ).toBeVisible(); - await expect(page.getByTestId("tooltip-Tools").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Memories").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Agents").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Helpers").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Utilities").first()).toBeVisible(); + await expect( + page.getByTestId("available-output-tools").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-output-memories").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-output-toolkits").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-output-chains").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-output-agents").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-output-helpers").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-output-langchain_utilities").first(), + ).toBeVisible(); + await page.getByTestId("icon-X").click(); await page.waitForTimeout(500); }); @@ -77,12 +93,10 @@ test("LLMChain - Tooltip", async ({ page }) => { .hover() .then(async () => { await expect( - page.getByTestId("tooltip-Model Specs").first(), + page.getByTestId("available-input-models").first(), ).toBeVisible(); await page.waitForTimeout(2000); - await expect(page.getByTestId("tooltip-Models").first()).toBeVisible(); - await page.getByTestId("icon-Search").click(); await page.waitForTimeout(500); @@ -100,12 +114,18 @@ test("LLMChain - Tooltip", async ({ page }) => { .then(async () => { await page.waitForTimeout(2000); - await expect(page.getByTestId("tooltip-Chains").first()).toBeVisible(); await expect( - page.getByTestId("tooltip-Experimental").first(), + page.getByTestId("available-input-chains").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-input-prototypes").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-input-agents").first(), + ).toBeVisible(); + await expect( + page.getByTestId("available-input-helpers").first(), ).toBeVisible(); - await expect(page.getByTestId("tooltip-Agents").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Helpers").first()).toBeVisible(); await page.waitForTimeout(500); }); @@ -176,26 +196,30 @@ test("LLMChain - Filter", async ({ page }) => { ) .click(); - await expect(page.getByTestId("disclosure-model specs")).toBeVisible(); - await expect(page.getByTestId("model_specsAnthropic").first()).toBeVisible(); - await expect(page.getByTestId("model_specsAmazon Bedrock")).toBeVisible(); - await expect(page.getByTestId("model_specsAzureChatOpenAI")).toBeVisible(); - await expect(page.getByTestId("model_specsChatLiteLLM")).toBeVisible(); - await expect(page.getByTestId("model_specsChatOllama")).toBeVisible(); - await expect(page.getByTestId("model_specsChatOpenAI")).toBeVisible(); - await expect(page.getByTestId("model_specsChatVertexAI")).toBeVisible(); + await expect(page.getByTestId("disclosure-models")).toBeVisible(); await expect( - page.getByTestId("model_specsGoogle Generative AI"), + page.getByTestId("modelsGoogle Generative AI").first(), + ).toBeVisible(); + await expect(page.getByTestId("chainsLLMChain").first()).toBeVisible(); + await expect( + page.getByTestId("langchain_utilitiesSearchApi").first(), ).toBeVisible(); await expect( - page.getByTestId("model_specsHugging Face Inference API"), + page.getByTestId("memoriesAstra DB Message Reader").first(), ).toBeVisible(); - await expect(page.getByTestId("model_specsOllama")).toBeVisible(); await expect( - page.getByTestId("model_specsQianfanChatEndpoint"), + page.getByTestId("prototypesFlow as Tool").first(), ).toBeVisible(); - await expect(page.getByTestId("model_specsQianfanLLMEndpoint")).toBeVisible(); - await expect(page.getByTestId("model_specsVertexAI")).toBeVisible(); + await expect( + page.getByTestId("retrieversAmazon Kendra Retriever").first(), + ).toBeVisible(); + await expect( + page.getByTestId("textsplittersCharacterTextSplitter").first(), + ).toBeVisible(); + await expect( + page.getByTestId("toolkitsVectorStoreInfo").first(), + ).toBeVisible(); + await expect(page.getByTestId("toolsSearchApi").first()).toBeVisible(); await page.getByPlaceholder("Search").click(); @@ -219,7 +243,6 @@ test("LLMChain - Filter", async ({ page }) => { .click(); await expect(page.getByTestId("disclosure-models")).toBeVisible(); - await expect(page.getByTestId("disclosure-model specs")).toBeVisible(); await page .locator( @@ -227,10 +250,8 @@ test("LLMChain - Filter", async ({ page }) => { ) .click(); - await expect(page.getByTestId("disclosure-saved")).toBeVisible(); - await expect(page.getByTestId("disclosure-helpers")).toBeVisible(); await expect(page.getByTestId("disclosure-agents")).toBeVisible(); await expect(page.getByTestId("disclosure-chains")).toBeVisible(); - await expect(page.getByTestId("disclosure-experimental")).toBeVisible(); + await expect(page.getByTestId("disclosure-prototypes")).toBeVisible(); }); diff --git a/src/frontend/tests/end-to-end/folders.spec.ts b/src/frontend/tests/end-to-end/folders.spec.ts index 99ed07669..d049b39f9 100644 --- a/src/frontend/tests/end-to-end/folders.spec.ts +++ b/src/frontend/tests/end-to-end/folders.spec.ts @@ -57,7 +57,7 @@ test("add folder by drag and drop", async ({ page }) => { await page.waitForTimeout(2000); const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/collection.json", + "tests/end-to-end/assets/collection.json", "utf-8", ); diff --git a/src/frontend/tests/end-to-end/generalBugs.spec.ts b/src/frontend/tests/end-to-end/generalBugs.spec.ts index 11ec86af4..a0e435fd5 100644 --- a/src/frontend/tests/end-to-end/generalBugs.spec.ts +++ b/src/frontend/tests/end-to-end/generalBugs.spec.ts @@ -85,6 +85,11 @@ test("erase button should clear the chat messages", async ({ page }) => { await page.getByPlaceholder("Send a message...").fill("Hello, how are you?"); await page.getByTestId("icon-LucideSend").click(); let valueUser = await page.getByTestId("sender_name_user").textContent(); + + await page.waitForSelector('[data-testid="sender_name_ai"]', { + timeout: 30000, + }); + let valueAI = await page.getByTestId("sender_name_ai").textContent(); expect(valueUser).toBe("User"); diff --git a/src/frontend/tests/end-to-end/inputListComponent.spec.ts b/src/frontend/tests/end-to-end/inputListComponent.spec.ts index e28ba67b2..fa91b685f 100644 --- a/src/frontend/tests/end-to-end/inputListComponent.spec.ts +++ b/src/frontend/tests/end-to-end/inputListComponent.spec.ts @@ -24,11 +24,11 @@ test("InputListComponent", async ({ page }) => { await page.waitForTimeout(3000); await page.getByTestId("extended-disclosure").click(); await page.getByPlaceholder("Search").click(); - await page.getByPlaceholder("Search").fill("astradb"); + await page.getByPlaceholder("Search").fill("url"); await page.waitForTimeout(1000); await page - .getByTestId("vectorsearchAstra DB Search") + .getByTestId("dataURL") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); await page.mouse.down(); @@ -36,95 +36,71 @@ test("InputListComponent", async ({ page }) => { await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); + + await page.getByTestId("input-list-input_urls-0").fill("test test test test"); + + await page.getByTestId("input-list-plus-btn_urls-0").click(); + + await page.getByTestId("input-list-plus-btn_urls-0").click(); + + await page + .getByTestId("input-list-input_urls-1") + .fill("test1 test1 test1 test1"); + + await page + .getByTestId("input-list-input_urls-2") + .fill("test2 test2 test2 test2"); + await page.getByTestId("div-generic-node").click(); await page.getByTestId("more-options-modal").click(); await page.getByTestId("edit-button-modal").click(); - expect( - await page.getByTestId("showmetadata_indexing_exclude").isChecked(), - ).toBeFalsy(); - await page.getByTestId("showmetadata_indexing_exclude").click(); - expect( - await page.getByTestId("showmetadata_indexing_exclude").isChecked(), - ).toBeTruthy(); - - expect( - await page.getByTestId("showmetadata_indexing_include").isChecked(), - ).toBeFalsy(); - await page.getByTestId("showmetadata_indexing_include").click(); - expect( - await page.getByTestId("showmetadata_indexing_include").isChecked(), - ).toBeTruthy(); - - await page - .getByTestId("input-list-input-edit_metadata_indexing_include-0") - .fill("test test test test"); - - await page - .getByTestId("input-list-plus-btn-edit_metadata_indexing_include-0") - .click(); - - await page - .getByTestId("input-list-input-edit_metadata_indexing_include-1") - .fill("test1 test1 test1 test1"); - - await page.getByText("Save Changes", { exact: true }).click(); - - await page - .getByTestId("input-list-input_metadata_indexing_include-0") - .fill("test test test test"); - const value0 = await page - .getByTestId("input-list-input_metadata_indexing_include-0") + .getByTestId("input-list-input-edit_urls-0") .inputValue(); const value1 = await page - .getByTestId("input-list-input_metadata_indexing_include-1") + .getByTestId("input-list-input-edit_urls-1") + .inputValue(); + + const value2 = await page + .getByTestId("input-list-input-edit_urls-2") .inputValue(); if ( value0 !== "test test test test" || - value1 !== "test1 test1 test1 test1" + value1 !== "test1 test1 test1 test1" || + value2 !== "test2 test2 test2 test2" ) { expect(false).toBeTruthy(); } - await page - .getByTestId("input-list-minus-btn_metadata_indexing_include-1") - .click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); const plusButtonLocator = page.getByTestId( - "input-list-plus-btn_metadata_indexing_include-1", + "input-list-minus-btn-edit_urls-1", ); const elementCount = await plusButtonLocator?.count(); - if (elementCount > 0) { + if (elementCount > 1) { expect(false).toBeTruthy(); } - await page - .getByTestId("input-list-plus-btn_metadata_indexing_include-0") - .click(); - await page - .getByTestId("input-list-plus-btn_metadata_indexing_include-0") - .click(); - await page - .getByTestId("input-list-plus-btn_metadata_indexing_include-0") - .click(); - await page - .getByTestId("input-list-plus-btn_metadata_indexing_include-0") - .click(); + await page.getByText("Save Changes", { exact: true }).click(); + await page.getByTestId("input-list-minus-btn_urls-2").isHidden(); + + await page.getByTestId("input-list-plus-btn_urls-0").click(); + await page.getByTestId("input-list-plus-btn_urls-0").click(); + + await page.getByTestId("input-list-input_urls-0").fill("test test test test"); await page - .getByTestId("input-list-input_metadata_indexing_include-0") - .fill("test test test test"); - await page - .getByTestId("input-list-input_metadata_indexing_include-1") + .getByTestId("input-list-input_urls-1") .fill("test1 test1 test1 test1"); await page - .getByTestId("input-list-input_metadata_indexing_include-2") + .getByTestId("input-list-input_urls-2") .fill("test2 test2 test2 test2"); await page - .getByTestId("input-list-input_metadata_indexing_include-3") + .getByTestId("input-list-input_urls-3") .fill("test3 test3 test3 test3"); await page.getByTestId("div-generic-node").click(); @@ -132,16 +108,16 @@ test("InputListComponent", async ({ page }) => { await page.getByTestId("edit-button-modal").click(); const value0Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-0") + .getByTestId("input-list-input-edit_urls-0") .inputValue(); const value1Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-1") + .getByTestId("input-list-input-edit_urls-1") .inputValue(); const value2Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-2") + .getByTestId("input-list-input-edit_urls-2") .inputValue(); const value3Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-3") + .getByTestId("input-list-input-edit_urls-3") .inputValue(); if ( @@ -153,23 +129,17 @@ test("InputListComponent", async ({ page }) => { expect(false).toBeTruthy(); } - await page - .getByTestId("input-list-minus-btn-edit_metadata_indexing_include-1") - .click(); - await page - .getByTestId("input-list-minus-btn-edit_metadata_indexing_include-1") - .click(); - await page - .getByTestId("input-list-minus-btn-edit_metadata_indexing_include-1") - .click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); const plusButtonLocatorEdit0 = await page.getByTestId( - "input-list-plus-btn-edit_metadata_indexing_include-0", + "input-list-plus-btn-edit_urls-0", ); const elementCountEdit0 = await plusButtonLocatorEdit0?.count(); const plusButtonLocatorEdit2 = await page.getByTestId( - "input-list-plus-btn-edit_metadata_indexing_include-2", + "input-list-plus-btn-edit_urls-1", ); const elementCountEdit2 = await plusButtonLocatorEdit2?.count(); @@ -178,13 +148,13 @@ test("InputListComponent", async ({ page }) => { } const minusButtonLocatorEdit1 = await page.getByTestId( - "input-list-minus-btn-edit_metadata_indexing_include-1", + "input-list-minus-btn-edit_urls-1", ); const elementCountMinusEdit1 = await minusButtonLocatorEdit1?.count(); const minusButtonLocatorEdit2 = await page.getByTestId( - "input-list-minus-btn-edit_metadata_indexing_include-2", + "input-list-minus-btn-edit_urls-2", ); const elementCountMinusEdit2 = await minusButtonLocatorEdit2?.count(); diff --git a/src/frontend/tests/end-to-end/intComponent.spec.ts b/src/frontend/tests/end-to-end/intComponent.spec.ts index aa54ac5b4..30522d397 100644 --- a/src/frontend/tests/end-to-end/intComponent.spec.ts +++ b/src/frontend/tests/end-to-end/intComponent.spec.ts @@ -30,7 +30,7 @@ test("IntComponent", async ({ page }) => { await page.waitForTimeout(1000); await page - .getByTestId("model_specsChatOpenAI") + .getByTestId("modelsOpenAI") .first() .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); @@ -65,7 +65,7 @@ test("IntComponent", async ({ page }) => { expect(false).toBeTruthy(); } - await page.getByTestId("title-ChatOpenAI").click(); + await page.getByTestId("title-OpenAI").click(); await page.getByTitle("fit view").click(); await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); diff --git a/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts b/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts index 31a4521ae..685f5b4fd 100644 --- a/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts +++ b/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts @@ -30,7 +30,7 @@ test("KeypairListComponent", async ({ page }) => { await page.waitForTimeout(1000); await page - .getByTestId("model_specsAmazon Bedrock") + .getByTestId("modelsAmazon Bedrock") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); await page.mouse.down(); @@ -38,6 +38,14 @@ test("KeypairListComponent", async ({ page }) => { await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); + + await page.getByTestId("more-options-modal").click(); + await page.getByTestId("edit-button-modal").click(); + + await page.getByTestId("showmodel_kwargs").click(); + expect(await page.getByTestId("showmodel_kwargs").isChecked()).toBeTruthy(); + await page.getByText("Save Changes", { exact: true }).click(); + await page.locator('//*[@id="keypair0"]').click(); await page.locator('//*[@id="keypair0"]').fill("testtesttesttest"); await page.locator('//*[@id="keypair100"]').click(); diff --git a/src/frontend/tests/end-to-end/promptModalComponent.spec.ts b/src/frontend/tests/end-to-end/promptModalComponent.spec.ts index b91cb6ed5..74bc44480 100644 --- a/src/frontend/tests/end-to-end/promptModalComponent.spec.ts +++ b/src/frontend/tests/end-to-end/promptModalComponent.spec.ts @@ -72,6 +72,8 @@ test("PromptTemplateComponent", async ({ page }) => { expect(false).toBeTruthy(); } + await page.getByTestId("div-generic-node").click(); + await page.getByTestId("more-options-modal").click(); await page.getByTestId("save-button-modal").click(); @@ -102,13 +104,16 @@ test("PromptTemplateComponent", async ({ page }) => { await page.getByTestId("more-options-modal").click(); await page.getByTestId("edit-button-modal").click(); - value = await page.locator('//*[@id="textarea-edit-prompt"]').inputValue(); + value = + (await page.locator('//*[@id="textarea-edit-prompt"]').textContent()) ?? ""; if (value != "prompt_value_!@#!@#") { expect(false).toBeTruthy(); } - value = await page.locator('//*[@id="textarea-edit-prompt1"]').inputValue(); + value = + (await page.locator('//*[@id="textarea-edit-prompt1"]').textContent()) ?? + ""; if (value != "prompt_name_test_123123!@#!@#") { expect(false).toBeTruthy(); @@ -122,13 +127,20 @@ test("PromptTemplateComponent", async ({ page }) => { expect(false).toBeTruthy(); } + await page.locator('//*[@id="textarea-edit-prompt1"]').click(); await page - .locator('//*[@id="textarea-edit-prompt1"]') + .getByTestId("text-area-modal") .fill("prompt_edit_test_12312312321!@#$"); + + await page.getByText("Finish Editing", { exact: true }).click(); + + await page.locator('//*[@id="textarea-edit-prompt"]').click(); await page - .locator('//*[@id="textarea-edit-prompt"]') + .getByTestId("text-area-modal") .fill("prompt_edit_test_44444444444!@#$"); + await page.getByText("Finish Editing", { exact: true }).click(); + await page.locator('//*[@id="showtemplate"]').click(); expect(await page.locator('//*[@id="showtemplate"]').isChecked()).toBeFalsy(); @@ -174,13 +186,16 @@ test("PromptTemplateComponent", async ({ page }) => { await page.locator('//*[@id="showprompt1"]').click(); expect(await page.locator('//*[@id="showprompt1"]').isChecked()).toBeTruthy(); - value = await page.locator('//*[@id="textarea-edit-prompt"]').inputValue(); + value = + (await page.locator('//*[@id="textarea-edit-prompt"]').textContent()) ?? ""; if (value != "prompt_edit_test_44444444444!@#$") { expect(false).toBeTruthy(); } - value = await page.locator('//*[@id="textarea-edit-prompt1"]').inputValue(); + value = + (await page.locator('//*[@id="textarea-edit-prompt1"]').textContent()) ?? + ""; if (value != "prompt_edit_test_12312312321!@#$") { expect(false).toBeTruthy(); diff --git a/src/frontend/tests/end-to-end/saveComponents.spec.ts b/src/frontend/tests/end-to-end/saveComponents.spec.ts index fa9dbbc00..17be7622b 100644 --- a/src/frontend/tests/end-to-end/saveComponents.spec.ts +++ b/src/frontend/tests/end-to-end/saveComponents.spec.ts @@ -26,7 +26,7 @@ test.describe("save component tests", () => { // Read your file into a buffer. const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/flow_group_test.json", + "tests/end-to-end/assets/flow_group_test.json", "utf-8", ); diff --git a/src/frontend/tests/end-to-end/store.spec.ts b/src/frontend/tests/end-to-end/store.spec.ts index bcd5ec15b..9ca0b040d 100644 --- a/src/frontend/tests/end-to-end/store.spec.ts +++ b/src/frontend/tests/end-to-end/store.spec.ts @@ -259,6 +259,10 @@ test("should share component with share button", async ({ page }) => { await page.getByText("Save").last().click(); await page.getByText("Close").last().click(); + await page.waitForSelector('[data-testid="icon-Share3"]', { + timeout: 100000, + }); + await page.getByTestId("icon-Share3").first().click(); await page.getByText("Name:").isVisible(); await page.getByText("Description:").isVisible(); diff --git a/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts b/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts index 590d43933..54cb1f1ad 100644 --- a/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts +++ b/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts @@ -21,8 +21,17 @@ test("TextAreaModalComponent", async ({ page }) => { } await page.getByTestId("blank-flow").click(); - await page.waitForTimeout(3000); - await page.getByTestId("extended-disclosure").click(); + + await page.waitForSelector('[data-testid="extended-disclosure"]', { + timeout: 30000, + }); + const focusElementsOnBoard = async ({ page }) => { + const focusElements = await page.getByTestId("extended-disclosure"); + await focusElements.click(); + }; + + await focusElementsOnBoard({ page }); + await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").fill("prompt"); diff --git a/src/frontend/tests/end-to-end/textInputOutput.spec.ts b/src/frontend/tests/end-to-end/textInputOutput.spec.ts index 586e1361e..40b054c59 100644 --- a/src/frontend/tests/end-to-end/textInputOutput.spec.ts +++ b/src/frontend/tests/end-to-end/textInputOutput.spec.ts @@ -29,8 +29,17 @@ test("TextInputOutputComponent", async ({ page }) => { await page.waitForTimeout(1000); await page.getByTestId("blank-flow").click(); - await page.waitForTimeout(3000); - await page.getByTestId("extended-disclosure").click(); + await page.waitForSelector('[data-testid="extended-disclosure"]', { + timeout: 30000, + }); + + const focusElementsOnBoard = async ({ page }) => { + const focusElements = await page.getByTestId("extended-disclosure"); + focusElements.click(); + }; + + await focusElementsOnBoard({ page }); + await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").fill("text input"); await page.waitForTimeout(1000); @@ -56,7 +65,15 @@ test("TextInputOutputComponent", async ({ page }) => { await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); - // Click and hold on the first element + await page + .locator( + '//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]/div/div[2]/div[5]/button/div[1]', + ) + .waitFor({ + state: "visible", + timeout: 30000, + }); + await page .locator( '//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]/div/div[2]/div[5]/button/div[1]', @@ -64,6 +81,15 @@ test("TextInputOutputComponent", async ({ page }) => { .hover(); await page.mouse.down(); + await page + .locator( + '//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[2]/div/div[2]/div[3]/div/button/div[1]', + ) + .waitFor({ + state: "visible", + timeout: 30000, + }); + // Move to the second element await page .locator( @@ -88,6 +114,15 @@ test("TextInputOutputComponent", async ({ page }) => { await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); + await page + .locator( + '//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[2]/div/div[2]/div[15]/button/div[1]', + ) + .waitFor({ + state: "visible", + timeout: 30000, + }); + // Click and hold on the first element await page .locator( @@ -96,6 +131,15 @@ test("TextInputOutputComponent", async ({ page }) => { .hover(); await page.mouse.down(); + await page + .locator( + '//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[3]/div/div[2]/div[3]/div/button/div[1]', + ) + .waitFor({ + state: "visible", + timeout: 30000, + }); + // Move to the second element await page .locator( diff --git a/src/frontend/tests/end-to-end/toggleComponent.spec.ts b/src/frontend/tests/end-to-end/toggleComponent.spec.ts index 58d909af4..5c8eef429 100644 --- a/src/frontend/tests/end-to-end/toggleComponent.spec.ts +++ b/src/frontend/tests/end-to-end/toggleComponent.spec.ts @@ -21,8 +21,16 @@ test("ToggleComponent", async ({ page }) => { } await page.getByTestId("blank-flow").click(); - await page.waitForTimeout(3000); - await page.getByTestId("extended-disclosure").click(); + + await page.waitForSelector('[data-testid="extended-disclosure"]', { + timeout: 30000, + }); + const focusElementsOnBoard = async ({ page }) => { + const focusElements = await page.getByTestId("extended-disclosure"); + focusElements.click(); + }; + + await focusElementsOnBoard({ page }); await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").fill("directory"); diff --git a/src/frontend/tests/end-to-end/tweaks_test.spec.ts b/src/frontend/tests/end-to-end/tweaks_test.spec.ts index 871e8a2ba..bc4ab7c56 100644 --- a/src/frontend/tests/end-to-end/tweaks_test.spec.ts +++ b/src/frontend/tests/end-to-end/tweaks_test.spec.ts @@ -108,7 +108,13 @@ test("check if tweaks are updating when someothing on the flow changes", async ( .getByTestId("popover-anchor-input-persist_directory") .fill("persist_directory_123123123!@#$&*(&%$@"); - await page.getByText("API", { exact: true }).first().click(); + const focusElementsOnBoard = async ({ page }) => { + await page.waitForSelector("text=API", { timeout: 30000 }); + const focusElements = await page.getByText("API", { exact: true }).first(); + await focusElements.click(); + }; + + await focusElementsOnBoard({ page }); await page.getByText("Tweaks").nth(1).click(); diff --git a/src/frontend/tests/end-to-end/twoEdges.spec.ts b/src/frontend/tests/end-to-end/twoEdges.spec.ts index abae18ba3..b40ef8a4a 100644 --- a/src/frontend/tests/end-to-end/twoEdges.spec.ts +++ b/src/frontend/tests/end-to-end/twoEdges.spec.ts @@ -24,10 +24,23 @@ test("user should be able to see multiple edges and interact with them", async ( await page.waitForTimeout(1000); await page.getByText("Vector Store RAG", { exact: true }).last().click(); - await page.waitForTimeout(3000); + await page.waitForTimeout(5000); await page.getByText("Retriever", { exact: true }).first().isVisible(); await page.getByText("Search Results", { exact: true }).first().isVisible(); - await page.getByTestId("icon-Eye").nth(24).click(); + + const focusElementsOnBoard = async ({ page }) => { + await page.waitForSelector('[title="fit view"]', { timeout: 30000 }); + const focusElements = await page.getByTitle("fit view"); + await focusElements.click(); + }; + + await focusElementsOnBoard({ page }); + + await page.getByTitle("zoom out").click(); + await page.getByTitle("zoom out").click(); + await page.getByTitle("zoom out").click(); + + await page.getByTestId("output-inspection-retriever").first().click(); await page.getByText("Retriever", { exact: true }).first().isHidden(); await page.getByTestId("icon-ChevronDown").last().isVisible(); await page.getByTestId("icon-ChevronDown").last().click(); diff --git a/src/frontend/tests/end-to-end/userSettings.spec.ts b/src/frontend/tests/end-to-end/userSettings.spec.ts index df760cbca..1876031fc 100644 --- a/src/frontend/tests/end-to-end/userSettings.spec.ts +++ b/src/frontend/tests/end-to-end/userSettings.spec.ts @@ -62,10 +62,19 @@ test("should interact with global variables", async ({ page }) => { await page.getByText(randomName).isVisible(); - await page - .getByLabel("Press Space to toggle all rows selection (unchecked)") - .nth(0) - .click(); + const focusElementsOnBoard = async ({ page }) => { + await page.waitForSelector( + '[aria-label="Press Space to toggle all rows selection (unchecked)"]', + { timeout: 30000 }, + ); + const focusElements = await page + .getByLabel("Press Space to toggle all rows selection (unchecked)") + .first(); + await focusElements.click(); + }; + + await focusElementsOnBoard({ page }); + await page.getByTestId("icon-Trash2").click(); await page.getByText("No data available").isVisible(); }); From 791bd70c040611ab44aa0d34614bf8d482c791c0 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 25 Jun 2024 14:12:22 -0300 Subject: [PATCH 07/12] chore: Fix curl command in release.yml to wait for server start --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 97e175cfd..9f84be063 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,7 +62,7 @@ jobs: python -m langflow run --host 127.0.0.1 --port 7860 & SERVER_PID=$! # Wait for the server to start - timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) + timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) # Terminate the server kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) sleep 10 # give the server some time to terminate From 8ea95420c74fd53eb5e078b785c11ef3df5a03fe Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 25 Jun 2024 10:13:04 -0700 Subject: [PATCH 08/12] Update workflows for better test coverage and integration (#2344) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ (typescript_test.yml): add workflow_dispatch event to trigger workflow manually with branch input parameter 🔧 (typescript_test.yml): update workflow to checkout code from the specified branch when triggered manually * 📝 (lint-py.yml): update linting workflow to trigger on specific pull request events and checks requested action 📝 (lint-py.yml): add a specific job to run Mypy for static type checking in the linting workflow * 🔧 (python_test.yml): update pull_request event types and branches to trigger on more actions for better test coverage and integration --- .github/workflows/lint-py.yml | 7 +++++-- .github/workflows/python_test.yml | 13 ++++--------- .github/workflows/typescript_test.yml | 13 ++++++++++--- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/workflows/lint-py.yml b/.github/workflows/lint-py.yml index 9dab54eb8..8a4abe0f9 100644 --- a/.github/workflows/lint-py.yml +++ b/.github/workflows/lint-py.yml @@ -2,19 +2,20 @@ name: Lint Python on: pull_request: + types: [opened, synchronize, reopened] paths: - "poetry.lock" - "pyproject.toml" - "src/backend/**" - "tests/**" merge_group: - branches: [dev] - + types: [checks_requested] env: POETRY_VERSION: "1.8.2" jobs: lint: + name: Run Mypy runs-on: ubuntu-latest strategy: matrix: @@ -34,6 +35,8 @@ jobs: run: | poetry env use ${{ matrix.python-version }} poetry install + - name: Run Mypy + run: | make lint env: GITHUB_TOKEN: ${{ secrets.github_token }} diff --git a/.github/workflows/python_test.yml b/.github/workflows/python_test.yml index 4846f59fb..9e065c58f 100644 --- a/.github/workflows/python_test.yml +++ b/.github/workflows/python_test.yml @@ -1,26 +1,21 @@ name: Python tests on: - push: - branches: [main] - paths: - - "poetry.lock" - - "pyproject.toml" - - "src/backend/**" pull_request: - branches: [dev] + types: [opened, synchronize, reopened] + branches: [dev, main] paths: - "poetry.lock" - "pyproject.toml" - "src/backend/**" merge_group: - branches: [dev] - + types: [checks_requested] env: POETRY_VERSION: "1.8.2" jobs: build: + name: Run Unit Tests runs-on: ubuntu-latest strategy: matrix: diff --git a/.github/workflows/typescript_test.yml b/.github/workflows/typescript_test.yml index 8fd809020..bd06b5dab 100644 --- a/.github/workflows/typescript_test.yml +++ b/.github/workflows/typescript_test.yml @@ -1,9 +1,13 @@ name: Run Frontend Tests on: - pull_request: - paths: - - "src/frontend/**" + workflow_dispatch: + inputs: + branch: + description: "Branch to run tests on" + required: true + type: string + env: POETRY_VERSION: "1.8.2" @@ -15,6 +19,7 @@ env: jobs: setup-and-test: + name: Run Frontend Tests on branch ${{ inputs.branch }} runs-on: ubuntu-latest strategy: fail-fast: false @@ -24,6 +29,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} - name: Setup Node.js uses: actions/setup-node@v4 From f5835152b3568a693790bfc226dab2ec2ec317df Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 25 Jun 2024 14:42:19 -0300 Subject: [PATCH 09/12] chore: Update authContext imports and remove duplicate imports --- src/frontend/src/contexts/authContext.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index 50a0cf4e7..cfdbdfb4f 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -12,10 +12,6 @@ import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVa import { useStoreStore } from "../stores/storeStore"; import { Users } from "../types/api"; import { AuthContextType } from "../types/contexts/auth"; -import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVariables"; -import { useStoreStore } from "../stores/storeStore"; -import { Users } from "../types/api"; -import { AuthContextType } from "../types/contexts/auth"; const initialValue: AuthContextType = { isAdmin: false, From 2020a356dd02f3a9a16a96f901ba8a16771101df Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 25 Jun 2024 14:56:29 -0300 Subject: [PATCH 10/12] Refactor telemetry service payload field names for consistency --- src/backend/base/langflow/api/v1/chat.py | 30 +++++++++---------- src/backend/base/langflow/api/v1/endpoints.py | 19 ++++++++---- .../langflow/services/telemetry/schema.py | 24 +++++++-------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/backend/base/langflow/api/v1/chat.py b/src/backend/base/langflow/api/v1/chat.py index dc44d498b..e19342568 100644 --- a/src/backend/base/langflow/api/v1/chat.py +++ b/src/backend/base/langflow/api/v1/chat.py @@ -121,9 +121,9 @@ async def retrieve_vertices_order( background_tasks.add_task( telemetry_service.log_package_playground, PlaygroundPayload( - seconds=int(time.perf_counter() - start_time), - componentCount=components_count, - success=True, + playgroundSeconds=int(time.perf_counter() - start_time), + playgroundComponentCount=components_count, + playgroundSuccess=True, ), ) return VerticesOrderResponse(ids=first_layer, run_id=graph._run_id, vertices_to_run=vertices_to_run) @@ -131,10 +131,10 @@ async def retrieve_vertices_order( background_tasks.add_task( telemetry_service.log_package_playground, PlaygroundPayload( - seconds=int(time.perf_counter() - start_time), - componentCount=components_count, - success=False, - errorMessage=str(exc), + playgroundSeconds=int(time.perf_counter() - start_time), + playgroundComponentCount=components_count, + playgroundSuccess=False, + playgroundErrorMessage=str(exc), ), ) if "stream or streaming set to True" in str(exc): @@ -280,10 +280,10 @@ async def build_vertex( background_tasks.add_task( telemetry_service.log_package_component, ComponentPayload( - name=vertex_id, - seconds=int(time.perf_counter() - start_time), - success=valid, - errorMessage=params, + componentName=vertex_id, + componentSeconds=int(time.perf_counter() - start_time), + componentSuccess=valid, + componentErrorMessage=params, ), ) return build_response @@ -291,10 +291,10 @@ async def build_vertex( background_tasks.add_task( telemetry_service.log_package_component, ComponentPayload( - name=vertex_id, - seconds=int(time.perf_counter() - start_time), - success=False, - errorMessage=str(exc), + componentName=vertex_id, + componentSeconds=int(time.perf_counter() - start_time), + componentSuccess=False, + componentErrorMessage=str(exc), ), ) logger.error(f"Error building Component:\n\n{exc}") diff --git a/src/backend/base/langflow/api/v1/endpoints.py b/src/backend/base/langflow/api/v1/endpoints.py index d8b5e9da8..92358111a 100644 --- a/src/backend/base/langflow/api/v1/endpoints.py +++ b/src/backend/base/langflow/api/v1/endpoints.py @@ -209,7 +209,7 @@ async def simplified_run_flow( end_time = time.perf_counter() background_tasks.add_task( telemetry_service.log_package_run, - RunPayload(IsWebhook=False, seconds=int(end_time - start_time), success=True, errorMessage=""), + RunPayload(runIsWebhook=False, runSeconds=int(end_time - start_time), runSuccess=True, runErrorMessage=""), ) return result @@ -217,7 +217,9 @@ async def simplified_run_flow( end_time = time.perf_counter() background_tasks.add_task( telemetry_service.log_package_run, - RunPayload(IsWebhook=False, seconds=int(end_time - start_time), success=False, errorMessage=str(exc)), + RunPayload( + runIsWebhook=False, runSeconds=int(end_time - start_time), runSuccess=False, runErrorMessage=str(exc) + ), ) if "badly formed hexadecimal UUID string" in str(exc): # This means the Flow ID is not a valid UUID which means it can't find the flow @@ -231,7 +233,9 @@ async def simplified_run_flow( logger.exception(exc) background_tasks.add_task( telemetry_service.log_package_run, - RunPayload(IsWebhook=False, seconds=int(end_time - start_time), success=False, errorMessage=str(exc)), + RunPayload( + runIsWebhook=False, runSeconds=int(end_time - start_time), runSuccess=False, runErrorMessage=str(exc) + ), ) raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)) from exc @@ -290,14 +294,19 @@ async def webhook_run_flow( ) background_tasks.add_task( telemetry_service.log_package_run, - RunPayload(IsWebhook=True, seconds=int(time.perf_counter() - start_time), success=True, errorMessage=""), + RunPayload( + runIsWebhook=True, runSeconds=int(time.perf_counter() - start_time), runSuccess=True, runErrorMessage="" + ), ) return {"message": "Task started in the background", "status": "in progress"} except Exception as exc: background_tasks.add_task( telemetry_service.log_package_run, RunPayload( - IsWebhook=True, seconds=int(time.perf_counter() - start_time), success=False, errorMessage=str(exc) + runIsWebhook=True, + runSeconds=int(time.perf_counter() - start_time), + runSuccess=False, + runErrorMessage=str(exc), ), ) if "Flow ID is required" in str(exc) or "Request body is empty" in str(exc): diff --git a/src/backend/base/langflow/services/telemetry/schema.py b/src/backend/base/langflow/services/telemetry/schema.py index bba7a23e4..9d62e128a 100644 --- a/src/backend/base/langflow/services/telemetry/schema.py +++ b/src/backend/base/langflow/services/telemetry/schema.py @@ -2,10 +2,10 @@ from pydantic import BaseModel class RunPayload(BaseModel): - IsWebhook: bool = False - seconds: int - success: bool - errorMessage: str = "" + runIsWebhook: bool = False + runSeconds: int + runSuccess: bool + runErrorMessage: str = "" class ShutdownPayload(BaseModel): @@ -23,14 +23,14 @@ class VersionPayload(BaseModel): class PlaygroundPayload(BaseModel): - seconds: int - componentCount: int | None = None - success: bool - errorMessage: str = "" + playgroundSeconds: int + playgroundComponentCount: int | None = None + playgroundSuccess: bool + playgroundErrorMessage: str = "" class ComponentPayload(BaseModel): - name: str - seconds: int - success: bool - errorMessage: str + componentName: str + componentSeconds: int + componentSuccess: bool + componentErrorMessage: str From ad4d7c0090d26ffbf95947f4108860854e84db81 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 25 Jun 2024 14:59:33 -0300 Subject: [PATCH 11/12] chore: Update package versions in pyproject.toml files --- pyproject.toml | 2 +- src/backend/base/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8ffb4ccf5..1bd744a36 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.4" +version = "1.0.5" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 100bcbd2b..6f305ea85 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow-base" -version = "0.0.80" +version = "0.0.81" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ From 20ceb42504087c712aaee41bfc17a870ae0109d4 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 25 Jun 2024 15:33:42 -0300 Subject: [PATCH 12/12] chore: Update release.yml to use the correct branch for the commit --- .github/workflows/release.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9f84be063..ec9828c0a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,11 +14,7 @@ on: required: false type: boolean default: true - branch: - description: "Branch to release from" - required: true - type: string - default: "main" + env: POETRY_VERSION: "1.8.2" @@ -180,4 +176,4 @@ jobs: generateReleaseNotes: true prerelease: ${{ inputs.pre_release }} tag: v${{ needs.release-main.outputs.version }} - commit: ${{ inputs.branch }} \ No newline at end of file + commit: ${{ github.ref }} \ No newline at end of file