diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 000000000..f5008c586 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,2 @@ + +make format \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 656838e88..f32cbfc6b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,7 +9,7 @@ env: POETRY_VERSION: "1.4.0" jobs: - build: + lint: runs-on: ubuntu-latest strategy: matrix: diff --git a/.gitignore b/.gitignore index c2ffb8276..cb7805a70 100644 --- a/.gitignore +++ b/.gitignore @@ -5,12 +5,13 @@ npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* +qdrant_storage # Mac .DS_Store # VSCode -.vscode +.vscode/settings.json .chroma .ruff_cache diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..b0a48cdc6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,35 @@ +{ + "configurations": [ + { + "name": "Python: FastAPI", + "type": "python", + "request": "launch", + "module": "uvicorn", + "args": [ + "langflow.main:app", + "--port", + "7860", + "--reload", + "--log-level", + "debug" + ], + "jinja": true, + "justMyCode": false + }, + { + "name": "Python: Remote Attach", + "type": "python", + "request": "attach", + "justMyCode": true, + "connect": { + "port": 5678 + }, + "pathMappings": [ + { + "localRoot": "${workspaceFolder}", + "remoteRoot": "." + } + ] + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f98336ba9..001417643 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,6 +42,35 @@ the system we use to tag our issues and pull requests. ### Local development You can develop LangFlow using docker compose, or locally. +We provide a .vscode/launch.json file for debugging the backend in VSCode, which is a lot faster than using docker compose. + +Setting up hooks: +```bash +make init +``` + +This will install the pre-commit hooks, which will run `make format` on every commit. + +It is advised to run `make lint` before pushing to the repository. + +#### **Locally** +Run locally by cloning the repository and installing the dependencies. We recommend using a virtual environment to isolate the dependencies from your system. + +Before you start, make sure you have the following installed: + - Poetry (>=1.4) + - Node.js + +For the backend, you will need to install the dependencies and start the development server. +```bash +make install_backend +make backend +``` +For the frontend, you will need to install the dependencies and start the development server. +```bash +make frontend +``` + + #### **Docker compose** This will run the backend and frontend in separate containers. The frontend will be available at `localhost:3000` and the backend at `localhost:7860`. ```bash @@ -50,22 +79,4 @@ docker compose up --build make dev build=1 ``` -#### **Locally** -Run locally by cloning the repository and installing the dependencies. We recommend using a virtual environment to isolate the dependencies from your system. - -Before you start, make sure you have the following installed: - - Poetry - - Node.js - -For the backend, you will need to install the dependencies and start the development server. -```bash -poetry install -make run_backend -``` -For the frontend, you will need to install the dependencies and start the development server. -```bash -cd src/frontend -npm install -npm start -``` diff --git a/Makefile b/Makefile index 0d8556e47..e03967b23 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,11 @@ -.PHONY: all format lint build build_frontend install_frontend run_frontend run_backend dev help tests coverage +.PHONY: all init format lint build build_frontend install_frontend run_frontend run_backend dev help tests coverage all: help +init: + @echo 'Installing pre-commit hooks' + git config core.hooksPath .githooks + coverage: poetry run pytest --cov \ --cov-config=.coveragerc \ @@ -13,7 +17,8 @@ tests: format: poetry run black . - poetry run ruff --select I --fix . + poetry run ruff . --fix + cd src/frontend && npm run format lint: poetry run mypy . diff --git a/poetry.lock b/poetry.lock index 34eaaa572..aad835dc1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -5,7 +5,7 @@ name = "aiofiles" version = "23.1.0" description = "File support for asyncio." category = "main" -optional = true +optional = false python-versions = ">=3.7,<4.0" files = [ {file = "aiofiles-23.1.0-py3-none-any.whl", hash = "sha256:9312414ae06472eb6f1d163f555e466a23aed1c8f60c30cccf7121dba2e53eb2"}, @@ -141,7 +141,7 @@ name = "aiostream" version = "0.4.5" description = "Generator-based operators for asynchronous iteration" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "aiostream-0.4.5-py3-none-any.whl", hash = "sha256:25b7c2d9c83570d78c0ef5a20e949b7d0b8ea3b0b0a4f22c49d3f721105a6057"}, @@ -150,24 +150,25 @@ files = [ [[package]] name = "anyio" -version = "3.6.2" +version = "3.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7" files = [ - {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, - {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, + {file = "anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0"}, + {file = "anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce"}, ] [package.dependencies] +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" [package.extras] -doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"] -trio = ["trio (>=0.16,<0.22)"] +doc = ["Sphinx (>=6.1.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme", "sphinxcontrib-jquery"] +test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (<0.22)"] [[package]] name = "appnope" @@ -183,22 +184,38 @@ files = [ [[package]] name = "argilla" -version = "0.0.1" -description = "" +version = "1.3.2" +description = "Open-source tool for exploring, labeling, and monitoring data for NLP projects." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "argilla-0.0.1-py3-none-any.whl", hash = "sha256:8bdc3c505bcfb47ba4b91f5658034eae53bf7d4f9317980397605c0c55817396"}, - {file = "argilla-0.0.1.tar.gz", hash = "sha256:5017854754e89f573b31af25b25b803f51cea9ca1fa0bcf00505dee1f45cf7c9"}, + {file = "argilla-1.3.2-py3-none-any.whl", hash = "sha256:2471d750f79bd1ac17c56be420781299a6b921405b473a272c402b71fddf45bf"}, + {file = "argilla-1.3.2.tar.gz", hash = "sha256:bbf5a12acb7a8d8cd91852c86c432684464ad095bba6a9d8ab95ab56a5e06255"}, ] +[package.dependencies] +backoff = "*" +deprecated = ">=1.2.0,<1.3.0" +httpx = ">=0.15,<0.24" +monotonic = "*" +numpy = "<1.24.0" +packaging = ">=20.0" +pandas = ">=1.0.0,<2.0.0" +pydantic = ">=1.7.1" +tqdm = ">=4.27.0" +wrapt = ">=1.13,<1.15" + +[package.extras] +listeners = ["prodict (>=0.8.0,<0.9.0)", "schedule (>=1.1.0,<1.2.0)"] +server = ["Deprecated (>=1.2.0,<1.3.0)", "PyYAML (>=5.4.1,<6.1.0)", "aiofiles (>=0.6,<22.2)", "brotli-asgi (>=1.1,<1.3)", "elasticsearch (>=7.11.0,<8.6.0)", "fastapi (>=0.75,<0.89)", "luqum (>=0.11,<0.13)", "opensearch-py (>=1.0,<2.1)", "passlib[bcrypt] (>=1.7.4,<1.8.0)", "psutil (>=5.8,<5.10)", "python-jose[cryptography] (>=3.2,<3.4)", "python-multipart (>=0.0.5,<0.1.0)", "scikit-learn (>=0.24.2)", "segment-analytics-python (==2.2.0)", "smart-open", "uvicorn[standard] (>=0.15.0,<0.21.0)"] + [[package]] name = "asgiref" version = "3.7.1" description = "ASGI specs, helper code, and adapters" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "asgiref-3.7.1-py3-none-any.whl", hash = "sha256:33958cb2e4b3cd8b1b06ef295bd8605cde65b11df51d3beab39e2e149a610ab3"}, @@ -260,6 +277,21 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +[[package]] +name = "authlib" +version = "1.2.0" +description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "Authlib-1.2.0-py2.py3-none-any.whl", hash = "sha256:4ddf4fd6cfa75c9a460b361d4bd9dac71ffda0be879dbe4292a02e92349ad55a"}, + {file = "Authlib-1.2.0.tar.gz", hash = "sha256:4fa3e80883a5915ef9f5bc28630564bc4ed5b5af39812a3ff130ec76bd631e9d"}, +] + +[package.dependencies] +cryptography = ">=3.2" + [[package]] name = "backcall" version = "0.2.0" @@ -802,6 +834,48 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cryptography" +version = "40.0.2" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, + {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, + {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, + {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +pep8test = ["black", "check-manifest", "mypy", "ruff"] +sdist = ["setuptools-rust (>=0.11.4)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] +tox = ["tox"] + [[package]] name = "dataclasses-json" version = "0.5.7" @@ -854,7 +928,7 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "dev" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -867,7 +941,7 @@ name = "deprecated" version = "1.2.13" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." category = "main" -optional = true +optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, @@ -900,7 +974,7 @@ name = "docarray" version = "0.21.0" description = "The data structure for unstructured data" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "docarray-0.21.0.tar.gz", hash = "sha256:3c9f605123800c1b0cdf8c458be3fb19c05e9a81f723e51200ef531b02e689ee"}, @@ -929,7 +1003,7 @@ name = "docker" version = "6.1.2" description = "A Python library for the Docker Engine API." category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "docker-6.1.2-py3-none-any.whl", hash = "sha256:134cd828f84543cbf8e594ff81ca90c38288df3c0a559794c12f2e4b634ea19e"}, @@ -1018,7 +1092,7 @@ name = "ecdsa" version = "0.18.0" description = "ECDSA cryptographic signature library (pure python)" category = "main" -optional = true +optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"}, @@ -1048,7 +1122,7 @@ files = [ name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1129,14 +1203,14 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "p [[package]] name = "flatbuffers" -version = "23.5.9" +version = "23.5.26" description = "The FlatBuffers serialization format for Python" category = "main" optional = false python-versions = "*" files = [ - {file = "flatbuffers-23.5.9-py2.py3-none-any.whl", hash = "sha256:a02eb8c2d61cba153cd211937de8f8f7764b6a7510971b2c4684ed8b02e6e571"}, - {file = "flatbuffers-23.5.9.tar.gz", hash = "sha256:93a506b6ab771c79ce816e7b35a93ed08ec5b4c9edb811101a22c44a4152f018"}, + {file = "flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1"}, + {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"}, ] [[package]] @@ -1267,20 +1341,20 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.18.1" +version = "2.19.0" description = "Google Authentication Library" category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.6" files = [ - {file = "google-auth-2.18.1.tar.gz", hash = "sha256:d7a3249027e7f464fbbfd7ee8319a08ad09d2eea51578575c4bd360ffa049ccb"}, - {file = "google_auth-2.18.1-py2.py3-none-any.whl", hash = "sha256:55a395cdfd3f3dd3f649131d41f97c17b4ed8a2aac1be3502090c716314e8a37"}, + {file = "google-auth-2.19.0.tar.gz", hash = "sha256:f39d528077ac540793dd3c22a8706178f157642a67d874db25c640b7fead277e"}, + {file = "google_auth-2.19.0-py2.py3-none-any.whl", hash = "sha256:be617bfaf77774008e9d177573f782e109188c8a64ae6e744285df5cea3e7df6"}, ] [package.dependencies] cachetools = ">=2.0.0,<6.0" pyasn1-modules = ">=0.2.1" -rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} +rsa = ">=3.1.4,<5" six = ">=1.9.0" urllib3 = "<2.0" @@ -1340,23 +1414,6 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0dev)"] -[[package]] -name = "gptcache" -version = "0.1.26" -description = "GPTCache, a powerful caching library that can be used to speed up and lower the cost of chat applications that rely on the LLM service. GPTCache works as a memcache for AIGC applications, similar to how Redis works for traditional applications." -category = "main" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "gptcache-0.1.26-py3-none-any.whl", hash = "sha256:878c7741ffadbb9766211768936880bd9a660cefa1ed5f3d3746eaf9db9e014c"}, - {file = "gptcache-0.1.26.tar.gz", hash = "sha256:f960a56fa6e6b0cf7c2151892714e6089ca206b067bee821ead4c1661e478f7c"}, -] - -[package.dependencies] -cachetools = "*" -numpy = "*" -requests = "*" - [[package]] name = "greenlet" version = "2.0.2" @@ -1436,7 +1493,7 @@ name = "grpcio" version = "1.47.5" description = "HTTP/2-based RPC framework" category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "grpcio-1.47.5-cp310-cp310-linux_armv7l.whl", hash = "sha256:acc73289d0c44650aa1f21eccfa967f5623b01c3b5e2b4596fe5f9c5bf10956d"}, @@ -1498,7 +1555,7 @@ name = "grpcio-health-checking" version = "1.47.5" description = "Standard Health Checking Service for gRPC" category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "grpcio-health-checking-1.47.5.tar.gz", hash = "sha256:74f36ef2ff704c46965bd74cdea51afc0bbcde641134c9d09ecb5063391db516"}, @@ -1514,7 +1571,7 @@ name = "grpcio-reflection" version = "1.47.5" description = "Standard Protobuf Reflection Service for gRPC" category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "grpcio-reflection-1.47.5.tar.gz", hash = "sha256:ac391ec327861f16bc870638101fee80799eccf39c5b09e9ddd776d6854b9873"}, @@ -1525,6 +1582,67 @@ files = [ grpcio = ">=1.47.5" protobuf = ">=3.12.0" +[[package]] +name = "grpcio-tools" +version = "1.47.5" +description = "Protobuf code generator for gRPC" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "grpcio-tools-1.47.5.tar.gz", hash = "sha256:62ced60566a4cbcf35c57e887e2e68b4f108b3474ef3ec0022d38cd579345f92"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-linux_armv7l.whl", hash = "sha256:9f92c561b245a562110bd84d3b64b016c8af5afde39febf1f71553ae56f6e8e4"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:a0a991844a024705ad177cb858d36e3e6b329ea4a78b7f4c597b2817fc2692e7"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:935976d5436d4306de052d1e00848fa25abc667e185aaaffcd367915f33a67c7"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2481dba6a30d415a4756cd88cc380780e3f00bb41d56b8f6547bc3c09c6f4e7f"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e62176978faa96b21e4e821e7070b0feed919726ff730c0b3b7e8d106ddb45bf"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:728eb1f4ef6d380366a2de9940d1f910ece8bf4e44de5ca935cd16d4394e82ff"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d58982c747e107f65c7307ec1646cce105b0785088287bf209f545377aeedaf4"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-win32.whl", hash = "sha256:ea6d8f07b087bc2d579b7727daee2abf38fe5dc475c9e7c4f16b4a2c31895319"}, + {file = "grpcio_tools-1.47.5-cp310-cp310-win_amd64.whl", hash = "sha256:5e7a4e68072639fa767bde1011f5d83f4461a8e60651ea202af597777ee1ffd7"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-linux_armv7l.whl", hash = "sha256:bb1e066fc50ef7503b024924858658692d3e98582a9727b156f2f845da70e11e"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-macosx_10_10_universal2.whl", hash = "sha256:7d3e397a27e652ae6579f1f7dc3fc0c771db977ccaaded1fe113e882df425c15"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:b19d8f1e8422826d49fc428acc66b69aa450c70f7090681df32d535188edf524"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0e017bd1022bc981fa1629e757e0d3d4a1991f999fb90ec714c2683fe05b8fa"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abb56ea33c4a33ee3b707f62339fd579e1a8dbbfeb7665d7ff85ee837cf64794"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:02882ff2f703b75d343991608b39104f1621508cf407e427a75c1794ed0fac95"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:84395aacae4f8a3358ad648a8bacf6b15bbb8946d8cf73f47dc77cfe1a154d48"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-win32.whl", hash = "sha256:de8901c64a1091cc474318e7a013af8c30feba34c7954c29ca8f477baf07db28"}, + {file = "grpcio_tools-1.47.5-cp36-cp36m-win_amd64.whl", hash = "sha256:37cb5c3d94ba1efef0d17a66e5e69b177fc934389eda8b76b161a6623e45e714"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-linux_armv7l.whl", hash = "sha256:5c2d3a35e9341ea9c68afe289054bd8604eda4214e6d916f97b19a316537a296"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:89733edb89ec28e52dd9cc25e90b78248b6edd265f564726be2a9c4b4ee78479"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:489f41535d779287759942c6cced93c4219ea53dad46ebdc4faca6220e1dba88"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:072c84f561912400363b81af6bf5424c38fab80f0c9436c0fe19b2e7c2bcf15c"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c650233420279f943bd1dcf286742aaeb4db7cc5f6554a5e8c16c2e4fa19a28f"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:dab220aba6b5777b16df5c5b3a30f831cdbc4f493eabdaf9f6585691bad5496a"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:309ca8508f361895ef2d4f533611272228d2412c8cae754b695673c7c65a2f8b"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-win32.whl", hash = "sha256:f8ce5fb65e97866257943cbf6d504195ab55e01ef467988d86322a36041b6de8"}, + {file = "grpcio_tools-1.47.5-cp37-cp37m-win_amd64.whl", hash = "sha256:b9154a18b0ad2bc4b9ceadedd7b67bb65b500b3427495b4d224a1a835aa55ce6"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-linux_armv7l.whl", hash = "sha256:aaa4063bc05a18f32ae98e414e2472477468b966b9a1425c41eec160250beff2"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:093da28f8ce3a0eedd5370b9f09f815fb6c01fd663d60734eab5b300b9a305ec"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:0771f57585b9070086dec509b02fa2804a9d4c395e95cd7a6cb42d8f4b5683f7"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68d4cdc674c8596da8e25cf37741aab3f07bdf38731510a92019e5ec57f5fcea"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08fdce5549acca9fd7a45084c62e8ab0a1ca1c530bcbfa089625e9523f224023"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8431b9ee083bec444ca6d48705b89774f97ba0a75e8c33ef3b9a2dc6ed2aa584"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf37376da0062155d728fb9a1d522ea8f5039ebf774885d269f7772cbc3a2e6"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-win32.whl", hash = "sha256:b65a59698f938fa59fd756799cd641c3755fb09cb95de008e4d67a9e5b1af6d5"}, + {file = "grpcio_tools-1.47.5-cp38-cp38-win_amd64.whl", hash = "sha256:17c2b5ce8b3100c8da4ae5070d8d2c2466f174e66d8127fb85ef8a7937a03853"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-linux_armv7l.whl", hash = "sha256:9070301f079fef76fb0d51b84f393c6738587f3a16a2f0ced303362b0cc0ecf6"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:5bcf01116a4d3bed2faf832f8c5618d1c69473576f3925240e3c5042dfbc115e"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:b555b954aa213eac8efe7df507a178c3ab7323df9f501846a1bbccdf81354831"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7604e08530b3edc688e41aa8af46051478d417b08afdf6fc2eafb5eb90528a26"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d3f80818a560abee8189c4f0b074f45c16309b4596e013cb6ce105a022c5965"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c801ebd7fa2304ff85aa15147f134aefe33132d85308c43e46f6a5be78b5a8a8"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:235adfc22e9c703533573344de1d2394ddd92b27c82eb259bb5fb46f885159b8"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-win32.whl", hash = "sha256:d659c257cbb48c843931b584d3c3da5473fa17275e0d04af79c9e9fdd6077179"}, + {file = "grpcio_tools-1.47.5-cp39-cp39-win_amd64.whl", hash = "sha256:9d121c63ff2fddeae2c65f6675eb944f47808a242b647d80b4661b2c5e1e6732"}, +] + +[package.dependencies] +grpcio = ">=1.47.5" +protobuf = ">=3.12.0,<4.0dev" +setuptools = "*" + [[package]] name = "gunicorn" version = "20.1.0" @@ -1558,6 +1676,22 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] +[[package]] +name = "h2" +version = "4.1.0" +description = "HTTP/2 State-Machine based protocol implementation" +category = "main" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, + {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, +] + +[package.dependencies] +hpack = ">=4.0,<5" +hyperframe = ">=6.0,<7" + [[package]] name = "hnswlib" version = "0.7.0" @@ -1572,11 +1706,23 @@ files = [ [package.dependencies] numpy = "*" +[[package]] +name = "hpack" +version = "4.0.0" +description = "Pure-Python HPACK header compression" +category = "main" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, + {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, +] + [[package]] name = "httpcore" version = "0.16.3" description = "A minimal low-level HTTP client." -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1667,7 +1813,7 @@ test = ["Cython (>=0.29.24,<0.30.0)"] name = "httpx" version = "0.23.3" description = "The next generation HTTP client." -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1677,6 +1823,7 @@ files = [ [package.dependencies] certifi = "*" +h2 = {version = ">=3,<5", optional = true, markers = "extra == \"http2\""} httpcore = ">=0.15.0,<0.17.0" rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} sniffio = "*" @@ -1733,6 +1880,18 @@ files = [ [package.dependencies] pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} +[[package]] +name = "hyperframe" +version = "6.0.1" +description = "HTTP/2 framing layer for Python" +category = "main" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, + {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, +] + [[package]] name = "idna" version = "3.4" @@ -1875,7 +2034,7 @@ name = "jcloud" version = "0.2.10" description = "Simplify deploying and managing Jina projects on Jina Cloud" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "jcloud-0.2.10.tar.gz", hash = "sha256:40f9e0f8cbef4a711d58941939e206923eb1fdd65941f7b4ded4f448cc5a927f"}, @@ -1918,7 +2077,7 @@ name = "jina" version = "3.15.2" description = "Build multimodal AI services via cloud native technologies · Neural Search · Generative AI · MLOps" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "jina-3.15.2.tar.gz", hash = "sha256:41c3fbe14736edf34e69b0245410554347b209aa01f4cf8e2c65d6e3972ba0b0"}, @@ -2036,7 +2195,7 @@ name = "jina-hubble-sdk" version = "0.38.0" description = "SDK for Hubble API at Jina AI." category = "main" -optional = true +optional = false python-versions = ">=3.7.0" files = [ {file = "jina-hubble-sdk-0.38.0.tar.gz", hash = "sha256:1667917ed16d75eddd1e0d3b8e9d78ffd611de59500abeca48b05040c7571c4c"}, @@ -2057,6 +2216,24 @@ rich = "*" [package.extras] full = ["aiohttp", "black (==22.3.0)", "docker", "filelock", "flake8 (==4.0.1)", "importlib-metadata", "isort (==5.10.1)", "mock (==4.0.3)", "pathspec", "pytest (==7.0.0)", "pytest-asyncio (==0.19.0)", "pytest-cov (==3.0.0)", "pytest-mock (==3.7.0)", "python-jose", "pyyaml", "requests", "rich"] +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "joblib" version = "1.2.0" @@ -2400,6 +2577,66 @@ profiling = ["gprof2dot"] rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] +[[package]] +name = "markupsafe" +version = "2.1.2" +description = "Safely add untrusted strings to HTML/XML markup." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, + {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, +] + [[package]] name = "marshmallow" version = "3.19.0" @@ -2776,40 +3013,40 @@ numpy = ">=1.13.3" [[package]] name = "numpy" -version = "1.24.3" -description = "Fundamental package for array computing in Python" +version = "1.23.5" +description = "NumPy is the fundamental package for array computing with Python." category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, - {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, - {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, - {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, - {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, - {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, - {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, - {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, - {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, - {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, - {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, + {file = "numpy-1.23.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63"}, + {file = "numpy-1.23.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d"}, + {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7903ba8ab592b82014713c491f6c5d3a1cde5b4a3bf116404e08f5b52f6daf43"}, + {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e05b1c973a9f858c74367553e236f287e749465f773328c8ef31abe18f691e1"}, + {file = "numpy-1.23.5-cp310-cp310-win32.whl", hash = "sha256:522e26bbf6377e4d76403826ed689c295b0b238f46c28a7251ab94716da0b280"}, + {file = "numpy-1.23.5-cp310-cp310-win_amd64.whl", hash = "sha256:dbee87b469018961d1ad79b1a5d50c0ae850000b639bcb1b694e9981083243b6"}, + {file = "numpy-1.23.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ce571367b6dfe60af04e04a1834ca2dc5f46004ac1cc756fb95319f64c095a96"}, + {file = "numpy-1.23.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56e454c7833e94ec9769fa0f86e6ff8e42ee38ce0ce1fa4cbb747ea7e06d56aa"}, + {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5039f55555e1eab31124a5768898c9e22c25a65c1e0037f4d7c495a45778c9f2"}, + {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f545efd1108e647604a1b5aa809591ccd2540f468a880bedb97247e72db387"}, + {file = "numpy-1.23.5-cp311-cp311-win32.whl", hash = "sha256:b2a9ab7c279c91974f756c84c365a669a887efa287365a8e2c418f8b3ba73fb0"}, + {file = "numpy-1.23.5-cp311-cp311-win_amd64.whl", hash = "sha256:0cbe9848fad08baf71de1a39e12d1b6310f1d5b2d0ea4de051058e6e1076852d"}, + {file = "numpy-1.23.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f063b69b090c9d918f9df0a12116029e274daf0181df392839661c4c7ec9018a"}, + {file = "numpy-1.23.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0aaee12d8883552fadfc41e96b4c82ee7d794949e2a7c3b3a7201e968c7ecab9"}, + {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92c8c1e89a1f5028a4c6d9e3ccbe311b6ba53694811269b992c0b224269e2398"}, + {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d208a0f8729f3fb790ed18a003f3a57895b989b40ea4dce4717e9cf4af62c6bb"}, + {file = "numpy-1.23.5-cp38-cp38-win32.whl", hash = "sha256:06005a2ef6014e9956c09ba07654f9837d9e26696a0470e42beedadb78c11b07"}, + {file = "numpy-1.23.5-cp38-cp38-win_amd64.whl", hash = "sha256:ca51fcfcc5f9354c45f400059e88bc09215fb71a48d3768fb80e357f3b457e1e"}, + {file = "numpy-1.23.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8969bfd28e85c81f3f94eb4a66bc2cf1dbdc5c18efc320af34bffc54d6b1e38f"}, + {file = "numpy-1.23.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7ac231a08bb37f852849bbb387a20a57574a97cfc7b6cabb488a4fc8be176de"}, + {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf837dc63ba5c06dc8797c398db1e223a466c7ece27a1f7b5232ba3466aafe3d"}, + {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719"}, + {file = "numpy-1.23.5-cp39-cp39-win32.whl", hash = "sha256:af1da88f6bc3d2338ebbf0e22fe487821ea4d8e89053e25fa59d1d79786e7481"}, + {file = "numpy-1.23.5-cp39-cp39-win_amd64.whl", hash = "sha256:09b7847f7e83ca37c6e627682f145856de331049013853f344f37b0c9690e3df"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:abdde9f795cf292fb9651ed48185503a2ff29be87770c3b8e2a14b0cd7aa16f8"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a909a8bae284d46bbfdefbdd4a262ba19d3bc9921b1e76126b1d21c3c34135"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:01dd17cbb340bf0fc23981e52e1d18a9d4050792e8fb8363cecbf066a84b827d"}, + {file = "numpy-1.23.5.tar.gz", hash = "sha256:1b1766d6f397c18153d40015ddfc79ddb715cabadc04d2d228d4e5a8bc4ded1a"}, ] [[package]] @@ -2923,7 +3160,7 @@ name = "opentelemetry-api" version = "1.18.0" description = "OpenTelemetry Python API" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_api-1.18.0-py3-none-any.whl", hash = "sha256:d05bcc94ec239fd76fd90d784c5e3ad081a8a1ac2ffc8a2c83a49ace052d1492"}, @@ -2940,7 +3177,7 @@ name = "opentelemetry-exporter-otlp" version = "1.18.0" description = "OpenTelemetry Collector Exporters" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp-1.18.0-py3-none-any.whl", hash = "sha256:2b8d18aa3f8fa360df2fe6c274132cf38939a02f8aa621d6ed060a920aa9e4c6"}, @@ -2956,7 +3193,7 @@ name = "opentelemetry-exporter-otlp-proto-common" version = "1.18.0" description = "OpenTelemetry Protobuf encoding" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp_proto_common-1.18.0-py3-none-any.whl", hash = "sha256:276073ccc8c6e6570fe05ca8ca0de77d662bc89bc614ec8bfbc855112f7e25e3"}, @@ -2971,7 +3208,7 @@ name = "opentelemetry-exporter-otlp-proto-grpc" version = "1.18.0" description = "OpenTelemetry Collector Protobuf over gRPC Exporter" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp_proto_grpc-1.18.0-py3-none-any.whl", hash = "sha256:c773bc9df2c9d6464f0d5936963399b2fc440f0616c1277f29512d540ad7e0a2"}, @@ -2996,7 +3233,7 @@ name = "opentelemetry-exporter-otlp-proto-http" version = "1.18.0" description = "OpenTelemetry Collector Protobuf over HTTP Exporter" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp_proto_http-1.18.0-py3-none-any.whl", hash = "sha256:c22110705473f1c61bd4d74ded3b8bd3fac66ffbe7d9ba376267d8539919ed90"}, @@ -3021,7 +3258,7 @@ name = "opentelemetry-exporter-prometheus" version = "1.12.0rc1" description = "Prometheus Metric Exporter for OpenTelemetry" category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "opentelemetry-exporter-prometheus-1.12.0rc1.tar.gz", hash = "sha256:f10c6c243d69d5b63f755885b36a4ce8ef2cdf3e737c4e6bf00f32e87668f0a9"}, @@ -3038,7 +3275,7 @@ name = "opentelemetry-instrumentation" version = "0.39b0" description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation-0.39b0-py3-none-any.whl", hash = "sha256:fcfd74413159fe797e343104f7e85a3f8146713634debcac10a057ac7f1eb011"}, @@ -3055,7 +3292,7 @@ name = "opentelemetry-instrumentation-aiohttp-client" version = "0.39b0" description = "OpenTelemetry aiohttp client instrumentation" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_aiohttp_client-0.39b0-py3-none-any.whl", hash = "sha256:315adf314f35532677b7ae2abd9a663ec86df7183594605592f0e89e599d86ca"}, @@ -3078,7 +3315,7 @@ name = "opentelemetry-instrumentation-asgi" version = "0.39b0" description = "ASGI instrumentation for OpenTelemetry" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_asgi-0.39b0-py3-none-any.whl", hash = "sha256:cb9cbf56e32be12b0e5e70c21cf27999f10920afc73110457f4e4b0ec4078c5f"}, @@ -3101,7 +3338,7 @@ name = "opentelemetry-instrumentation-fastapi" version = "0.39b0" description = "OpenTelemetry FastAPI Instrumentation" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_fastapi-0.39b0-py3-none-any.whl", hash = "sha256:33223b46393ef63229d35c4e0903e900674d3dfc65ada49fbfd51db8742295cb"}, @@ -3124,7 +3361,7 @@ name = "opentelemetry-instrumentation-grpc" version = "0.39b0" description = "OpenTelemetry gRPC instrumentation" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_grpc-0.39b0-py3-none-any.whl", hash = "sha256:1ab7a1e4a43efd8e827d1666065253fdc4dca76ca7bcf43417fe7523999e3145"}, @@ -3147,7 +3384,7 @@ name = "opentelemetry-proto" version = "1.18.0" description = "OpenTelemetry Python Proto" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_proto-1.18.0-py3-none-any.whl", hash = "sha256:34d1c49283f0246a58761d9322d5a79702a09afda0bb181bb6378ed26862e446"}, @@ -3162,7 +3399,7 @@ name = "opentelemetry-sdk" version = "1.18.0" description = "OpenTelemetry Python SDK" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_sdk-1.18.0-py3-none-any.whl", hash = "sha256:a097cc1e0db6ff33b4d250a9350dc17975d24a22aa667fca2866e60c51306723"}, @@ -3180,7 +3417,7 @@ name = "opentelemetry-semantic-conventions" version = "0.39b0" description = "OpenTelemetry Semantic Conventions" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_semantic_conventions-0.39b0-py3-none-any.whl", hash = "sha256:0dd7a9dc0dfde2335f643705bba8f7c44182c797bc208b7601f0b8e8211cfd5c"}, @@ -3192,7 +3429,7 @@ name = "opentelemetry-util-http" version = "0.39b0" description = "Web util for OpenTelemetry" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_util_http-0.39b0-py3-none-any.whl", hash = "sha256:587c3f8931b8a1e910a04fd736e8ff1386fe25c09dc92dc85104679112221483"}, @@ -3454,6 +3691,26 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "portalocker" +version = "2.7.0" +description = "Wraps the portalocker recipe for easy usage" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "portalocker-2.7.0-py2.py3-none-any.whl", hash = "sha256:a07c5b4f3985c3cf4798369631fb7011adb498e2a46d8440efc75a8f29a0f983"}, + {file = "portalocker-2.7.0.tar.gz", hash = "sha256:032e81d534a88ec1736d03f780ba073f047a06c478b06e2937486f334e955c51"}, +] + +[package.dependencies] +pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""} + +[package.extras] +docs = ["sphinx (>=1.7.1)"] +redis = ["redis"] +tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)"] + [[package]] name = "posthog" version = "3.0.1" @@ -3483,7 +3740,7 @@ name = "prometheus-client" version = "0.17.0" description = "Python client for the Prometheus monitoring system." category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "prometheus_client-0.17.0-py3-none-any.whl", hash = "sha256:a77b708cf083f4d1a3fb3ce5c95b4afa32b9c521ae363354a4a910204ea095ce"}, @@ -3510,25 +3767,34 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "4.23.1" -description = "" +version = "3.20.3" +description = "Protocol Buffers" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "protobuf-4.23.1-cp310-abi3-win32.whl", hash = "sha256:410bcc0a5b279f634d3e16082ce221dfef7c3392fac723500e2e64d1806dd2be"}, - {file = "protobuf-4.23.1-cp310-abi3-win_amd64.whl", hash = "sha256:32e78beda26d7a101fecf15d7a4a792278a0d26a31bc327ff05564a9d68ab8ee"}, - {file = "protobuf-4.23.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f9510cac91e764e86acd74e2b7f7bc5e6127a7f3fb646d7c8033cfb84fd1176a"}, - {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:346990f634272caac1f09efbcfbbacb23098b1f606d172534c6fa2d9758bb436"}, - {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:3ce113b3f3362493bddc9069c2163a38f240a9ed685ff83e7bcb756b05e1deb0"}, - {file = "protobuf-4.23.1-cp37-cp37m-win32.whl", hash = "sha256:2036a3a1e7fc27f973fa0a7888dce712393af644f4695385f117886abc792e39"}, - {file = "protobuf-4.23.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3b8905eafe4439076e1f58e9d1fa327025fd2777cf90f14083092ae47f77b0aa"}, - {file = "protobuf-4.23.1-cp38-cp38-win32.whl", hash = "sha256:5b9cd6097e6acae48a68cb29b56bc79339be84eca65b486910bb1e7a30e2b7c1"}, - {file = "protobuf-4.23.1-cp38-cp38-win_amd64.whl", hash = "sha256:decf119d54e820f298ee6d89c72d6b289ea240c32c521f00433f9dc420595f38"}, - {file = "protobuf-4.23.1-cp39-cp39-win32.whl", hash = "sha256:91fac0753c3c4951fbb98a93271c43cc7cf3b93cf67747b3e600bb1e5cc14d61"}, - {file = "protobuf-4.23.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac50be82491369a9ec3710565777e4da87c6d2e20404e0abb1f3a8f10ffd20f0"}, - {file = "protobuf-4.23.1-py3-none-any.whl", hash = "sha256:65f0ac96ef67d7dd09b19a46aad81a851b6f85f89725577f16de38f2d68ad477"}, - {file = "protobuf-4.23.1.tar.gz", hash = "sha256:95789b569418a3e32a53f43d7763be3d490a831e9c08042539462b6d972c2d7e"}, + {file = "protobuf-3.20.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99"}, + {file = "protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e"}, + {file = "protobuf-3.20.3-cp310-cp310-win32.whl", hash = "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c"}, + {file = "protobuf-3.20.3-cp310-cp310-win_amd64.whl", hash = "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7"}, + {file = "protobuf-3.20.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469"}, + {file = "protobuf-3.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4"}, + {file = "protobuf-3.20.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4"}, + {file = "protobuf-3.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454"}, + {file = "protobuf-3.20.3-cp37-cp37m-win32.whl", hash = "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905"}, + {file = "protobuf-3.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c"}, + {file = "protobuf-3.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7"}, + {file = "protobuf-3.20.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"}, + {file = "protobuf-3.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050"}, + {file = "protobuf-3.20.3-cp38-cp38-win32.whl", hash = "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86"}, + {file = "protobuf-3.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9"}, + {file = "protobuf-3.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b"}, + {file = "protobuf-3.20.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b"}, + {file = "protobuf-3.20.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402"}, + {file = "protobuf-3.20.3-cp39-cp39-win32.whl", hash = "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480"}, + {file = "protobuf-3.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7"}, + {file = "protobuf-3.20.3-py2.py3-none-any.whl", hash = "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db"}, + {file = "protobuf-3.20.3.tar.gz", hash = "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2"}, ] [[package]] @@ -3968,7 +4234,7 @@ name = "python-jose" version = "3.3.0" description = "JOSE implementation in Python" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "python-jose-3.3.0.tar.gz", hash = "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a"}, @@ -4002,7 +4268,7 @@ name = "python-multipart" version = "0.0.6" description = "A streaming multipart parser for Python" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"}, @@ -4116,94 +4382,116 @@ files = [ [[package]] name = "pyzmq" -version = "25.0.2" +version = "25.1.0" description = "Python bindings for 0MQ" category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ac178e666c097c8d3deb5097b58cd1316092fc43e8ef5b5fdb259b51da7e7315"}, - {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:659e62e1cbb063151c52f5b01a38e1df6b54feccfa3e2509d44c35ca6d7962ee"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8280ada89010735a12b968ec3ea9a468ac2e04fddcc1cede59cb7f5178783b9c"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b5eeb5278a8a636bb0abdd9ff5076bcbb836cd2302565df53ff1fa7d106d54"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a2e5fe42dfe6b73ca120b97ac9f34bfa8414feb15e00e37415dbd51cf227ef6"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:827bf60e749e78acb408a6c5af6688efbc9993e44ecc792b036ec2f4b4acf485"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7b504ae43d37e282301da586529e2ded8b36d4ee2cd5e6db4386724ddeaa6bbc"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb1f69a0a2a2b1aae8412979dd6293cc6bcddd4439bf07e4758d864ddb112354"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b9c9cc965cdf28381e36da525dcb89fc1571d9c54800fdcd73e3f73a2fc29bd"}, - {file = "pyzmq-25.0.2-cp310-cp310-win32.whl", hash = "sha256:24abbfdbb75ac5039205e72d6c75f10fc39d925f2df8ff21ebc74179488ebfca"}, - {file = "pyzmq-25.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6a821a506822fac55d2df2085a52530f68ab15ceed12d63539adc32bd4410f6e"}, - {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9af0bb0277e92f41af35e991c242c9c71920169d6aa53ade7e444f338f4c8128"}, - {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54a96cf77684a3a537b76acfa7237b1e79a8f8d14e7f00e0171a94b346c5293e"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88649b19ede1cab03b96b66c364cbbf17c953615cdbc844f7f6e5f14c5e5261c"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:715cff7644a80a7795953c11b067a75f16eb9fc695a5a53316891ebee7f3c9d5"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:312b3f0f066b4f1d17383aae509bacf833ccaf591184a1f3c7a1661c085063ae"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d488c5c8630f7e782e800869f82744c3aca4aca62c63232e5d8c490d3d66956a"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:38d9f78d69bcdeec0c11e0feb3bc70f36f9b8c44fc06e5d06d91dc0a21b453c7"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3059a6a534c910e1d5d068df42f60d434f79e6cc6285aa469b384fa921f78cf8"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6526d097b75192f228c09d48420854d53dfbc7abbb41b0e26f363ccb26fbc177"}, - {file = "pyzmq-25.0.2-cp311-cp311-win32.whl", hash = "sha256:5c5fbb229e40a89a2fe73d0c1181916f31e30f253cb2d6d91bea7927c2e18413"}, - {file = "pyzmq-25.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:ed15e3a2c3c2398e6ae5ce86d6a31b452dfd6ad4cd5d312596b30929c4b6e182"}, - {file = "pyzmq-25.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:032f5c8483c85bf9c9ca0593a11c7c749d734ce68d435e38c3f72e759b98b3c9"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:374b55516393bfd4d7a7daa6c3b36d6dd6a31ff9d2adad0838cd6a203125e714"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08bfcc21b5997a9be4fefa405341320d8e7f19b4d684fb9c0580255c5bd6d695"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1a843d26a8da1b752c74bc019c7b20e6791ee813cd6877449e6a1415589d22ff"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b48616a09d7df9dbae2f45a0256eee7b794b903ddc6d8657a9948669b345f220"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d4427b4a136e3b7f85516c76dd2e0756c22eec4026afb76ca1397152b0ca8145"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:26b0358e8933990502f4513c991c9935b6c06af01787a36d133b7c39b1df37fa"}, - {file = "pyzmq-25.0.2-cp36-cp36m-win32.whl", hash = "sha256:c8fedc3ccd62c6b77dfe6f43802057a803a411ee96f14e946f4a76ec4ed0e117"}, - {file = "pyzmq-25.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:2da6813b7995b6b1d1307329c73d3e3be2fd2d78e19acfc4eff2e27262732388"}, - {file = "pyzmq-25.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a35960c8b2f63e4ef67fd6731851030df68e4b617a6715dd11b4b10312d19fef"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef2a0b880ab40aca5a878933376cb6c1ec483fba72f7f34e015c0f675c90b20"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:85762712b74c7bd18e340c3639d1bf2f23735a998d63f46bb6584d904b5e401d"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:64812f29d6eee565e129ca14b0c785744bfff679a4727137484101b34602d1a7"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:510d8e55b3a7cd13f8d3e9121edf0a8730b87d925d25298bace29a7e7bc82810"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b164cc3c8acb3d102e311f2eb6f3c305865ecb377e56adc015cb51f721f1dda6"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:28fdb9224a258134784a9cf009b59265a9dde79582fb750d4e88a6bcbc6fa3dc"}, - {file = "pyzmq-25.0.2-cp37-cp37m-win32.whl", hash = "sha256:dd771a440effa1c36d3523bc6ba4e54ff5d2e54b4adcc1e060d8f3ca3721d228"}, - {file = "pyzmq-25.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:9bdc40efb679b9dcc39c06d25629e55581e4c4f7870a5e88db4f1c51ce25e20d"}, - {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:1f82906a2d8e4ee310f30487b165e7cc8ed09c009e4502da67178b03083c4ce0"}, - {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:21ec0bf4831988af43c8d66ba3ccd81af2c5e793e1bf6790eb2d50e27b3c570a"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbce982a17c88d2312ec2cf7673985d444f1beaac6e8189424e0a0e0448dbb3"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9e1d2f2d86fc75ed7f8845a992c5f6f1ab5db99747fb0d78b5e4046d041164d2"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e92ff20ad5d13266bc999a29ed29a3b5b101c21fdf4b2cf420c09db9fb690e"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edbbf06cc2719889470a8d2bf5072bb00f423e12de0eb9ffec946c2c9748e149"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77942243ff4d14d90c11b2afd8ee6c039b45a0be4e53fb6fa7f5e4fd0b59da39"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ab046e9cb902d1f62c9cc0eca055b1d11108bdc271caf7c2171487298f229b56"}, - {file = "pyzmq-25.0.2-cp38-cp38-win32.whl", hash = "sha256:ad761cfbe477236802a7ab2c080d268c95e784fe30cafa7e055aacd1ca877eb0"}, - {file = "pyzmq-25.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8560756318ec7c4c49d2c341012167e704b5a46d9034905853c3d1ade4f55bee"}, - {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:ab2c056ac503f25a63f6c8c6771373e2a711b98b304614151dfb552d3d6c81f6"}, - {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cca8524b61c0eaaa3505382dc9b9a3bc8165f1d6c010fdd1452c224225a26689"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb9f7eae02d3ac42fbedad30006b7407c984a0eb4189a1322241a20944d61e5"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5eaeae038c68748082137d6896d5c4db7927e9349237ded08ee1bbd94f7361c9"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a31992a8f8d51663ebf79df0df6a04ffb905063083d682d4380ab8d2c67257c"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6a979e59d2184a0c8f2ede4b0810cbdd86b64d99d9cc8a023929e40dce7c86cc"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1f124cb73f1aa6654d31b183810febc8505fd0c597afa127c4f40076be4574e0"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:65c19a63b4a83ae45d62178b70223adeee5f12f3032726b897431b6553aa25af"}, - {file = "pyzmq-25.0.2-cp39-cp39-win32.whl", hash = "sha256:83d822e8687621bed87404afc1c03d83fa2ce39733d54c2fd52d8829edb8a7ff"}, - {file = "pyzmq-25.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:24683285cc6b7bf18ad37d75b9db0e0fefe58404e7001f1d82bf9e721806daa7"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a4b4261eb8f9ed71f63b9eb0198dd7c934aa3b3972dac586d0ef502ba9ab08b"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:62ec8d979f56c0053a92b2b6a10ff54b9ec8a4f187db2b6ec31ee3dd6d3ca6e2"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:affec1470351178e892121b3414c8ef7803269f207bf9bef85f9a6dd11cde264"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc71111433bd6ec8607a37b9211f4ef42e3d3b271c6d76c813669834764b248"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6fadc60970714d86eff27821f8fb01f8328dd36bebd496b0564a500fe4a9e354"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:269968f2a76c0513490aeb3ba0dc3c77b7c7a11daa894f9d1da88d4a0db09835"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f7c8b8368e84381ae7c57f1f5283b029c888504aaf4949c32e6e6fb256ec9bf0"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25e6873a70ad5aa31e4a7c41e5e8c709296edef4a92313e1cd5fc87bbd1874e2"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b733076ff46e7db5504c5e7284f04a9852c63214c74688bdb6135808531755a3"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a6f6ae12478fdc26a6d5fdb21f806b08fa5403cd02fd312e4cb5f72df078f96f"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:67da1c213fbd208906ab3470cfff1ee0048838365135a9bddc7b40b11e6d6c89"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531e36d9fcd66f18de27434a25b51d137eb546931033f392e85674c7a7cea853"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34a6fddd159ff38aa9497b2e342a559f142ab365576284bc8f77cb3ead1f79c5"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b491998ef886662c1f3d49ea2198055a9a536ddf7430b051b21054f2a5831800"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5d496815074e3e3d183fe2c7fcea2109ad67b74084c254481f87b64e04e9a471"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:56a94ab1d12af982b55ca96c6853db6ac85505e820d9458ac76364c1998972f4"}, - {file = "pyzmq-25.0.2.tar.gz", hash = "sha256:6b8c1bbb70e868dc88801aa532cae6bd4e3b5233784692b786f17ad2962e5149"}, + {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:1a6169e69034eaa06823da6a93a7739ff38716142b3596c180363dee729d713d"}, + {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:19d0383b1f18411d137d891cab567de9afa609b214de68b86e20173dc624c101"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1e931d9a92f628858a50f5bdffdfcf839aebe388b82f9d2ccd5d22a38a789dc"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97d984b1b2f574bc1bb58296d3c0b64b10e95e7026f8716ed6c0b86d4679843f"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:154bddda2a351161474b36dba03bf1463377ec226a13458725183e508840df89"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cb6d161ae94fb35bb518b74bb06b7293299c15ba3bc099dccd6a5b7ae589aee3"}, + {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:90146ab578931e0e2826ee39d0c948d0ea72734378f1898939d18bc9c823fcf9"}, + {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:831ba20b660b39e39e5ac8603e8193f8fce1ee03a42c84ade89c36a251449d80"}, + {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3a522510e3434e12aff80187144c6df556bb06fe6b9d01b2ecfbd2b5bfa5c60c"}, + {file = "pyzmq-25.1.0-cp310-cp310-win32.whl", hash = "sha256:be24a5867b8e3b9dd5c241de359a9a5217698ff616ac2daa47713ba2ebe30ad1"}, + {file = "pyzmq-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:5693dcc4f163481cf79e98cf2d7995c60e43809e325b77a7748d8024b1b7bcba"}, + {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:13bbe36da3f8aaf2b7ec12696253c0bf6ffe05f4507985a8844a1081db6ec22d"}, + {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:69511d604368f3dc58d4be1b0bad99b61ee92b44afe1cd9b7bd8c5e34ea8248a"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a983c8694667fd76d793ada77fd36c8317e76aa66eec75be2653cef2ea72883"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:332616f95eb400492103ab9d542b69d5f0ff628b23129a4bc0a2fd48da6e4e0b"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58416db767787aedbfd57116714aad6c9ce57215ffa1c3758a52403f7c68cff5"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cad9545f5801a125f162d09ec9b724b7ad9b6440151b89645241d0120e119dcc"}, + {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d6128d431b8dfa888bf51c22a04d48bcb3d64431caf02b3cb943269f17fd2994"}, + {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2b15247c49d8cbea695b321ae5478d47cffd496a2ec5ef47131a9e79ddd7e46c"}, + {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:442d3efc77ca4d35bee3547a8e08e8d4bb88dadb54a8377014938ba98d2e074a"}, + {file = "pyzmq-25.1.0-cp311-cp311-win32.whl", hash = "sha256:65346f507a815a731092421d0d7d60ed551a80d9b75e8b684307d435a5597425"}, + {file = "pyzmq-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b45d722046fea5a5694cba5d86f21f78f0052b40a4bbbbf60128ac55bfcc7b6"}, + {file = "pyzmq-25.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f45808eda8b1d71308c5416ef3abe958f033fdbb356984fabbfc7887bed76b3f"}, + {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b697774ea8273e3c0460cf0bba16cd85ca6c46dfe8b303211816d68c492e132"}, + {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b324fa769577fc2c8f5efcd429cef5acbc17d63fe15ed16d6dcbac2c5eb00849"}, + {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5873d6a60b778848ce23b6c0ac26c39e48969823882f607516b91fb323ce80e5"}, + {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f0d9e7ba6a815a12c8575ba7887da4b72483e4cfc57179af10c9b937f3f9308f"}, + {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:414b8beec76521358b49170db7b9967d6974bdfc3297f47f7d23edec37329b00"}, + {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:01f06f33e12497dca86353c354461f75275a5ad9eaea181ac0dc1662da8074fa"}, + {file = "pyzmq-25.1.0-cp36-cp36m-win32.whl", hash = "sha256:b5a07c4f29bf7cb0164664ef87e4aa25435dcc1f818d29842118b0ac1eb8e2b5"}, + {file = "pyzmq-25.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:968b0c737797c1809ec602e082cb63e9824ff2329275336bb88bd71591e94a90"}, + {file = "pyzmq-25.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:47b915ba666c51391836d7ed9a745926b22c434efa76c119f77bcffa64d2c50c"}, + {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5af31493663cf76dd36b00dafbc839e83bbca8a0662931e11816d75f36155897"}, + {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5489738a692bc7ee9a0a7765979c8a572520d616d12d949eaffc6e061b82b4d1"}, + {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1fc56a0221bdf67cfa94ef2d6ce5513a3d209c3dfd21fed4d4e87eca1822e3a3"}, + {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:75217e83faea9edbc29516fc90c817bc40c6b21a5771ecb53e868e45594826b0"}, + {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3830be8826639d801de9053cf86350ed6742c4321ba4236e4b5568528d7bfed7"}, + {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3575699d7fd7c9b2108bc1c6128641a9a825a58577775ada26c02eb29e09c517"}, + {file = "pyzmq-25.1.0-cp37-cp37m-win32.whl", hash = "sha256:95bd3a998d8c68b76679f6b18f520904af5204f089beebb7b0301d97704634dd"}, + {file = "pyzmq-25.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:dbc466744a2db4b7ca05589f21ae1a35066afada2f803f92369f5877c100ef62"}, + {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:3bed53f7218490c68f0e82a29c92335daa9606216e51c64f37b48eb78f1281f4"}, + {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eb52e826d16c09ef87132c6e360e1879c984f19a4f62d8a935345deac43f3c12"}, + {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ddbef8b53cd16467fdbfa92a712eae46dd066aa19780681a2ce266e88fbc7165"}, + {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9301cf1d7fc1ddf668d0abbe3e227fc9ab15bc036a31c247276012abb921b5ff"}, + {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e23a8c3b6c06de40bdb9e06288180d630b562db8ac199e8cc535af81f90e64b"}, + {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4a82faae00d1eed4809c2f18b37f15ce39a10a1c58fe48b60ad02875d6e13d80"}, + {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8398a1b1951aaa330269c35335ae69744be166e67e0ebd9869bdc09426f3871"}, + {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d40682ac60b2a613d36d8d3a0cd14fbdf8e7e0618fbb40aa9fa7b796c9081584"}, + {file = "pyzmq-25.1.0-cp38-cp38-win32.whl", hash = "sha256:33d5c8391a34d56224bccf74f458d82fc6e24b3213fc68165c98b708c7a69325"}, + {file = "pyzmq-25.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c66b7ff2527e18554030319b1376d81560ca0742c6e0b17ff1ee96624a5f1afd"}, + {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:af56229ea6527a849ac9fb154a059d7e32e77a8cba27e3e62a1e38d8808cb1a5"}, + {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bdca18b94c404af6ae5533cd1bc310c4931f7ac97c148bbfd2cd4bdd62b96253"}, + {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b6b42f7055bbc562f63f3df3b63e3dd1ebe9727ff0f124c3aa7bcea7b3a00f9"}, + {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c2fc7aad520a97d64ffc98190fce6b64152bde57a10c704b337082679e74f67"}, + {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be86a26415a8b6af02cd8d782e3a9ae3872140a057f1cadf0133de685185c02b"}, + {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:851fb2fe14036cfc1960d806628b80276af5424db09fe5c91c726890c8e6d943"}, + {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2a21fec5c3cea45421a19ccbe6250c82f97af4175bc09de4d6dd78fb0cb4c200"}, + {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bad172aba822444b32eae54c2d5ab18cd7dee9814fd5c7ed026603b8cae2d05f"}, + {file = "pyzmq-25.1.0-cp39-cp39-win32.whl", hash = "sha256:4d67609b37204acad3d566bb7391e0ecc25ef8bae22ff72ebe2ad7ffb7847158"}, + {file = "pyzmq-25.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:71c7b5896e40720d30cd77a81e62b433b981005bbff0cb2f739e0f8d059b5d99"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4cb27ef9d3bdc0c195b2dc54fcb8720e18b741624686a81942e14c8b67cc61a6"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0c4fc2741e0513b5d5a12fe200d6785bbcc621f6f2278893a9ca7bed7f2efb7d"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fc34fdd458ff77a2a00e3c86f899911f6f269d393ca5675842a6e92eea565bae"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8751f9c1442624da391bbd92bd4b072def6d7702a9390e4479f45c182392ff78"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6581e886aec3135964a302a0f5eb68f964869b9efd1dbafdebceaaf2934f8a68"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5482f08d2c3c42b920e8771ae8932fbaa0a67dff925fc476996ddd8155a170f3"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7fbcafa3ea16d1de1f213c226005fea21ee16ed56134b75b2dede5a2129e62"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:adecf6d02b1beab8d7c04bc36f22bb0e4c65a35eb0b4750b91693631d4081c70"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6d39e42a0aa888122d1beb8ec0d4ddfb6c6b45aecb5ba4013c27e2f28657765"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7018289b402ebf2b2c06992813523de61d4ce17bd514c4339d8f27a6f6809492"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9e68ae9864d260b18f311b68d29134d8776d82e7f5d75ce898b40a88df9db30f"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e21cc00e4debe8f54c3ed7b9fcca540f46eee12762a9fa56feb8512fd9057161"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f666ae327a6899ff560d741681fdcdf4506f990595201ed39b44278c471ad98"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f5efcc29056dfe95e9c9db0dfbb12b62db9c4ad302f812931b6d21dd04a9119"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:48e5e59e77c1a83162ab3c163fc01cd2eebc5b34560341a67421b09be0891287"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:108c96ebbd573d929740d66e4c3d1bdf31d5cde003b8dc7811a3c8c5b0fc173b"}, + {file = "pyzmq-25.1.0.tar.gz", hash = "sha256:80c41023465d36280e801564a69cbfce8ae85ff79b080e1913f6e90481fb8957"}, ] [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "qdrant-client" +version = "1.2.0" +description = "Client library for the Qdrant vector search engine" +category = "main" +optional = false +python-versions = ">=3.7,<3.12" +files = [ + {file = "qdrant_client-1.2.0-py3-none-any.whl", hash = "sha256:e84e43bee529e27990aa5bad487bab4204eb20bda0414916498d8bb80ce601e6"}, + {file = "qdrant_client-1.2.0.tar.gz", hash = "sha256:5a3d9f89adce392a2ba619cfd5b9f7afb13e5146c49e88ed80469993f0fadbf0"}, +] + +[package.dependencies] +grpcio = ">=1.41.0" +grpcio-tools = ">=1.41.0" +httpx = {version = ">=0.14.0", extras = ["http2"]} +numpy = {version = ">=1.21", markers = "python_version >= \"3.8\""} +portalocker = ">=2.7.0,<3.0.0" +pydantic = ">=1.8,<2.0" +typing-extensions = ">=4.0.0,<4.6.0" +urllib3 = ">=1.26.14,<2.0.0" + [[package]] name = "regex" version = "2023.5.5" @@ -4304,21 +4592,21 @@ files = [ [[package]] name = "requests" -version = "2.31.0" +version = "2.28.2" description = "Python HTTP for Humans." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.7, <4" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, + {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" +urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] @@ -4328,7 +4616,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rfc3986" version = "1.5.0" description = "Validating URI References per RFC 3986" -category = "dev" +category = "main" optional = false python-versions = "*" files = [ @@ -4403,6 +4691,166 @@ files = [ {file = "ruff-0.0.254.tar.gz", hash = "sha256:0eb66c9520151d3bd950ea43b3a088618a8e4e10a5014a72687881e6f3606312"}, ] +[[package]] +name = "scikit-learn" +version = "1.2.2" +description = "A set of python modules for machine learning and data mining" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "scikit-learn-1.2.2.tar.gz", hash = "sha256:8429aea30ec24e7a8c7ed8a3fa6213adf3814a6efbea09e16e0a0c71e1a1a3d7"}, + {file = "scikit_learn-1.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99cc01184e347de485bf253d19fcb3b1a3fb0ee4cea5ee3c43ec0cc429b6d29f"}, + {file = "scikit_learn-1.2.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e6e574db9914afcb4e11ade84fab084536a895ca60aadea3041e85b8ac963edb"}, + {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fe83b676f407f00afa388dd1fdd49e5c6612e551ed84f3b1b182858f09e987d"}, + {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2642baa0ad1e8f8188917423dd73994bf25429f8893ddbe115be3ca3183584"}, + {file = "scikit_learn-1.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ad66c3848c0a1ec13464b2a95d0a484fd5b02ce74268eaa7e0c697b904f31d6c"}, + {file = "scikit_learn-1.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfeaf8be72117eb61a164ea6fc8afb6dfe08c6f90365bde2dc16456e4bc8e45f"}, + {file = "scikit_learn-1.2.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:fe0aa1a7029ed3e1dcbf4a5bc675aa3b1bc468d9012ecf6c6f081251ca47f590"}, + {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:065e9673e24e0dc5113e2dd2b4ca30c9d8aa2fa90f4c0597241c93b63130d233"}, + {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf036ea7ef66115e0d49655f16febfa547886deba20149555a41d28f56fd6d3c"}, + {file = "scikit_learn-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8b0670d4224a3c2d596fd572fb4fa673b2a0ccfb07152688ebd2ea0b8c61025c"}, + {file = "scikit_learn-1.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9c710ff9f9936ba8a3b74a455ccf0dcf59b230caa1e9ba0223773c490cab1e51"}, + {file = "scikit_learn-1.2.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:2dd3ffd3950e3d6c0c0ef9033a9b9b32d910c61bd06cb8206303fb4514b88a49"}, + {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44b47a305190c28dd8dd73fc9445f802b6ea716669cfc22ab1eb97b335d238b1"}, + {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:953236889928d104c2ef14027539f5f2609a47ebf716b8cbe4437e85dce42744"}, + {file = "scikit_learn-1.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:7f69313884e8eb311460cc2f28676d5e400bd929841a2c8eb8742ae78ebf7c20"}, + {file = "scikit_learn-1.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8156db41e1c39c69aa2d8599ab7577af53e9e5e7a57b0504e116cc73c39138dd"}, + {file = "scikit_learn-1.2.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fe175ee1dab589d2e1033657c5b6bec92a8a3b69103e3dd361b58014729975c3"}, + {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d5312d9674bed14f73773d2acf15a3272639b981e60b72c9b190a0cffed5bad"}, + {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea061bf0283bf9a9f36ea3c5d3231ba2176221bbd430abd2603b1c3b2ed85c89"}, + {file = "scikit_learn-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6477eed40dbce190f9f9e9d0d37e020815825b300121307942ec2110302b66a3"}, +] + +[package.dependencies] +joblib = ">=1.1.1" +numpy = ">=1.17.3" +scipy = ">=1.3.2" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=22.3.0)", "flake8 (>=3.8.2)", "matplotlib (>=3.1.3)", "mypy (>=0.961)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=5.3.1)", "pytest-cov (>=2.9.0)", "scikit-image (>=0.16.2)"] + +[[package]] +name = "scipy" +version = "1.10.1" +description = "Fundamental algorithms for scientific computing in Python" +category = "main" +optional = false +python-versions = "<3.12,>=3.8" +files = [ + {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, + {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, + {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, + {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"}, + {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"}, + {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"}, + {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"}, + {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"}, + {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"}, + {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"}, + {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"}, + {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"}, + {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"}, + {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"}, + {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"}, + {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"}, + {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"}, + {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"}, + {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"}, + {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, + {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, +] + +[package.dependencies] +numpy = ">=1.19.5,<1.27.0" + +[package.extras] +dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "sentence-transformers" +version = "2.2.2" +description = "Multilingual text embeddings" +category = "main" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "sentence-transformers-2.2.2.tar.gz", hash = "sha256:dbc60163b27de21076c9a30d24b5b7b6fa05141d68cf2553fa9a77bf79a29136"}, +] + +[package.dependencies] +huggingface-hub = ">=0.4.0" +nltk = "*" +numpy = "*" +scikit-learn = "*" +scipy = "*" +sentencepiece = "*" +torch = ">=1.6.0" +torchvision = "*" +tqdm = "*" +transformers = ">=4.6.0,<5.0.0" + +[[package]] +name = "sentencepiece" +version = "0.1.99" +description = "SentencePiece python wrapper" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0eb528e70571b7c02723e5804322469b82fe7ea418c96051d0286c0fa028db73"}, + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:77d7fafb2c4e4659cbdf303929503f37a26eabc4ff31d3a79bf1c5a1b338caa7"}, + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be9cf5b9e404c245aeb3d3723c737ba7a8f5d4ba262ef233a431fa6c45f732a0"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baed1a26464998f9710d20e52607c29ffd4293e7c71c6a1f83f51ad0911ec12c"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9832f08bb372d4c8b567612f8eab9e36e268dff645f1c28f9f8e851be705f6d1"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:019e7535108e309dae2b253a75834fc3128240aa87c00eb80732078cdc182588"}, + {file = "sentencepiece-0.1.99-cp310-cp310-win32.whl", hash = "sha256:fa16a830416bb823fa2a52cbdd474d1f7f3bba527fd2304fb4b140dad31bb9bc"}, + {file = "sentencepiece-0.1.99-cp310-cp310-win_amd64.whl", hash = "sha256:14b0eccb7b641d4591c3e12ae44cab537d68352e4d3b6424944f0c447d2348d5"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6d3c56f24183a1e8bd61043ff2c58dfecdc68a5dd8955dc13bab83afd5f76b81"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed6ea1819fd612c989999e44a51bf556d0ef6abfb553080b9be3d347e18bcfb7"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2a0260cd1fb7bd8b4d4f39dc2444a8d5fd4e0a0c4d5c899810ef1abf99b2d45"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a1abff4d1ff81c77cac3cc6fefa34fa4b8b371e5ee51cb7e8d1ebc996d05983"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:004e6a621d4bc88978eecb6ea7959264239a17b70f2cbc348033d8195c9808ec"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db361e03342c41680afae5807590bc88aa0e17cfd1a42696a160e4005fcda03b"}, + {file = "sentencepiece-0.1.99-cp311-cp311-win32.whl", hash = "sha256:2d95e19168875b70df62916eb55428a0cbcb834ac51d5a7e664eda74def9e1e0"}, + {file = "sentencepiece-0.1.99-cp311-cp311-win_amd64.whl", hash = "sha256:f90d73a6f81248a909f55d8e6ef56fec32d559e1e9af045f0b0322637cb8e5c7"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:62e24c81e74bd87a6e0d63c51beb6527e4c0add67e1a17bac18bcd2076afcfeb"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57efcc2d51caff20d9573567d9fd3f854d9efe613ed58a439c78c9f93101384a"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a904c46197993bd1e95b93a6e373dca2f170379d64441041e2e628ad4afb16f"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89adf59854741c0d465f0e1525b388c0d174f611cc04af54153c5c4f36088c4"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-win32.whl", hash = "sha256:47c378146928690d1bc106fdf0da768cebd03b65dd8405aa3dd88f9c81e35dba"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-win_amd64.whl", hash = "sha256:9ba142e7a90dd6d823c44f9870abdad45e6c63958eb60fe44cca6828d3b69da2"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b7b1a9ae4d7c6f1f867e63370cca25cc17b6f4886729595b885ee07a58d3cec3"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0f644c9d4d35c096a538507b2163e6191512460035bf51358794a78515b74f7"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8843d23a0f686d85e569bd6dcd0dd0e0cbc03731e63497ca6d5bacd18df8b85"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33e6f690a1caebb4867a2e367afa1918ad35be257ecdb3455d2bbd787936f155"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-win32.whl", hash = "sha256:8a321866c2f85da7beac74a824b4ad6ddc2a4c9bccd9382529506d48f744a12c"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-win_amd64.whl", hash = "sha256:c42f753bcfb7661c122a15b20be7f684b61fc8592c89c870adf52382ea72262d"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85b476406da69c70586f0bb682fcca4c9b40e5059814f2db92303ea4585c650c"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cfbcfe13c69d3f87b7fcd5da168df7290a6d006329be71f90ba4f56bc77f8561"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:445b0ec381af1cd4eef95243e7180c63d9c384443c16c4c47a28196bd1cda937"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6890ea0f2b4703f62d0bf27932e35808b1f679bdb05c7eeb3812b935ba02001"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb71af492b0eefbf9f2501bec97bcd043b6812ab000d119eaf4bd33f9e283d03"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27b866b5bd3ddd54166bbcbf5c8d7dd2e0b397fac8537991c7f544220b1f67bc"}, + {file = "sentencepiece-0.1.99-cp38-cp38-win32.whl", hash = "sha256:b133e8a499eac49c581c3c76e9bdd08c338cc1939e441fee6f92c0ccb5f1f8be"}, + {file = "sentencepiece-0.1.99-cp38-cp38-win_amd64.whl", hash = "sha256:0eaf3591dd0690a87f44f4df129cf8d05d8a4029b5b6709b489b8e27f9a9bcff"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38efeda9bbfb55052d482a009c6a37e52f42ebffcea9d3a98a61de7aee356a28"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6c030b081dc1e1bcc9fadc314b19b740715d3d566ad73a482da20d7d46fd444c"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84dbe53e02e4f8a2e45d2ac3e430d5c83182142658e25edd76539b7648928727"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b0f55d0a0ee1719b4b04221fe0c9f0c3461dc3dabd77a035fa2f4788eb3ef9a"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e800f206cd235dc27dc749299e05853a4e4332e8d3dfd81bf13d0e5b9007d9"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae1c40cda8f9d5b0423cfa98542735c0235e7597d79caf318855cdf971b2280"}, + {file = "sentencepiece-0.1.99-cp39-cp39-win32.whl", hash = "sha256:c84ce33af12ca222d14a1cdd37bd76a69401e32bc68fe61c67ef6b59402f4ab8"}, + {file = "sentencepiece-0.1.99-cp39-cp39-win_amd64.whl", hash = "sha256:350e5c74d739973f1c9643edb80f7cc904dc948578bcb1d43c6f2b173e5d18dd"}, + {file = "sentencepiece-0.1.99.tar.gz", hash = "sha256:189c48f5cb2949288f97ccdb97f0473098d9c3dcf5a3d99d4eabe719ec27297f"}, +] + [[package]] name = "setuptools" version = "67.8.0" @@ -4624,6 +5072,18 @@ typing-extensions = ">=4.4.0,<5.0.0" [package.extras] dev = ["aiohttp (>=3.8.1)", "click (>=8.1.2)", "msgpack (>=1.0.3)"] +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, + {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, +] + [[package]] name = "tiktoken" version = "0.3.3" @@ -4749,6 +5209,85 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "torch" +version = "2.0.1" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +category = "main" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "torch-2.0.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:8ced00b3ba471856b993822508f77c98f48a458623596a4c43136158781e306a"}, + {file = "torch-2.0.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:359bfaad94d1cda02ab775dc1cc386d585712329bb47b8741607ef6ef4950747"}, + {file = "torch-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:7c84e44d9002182edd859f3400deaa7410f5ec948a519cc7ef512c2f9b34d2c4"}, + {file = "torch-2.0.1-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:567f84d657edc5582d716900543e6e62353dbe275e61cdc36eda4929e46df9e7"}, + {file = "torch-2.0.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:787b5a78aa7917465e9b96399b883920c88a08f4eb63b5a5d2d1a16e27d2f89b"}, + {file = "torch-2.0.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:e617b1d0abaf6ced02dbb9486803abfef0d581609b09641b34fa315c9c40766d"}, + {file = "torch-2.0.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b6019b1de4978e96daa21d6a3ebb41e88a0b474898fe251fd96189587408873e"}, + {file = "torch-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:dbd68cbd1cd9da32fe5d294dd3411509b3d841baecb780b38b3b7b06c7754434"}, + {file = "torch-2.0.1-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:ef654427d91600129864644e35deea761fb1fe131710180b952a6f2e2207075e"}, + {file = "torch-2.0.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:25aa43ca80dcdf32f13da04c503ec7afdf8e77e3a0183dd85cd3e53b2842e527"}, + {file = "torch-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5ef3ea3d25441d3957348f7e99c7824d33798258a2bf5f0f0277cbcadad2e20d"}, + {file = "torch-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0882243755ff28895e8e6dc6bc26ebcf5aa0911ed81b2a12f241fc4b09075b13"}, + {file = "torch-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:f66aa6b9580a22b04d0af54fcd042f52406a8479e2b6a550e3d9f95963e168c8"}, + {file = "torch-2.0.1-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:1adb60d369f2650cac8e9a95b1d5758e25d526a34808f7448d0bd599e4ae9072"}, + {file = "torch-2.0.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:1bcffc16b89e296826b33b98db5166f990e3b72654a2b90673e817b16c50e32b"}, + {file = "torch-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:e10e1597f2175365285db1b24019eb6f04d53dcd626c735fc502f1e8b6be9875"}, + {file = "torch-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:423e0ae257b756bb45a4b49072046772d1ad0c592265c5080070e0767da4e490"}, + {file = "torch-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8742bdc62946c93f75ff92da00e3803216c6cce9b132fbca69664ca38cfb3e18"}, + {file = "torch-2.0.1-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:c62df99352bd6ee5a5a8d1832452110435d178b5164de450831a3a8cc14dc680"}, + {file = "torch-2.0.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:671a2565e3f63b8fe8e42ae3e36ad249fe5e567435ea27b94edaa672a7d0c416"}, +] + +[package.dependencies] +filelock = "*" +jinja2 = "*" +networkx = "*" +sympy = "*" +typing-extensions = "*" + +[package.extras] +opt-einsum = ["opt-einsum (>=3.3)"] + +[[package]] +name = "torchvision" +version = "0.15.2" +description = "image and video datasets and models for torch deep learning" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "torchvision-0.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7754088774e810c5672b142a45dcf20b1bd986a5a7da90f8660c43dc43fb850c"}, + {file = "torchvision-0.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37eb138e13f6212537a3009ac218695483a635c404b6cc1d8e0d0d978026a86d"}, + {file = "torchvision-0.15.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:54143f7cc0797d199b98a53b7d21c3f97615762d4dd17ad45a41c7e80d880e73"}, + {file = "torchvision-0.15.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:1eefebf5fbd01a95fe8f003d623d941601c94b5cec547b420da89cb369d9cf96"}, + {file = "torchvision-0.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:96fae30c5ca8423f4b9790df0f0d929748e32718d88709b7b567d2f630c042e3"}, + {file = "torchvision-0.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5f35f6bd5bcc4568e6522e4137fa60fcc72f4fa3e615321c26cd87e855acd398"}, + {file = "torchvision-0.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:757505a0ab2be7096cb9d2bf4723202c971cceddb72c7952a7e877f773de0f8a"}, + {file = "torchvision-0.15.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:012ad25cfd9019ff9b0714a168727e3845029be1af82296ff1e1482931fa4b80"}, + {file = "torchvision-0.15.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b02a7ffeaa61448737f39a4210b8ee60234bda0515a0c0d8562f884454105b0f"}, + {file = "torchvision-0.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:10be76ceded48329d0a0355ac33da131ee3993ff6c125e4a02ab34b5baa2472c"}, + {file = "torchvision-0.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f12415b686dba884fb086f53ac803f692be5a5cdd8a758f50812b30fffea2e4"}, + {file = "torchvision-0.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:31211c01f8b8ec33b8a638327b5463212e79a03e43c895f88049f97af1bd12fd"}, + {file = "torchvision-0.15.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c55f9889e436f14b4f84a9c00ebad0d31f5b4626f10cf8018e6c676f92a6d199"}, + {file = "torchvision-0.15.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:9a192f2aa979438f23c20e883980b23d13268ab9f819498774a6d2eb021802c2"}, + {file = "torchvision-0.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:c07071bc8d02aa8fcdfe139ab6a1ef57d3b64c9e30e84d12d45c9f4d89fb6536"}, + {file = "torchvision-0.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4790260fcf478a41c7ecc60a6d5200a88159fdd8d756e9f29f0f8c59c4a67a68"}, + {file = "torchvision-0.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:987ab62225b4151a11e53fd06150c5258ced24ac9d7c547e0e4ab6fbca92a5ce"}, + {file = "torchvision-0.15.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:63df26673e66cba3f17e07c327a8cafa3cce98265dbc3da329f1951d45966838"}, + {file = "torchvision-0.15.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b85f98d4cc2f72452f6792ab4463a3541bc5678a8cdd3da0e139ba2fe8b56d42"}, + {file = "torchvision-0.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:07c462524cc1bba5190c16a9d47eac1fca024d60595a310f23c00b4ffff18b30"}, +] + +[package.dependencies] +numpy = "*" +pillow = ">=5.3.0,<8.3.0 || >=8.4.0" +requests = "*" +torch = "2.0.1" + +[package.extras] +scipy = ["scipy"] + [[package]] name = "tornado" version = "6.3.2" @@ -4807,6 +5346,74 @@ files = [ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +[[package]] +name = "transformers" +version = "4.29.0" +description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" +category = "main" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "transformers-4.29.0-py3-none-any.whl", hash = "sha256:51f89cbdd515dffac38c002277511d004e1a12a284ab852a4d5641430a409d1f"}, + {file = "transformers-4.29.0.tar.gz", hash = "sha256:b5dff9ce3708dc6639d892435fa69c51dee5c89870f888fa59ef0fc3baa3d8c7"}, +] + +[package.dependencies] +filelock = "*" +huggingface-hub = ">=0.11.0,<1.0" +numpy = ">=1.17" +packaging = ">=20.0" +pyyaml = ">=5.1" +regex = "!=2019.12.17" +requests = "*" +tokenizers = ">=0.11.1,<0.11.3 || >0.11.3,<0.14" +tqdm = ">=4.27" + +[package.extras] +accelerate = ["accelerate (>=0.19.0)"] +all = ["Pillow", "accelerate (>=0.19.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.6.9)", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "numba (<0.57.0)", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf (<=3.20.2)", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"] +audio = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)"] +codecarbon = ["codecarbon (==1.2.0)"] +deepspeed = ["accelerate (>=0.19.0)", "deepspeed (>=0.8.3)"] +deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.19.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.8.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf (<=3.20.2)", "psutil", "pytest", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "sentencepiece (>=0.1.91,!=0.1.92)", "timeout-decorator"] +dev = ["GitPython (<3.1.19)", "Pillow", "accelerate (>=0.19.0)", "av (==9.2.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.6.9)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "numba (<0.57.0)", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf (<=3.20.2)", "psutil", "pyctcdecode (>=0.4.0)", "pytest", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +dev-tensorflow = ["GitPython (<3.1.19)", "Pillow", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "numba (<0.57.0)", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf (<=3.20.2)", "psutil", "pyctcdecode (>=0.4.0)", "pytest", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "urllib3 (<2.0.0)"] +dev-torch = ["GitPython (<3.1.19)", "Pillow", "accelerate (>=0.19.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "numba (<0.57.0)", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf (<=3.20.2)", "psutil", "pyctcdecode (>=0.4.0)", "pytest", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +docs = ["Pillow", "accelerate (>=0.19.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.6.9)", "hf-doc-builder", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "numba (<0.57.0)", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf (<=3.20.2)", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"] +docs-specific = ["hf-doc-builder"] +fairscale = ["fairscale (>0.3)"] +flax = ["flax (>=0.4.1,<=0.6.9)", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "optax (>=0.0.8,<=0.1.4)"] +flax-speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)"] +ftfy = ["ftfy"] +integrations = ["optuna", "ray[tune]", "sigopt"] +ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"] +modelcreation = ["cookiecutter (==1.7.3)"] +natten = ["natten (>=0.14.6)"] +onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"] +onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"] +optuna = ["optuna"] +quality = ["GitPython (<3.1.19)", "black (>=23.1,<24.0)", "datasets (!=2.5.0)", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "ruff (>=0.0.241,<=0.0.259)", "urllib3 (<2.0.0)"] +ray = ["ray[tune]"] +retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] +sagemaker = ["sagemaker (>=2.31.0)"] +sentencepiece = ["protobuf (<=3.20.2)", "sentencepiece (>=0.1.91,!=0.1.92)"] +serving = ["fastapi", "pydantic", "starlette", "uvicorn"] +sigopt = ["sigopt"] +sklearn = ["scikit-learn"] +speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +testing = ["GitPython (<3.1.19)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf (<=3.20.2)", "psutil", "pytest", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "timeout-decorator"] +tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx"] +tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx"] +tf-speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)"] +timm = ["timm"] +tokenizers = ["tokenizers (>=0.11.1,!=0.11.3,<0.14)"] +torch = ["accelerate (>=0.19.0)", "torch (>=1.9,!=1.12.0)"] +torch-speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +torch-vision = ["Pillow", "torchvision"] +torchhub = ["filelock", "huggingface-hub (>=0.11.0,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf (<=3.20.2)", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "tqdm (>=4.27)"] +video = ["av (==9.2.0)", "decord (==0.6.0)"] +vision = ["Pillow"] + [[package]] name = "typer" version = "0.7.0" @@ -4893,14 +5500,14 @@ files = [ [[package]] name = "typing-extensions" -version = "4.6.2" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.6.2-py3-none-any.whl", hash = "sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98"}, - {file = "typing_extensions-4.6.2.tar.gz", hash = "sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c"}, + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] [[package]] @@ -5074,6 +5681,23 @@ dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flak docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] +[[package]] +name = "validators" +version = "0.20.0" +description = "Python Data Validation for Humans™." +category = "main" +optional = false +python-versions = ">=3.4" +files = [ + {file = "validators-0.20.0.tar.gz", hash = "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a"}, +] + +[package.dependencies] +decorator = ">=3.4.0" + +[package.extras] +test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] + [[package]] name = "watchfiles" version = "0.19.0" @@ -5121,12 +5745,33 @@ files = [ {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] +[[package]] +name = "weaviate-client" +version = "3.19.2" +description = "A python native weaviate client" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "weaviate-client-3.19.2.tar.gz", hash = "sha256:662cb2a5f6dacc2c9cdf6db2df70e9a3ac9d18b404d0c2ff971d9cb85d84ebed"}, + {file = "weaviate_client-3.19.2-py3-none-any.whl", hash = "sha256:f4bbfb868907089f57fdfb836c4d00cf8a6fc5e296fa08879681ba1d2273cd40"}, +] + +[package.dependencies] +authlib = ">=1.1.0" +requests = ">=2.28.0,<2.29.0" +tqdm = ">=4.59.0,<5.0.0" +validators = ">=0.18.2,<=0.21.0" + +[package.extras] +grpc = ["grpcio", "grpcio-tools"] + [[package]] name = "websocket-client" version = "1.5.2" description = "WebSocket client for Python with low level API options" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "websocket-client-1.5.2.tar.gz", hash = "sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b"}, @@ -5235,87 +5880,76 @@ requests = ">=2.0.0,<3.0.0" [[package]] name = "wrapt" -version = "1.15.0" +version = "1.14.1" description = "Module for decorators, wrappers and monkey patching." category = "main" -optional = true +optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ - {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, - {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, - {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, - {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, - {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, - {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, - {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, - {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, - {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, - {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, - {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, - {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, - {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, - {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, - {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, - {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, - {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, - {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, - {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, + {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, + {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, + {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, + {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, + {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, + {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, + {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, + {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, + {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, + {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, + {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, + {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, + {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, + {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, + {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, + {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] [[package]] @@ -5498,5 +6132,5 @@ deploy = ["langchain-serve"] [metadata] lock-version = "2.0" -python-versions = "^3.9" -content-hash = "0ab60d05d829739ee29dd813743d302353765846cefa71b64ade9778039f0c7c" +python-versions = ">=3.9,<3.12" +content-hash = "abbb024a67e3326821999f9a0a6164b13e877b0b72d1cd6912ca694c83fffa22" diff --git a/pyproject.toml b/pyproject.toml index 32e4f488f..1cb6f3581 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ include = ["src/backend/langflow/*", "src/backend/langflow/**/*"] langflow = "langflow.__main__:main" [tool.poetry.dependencies] -python = "^3.9" +python = ">=3.9,<3.12" fastapi = "^0.92.0" uvicorn = "^0.20.0" beautifulsoup4 = "^4.11.2" @@ -47,11 +47,14 @@ fake-useragent = "^1.1.3" docstring-parser = "^0.15" psycopg2-binary = "^2.9.6" pyarrow = "^11.0.0" -websockets = "^11.0.2" tiktoken = "^0.3.3" wikipedia = "^1.4.0" -gptcache = "^0.1.23" langchain-serve = { version = "^0.0.33", optional = true } +qdrant-client = "^1.2.0" +websockets = "^11.0.3" +weaviate-client = "^3.19.2" +jina = "3.15.2" +sentence-transformers = "^2.2.2" [tool.poetry.group.dev.dependencies] black = "^23.1.0" diff --git a/src/backend/langflow/__main__.py b/src/backend/langflow/__main__.py index 21833d551..af57ed381 100644 --- a/src/backend/langflow/__main__.py +++ b/src/backend/langflow/__main__.py @@ -18,59 +18,10 @@ def get_number_of_workers(workers=None): return workers -def update_settings(config: str): +def update_settings(config: str, dev: bool = False): """Update the settings from a config file.""" if config: - settings.update_from_yaml(config) - - -@app.command() -def serve( - host: str = typer.Option("127.0.0.1", help="Host to bind the server to."), - workers: int = typer.Option(1, help="Number of worker processes."), - timeout: int = typer.Option(60, help="Worker timeout in seconds."), - port: int = typer.Option(7860, help="Port to listen on."), - config: str = typer.Option("config.yaml", help="Path to the configuration file."), - log_level: str = typer.Option("info", help="Logging level."), - log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."), - jcloud: bool = typer.Option(False, help="Deploy on Jina AI Cloud"), -): - """ - Run the Langflow server. - """ - - if jcloud: - return serve_on_jcloud() - - configure(log_level=log_level, log_file=log_file) - update_settings(config) - app = create_app() - # get the directory of the current file - path = Path(__file__).parent - static_files_dir = path / "frontend" - app.mount( - "/", - StaticFiles(directory=static_files_dir, html=True), - name="static", - ) - options = { - "bind": f"{host}:{port}", - "workers": get_number_of_workers(workers), - "worker_class": "uvicorn.workers.UvicornWorker", - "timeout": timeout, - } - - if platform.system() in ["Darwin", "Windows"]: - # Run using uvicorn on MacOS and Windows - # Windows doesn't support gunicorn - # MacOS requires an env variable to be set to use gunicorn - import uvicorn - - uvicorn.run(app, host=host, port=port, log_level=log_level) - else: - from langflow.server import LangflowApplication - - LangflowApplication(app, options).run() + settings.update_from_yaml(config, dev=dev) def serve_on_jcloud(): @@ -119,6 +70,56 @@ def serve_on_jcloud(): click.secho("https://github.com/jina-ai/langchain-serve", fg="blue") +@app.command() +def serve( + host: str = typer.Option("127.0.0.1", help="Host to bind the server to."), + workers: int = typer.Option(1, help="Number of worker processes."), + timeout: int = typer.Option(60, help="Worker timeout in seconds."), + port: int = typer.Option(7860, help="Port to listen on."), + config: str = typer.Option("config.yaml", help="Path to the configuration file."), + log_level: str = typer.Option("info", help="Logging level."), + log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."), + jcloud: bool = typer.Option(False, help="Deploy on Jina AI Cloud"), + dev: bool = typer.Option(False, help="Run in development mode (may contain bugs)"), +): + """ + Run the Langflow server. + """ + + if jcloud: + return serve_on_jcloud() + + configure(log_level=log_level, log_file=log_file) + update_settings(config, dev=dev) + app = create_app() + # get the directory of the current file + path = Path(__file__).parent + static_files_dir = path / "frontend" + app.mount( + "/", + StaticFiles(directory=static_files_dir, html=True), + name="static", + ) + options = { + "bind": f"{host}:{port}", + "workers": get_number_of_workers(workers), + "worker_class": "uvicorn.workers.UvicornWorker", + "timeout": timeout, + } + + if platform.system() in ["Darwin", "Windows"]: + # Run using uvicorn on MacOS and Windows + # Windows doesn't support gunicorn + # MacOS requires an env variable to be set to use gunicorn + import uvicorn + + uvicorn.run(app, host=host, port=port, log_level=log_level) + else: + from langflow.server import LangflowApplication + + LangflowApplication(app, options).run() + + def main(): app() diff --git a/src/backend/langflow/api/chat_manager.py b/src/backend/langflow/api/chat_manager.py index 663243d17..8b1c7a621 100644 --- a/src/backend/langflow/api/chat_manager.py +++ b/src/backend/langflow/api/chat_manager.py @@ -29,10 +29,10 @@ class ChatHistory(Subject): if not isinstance(message, FileResponse): self.notify() - def get_history(self, client_id: str, filter=True) -> List[ChatMessage]: + def get_history(self, client_id: str, filter_messages=True) -> List[ChatMessage]: """Get the chat history for a client.""" if history := self.history.get(client_id, []): - if filter: + if filter_messages: return [msg for msg in history if msg.type not in ["start", "stream"]] return history else: @@ -54,7 +54,9 @@ class ChatManager: """Send the last chat message to the client.""" client_id = self.cache_manager.current_client_id if client_id in self.active_connections: - chat_response = self.chat_history.get_history(client_id, filter=False)[-1] + chat_response = self.chat_history.get_history( + client_id, filter_messages=False + )[-1] if chat_response.is_bot: # Process FileResponse if isinstance(chat_response, FileResponse): @@ -128,7 +130,7 @@ class ChatManager: raise e # Send a response back to the frontend, if needed intermediate_steps = intermediate_steps or "" - history = self.chat_history.get_history(client_id, filter=False) + history = self.chat_history.get_history(client_id, filter_messages=False) file_responses = [] if history: # Iterate backwards through the history diff --git a/src/backend/langflow/cache/base.py b/src/backend/langflow/cache/base.py index 1f2039b27..0f1ff5d92 100644 --- a/src/backend/langflow/cache/base.py +++ b/src/backend/langflow/cache/base.py @@ -120,7 +120,7 @@ def save_binary_file(content: str, file_name: str, accepted_types: list[str]) -> # Get the destination folder cache_path = Path(tempfile.gettempdir()) / PREFIX - if content is None: + if not content: raise ValueError("Please, reload the file in the loader.") data = content.split(",")[1] decoded_bytes = base64.b64decode(data) diff --git a/src/backend/langflow/config.yaml b/src/backend/langflow/config.yaml index 84fd12fcd..b1da1b622 100644 --- a/src/backend/langflow/config.yaml +++ b/src/backend/langflow/config.yaml @@ -1,3 +1,12 @@ +--- +agents: + - ZeroShotAgent + - JsonAgent + - CSVAgent + - initialize_agent + - VectorStoreAgent + - VectorStoreRouterAgent + - SQLAgent chains: - LLMChain - LLMMathChain @@ -7,24 +16,35 @@ chains: - MidJourneyPromptChain - TimeTravelGuideChain - SQLDatabaseChain - -agents: - - ZeroShotAgent - - JsonAgent - - CSVAgent - - initialize_agent - - VectorStoreAgent - - VectorStoreRouterAgent - - SQLAgent - -prompts: - - PromptTemplate - - FewShotPromptTemplate - - ZeroShotPrompt - # Wait more tests - # - ChatPromptTemplate - # - SystemMessagePromptTemplate - # - HumanMessagePromptTemplate +documentloaders: + - AirbyteJSONLoader + - CoNLLULoader + - CSVLoader + - UnstructuredEmailLoader + - EverNoteLoader + - FacebookChatLoader + - GutenbergLoader + - BSHTMLLoader + - UnstructuredHTMLLoader + # - UnstructuredImageLoader # Issue with Python 3.11 (https://github.com/Unstructured-IO/unstructured-inference/issues/83) + - UnstructuredMarkdownLoader + - PyPDFLoader + - UnstructuredPowerPointLoader + - SRTLoader + - TelegramChatLoader + - TextLoader + - UnstructuredWordDocumentLoader + - WebBaseLoader + - AZLyricsLoader + - CollegeConfidentialLoader + - HNLoader + - IFixitLoader + - IMSDbLoader + - GitbookLoader + - ReadTheDocsLoader +embeddings: + - OpenAIEmbeddings + - HuggingFaceEmbeddings llms: - OpenAI @@ -32,7 +52,21 @@ llms: - ChatOpenAI - HuggingFaceHub - LlamaCpp - +memories: + - ConversationBufferMemory + - ConversationSummaryMemory + - ConversationKGMemory +prompts: + - PromptTemplate + - FewShotPromptTemplate + - ZeroShotPrompt +textsplitters: + - CharacterTextSplitter +toolkits: + - OpenAPIToolkit + - JsonToolkit + - VectorStoreInfo + - VectorStoreRouterToolkit tools: - Search - PAL-MATH @@ -63,57 +97,6 @@ tools: - RequestsDeleteTool - WikipediaQueryRun - WolframAlphaQueryRun - -wrappers: - - RequestsWrapper - -toolkits: - - OpenAPIToolkit - - JsonToolkit - - VectorStoreInfo - - VectorStoreRouterToolkit - -memories: - - ConversationBufferMemory - - ConversationSummaryMemory - - ConversationKGMemory - -embeddings: - - OpenAIEmbeddings - -vectorstores: - - Chroma - -documentloaders: - - AirbyteJSONLoader - - CoNLLULoader - - CSVLoader - - UnstructuredEmailLoader - - EverNoteLoader - - FacebookChatLoader - - GutenbergLoader - - BSHTMLLoader - - UnstructuredHTMLLoader - # - UnstructuredImageLoader # Issue with Python 3.11 (https://github.com/Unstructured-IO/unstructured-inference/issues/83) - - UnstructuredMarkdownLoader - - PyPDFLoader - - UnstructuredPowerPointLoader - - SRTLoader - - TelegramChatLoader - - TextLoader - - UnstructuredWordDocumentLoader - - WebBaseLoader - - AZLyricsLoader - - CollegeConfidentialLoader - - HNLoader - - IFixitLoader - - IMSDbLoader - - GitbookLoader - - ReadTheDocsLoader - -textsplitters: - - CharacterTextSplitter - utilities: - BingSearchAPIWrapper - GoogleSearchAPIWrapper @@ -125,5 +108,12 @@ utilities: - WolframAlphaAPIWrapper # - ZapierNLAWrapper - SQLDatabase - -dev: false +vectorstores: + - Chroma + - Qdrant + - Weaviate +wrappers: + - RequestsWrapper # Wait more tests + # - ChatPromptTemplate + # - SystemMessagePromptTemplate + # - HumanMessagePromptTemplate diff --git a/src/backend/langflow/custom/customs.py b/src/backend/langflow/custom/customs.py index 2b2ccc43f..ee266b0ee 100644 --- a/src/backend/langflow/custom/customs.py +++ b/src/backend/langflow/custom/customs.py @@ -1,24 +1,27 @@ -from langflow.template import nodes +from langflow.template import frontend_node # These should always be instantiated CUSTOM_NODES = { - "prompts": {"ZeroShotPrompt": nodes.ZeroShotPromptNode()}, - "tools": {"PythonFunction": nodes.PythonFunctionNode(), "Tool": nodes.ToolNode()}, + "prompts": {"ZeroShotPrompt": frontend_node.prompts.ZeroShotPromptNode()}, + "tools": { + "PythonFunction": frontend_node.tools.PythonFunctionNode(), + "Tool": frontend_node.tools.ToolNode(), + }, "agents": { - "JsonAgent": nodes.JsonAgentNode(), - "CSVAgent": nodes.CSVAgentNode(), - "initialize_agent": nodes.InitializeAgentNode(), - "VectorStoreAgent": nodes.VectorStoreAgentNode(), - "VectorStoreRouterAgent": nodes.VectorStoreRouterAgentNode(), - "SQLAgent": nodes.SQLAgentNode(), + "JsonAgent": frontend_node.agents.JsonAgentNode(), + "CSVAgent": frontend_node.agents.CSVAgentNode(), + "initialize_agent": frontend_node.agents.InitializeAgentNode(), + "VectorStoreAgent": frontend_node.agents.VectorStoreAgentNode(), + "VectorStoreRouterAgent": frontend_node.agents.VectorStoreRouterAgentNode(), + "SQLAgent": frontend_node.agents.SQLAgentNode(), }, "utilities": { - "SQLDatabase": nodes.SQLDatabaseNode(), + "SQLDatabase": frontend_node.agents.SQLDatabaseNode(), }, "chains": { - "SeriesCharacterChain": nodes.SeriesCharacterChainNode(), - "TimeTravelGuideChain": nodes.TimeTravelGuideChainNode(), - "MidJourneyPromptChain": nodes.MidJourneyPromptChainNode(), + "SeriesCharacterChain": frontend_node.chains.SeriesCharacterChainNode(), + "TimeTravelGuideChain": frontend_node.chains.TimeTravelGuideChainNode(), + "MidJourneyPromptChain": frontend_node.chains.MidJourneyPromptChainNode(), }, } diff --git a/src/backend/langflow/graph/base.py b/src/backend/langflow/graph/base.py index 976a9c1cf..187d2983e 100644 --- a/src/backend/langflow/graph/base.py +++ b/src/backend/langflow/graph/base.py @@ -180,7 +180,13 @@ class Node: elif isinstance(value, list) and all( isinstance(node, Node) for node in value ): - self.params[key] = [node.build() for node in value] # type: ignore + self.params[key] = [] + for node in value: + built = node.build() + if isinstance(built, list): + self.params[key].extend(built) + else: + self.params[key].append(built) # Get the class from LANGCHAIN_TYPES_DICT # and instantiate it with the params diff --git a/src/backend/langflow/graph/nodes.py b/src/backend/langflow/graph/nodes.py index f33a0fcef..189e40b5c 100644 --- a/src/backend/langflow/graph/nodes.py +++ b/src/backend/langflow/graph/nodes.py @@ -1,4 +1,3 @@ -from copy import deepcopy from typing import Any, Dict, List, Optional, Union from langflow.graph.base import Node diff --git a/src/backend/langflow/interface/agents/custom.py b/src/backend/langflow/interface/agents/custom.py index 0cbf7baca..4654ef7cb 100644 --- a/src/backend/langflow/interface/agents/custom.py +++ b/src/backend/langflow/interface/agents/custom.py @@ -28,7 +28,6 @@ from langchain.agents.agent_toolkits.vectorstore.prompt import ( ROUTER_PREFIX as VECTORSTORE_ROUTER_PREFIX, ) from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS -from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS as SQL_FORMAT_INSTRUCTIONS from langchain.base_language import BaseLanguageModel from langchain.memory.chat_memory import BaseChatMemory from langchain.sql_database import SQLDatabase @@ -220,7 +219,7 @@ class SQLAgent(CustomAgentExecutor): QuerySQLDataBaseTool(db=db), # type: ignore InfoSQLDatabaseTool(db=db), # type: ignore ListSQLDatabaseTool(db=db), # type: ignore - QueryCheckerTool(db=db, llm_chain=llmchain), # type: ignore + QueryCheckerTool(db=db, llm_chain=llmchain, llm=llm), # type: ignore ] prefix = SQL_PREFIX.format(dialect=toolkit.dialect, top_k=10) @@ -228,7 +227,7 @@ class SQLAgent(CustomAgentExecutor): tools=tools, # type: ignore prefix=prefix, suffix=SQL_SUFFIX, - format_instructions=SQL_FORMAT_INSTRUCTIONS, + format_instructions=FORMAT_INSTRUCTIONS, ) llm_chain = LLMChain( llm=llm, diff --git a/src/backend/langflow/interface/base.py b/src/backend/langflow/interface/base.py index 663700ffd..48d6dccc4 100644 --- a/src/backend/langflow/interface/base.py +++ b/src/backend/langflow/interface/base.py @@ -3,7 +3,9 @@ from typing import Any, Dict, List, Optional, Type, Union from pydantic import BaseModel -from langflow.template.base import FrontendNode, Template, TemplateField +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template from langflow.utils.logger import logger # Assuming necessary imports for Field, Template, and FrontendNode classes @@ -42,7 +44,7 @@ class LangChainTypeCreator(BaseModel, ABC): # so we should update the result dict node = self.frontend_node(name) if node is not None: - node = node.to_dict() + node = node.to_dict() # type: ignore result[self.type_name].update(node) return result diff --git a/src/backend/langflow/interface/chains/base.py b/src/backend/langflow/interface/chains/base.py index 7b8da370b..ad66f07b2 100644 --- a/src/backend/langflow/interface/chains/base.py +++ b/src/backend/langflow/interface/chains/base.py @@ -4,7 +4,7 @@ from langflow.custom.customs import get_custom_nodes from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import chain_type_to_cls_dict from langflow.settings import settings -from langflow.template.nodes import ChainFrontendNode +from langflow.template.frontend_node.chains import ChainFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/custom_lists.py b/src/backend/langflow/interface/custom_lists.py index f07b03f04..0fea838b6 100644 --- a/src/backend/langflow/interface/custom_lists.py +++ b/src/backend/langflow/interface/custom_lists.py @@ -9,12 +9,9 @@ from langchain import ( memory, requests, text_splitter, - utilities, - vectorstores, ) from langchain.agents import agent_toolkits from langchain.chat_models import ChatOpenAI -from langchain.sql_database import SQLDatabase from langflow.interface.importing.utils import import_class @@ -60,11 +57,6 @@ embedding_type_to_cls_dict: dict[str, Any] = { for embedding_name in embeddings.__all__ } -## Vector Stores -vectorstores_type_to_cls_dict: dict[str, Any] = { - vectorstore_name: import_class(f"langchain.vectorstores.{vectorstore_name}") - for vectorstore_name in vectorstores.__all__ -} ## Document Loaders documentloaders_type_to_cls_dict: dict[str, Any] = { @@ -78,9 +70,3 @@ documentloaders_type_to_cls_dict: dict[str, Any] = { textsplitter_type_to_cls_dict: dict[str, Any] = dict( inspect.getmembers(text_splitter, inspect.isclass) ) - -## Utilities -utility_type_to_cls_dict: dict[str, Any] = dict( - inspect.getmembers(utilities, inspect.isclass) -) -utility_type_to_cls_dict["SQLDatabase"] = SQLDatabase diff --git a/src/backend/langflow/interface/embeddings/base.py b/src/backend/langflow/interface/embeddings/base.py index 933d8ad39..1dfa05a99 100644 --- a/src/backend/langflow/interface/embeddings/base.py +++ b/src/backend/langflow/interface/embeddings/base.py @@ -3,8 +3,8 @@ from typing import Dict, List, Optional, Type from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import embedding_type_to_cls_dict from langflow.settings import settings -from langflow.template.base import FrontendNode -from langflow.template.nodes import EmbeddingFrontendNode +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.frontend_node.embeddings import EmbeddingFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/importing/utils.py b/src/backend/langflow/interface/importing/utils.py index 8c65bf60e..d08e52999 100644 --- a/src/backend/langflow/interface/importing/utils.py +++ b/src/backend/langflow/interface/importing/utils.py @@ -71,9 +71,9 @@ def import_class(class_path: str) -> Any: def import_prompt(prompt: str) -> Type[PromptTemplate]: + """Import prompt from prompt name""" from langflow.interface.prompts.custom import CUSTOM_PROMPTS - """Import prompt from prompt name""" if prompt == "ZeroShotPrompt": return import_class("langchain.prompts.PromptTemplate") elif prompt in CUSTOM_PROMPTS: diff --git a/src/backend/langflow/interface/llms/base.py b/src/backend/langflow/interface/llms/base.py index 04a36eb2d..66e153880 100644 --- a/src/backend/langflow/interface/llms/base.py +++ b/src/backend/langflow/interface/llms/base.py @@ -3,7 +3,7 @@ from typing import Dict, List, Optional, Type from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import llm_type_to_cls_dict from langflow.settings import settings -from langflow.template.nodes import LLMFrontendNode +from langflow.template.frontend_node.llms import LLMFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/loading.py b/src/backend/langflow/interface/loading.py index bd2946a3e..cd6898a7f 100644 --- a/src/backend/langflow/interface/loading.py +++ b/src/backend/langflow/interface/loading.py @@ -152,10 +152,10 @@ def instantiate_utility(node_type, class_object, params): def load_flow_from_json(path: str, build=True): + """Load flow from json file""" # This is done to avoid circular imports from langflow.graph import Graph - """Load flow from json file""" with open(path, "r", encoding="utf-8") as f: flow_graph = json.load(f) data_graph = flow_graph["data"] diff --git a/src/backend/langflow/interface/memories/base.py b/src/backend/langflow/interface/memories/base.py index f26b09351..f0d8f88f5 100644 --- a/src/backend/langflow/interface/memories/base.py +++ b/src/backend/langflow/interface/memories/base.py @@ -3,8 +3,8 @@ from typing import Dict, List, Optional, Type from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import memory_type_to_cls_dict from langflow.settings import settings -from langflow.template.base import FrontendNode -from langflow.template.nodes import MemoryFrontendNode +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.frontend_node.memories import MemoryFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/prompts/base.py b/src/backend/langflow/interface/prompts/base.py index 5f83a5412..39bd94c5b 100644 --- a/src/backend/langflow/interface/prompts/base.py +++ b/src/backend/langflow/interface/prompts/base.py @@ -6,7 +6,7 @@ from langflow.custom.customs import get_custom_nodes from langflow.interface.base import LangChainTypeCreator from langflow.interface.importing.utils import import_class from langflow.settings import settings -from langflow.template.nodes import PromptFrontendNode +from langflow.template.frontend_node.prompts import PromptFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/tools/base.py b/src/backend/langflow/interface/tools/base.py index 888accb29..a8e7045c0 100644 --- a/src/backend/langflow/interface/tools/base.py +++ b/src/backend/langflow/interface/tools/base.py @@ -16,7 +16,8 @@ from langflow.interface.tools.constants import ( ) from langflow.interface.tools.util import get_tool_params from langflow.settings import settings -from langflow.template.base import Template, TemplateField +from langflow.template.field.base import TemplateField +from langflow.template.template.base import Template from langflow.utils import util from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/utilities/base.py b/src/backend/langflow/interface/utilities/base.py index e60e344ad..6c12b0186 100644 --- a/src/backend/langflow/interface/utilities/base.py +++ b/src/backend/langflow/interface/utilities/base.py @@ -1,9 +1,12 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Type + +from langchain import SQLDatabase, utilities from langflow.custom.customs import get_custom_nodes from langflow.interface.base import LangChainTypeCreator -from langflow.interface.custom_lists import utility_type_to_cls_dict +from langflow.interface.importing.utils import import_class from langflow.settings import settings +from langflow.template.frontend_node.utilities import UtilitiesFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class @@ -11,16 +14,39 @@ from langflow.utils.util import build_template_from_class class UtilityCreator(LangChainTypeCreator): type_name: str = "utilities" + @property + def frontend_node_class(self) -> Type[UtilitiesFrontendNode]: + return UtilitiesFrontendNode + @property def type_to_loader_dict(self) -> Dict: - return utility_type_to_cls_dict + """ + Returns a dictionary mapping utility names to their corresponding loader classes. + If the dictionary has not been created yet, it is created by importing all utility classes + from the langchain.chains module and filtering them according to the settings.utilities list. + """ + if self.type_dict is None: + self.type_dict = { + utility_name: import_class(f"langchain.utilities.{utility_name}") + for utility_name in utilities.__all__ + } + self.type_dict["SQLDatabase"] = SQLDatabase + # Filter according to settings.utilities + self.type_dict = { + name: utility + for name, utility in self.type_dict.items() + if name in settings.utilities or settings.dev + } + + return self.type_dict def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of a utility.""" try: - if name in get_custom_nodes(self.type_name).keys(): - return get_custom_nodes(self.type_name)[name] - return build_template_from_class(name, utility_type_to_cls_dict) + custom_nodes = get_custom_nodes(self.type_name) + if name in custom_nodes.keys(): + return custom_nodes[name] + return build_template_from_class(name, self.type_to_loader_dict) except ValueError as exc: raise ValueError(f"Utility {name} not found") from exc @@ -29,11 +55,7 @@ class UtilityCreator(LangChainTypeCreator): return None def to_list(self) -> List[str]: - return [ - utility.__name__ - for utility in self.type_to_loader_dict.values() - if utility.__name__ in settings.utilities or settings.dev - ] + return list(self.type_to_loader_dict.keys()) utility_creator = UtilityCreator() diff --git a/src/backend/langflow/interface/vector_store/base.py b/src/backend/langflow/interface/vector_store/base.py index 7fca2ba0c..7ec1e0f5b 100644 --- a/src/backend/langflow/interface/vector_store/base.py +++ b/src/backend/langflow/interface/vector_store/base.py @@ -1,43 +1,41 @@ -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional, Type + +from langchain import vectorstores from langflow.interface.base import LangChainTypeCreator -from langflow.interface.custom_lists import vectorstores_type_to_cls_dict +from langflow.interface.importing.utils import import_class from langflow.settings import settings +from langflow.template.frontend_node.vectorstores import VectorStoreFrontendNode from langflow.utils.logger import logger -from langflow.utils.util import build_template_from_class +from langflow.utils.util import build_template_from_method class VectorstoreCreator(LangChainTypeCreator): type_name: str = "vectorstores" + @property + def frontend_node_class(self) -> Type[VectorStoreFrontendNode]: + return VectorStoreFrontendNode + @property def type_to_loader_dict(self) -> Dict: - return vectorstores_type_to_cls_dict + if self.type_dict is None: + self.type_dict: dict[str, Any] = { + vectorstore_name: import_class( + f"langchain.vectorstores.{vectorstore_name}" + ) + for vectorstore_name in vectorstores.__all__ + } + return self.type_dict def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of an embedding.""" try: - signature = build_template_from_class(name, vectorstores_type_to_cls_dict) - - # TODO: Use FrontendendNode class to build the signature - signature["template"] = { - "documents": { - "type": "TextSplitter", - "required": True, - "show": True, - "name": "documents", - "display_name": "Text Splitter", - }, - "embedding": { - "type": "Embeddings", - "required": True, - "show": True, - "name": "embedding", - "display_name": "Embedding", - }, - } - return signature - + return build_template_from_method( + name, + type_to_cls_dict=self.type_to_loader_dict, + method_name="from_texts", + ) except ValueError as exc: raise ValueError(f"Vector Store {name} not found") from exc except AttributeError as exc: diff --git a/src/backend/langflow/settings.py b/src/backend/langflow/settings.py index 48aa5939d..5ef61ab7b 100644 --- a/src/backend/langflow/settings.py +++ b/src/backend/langflow/settings.py @@ -32,7 +32,7 @@ class Settings(BaseSettings): values[key] = [] return values - def update_from_yaml(self, file_path: str): + def update_from_yaml(self, file_path: str, dev: bool = False): new_settings = load_settings_from_yaml(file_path) self.chains = new_settings.chains or [] self.agents = new_settings.agents or [] @@ -44,7 +44,7 @@ class Settings(BaseSettings): self.toolkits = new_settings.toolkits or [] self.textsplitters = new_settings.textsplitters or [] self.utilities = new_settings.utilities or [] - self.dev = new_settings.dev or False + self.dev = dev def save_settings_to_yaml(settings: Settings, file_path: str): diff --git a/src/backend/langflow/template/base.py b/src/backend/langflow/template/base.py index 5273782ed..8b1378917 100644 --- a/src/backend/langflow/template/base.py +++ b/src/backend/langflow/template/base.py @@ -1,251 +1 @@ -from abc import ABC -from typing import Any, Callable, Dict, Optional, Union -from pydantic import BaseModel - -from langflow.template.constants import FORCE_SHOW_FIELDS -from langflow.utils import constants - - -class TemplateFieldCreator(BaseModel, ABC): - field_type: str = "str" - required: bool = False - placeholder: str = "" - is_list: bool = False - show: bool = True - multiline: bool = False - value: Any = None - suffixes: list[str] = [] - fileTypes: list[str] = [] - file_types: list[str] = [] - content: Union[str, None] = None - password: bool = False - options: list[str] = [] - name: str = "" - display_name: Optional[str] = None - advanced: bool = False - - def to_dict(self): - result = self.dict() - # Remove key if it is None - for key in list(result.keys()): - if result[key] is None or result[key] == []: - del result[key] - result["type"] = result.pop("field_type") - result["list"] = result.pop("is_list") - - if result.get("file_types"): - result["fileTypes"] = result.pop("file_types") - - if self.field_type == "file": - result["content"] = self.content - return result - - def process_field( - self, key: str, value: Dict[str, Any], name: Optional[str] = None - ) -> None: - _type = value["type"] - - # Remove 'Optional' wrapper - if "Optional" in _type: - _type = _type.replace("Optional[", "")[:-1] - - # Check for list type - if "List" in _type: - _type = _type.replace("List[", "")[:-1] - self.is_list = True - - # Replace 'Mapping' with 'dict' - if "Mapping" in _type: - _type = _type.replace("Mapping", "dict") - - # Change type from str to Tool - self.field_type = "Tool" if key in {"allowed_tools"} else self.field_type - - self.field_type = "int" if key in {"max_value_length"} else self.field_type - - # Show or not field - self.show = bool( - (self.required and key not in ["input_variables"]) - or key in FORCE_SHOW_FIELDS - or "api_key" in key - ) - - # Add password field - self.password = any( - text in key.lower() for text in {"password", "token", "api", "key"} - ) - - # Add multline - self.multiline = key in { - "suffix", - "prefix", - "template", - "examples", - "code", - "headers", - } - - # Replace dict type with str - if "dict" in self.field_type.lower(): - self.field_type = "code" - - if key == "dict_": - self.field_type = "file" - self.suffixes = [".json", ".yaml", ".yml"] - self.file_types = ["json", "yaml", "yml"] - - # Replace default value with actual value - if "default" in value: - self.value = value["default"] - - if key == "headers": - self.value = """{'Authorization': - 'Bearer '}""" - - # Add options to openai - if name == "OpenAI" and key == "model_name": - self.options = constants.OPENAI_MODELS - self.is_list = True - elif name == "ChatOpenAI" and key == "model_name": - self.options = constants.CHAT_OPENAI_MODELS - self.is_list = True - - -class TemplateField(TemplateFieldCreator): - pass - - -class Template(BaseModel): - type_name: str - fields: list[TemplateField] - - def process_fields( - self, - name: Optional[str] = None, - format_field_func: Union[Callable, None] = None, - ): - if format_field_func: - for field in self.fields: - format_field_func(field, name) - - def to_dict(self, format_field_func=None): - self.process_fields(self.type_name, format_field_func) - result = {field.name: field.to_dict() for field in self.fields} - result["_type"] = self.type_name # type: ignore - return result - - -class FrontendNode(BaseModel): - template: Template - description: str - base_classes: list - name: str = "" - - def to_dict(self): - return { - self.name: { - "template": self.template.to_dict(self.format_field), - "description": self.description, - "base_classes": self.base_classes, - } - } - - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - key = field.name - value = field.to_dict() - _type = value["type"] - - # Remove 'Optional' wrapper - if "Optional" in _type: - _type = _type.replace("Optional[", "")[:-1] - - # Check for list type - if "List" in _type or "Sequence" in _type: - _type = _type.replace("List[", "") - _type = _type.replace("Sequence[", "")[:-1] - field.is_list = True - - # Replace 'Mapping' with 'dict' - if "Mapping" in _type: - _type = _type.replace("Mapping", "dict") - - # {'type': 'Union[float, Tuple[float, float], NoneType]'} != {'type': 'float'} - if "Union" in _type: - _type = _type.replace("Union[", "")[:-1] - _type = _type.split(",")[0] - _type = _type.replace("]", "").replace("[", "") - - field.field_type = _type - - # Change type from str to Tool - field.field_type = "Tool" if key in {"allowed_tools"} else field.field_type - - field.field_type = "int" if key in {"max_value_length"} else field.field_type - - # Show or not field - field.show = bool( - (field.required and key not in ["input_variables"]) - or key in FORCE_SHOW_FIELDS - or "api" in key - or ("key" in key and "input" not in key and "output" not in key) - ) - - # Add password field - field.password = ( - any(text in key.lower() for text in {"password", "token", "api", "key"}) - and field.show - ) - - # Add multline - field.multiline = key in { - "suffix", - "prefix", - "template", - "examples", - "code", - "headers", - "description", - } - - # Replace dict type with str - if "dict" in field.field_type.lower(): - field.field_type = "code" - - if key == "dict_": - field.field_type = "file" - field.suffixes = [".json", ".yaml", ".yml"] - field.file_types = ["json", "yaml", "yml"] - - # Replace default value with actual value - if "default" in value: - field.value = value["default"] - - if key == "headers": - field.value = """{'Authorization': - 'Bearer '}""" - - # Add options to openai - if name == "OpenAI" and key == "model_name": - field.options = constants.OPENAI_MODELS - field.is_list = True - elif name == "ChatOpenAI": - if key == "model_name": - field.options = constants.CHAT_OPENAI_MODELS - field.is_list = True - if "api_key" in key and "OpenAI" in str(name): - field.display_name = "OpenAI API Key" - field.required = False - if field.value is None: - field.value = "" - - if "kwargs" in field.name.lower(): - field.advanced = True - field.required = False - field.show = False - # If the field.name contains api or api and key, then it might be an api key - # other conditions are to make sure that it is not an input or output variable - if "api" in key.lower() and "key" in key.lower(): - field.required = False - field.advanced = False diff --git a/src/backend/langflow/template/field/__init__.py b/src/backend/langflow/template/field/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/langflow/template/field/base.py b/src/backend/langflow/template/field/base.py new file mode 100644 index 000000000..a1de2c1b6 --- /dev/null +++ b/src/backend/langflow/template/field/base.py @@ -0,0 +1,43 @@ +from abc import ABC +from typing import Any, Optional, Union + +from pydantic import BaseModel + + +class TemplateFieldCreator(BaseModel, ABC): + field_type: str = "str" + required: bool = False + placeholder: str = "" + is_list: bool = False + show: bool = True + multiline: bool = False + value: Any = None + suffixes: list[str] = [] + fileTypes: list[str] = [] + file_types: list[str] = [] + content: Union[str, None] = None + password: bool = False + options: list[str] = [] + name: str = "" + display_name: Optional[str] = None + advanced: bool = False + + def to_dict(self): + result = self.dict() + # Remove key if it is None + for key in list(result.keys()): + if result[key] is None or result[key] == []: + del result[key] + result["type"] = result.pop("field_type") + result["list"] = result.pop("is_list") + + if result.get("file_types"): + result["fileTypes"] = result.pop("file_types") + + if self.field_type == "file": + result["content"] = self.content + return result + + +class TemplateField(TemplateFieldCreator): + pass diff --git a/src/backend/langflow/template/frontend_node/__init__.py b/src/backend/langflow/template/frontend_node/__init__.py new file mode 100644 index 000000000..1aa946d41 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/__init__.py @@ -0,0 +1,21 @@ +from langflow.template.frontend_node import ( + agents, + chains, + embeddings, + llms, + memories, + prompts, + tools, + vectorstores, +) + +__all__ = [ + "agents", + "chains", + "embeddings", + "memories", + "tools", + "llms", + "prompts", + "vectorstores", +] diff --git a/src/backend/langflow/template/frontend_node/agents.py b/src/backend/langflow/template/frontend_node/agents.py new file mode 100644 index 000000000..e4fe40187 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/agents.py @@ -0,0 +1,233 @@ +from typing import Optional + +from langchain.agents import types + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template + +NON_CHAT_AGENTS = { + agent_type: agent_class + for agent_type, agent_class in types.AGENT_TO_CLASS.items() + if "chat" not in agent_type.value +} + + +class SQLAgentNode(FrontendNode): + name: str = "SQLAgent" + template: Template = Template( + type_name="sql_agent", + fields=[ + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=False, + value="", + name="database_uri", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct a sql agent from an LLM and tools.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class VectorStoreRouterAgentNode(FrontendNode): + name: str = "VectorStoreRouterAgent" + template: Template = Template( + type_name="vectorstorerouter_agent", + fields=[ + TemplateField( + field_type="VectorStoreRouterToolkit", + required=True, + show=True, + name="vectorstoreroutertoolkit", + display_name="Vector Store Router Toolkit", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct an agent from a Vector Store Router.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class VectorStoreAgentNode(FrontendNode): + name: str = "VectorStoreAgent" + template: Template = Template( + type_name="vectorstore_agent", + fields=[ + TemplateField( + field_type="VectorStoreInfo", + required=True, + show=True, + name="vectorstoreinfo", + display_name="Vector Store Info", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct an agent from a Vector Store.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class SQLDatabaseNode(FrontendNode): + name: str = "SQLDatabase" + template: Template = Template( + type_name="sql_database", + fields=[ + TemplateField( + field_type="str", + required=True, + is_list=False, + show=True, + multiline=False, + value="", + name="uri", + ), + ], + ) + description: str = """SQLAlchemy wrapper around a database.""" + base_classes: list[str] = ["SQLDatabase"] + + def to_dict(self): + return super().to_dict() + + +class CSVAgentNode(FrontendNode): + name: str = "CSVAgent" + template: Template = Template( + type_name="csv_agent", + fields=[ + TemplateField( + field_type="file", + required=True, + show=True, + name="path", + value="", + suffixes=[".csv"], + fileTypes=["csv"], + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct a json agent from a CSV and tools.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class InitializeAgentNode(FrontendNode): + name: str = "initialize_agent" + template: Template = Template( + type_name="initailize_agent", + fields=[ + TemplateField( + field_type="str", + required=True, + is_list=True, + show=True, + multiline=False, + options=list(NON_CHAT_AGENTS.keys()), + value=list(NON_CHAT_AGENTS.keys())[0], + name="agent", + advanced=False, + ), + TemplateField( + field_type="BaseChatMemory", + required=False, + show=True, + name="memory", + advanced=False, + ), + TemplateField( + field_type="Tool", + required=False, + show=True, + name="tools", + is_list=True, + advanced=False, + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + advanced=False, + ), + ], + ) + description: str = """Construct a json agent from an LLM and tools.""" + base_classes: list[str] = ["AgentExecutor", "function"] + + def to_dict(self): + return super().to_dict() + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + # do nothing and don't return anything + pass + + +class JsonAgentNode(FrontendNode): + name: str = "JsonAgent" + template: Template = Template( + type_name="json_agent", + fields=[ + TemplateField( + field_type="BaseToolkit", + required=True, + show=True, + name="toolkit", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct a json agent from an LLM and tools.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() diff --git a/src/backend/langflow/template/frontend_node/base.py b/src/backend/langflow/template/frontend_node/base.py new file mode 100644 index 000000000..2714cd4ae --- /dev/null +++ b/src/backend/langflow/template/frontend_node/base.py @@ -0,0 +1,200 @@ +import re +from typing import List, Optional + +from pydantic import BaseModel + +from langflow.template.constants import FORCE_SHOW_FIELDS +from langflow.template.field.base import TemplateField +from langflow.template.template.base import Template +from langflow.utils import constants + + +class FrontendNode(BaseModel): + template: Template + description: str + base_classes: List[str] + name: str = "" + + def to_dict(self) -> dict: + return { + self.name: { + "template": self.template.to_dict(self.format_field), + "description": self.description, + "base_classes": self.base_classes, + } + } + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + """Formats a given field based on its attributes and value.""" + SPECIAL_FIELD_HANDLERS = { + "allowed_tools": lambda field: "Tool", + "max_value_length": lambda field: "int", + } + + key = field.name + value = field.to_dict() + _type = value["type"] + + _type = FrontendNode.remove_optional(_type) + _type, is_list = FrontendNode.check_for_list_type(_type) + field.is_list = is_list or field.is_list + _type = FrontendNode.replace_mapping_with_dict(_type) + _type = FrontendNode.handle_union_type(_type) + + field.field_type = FrontendNode.handle_special_field( + field, key, _type, SPECIAL_FIELD_HANDLERS + ) + field.field_type = FrontendNode.handle_dict_type(field, _type) + field.show = FrontendNode.should_show_field(key, field.required) + field.password = FrontendNode.should_be_password(key, field.show) + field.multiline = FrontendNode.should_be_multiline(key) + + FrontendNode.replace_default_value(field, value) + FrontendNode.handle_specific_field_values(field, key, name) + FrontendNode.handle_kwargs_field(field) + FrontendNode.handle_api_key_field(field, key) + + @staticmethod + def remove_optional(_type: str) -> str: + """Removes 'Optional' wrapper from the type if present.""" + return re.sub(r"Optional\[(.*)\]", r"\1", _type) + + @staticmethod + def check_for_list_type(_type: str) -> tuple: + """Checks for list type and returns the modified type and a boolean indicating if it's a list.""" + is_list = "List" in _type or "Sequence" in _type + if is_list: + _type = re.sub(r"(List|Sequence)\[(.*)\]", r"\2", _type) + return _type, is_list + + @staticmethod + def replace_mapping_with_dict(_type: str) -> str: + """Replaces 'Mapping' with 'dict'.""" + return _type.replace("Mapping", "dict") + + @staticmethod + def handle_union_type(_type: str) -> str: + """Simplifies the 'Union' type to the first type in the Union.""" + if "Union" in _type: + _type = _type.replace("Union[", "")[:-1] + _type = _type.split(",")[0] + _type = _type.replace("]", "").replace("[", "") + return _type + + @staticmethod + def handle_special_field( + field, key: str, _type: str, SPECIAL_FIELD_HANDLERS + ) -> str: + """Handles special field by using the respective handler if present.""" + handler = SPECIAL_FIELD_HANDLERS.get(key) + return handler(field) if handler else _type + + @staticmethod + def handle_dict_type(field: TemplateField, _type: str) -> str: + """Handles 'dict' type by replacing it with 'code' or 'file' based on the field name.""" + if "dict" in _type.lower(): + if field.name == "dict_": + field.field_type = "file" + field.suffixes = [".json", ".yaml", ".yml"] + field.file_types = ["json", "yaml", "yml"] + else: + field.field_type = "code" + return _type + + @staticmethod + def replace_default_value(field: TemplateField, value: dict) -> None: + """Replaces default value with actual value if 'default' is present in value.""" + if "default" in value: + field.value = value["default"] + + @staticmethod + def handle_specific_field_values( + field: TemplateField, key: str, name: Optional[str] = None + ) -> None: + """Handles specific field values for certain fields.""" + if key == "headers": + field.value = """{'Authorization': + 'Bearer '}""" + if name == "OpenAI" and key == "model_name": + field.options = constants.OPENAI_MODELS + field.is_list = True + elif name == "ChatOpenAI" and key == "model_name": + field.options = constants.CHAT_OPENAI_MODELS + field.is_list = True + if "api_key" in key and "OpenAI" in str(name): + field.display_name = "OpenAI API Key" + field.required = False + if field.value is None: + field.value = "" + + @staticmethod + def handle_kwargs_field(field: TemplateField) -> None: + """Handles kwargs field by setting certain attributes.""" + if "kwargs" in field.name.lower(): + field.advanced = True + field.required = False + field.show = False + + @staticmethod + def handle_api_key_field(field: TemplateField, key: str) -> None: + """Handles api key field by setting certain attributes.""" + if "api" in key.lower() and "key" in key.lower(): + field.required = False + field.advanced = False + + field.display_name = key.replace("_", " ").title() + field.display_name = field.display_name.replace("Api", "API") + + @staticmethod + def should_show_field(key: str, required: bool) -> bool: + """Determines whether the field should be shown.""" + return ( + (required and key not in ["input_variables"]) + or key in FORCE_SHOW_FIELDS + or "api" in key + or ("key" in key and "input" not in key and "output" not in key) + ) + + @staticmethod + def should_be_password(key: str, show: bool) -> bool: + """Determines whether the field should be a password field.""" + return ( + any(text in key.lower() for text in {"password", "token", "api", "key"}) + and show + ) + + @staticmethod + def should_be_multiline(key: str) -> bool: + """Determines whether the field should be multiline.""" + return key in { + "suffix", + "prefix", + "template", + "examples", + "code", + "headers", + "description", + } + + @staticmethod + def replace_dict_with_code_or_file( + field: TemplateField, _type: str, key: str + ) -> str: + """Replaces 'dict' type with 'code' or 'file'.""" + if "dict" in _type.lower(): + if key == "dict_": + field.field_type = "file" + field.suffixes = [".json", ".yaml", ".yml"] + field.file_types = ["json", "yaml", "yml"] + else: + field.field_type = "code" + return field.field_type + + @staticmethod + def set_field_default_value(field: TemplateField, value: dict, key: str) -> None: + """Sets the field value with the default value if present.""" + if "default" in value: + field.value = value["default"] + if key == "headers": + field.value = """{'Authorization': 'Bearer '}""" diff --git a/src/backend/langflow/template/frontend_node/chains.py b/src/backend/langflow/template/frontend_node/chains.py new file mode 100644 index 000000000..cfcda2ef4 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/chains.py @@ -0,0 +1,157 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template + + +class ChainFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + + field.advanced = False + if "key" in field.name: + field.password = False + field.show = False + if field.name in ["input_key", "output_key"]: + field.required = True + field.show = True + field.advanced = True + + # Separated for possible future changes + if field.name == "prompt" and field.value is None: + field.required = True + field.show = True + field.advanced = False + if field.name == "memory": + field.required = False + field.show = True + field.advanced = False + if field.name == "verbose": + field.required = False + field.show = True + field.advanced = True + if field.name == "llm": + field.required = True + field.show = True + field.advanced = False + + +class SeriesCharacterChainNode(FrontendNode): + name: str = "SeriesCharacterChain" + template: Template = Template( + type_name="SeriesCharacterChain", + fields=[ + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="character", + ), + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="series", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = "SeriesCharacterChain is a chain you can use to have a conversation with a character from a series." # noqa + base_classes: list[str] = [ + "LLMChain", + "BaseCustomChain", + "Chain", + "ConversationChain", + "SeriesCharacterChain", + "function", + ] + + +class TimeTravelGuideChainNode(FrontendNode): + name: str = "TimeTravelGuideChain" + template: Template = Template( + type_name="TimeTravelGuideChain", + fields=[ + TemplateField( + field_type="BaseLanguageModel", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="llm", + display_name="LLM", + ), + TemplateField( + field_type="BaseChatMemory", + required=False, + show=True, + name="memory", + advanced=False, + ), + ], + ) + description: str = "Time travel guide chain to be used in the flow." + base_classes: list[str] = [ + "LLMChain", + "BaseCustomChain", + "TimeTravelGuideChain", + "Chain", + "ConversationChain", + ] + + +class MidJourneyPromptChainNode(FrontendNode): + name: str = "MidJourneyPromptChain" + template: Template = Template( + type_name="MidJourneyPromptChain", + fields=[ + TemplateField( + field_type="BaseLanguageModel", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="llm", + display_name="LLM", + ), + TemplateField( + field_type="BaseChatMemory", + required=False, + show=True, + name="memory", + advanced=False, + ), + ], + ) + description: str = "MidJourneyPromptChain is a chain you can use to generate new MidJourney prompts." + base_classes: list[str] = [ + "LLMChain", + "BaseCustomChain", + "Chain", + "ConversationChain", + "MidJourneyPromptChain", + ] diff --git a/src/backend/langflow/template/frontend_node/embeddings.py b/src/backend/langflow/template/frontend_node/embeddings.py new file mode 100644 index 000000000..d21e12e73 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/embeddings.py @@ -0,0 +1,38 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class EmbeddingFrontendNode(FrontendNode): + @staticmethod + def format_jina_fields(field: TemplateField): + if "jina" in field.name: + field.show = True + field.advanced = False + + if "auth" in field.name or "token" in field.name: + field.password = True + field.show = True + field.advanced = False + + if field.name == "jina_api_url": + field.show = True + field.advanced = True + field.display_name = "Jina API URL" + field.password = False + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + field.advanced = not field.required + field.show = True + if field.name == "headers": + field.show = False + + if "openai" in field.name: + field.show = True + field.advanced = "api_key" not in field.name + + # Format Jina fields + EmbeddingFrontendNode.format_jina_fields(field) diff --git a/src/backend/langflow/template/frontend_node/llms.py b/src/backend/langflow/template/frontend_node/llms.py new file mode 100644 index 000000000..4dc32dff1 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/llms.py @@ -0,0 +1,50 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class LLMFrontendNode(FrontendNode): + @staticmethod + def format_openai_field(field: TemplateField): + if "openai" in field.name.lower(): + field.display_name = ( + field.name.title().replace("Openai", "OpenAI").replace("_", " ") + ).replace("Api", "API") + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + display_names_dict = { + "huggingfacehub_api_token": "HuggingFace Hub API Token", + } + FrontendNode.format_field(field, name) + SHOW_FIELDS = ["repo_id"] + if field.name in SHOW_FIELDS: + field.show = True + + if "api" in field.name and ("key" in field.name or "token" in field.name): + field.password = True + field.show = True + # Required should be False to support + # loading the API key from environment variables + field.required = False + field.advanced = False + + if field.name == "task": + field.required = True + field.show = True + field.is_list = True + field.options = ["text-generation", "text2text-generation"] + field.advanced = True + + if display_name := display_names_dict.get(field.name): + field.display_name = display_name + if field.name == "model_kwargs": + field.field_type = "code" + field.advanced = True + field.show = True + elif field.name in ["model_name", "temperature"]: + field.advanced = False + field.show = True + + LLMFrontendNode.format_openai_field(field) diff --git a/src/backend/langflow/template/frontend_node/memories.py b/src/backend/langflow/template/frontend_node/memories.py new file mode 100644 index 000000000..91d892627 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/memories.py @@ -0,0 +1,20 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class MemoryFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + + if not isinstance(field.value, str): + field.value = None + if field.name == "k": + field.required = True + field.show = True + field.field_type = "int" + field.value = 10 + field.display_name = "Memory Size" + field.password = False diff --git a/src/backend/langflow/template/frontend_node/prompts.py b/src/backend/langflow/template/frontend_node/prompts.py new file mode 100644 index 000000000..830623a7e --- /dev/null +++ b/src/backend/langflow/template/frontend_node/prompts.py @@ -0,0 +1,111 @@ +from typing import Optional + +from langchain.agents.mrkl import prompt + +from langflow.template.constants import DEFAULT_PROMPT, HUMAN_PROMPT, SYSTEM_PROMPT +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template + + +class PromptFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + # if field.field_type == "StringPromptTemplate" + # change it to str + PROMPT_FIELDS = [ + "template", + "suffix", + "prefix", + "examples", + "format_instructions", + ] + if field.field_type == "StringPromptTemplate" and "Message" in str(name): + field.field_type = "prompt" + field.multiline = True + field.value = HUMAN_PROMPT if "Human" in field.name else SYSTEM_PROMPT + if field.name == "template" and field.value == "": + field.value = DEFAULT_PROMPT + + if field.name in PROMPT_FIELDS: + field.field_type = "prompt" + field.advanced = False + + if ( + "Union" in field.field_type + and "BaseMessagePromptTemplate" in field.field_type + ): + field.field_type = "BaseMessagePromptTemplate" + + # All prompt fields should be password=False + field.password = False + + +class PromptTemplateNode(FrontendNode): + name: str = "PromptTemplate" + template: Template + description: str + base_classes: list[str] = ["BasePromptTemplate"] + + def to_dict(self): + return super().to_dict() + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + if field.name == "examples": + field.advanced = False + + +class BasePromptFrontendNode(FrontendNode): + name: str + template: Template + description: str + base_classes: list[str] + + def to_dict(self): + return super().to_dict() + + +class ZeroShotPromptNode(BasePromptFrontendNode): + name: str = "ZeroShotPrompt" + template: Template = Template( + type_name="zero_shot", + fields=[ + TemplateField( + field_type="str", + required=False, + placeholder="", + is_list=False, + show=True, + multiline=True, + value=prompt.PREFIX, + name="prefix", + ), + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=True, + value=prompt.SUFFIX, + name="suffix", + ), + TemplateField( + field_type="str", + required=False, + placeholder="", + is_list=False, + show=True, + multiline=True, + value=prompt.FORMAT_INSTRUCTIONS, + name="format_instructions", + ), + ], + ) + description: str = "Prompt template for Zero Shot Agent." + base_classes: list[str] = ["BasePromptTemplate"] + + def to_dict(self): + return super().to_dict() diff --git a/src/backend/langflow/template/frontend_node/tools.py b/src/backend/langflow/template/frontend_node/tools.py new file mode 100644 index 000000000..2819be4d9 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/tools.py @@ -0,0 +1,83 @@ +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template +from langflow.utils.constants import DEFAULT_PYTHON_FUNCTION + + +class ToolNode(FrontendNode): + name: str = "Tool" + template: Template = Template( + type_name="Tool", + fields=[ + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=True, + value="", + name="name", + advanced=False, + ), + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=True, + value="", + name="description", + advanced=False, + ), + TemplateField( + name="func", + field_type="function", + required=True, + is_list=False, + show=True, + multiline=True, + advanced=False, + ), + TemplateField( + field_type="bool", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=False, + value=False, + name="return_direct", + ), + ], + ) + description: str = "Tool to be used in the flow." + base_classes: list[str] = ["Tool"] + + def to_dict(self): + return super().to_dict() + + +class PythonFunctionNode(FrontendNode): + name: str = "PythonFunction" + template: Template = Template( + type_name="python_function", + fields=[ + TemplateField( + field_type="code", + required=True, + placeholder="", + is_list=False, + show=True, + value=DEFAULT_PYTHON_FUNCTION, + name="code", + advanced=False, + ) + ], + ) + description: str = "Python function to be executed." + base_classes: list[str] = ["function"] + + def to_dict(self): + return super().to_dict() diff --git a/src/backend/langflow/template/frontend_node/utilities.py b/src/backend/langflow/template/frontend_node/utilities.py new file mode 100644 index 000000000..615d7d12f --- /dev/null +++ b/src/backend/langflow/template/frontend_node/utilities.py @@ -0,0 +1,22 @@ +import ast +import json +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class UtilitiesFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + # field.field_type could be "Literal['news', 'search', 'places', 'images'] + # we need to convert it to a list + if "Literal" in field.field_type: + field.options = ast.literal_eval(field.field_type.replace("Literal", "")) + field.is_list = True + field.field_type = "str" + + if isinstance(field.value, dict): + field.field_type = "code" + field.value = json.dumps(field.value, indent=4) diff --git a/src/backend/langflow/template/frontend_node/vectorstores.py b/src/backend/langflow/template/frontend_node/vectorstores.py new file mode 100644 index 000000000..76f623852 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/vectorstores.py @@ -0,0 +1,64 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class VectorStoreFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + # Define common field attributes + basic_fields = ["work_dir", "collection_name", "api_key", "location"] + advanced_fields = [ + "n_dim", + "key", + "prefix", + "distance_func", + "content_payload_key", + "metadata_payload_key", + "timeout", + "host", + "path", + "url", + "port", + "https", + "prefer_grpc", + "grpc_port", + ] + + # Check and set field attributes + if field.name == "texts": + field.name = "documents" + field.field_type = "TextSplitter" + field.display_name = "Text Splitter" + field.required = True + field.show = True + field.advanced = False + + elif "embedding" in field.name: + # for backwards compatibility + field.name = "embedding" + field.required = True + field.show = True + field.advanced = False + field.display_name = "Embedding" + field.field_type = "Embeddings" + + elif field.name in basic_fields: + field.show = True + field.advanced = False + if field.name == "api_key": + field.display_name = "API Key" + field.password = True + elif field.name == "location": + field.value = ":memory:" + field.placeholder = ":memory:" + + elif field.name in advanced_fields: + field.show = True + field.advanced = True + if "key" in field.name: + field.password = False + # TODO: Weaviate requires weaviate_url to be passed as it is not part of + # the class or from_texts method. We need the add_extra_fields to fix this diff --git a/src/backend/langflow/template/nodes.py b/src/backend/langflow/template/nodes.py index 9fad19508..8b1378917 100644 --- a/src/backend/langflow/template/nodes.py +++ b/src/backend/langflow/template/nodes.py @@ -1,630 +1 @@ -from typing import Optional -from langchain.agents import loading -from langchain.agents.mrkl import prompt - -from langflow.template.base import FrontendNode, Template, TemplateField -from langflow.template.constants import DEFAULT_PROMPT, HUMAN_PROMPT, SYSTEM_PROMPT -from langflow.utils.constants import DEFAULT_PYTHON_FUNCTION - -NON_CHAT_AGENTS = { - agent_type: agent_class - for agent_type, agent_class in loading.AGENT_TO_CLASS.items() - if "chat" not in agent_type.value -} - - -class BasePromptFrontendNode(FrontendNode): - name: str - template: Template - description: str - base_classes: list[str] - - def to_dict(self): - return super().to_dict() - - -class ZeroShotPromptNode(BasePromptFrontendNode): - name: str = "ZeroShotPrompt" - template: Template = Template( - type_name="zero_shot", - fields=[ - TemplateField( - field_type="str", - required=False, - placeholder="", - is_list=False, - show=True, - multiline=True, - value=prompt.PREFIX, - name="prefix", - ), - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=True, - value=prompt.SUFFIX, - name="suffix", - ), - TemplateField( - field_type="str", - required=False, - placeholder="", - is_list=False, - show=True, - multiline=True, - value=prompt.FORMAT_INSTRUCTIONS, - name="format_instructions", - ), - ], - ) - description: str = "Prompt template for Zero Shot Agent." - base_classes: list[str] = ["BasePromptTemplate"] - - def to_dict(self): - return super().to_dict() - - -class PromptTemplateNode(FrontendNode): - name: str = "PromptTemplate" - template: Template - description: str - base_classes: list[str] = ["BasePromptTemplate"] - - def to_dict(self): - return super().to_dict() - - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - if field.name == "examples": - field.advanced = False - - -class PythonFunctionNode(FrontendNode): - name: str = "PythonFunction" - template: Template = Template( - type_name="python_function", - fields=[ - TemplateField( - field_type="code", - required=True, - placeholder="", - is_list=False, - show=True, - value=DEFAULT_PYTHON_FUNCTION, - name="code", - advanced=False, - ) - ], - ) - description: str = "Python function to be executed." - base_classes: list[str] = ["function"] - - def to_dict(self): - return super().to_dict() - - -class MidJourneyPromptChainNode(FrontendNode): - name: str = "MidJourneyPromptChain" - template: Template = Template( - type_name="MidJourneyPromptChain", - fields=[ - TemplateField( - field_type="BaseLanguageModel", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="llm", - display_name="LLM", - ), - TemplateField( - field_type="BaseChatMemory", - required=False, - show=True, - name="memory", - advanced=False, - ), - ], - ) - description: str = "MidJourneyPromptChain is a chain you can use to generate new MidJourney prompts." - base_classes: list[str] = [ - "LLMChain", - "BaseCustomChain", - "Chain", - "ConversationChain", - "MidJourneyPromptChain", - ] - - -class TimeTravelGuideChainNode(FrontendNode): - name: str = "TimeTravelGuideChain" - template: Template = Template( - type_name="TimeTravelGuideChain", - fields=[ - TemplateField( - field_type="BaseLanguageModel", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="llm", - display_name="LLM", - ), - TemplateField( - field_type="BaseChatMemory", - required=False, - show=True, - name="memory", - advanced=False, - ), - ], - ) - description: str = "Time travel guide chain to be used in the flow." - base_classes: list[str] = [ - "LLMChain", - "BaseCustomChain", - "TimeTravelGuideChain", - "Chain", - "ConversationChain", - ] - - -class SeriesCharacterChainNode(FrontendNode): - name: str = "SeriesCharacterChain" - template: Template = Template( - type_name="SeriesCharacterChain", - fields=[ - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="character", - ), - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="series", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = "SeriesCharacterChain is a chain you can use to have a conversation with a character from a series." # noqa - base_classes: list[str] = [ - "LLMChain", - "BaseCustomChain", - "Chain", - "ConversationChain", - "SeriesCharacterChain", - "function", - ] - - -class ToolNode(FrontendNode): - name: str = "Tool" - template: Template = Template( - type_name="Tool", - fields=[ - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=True, - value="", - name="name", - advanced=False, - ), - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=True, - value="", - name="description", - advanced=False, - ), - TemplateField( - name="func", - field_type="function", - required=True, - is_list=False, - show=True, - multiline=True, - advanced=False, - ), - TemplateField( - field_type="bool", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=False, - value=False, - name="return_direct", - ), - ], - ) - description: str = "Tool to be used in the flow." - base_classes: list[str] = ["Tool"] - - def to_dict(self): - return super().to_dict() - - -class JsonAgentNode(FrontendNode): - name: str = "JsonAgent" - template: Template = Template( - type_name="json_agent", - fields=[ - TemplateField( - field_type="BaseToolkit", - required=True, - show=True, - name="toolkit", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct a json agent from an LLM and tools.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class InitializeAgentNode(FrontendNode): - name: str = "initialize_agent" - template: Template = Template( - type_name="initailize_agent", - fields=[ - TemplateField( - field_type="str", - required=True, - is_list=True, - show=True, - multiline=False, - options=list(NON_CHAT_AGENTS.keys()), - value=list(NON_CHAT_AGENTS.keys())[0], - name="agent", - advanced=False, - ), - TemplateField( - field_type="BaseChatMemory", - required=False, - show=True, - name="memory", - advanced=False, - ), - TemplateField( - field_type="Tool", - required=False, - show=True, - name="tools", - is_list=True, - advanced=False, - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - advanced=False, - ), - ], - ) - description: str = """Construct a json agent from an LLM and tools.""" - base_classes: list[str] = ["AgentExecutor", "function"] - - def to_dict(self): - return super().to_dict() - - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - # do nothing and don't return anything - pass - - -class CSVAgentNode(FrontendNode): - name: str = "CSVAgent" - template: Template = Template( - type_name="csv_agent", - fields=[ - TemplateField( - field_type="file", - required=True, - show=True, - name="path", - value="", - suffixes=[".csv"], - fileTypes=["csv"], - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct a json agent from a CSV and tools.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class SQLDatabaseNode(FrontendNode): - name: str = "SQLDatabase" - template: Template = Template( - type_name="sql_database", - fields=[ - TemplateField( - field_type="str", - required=True, - is_list=False, - show=True, - multiline=False, - value="", - name="uri", - ), - ], - ) - description: str = """SQLAlchemy wrapper around a database.""" - base_classes: list[str] = ["SQLDatabase"] - - def to_dict(self): - return super().to_dict() - - -class VectorStoreAgentNode(FrontendNode): - name: str = "VectorStoreAgent" - template: Template = Template( - type_name="vectorstore_agent", - fields=[ - TemplateField( - field_type="VectorStoreInfo", - required=True, - show=True, - name="vectorstoreinfo", - display_name="Vector Store Info", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct an agent from a Vector Store.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class VectorStoreRouterAgentNode(FrontendNode): - name: str = "VectorStoreRouterAgent" - template: Template = Template( - type_name="vectorstorerouter_agent", - fields=[ - TemplateField( - field_type="VectorStoreRouterToolkit", - required=True, - show=True, - name="vectorstoreroutertoolkit", - display_name="Vector Store Router Toolkit", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct an agent from a Vector Store Router.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class SQLAgentNode(FrontendNode): - name: str = "SQLAgent" - template: Template = Template( - type_name="sql_agent", - fields=[ - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=False, - value="", - name="database_uri", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct an agent from a Vector Store Router.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class PromptFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - # if field.field_type == "StringPromptTemplate" - # change it to str - PROMPT_FIELDS = [ - "template", - "suffix", - "prefix", - "examples", - "format_instructions", - ] - if field.field_type == "StringPromptTemplate" and "Message" in str(name): - field.field_type = "prompt" - field.multiline = True - field.value = HUMAN_PROMPT if "Human" in field.name else SYSTEM_PROMPT - if field.name == "template" and field.value == "": - field.value = DEFAULT_PROMPT - - if field.name in PROMPT_FIELDS: - field.field_type = "prompt" - field.advanced = False - - if ( - "Union" in field.field_type - and "BaseMessagePromptTemplate" in field.field_type - ): - field.field_type = "BaseMessagePromptTemplate" - - # All prompt fields should be password=False - field.password = False - - -class MemoryFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - - if not isinstance(field.value, str): - field.value = None - if field.name == "k": - field.required = True - field.show = True - field.field_type = "int" - field.value = 10 - field.display_name = "Memory Size" - field.password = False - - -class ChainFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - - field.advanced = False - if "key" in field.name: - field.password = False - field.show = False - if field.name in ["input_key", "output_key"]: - field.required = True - field.show = True - field.advanced = True - - # Separated for possible future changes - if field.name == "prompt" and field.value is None: - # if no prompt is provided, use the default prompt - field.required = False - field.show = True - field.advanced = False - if field.name == "memory": - field.required = False - field.show = True - field.advanced = False - if field.name == "verbose": - field.required = False - field.show = True - field.advanced = True - if field.name == "llm": - field.required = True - field.show = True - field.advanced = False - - -class LLMFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - display_names_dict = { - "huggingfacehub_api_token": "HuggingFace Hub API Token", - } - FrontendNode.format_field(field, name) - SHOW_FIELDS = ["repo_id"] - if field.name in SHOW_FIELDS: - field.show = True - - if "api" in field.name and ("key" in field.name or "token" in field.name): - field.password = True - field.show = True - # Required should be False to support - # loading the API key from environment variables - field.required = False - field.advanced = False - - if field.name == "task": - field.required = True - field.show = True - field.is_list = True - field.options = ["text-generation", "text2text-generation"] - field.advanced = True - - if display_name := display_names_dict.get(field.name): - field.display_name = display_name - if field.name == "model_kwargs": - field.field_type = "code" - field.advanced = True - field.show = True - elif field.name in ["model_name", "temperature"]: - field.advanced = False - field.show = True - - -class EmbeddingFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - if field.name == "headers": - field.show = False diff --git a/src/backend/langflow/template/template/__init__.py b/src/backend/langflow/template/template/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/langflow/template/template/base.py b/src/backend/langflow/template/template/base.py new file mode 100644 index 000000000..9279f5efb --- /dev/null +++ b/src/backend/langflow/template/template/base.py @@ -0,0 +1,25 @@ +from typing import Callable, Optional, Union + +from pydantic import BaseModel + +from langflow.template.field.base import TemplateField + + +class Template(BaseModel): + type_name: str + fields: list[TemplateField] + + def process_fields( + self, + name: Optional[str] = None, + format_field_func: Union[Callable, None] = None, + ): + if format_field_func: + for field in self.fields: + format_field_func(field, name) + + def to_dict(self, format_field_func=None): + self.process_fields(self.type_name, format_field_func) + result = {field.name: field.to_dict() for field in self.fields} + result["_type"] = self.type_name # type: ignore + return result diff --git a/src/backend/langflow/utils/util.py b/src/backend/langflow/utils/util.py index e959b0103..af49856d7 100644 --- a/src/backend/langflow/utils/util.py +++ b/src/backend/langflow/utils/util.py @@ -10,49 +10,6 @@ from langflow.template.constants import FORCE_SHOW_FIELDS from langflow.utils import constants -def build_template_from_parameters( - name: str, type_to_loader_dict: Dict, add_function: bool = False -): - # Retrieve the function that matches the provided name - func = None - for _, v in type_to_loader_dict.items(): - if v.__name__ == name: - func = v - break - - if func is None: - raise ValueError(f"{name} not found") - - # Process parameters - parameters = func.__annotations__ - variables = {} - for param_name, param_type in parameters.items(): - if param_name in ["return", "kwargs"]: - continue - - variables[param_name] = { - "type": param_type.__name__, - "default": parameters[param_name].__repr_args__()[0][1], - # Op - "placeholder": "", - } - - # Get the base classes of the return type - return_type = parameters.get("return") - base_classes = get_base_classes(return_type) if return_type else [] - if add_function: - base_classes.append("function") - - # Get the function's docstring - docs = inspect.getdoc(func) or "" - - return { - "template": format_dict(variables, name), - "description": docs["Description"], # type: ignore - "base_classes": base_classes, - } - - def build_template_from_function( name: str, type_to_loader_dict: Dict, add_function: bool = False ): @@ -160,6 +117,70 @@ def build_template_from_class( } +def build_template_from_method( + class_name: str, + method_name: str, + type_to_cls_dict: Dict, + add_function: bool = False, +): + classes = [item.__name__ for item in type_to_cls_dict.values()] + + # Raise error if class_name is not in classes + if class_name not in classes: + raise ValueError(f"{class_name} not found.") + + for _type, v in type_to_cls_dict.items(): + if v.__name__ == class_name: + _class = v + + # Check if the method exists in this class + if not hasattr(_class, method_name): + raise ValueError( + f"Method {method_name} not found in class {class_name}" + ) + + # Get the method + method = getattr(_class, method_name) + + # Get the docstring + docs = parse(method.__doc__) + + # Get the signature of the method + sig = inspect.signature(method) + + # Get the parameters of the method + params = sig.parameters + + # Initialize the variables dictionary with method parameters + variables = { + "_type": _type, + **{ + name: { + "default": param.default + if param.default != param.empty + else None, + "type": param.annotation + if param.annotation != param.empty + else None, + "required": param.default == param.empty, + } + for name, param in params.items() + }, + } + + base_classes = get_base_classes(_class) + + # Adding function to base classes to allow the output to be a function + if add_function: + base_classes.append("function") + + return { + "template": format_dict(variables, class_name), + "description": docs.short_description or "", + "base_classes": base_classes, + } + + def get_base_classes(cls): """Get the base classes of a class. These are used to determine the output of the nodes. diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index b98a26b64..607f4946c 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -7370,4 +7370,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/frontend/package.json b/src/frontend/package.json index 6315deb05..20c62c11d 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -38,7 +38,8 @@ "dev:docker": "vite --host 0.0.0.0", "start": "vite", "build": "vite build", - "serve": "vite preview" + "serve": "vite preview", + "format": "npx prettier --write \"src/**/*.{js,jsx,ts,tsx,json,md}\"" }, "eslintConfig": { "extends": [ diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index c79904661..d582b2d5b 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -17,191 +17,191 @@ import IntComponent from "../../../../components/intComponent"; import PromptAreaComponent from "../../../../components/promptComponent"; export default function ParameterComponent({ - left, - id, - data, - tooltipTitle, - title, - color, - type, - name = "", - required = false, + left, + id, + data, + tooltipTitle, + title, + color, + type, + name = "", + required = false, }: ParameterComponentType) { - const ref = useRef(null); - const updateNodeInternals = useUpdateNodeInternals(); - const [position, setPosition] = useState(0); - useEffect(() => { - if (ref.current && ref.current.offsetTop && ref.current.clientHeight) { - setPosition(ref.current.offsetTop + ref.current.clientHeight / 2); - updateNodeInternals(data.id); - } - }, [data.id, ref, updateNodeInternals]); + const ref = useRef(null); + const updateNodeInternals = useUpdateNodeInternals(); + const [position, setPosition] = useState(0); + useEffect(() => { + if (ref.current && ref.current.offsetTop && ref.current.clientHeight) { + setPosition(ref.current.offsetTop + ref.current.clientHeight / 2); + updateNodeInternals(data.id); + } + }, [data.id, ref, updateNodeInternals]); - useEffect(() => { - updateNodeInternals(data.id); - }, [data.id, position, updateNodeInternals]); + useEffect(() => { + updateNodeInternals(data.id); + }, [data.id, position, updateNodeInternals]); - const [enabled, setEnabled] = useState( - data.node.template[name]?.value ?? false - ); - const { reactFlowInstance } = useContext(typesContext); - let disabled = - reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false; - const { save } = useContext(TabsContext); + const [enabled, setEnabled] = useState( + data.node.template[name]?.value ?? false + ); + const { reactFlowInstance } = useContext(typesContext); + let disabled = + reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false; + const { save } = useContext(TabsContext); - return ( -
- <> -
- {title} - {required ? " *" : ""} -
- {left && - (type === "str" || - type === "bool" || - type === "float" || - type === "code" || - type === "prompt" || - type === "file" || - type === "int") ? ( - <> - ) : ( - - - isValidConnection(connection, reactFlowInstance) - } - className={classNames( - left ? "-ml-0.5 " : "-mr-0.5 ", - "w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800" - )} - style={{ - borderColor: color, - top: position, - }} - > - - )} + return ( +
+ <> +
+ {title} + {required ? " *" : ""} +
+ {left && + (type === "str" || + type === "bool" || + type === "float" || + type === "code" || + type === "prompt" || + type === "file" || + type === "int") ? ( + <> + ) : ( + + + isValidConnection(connection, reactFlowInstance) + } + className={classNames( + left ? "-ml-0.5 " : "-mr-0.5 ", + "w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800" + )} + style={{ + borderColor: color, + top: position, + }} + > + + )} - {left === true && - type === "str" && - !data.node.template[name].options ? ( -
- {data.node.template[name].list ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : data.node.template[name].multiline ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : ( - { - data.node.template[name].value = t; - save(); - }} - /> - )} -
- ) : left === true && type === "bool" ? ( -
- { - data.node.template[name].value = t; - setEnabled(t); - save(); - }} - /> -
- ) : left === true && type === "float" ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : left === true && - type === "str" && - data.node.template[name].options ? ( - (data.node.template[name].value = newValue)} - value={data.node.template[name].value ?? "Choose an option"} - > - ) : left === true && type === "code" ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : left === true && type === "file" ? ( - { - data.node.template[name].value = t; - }} - fileTypes={data.node.template[name].fileTypes} - suffixes={data.node.template[name].suffixes} - onFileChange={(t: string) => { - data.node.template[name].content = t; - save(); - }} - > - ) : left === true && type === "int" ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : left === true && type === "prompt" ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : ( - <> - )} - -
- ); + {left === true && + type === "str" && + !data.node.template[name].options ? ( +
+ {data.node.template[name].list ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : data.node.template[name].multiline ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : ( + { + data.node.template[name].value = t; + save(); + }} + /> + )} +
+ ) : left === true && type === "bool" ? ( +
+ { + data.node.template[name].value = t; + setEnabled(t); + save(); + }} + /> +
+ ) : left === true && type === "float" ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : left === true && + type === "str" && + data.node.template[name].options ? ( + (data.node.template[name].value = newValue)} + value={data.node.template[name].value ?? "Choose an option"} + > + ) : left === true && type === "code" ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : left === true && type === "file" ? ( + { + data.node.template[name].value = t; + }} + fileTypes={data.node.template[name].fileTypes} + suffixes={data.node.template[name].suffixes} + onFileChange={(t: string) => { + data.node.template[name].content = t; + save(); + }} + > + ) : left === true && type === "int" ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : left === true && type === "prompt" ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : ( + <> + )} + +
+ ); } diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 059fdfb81..1427d1a76 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -58,7 +58,6 @@ export default function GenericNode({ if (response.status === 200) { let jsonResponse = await response.json(); let jsonResponseParsed = await JSON.parse(jsonResponse); - console.log(jsonResponseParsed); setValidationStatus(jsonResponseParsed); } } catch (error) { @@ -86,6 +85,7 @@ export default function GenericNode({ deleteNode(data.id); return; } + console.log(data); return (
- {type === "error" ? ( -
-
-
-
-

- {dropItem.title} -

- {dropItem.list ? ( -
-
    - {dropItem.list.map((item, idx) => ( -
  • {item}
  • - ))} -
-
- ) : ( - <> - )} -
-
-
- -
-
-
- ) : type === "notice" ? ( -
-
-
-
-

{dropItem.title}

-

- {dropItem.link ? ( - - Details - - ) : ( - <> - )} -

-
-
-
- -
-
-
- ) : ( -
-
-
-
-

- {dropItem.title} -

-
-
-
- -
-
-
- )} - - ); + return ( + + {type === "error" ? ( +
+
+
+
+

+ {dropItem.title} +

+ {dropItem.list ? ( +
+
    + {dropItem.list.map((item, idx) => ( +
  • + {item} +
  • + ))} +
+
+ ) : ( + <> + )} +
+
+
+ +
+
+
+ ) : type === "notice" ? ( +
+
+
+
+

+ {dropItem.title} +

+

+ {dropItem.link ? ( + + Details + + ) : ( + <> + )} +

+
+
+
+ +
+
+
+ ) : ( +
+
+
+
+

+ {dropItem.title} +

+
+
+
+ +
+
+
+ )} +
+ ); } diff --git a/src/frontend/src/alerts/alertDropDown/index.tsx b/src/frontend/src/alerts/alertDropDown/index.tsx index 09c91c7ca..edd3bb23f 100644 --- a/src/frontend/src/alerts/alertDropDown/index.tsx +++ b/src/frontend/src/alerts/alertDropDown/index.tsx @@ -7,60 +7,60 @@ import { AlertDropdownType } from "../../types/alerts"; import { PopUpContext } from "../../contexts/popUpContext"; import { useOnClickOutside } from "../hooks/useOnClickOutside"; export default function AlertDropdown({}: AlertDropdownType) { - const { closePopUp } = useContext(PopUpContext); - const componentRef = useRef(null); + const { closePopUp } = useContext(PopUpContext); + const componentRef = useRef(null); - // Use the custom hook - useOnClickOutside(componentRef, () => { - closePopUp(); - }); + // Use the custom hook + useOnClickOutside(componentRef, () => { + closePopUp(); + }); - const { - notificationList, - clearNotificationList, - removeFromNotificationList, - } = useContext(alertContext); + const { + notificationList, + clearNotificationList, + removeFromNotificationList, + } = useContext(alertContext); - return ( -
-
- Notifications -
- - -
-
-
- {notificationList.length !== 0 ? ( - notificationList.map((alertItem, index) => ( - - )) - ) : ( -
- No new notifications -
- )} -
-
- ); + return ( +
+
+ Notifications +
+ + +
+
+
+ {notificationList.length !== 0 ? ( + notificationList.map((alertItem, index) => ( + + )) + ) : ( +
+ No new notifications +
+ )} +
+
+ ); } diff --git a/src/frontend/src/alerts/error/index.tsx b/src/frontend/src/alerts/error/index.tsx index 022ad8ba0..bcabe764f 100644 --- a/src/frontend/src/alerts/error/index.tsx +++ b/src/frontend/src/alerts/error/index.tsx @@ -4,63 +4,68 @@ import { useEffect, useState } from "react"; import { ErrorAlertType } from "../../types/alerts"; export default function ErrorAlert({ - title, - list = [], - id, - removeAlert, + title, + list = [], + id, + removeAlert, }: ErrorAlertType) { - const [show, setShow] = useState(true); - useEffect(() => { - if (show) { - setTimeout(() => { - setShow(false); - setTimeout(() => { - removeAlert(id); - }, 500); - }, 5000); - } - }, [id, removeAlert, show]); - return ( - -
{ - setShow(false); - setTimeout(() => { - removeAlert(id); - }, 500); - }} - className="rounded-md w-96 mt-6 shadow-xl bg-red-50 dark:bg-red-900 p-4 cursor-pointer" - > -
-
-
-
-

{title}

- {list.length !== 0 ? ( -
-
    - {list.map((item, index) => ( -
  • {item}
  • - ))} -
-
- ) : ( - <> - )} -
-
-
-
- ); + const [show, setShow] = useState(true); + useEffect(() => { + if (show) { + setTimeout(() => { + setShow(false); + setTimeout(() => { + removeAlert(id); + }, 500); + }, 5000); + } + }, [id, removeAlert, show]); + return ( + +
{ + setShow(false); + setTimeout(() => { + removeAlert(id); + }, 500); + }} + className="rounded-md w-96 mt-6 shadow-xl bg-red-50 dark:bg-red-900 p-4 cursor-pointer" + > +
+
+
+
+

+ {title} +

+ {list.length !== 0 ? ( +
+
    + {list.map((item, index) => ( +
  • {item}
  • + ))} +
+
+ ) : ( + <> + )} +
+
+
+
+ ); } diff --git a/src/frontend/src/alerts/hooks/useOnClickOutside/index.ts b/src/frontend/src/alerts/hooks/useOnClickOutside/index.ts index 3046d41a4..249133d96 100644 --- a/src/frontend/src/alerts/hooks/useOnClickOutside/index.ts +++ b/src/frontend/src/alerts/hooks/useOnClickOutside/index.ts @@ -1,33 +1,33 @@ import { useEffect } from "react"; export function useOnClickOutside(ref, handler) { - useEffect(() => { - const listener = (event) => { - // Do nothing if clicking ref's element or its children - if (!ref.current || ref.current.contains(event.target)) { - return; - } + useEffect(() => { + const listener = (event) => { + // Do nothing if clicking ref's element or its children + if (!ref.current || ref.current.contains(event.target)) { + return; + } - handler(event); - }; + handler(event); + }; - // Attach the listener to the document - document.addEventListener("mousedown", listener, { passive: true }); + // Attach the listener to the document + document.addEventListener("mousedown", listener, { passive: true }); - // Attach the listener to the react-flow instance - const reactFlowContainer = document.querySelector(".react-flow"); - if (reactFlowContainer) { - reactFlowContainer.addEventListener("mousedown", listener, { - passive: true, - }); - } + // Attach the listener to the react-flow instance + const reactFlowContainer = document.querySelector(".react-flow"); + if (reactFlowContainer) { + reactFlowContainer.addEventListener("mousedown", listener, { + passive: true, + }); + } - // Clean up the listener when the component is unmounted - return () => { - document.removeEventListener("mousedown", listener); - if (reactFlowContainer) { - reactFlowContainer.removeEventListener("mousedown", listener); - } - }; - }, [ref, handler]); // Rerun only if ref or handler changes + // Clean up the listener when the component is unmounted + return () => { + document.removeEventListener("mousedown", listener); + if (reactFlowContainer) { + reactFlowContainer.removeEventListener("mousedown", listener); + } + }; + }, [ref, handler]); // Rerun only if ref or handler changes } diff --git a/src/frontend/src/alerts/notice/index.tsx b/src/frontend/src/alerts/notice/index.tsx index e7e317157..1b2fb1514 100644 --- a/src/frontend/src/alerts/notice/index.tsx +++ b/src/frontend/src/alerts/notice/index.tsx @@ -5,63 +5,63 @@ import { Link } from "react-router-dom"; import { NoticeAlertType } from "../../types/alerts"; export default function NoticeAlert({ - title, - link = "", - id, - removeAlert, + title, + link = "", + id, + removeAlert, }: NoticeAlertType) { - const [show, setShow] = useState(true); - useEffect(() => { - if (show) { - setTimeout(() => { - setShow(false); - setTimeout(() => { - removeAlert(id); - }, 500); - }, 5000); - } - }, [id, removeAlert, show]); - return ( - -
{ - setShow(false); - removeAlert(id); - }} - className="rounded-md w-96 mt-6 shadow-xl bg-blue-50 dark:bg-blue-900 p-4" - > -
-
-
-
-

{title}

-

- {link !== "" ? ( - - Details - - ) : ( - <> - )} -

-
-
-
-
- ); + const [show, setShow] = useState(true); + useEffect(() => { + if (show) { + setTimeout(() => { + setShow(false); + setTimeout(() => { + removeAlert(id); + }, 500); + }, 5000); + } + }, [id, removeAlert, show]); + return ( + +
{ + setShow(false); + removeAlert(id); + }} + className="rounded-md w-96 mt-6 shadow-xl bg-blue-50 dark:bg-blue-900 p-4" + > +
+
+
+
+

{title}

+

+ {link !== "" ? ( + + Details + + ) : ( + <> + )} +

+
+
+
+
+ ); } diff --git a/src/frontend/src/alerts/success/index.tsx b/src/frontend/src/alerts/success/index.tsx index 6e82075f9..d915adfcd 100644 --- a/src/frontend/src/alerts/success/index.tsx +++ b/src/frontend/src/alerts/success/index.tsx @@ -4,50 +4,52 @@ import { useEffect, useState } from "react"; import { SuccessAlertType } from "../../types/alerts"; export default function SuccessAlert({ - title, - id, - removeAlert, + title, + id, + removeAlert, }: SuccessAlertType) { - const [show, setShow] = useState(true); - useEffect(() => { - if (show) { - setTimeout(() => { - setShow(false); - setTimeout(() => { - removeAlert(id); - }, 500); - }, 5000); - } - }, [id, removeAlert, show]); - return ( - -
{ - setShow(false); - removeAlert(id); - }} - className="rounded-md w-96 mt-6 shadow-xl bg-green-50 dark:bg-green-900 p-4" - > -
-
-
-
-

{title}

-
-
-
-
- ); + const [show, setShow] = useState(true); + useEffect(() => { + if (show) { + setTimeout(() => { + setShow(false); + setTimeout(() => { + removeAlert(id); + }, 500); + }, 5000); + } + }, [id, removeAlert, show]); + return ( + +
{ + setShow(false); + removeAlert(id); + }} + className="rounded-md w-96 mt-6 shadow-xl bg-green-50 dark:bg-green-900 p-4" + > +
+
+
+
+

+ {title} +

+
+
+
+
+ ); } diff --git a/src/frontend/src/components/CrashErrorComponent/index.tsx b/src/frontend/src/components/CrashErrorComponent/index.tsx index de3cea182..adc8909a8 100644 --- a/src/frontend/src/components/CrashErrorComponent/index.tsx +++ b/src/frontend/src/components/CrashErrorComponent/index.tsx @@ -1,33 +1,33 @@ export default function CrashErrorComponent({ error, resetErrorBoundary }) { - return ( -
-
-

- Oops! An unknown error has occurred. -

-

- Please click the 'Reset Application' button to restore the - application's state. If the error persists, please create an issue on - our GitHub page. We apologize for any inconvenience this may have - caused. -

-
- - - Create Issue - -
-
-
- ); + return ( +
+
+

+ Oops! An unknown error has occurred. +

+

+ Please click the 'Reset Application' button to restore the + application's state. If the error persists, please create an issue on + our GitHub page. We apologize for any inconvenience this may have + caused. +

+
+ + + Create Issue + +
+
+
+ ); } diff --git a/src/frontend/src/components/ExtraSidebarComponent/index.tsx b/src/frontend/src/components/ExtraSidebarComponent/index.tsx index 317f025ae..f5acd5a23 100644 --- a/src/frontend/src/components/ExtraSidebarComponent/index.tsx +++ b/src/frontend/src/components/ExtraSidebarComponent/index.tsx @@ -6,119 +6,119 @@ import { classNames } from "../../utils"; import { locationContext } from "../../contexts/locationContext"; export default function ExtraSidebar() { - const { - current, - isStackedOpen, - setIsStackedOpen, - extraNavigation, - extraComponent, - } = useContext(locationContext); - return ( - <> - - - ); + const { + current, + isStackedOpen, + setIsStackedOpen, + extraNavigation, + extraComponent, + } = useContext(locationContext); + return ( + <> + + + ); } diff --git a/src/frontend/src/components/LightTooltipComponent/index.tsx b/src/frontend/src/components/LightTooltipComponent/index.tsx index 334fc0e71..4cdc912d0 100644 --- a/src/frontend/src/components/LightTooltipComponent/index.tsx +++ b/src/frontend/src/components/LightTooltipComponent/index.tsx @@ -2,16 +2,16 @@ import { styled } from "@mui/material/styles"; import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip"; export const LightTooltip = styled(({ className, ...props }: TooltipProps) => ( - + ))(({ theme }) => ({ - [`& .${tooltipClasses.tooltip}`]: { - backgroundColor: theme.palette.common.white, - color: "rgba(0, 0, 0, 0.87)", - boxShadow: theme.shadows[2], - fontSize: 14, - }, - [`& .${tooltipClasses.arrow}:before`]: { - color: theme.palette.common.white, - boxShadow: theme.shadows[1], - }, + [`& .${tooltipClasses.tooltip}`]: { + backgroundColor: theme.palette.common.white, + color: "rgba(0, 0, 0, 0.87)", + boxShadow: theme.shadows[2], + fontSize: 14, + }, + [`& .${tooltipClasses.arrow}:before`]: { + color: theme.palette.common.white, + boxShadow: theme.shadows[1], + }, })); diff --git a/src/frontend/src/components/TooltipComponent/index.tsx b/src/frontend/src/components/TooltipComponent/index.tsx index f0a4eb8e6..0e571b1bc 100644 --- a/src/frontend/src/components/TooltipComponent/index.tsx +++ b/src/frontend/src/components/TooltipComponent/index.tsx @@ -3,13 +3,13 @@ import { LightTooltip } from "../LightTooltipComponent"; import { TooltipComponentType } from "../../types/components"; export default function Tooltip({ - children, - title, - placement, + children, + title, + placement, }: TooltipComponentType) { - return ( - - {children} - - ); + return ( + + {children} + + ); } diff --git a/src/frontend/src/components/chatComponent/chatMessage/index.tsx b/src/frontend/src/components/chatComponent/chatMessage/index.tsx index 9e3586d23..8ca2e56e3 100644 --- a/src/frontend/src/components/chatComponent/chatMessage/index.tsx +++ b/src/frontend/src/components/chatComponent/chatMessage/index.tsx @@ -1,7 +1,7 @@ import { - ChatBubbleLeftEllipsisIcon, - ChatBubbleOvalLeftEllipsisIcon, - PlusSmallIcon, + ChatBubbleLeftEllipsisIcon, + ChatBubbleOvalLeftEllipsisIcon, + PlusSmallIcon, } from "@heroicons/react/24/outline"; import { useState } from "react"; import { ChatMessageType } from "../../../types/chat"; @@ -10,49 +10,49 @@ import Convert from "ansi-to-html"; const convert = new Convert({ newline: true }); export default function ChatMessage({ chat }: { chat: ChatMessageType }) { - const [hidden, setHidden] = useState(true); - return ( -
- {!chat.isSend ? ( -
-
- {hidden && chat.thought && chat.thought !== "" && ( -
setHidden((prev) => !prev)} - className="absolute top-2 right-2 cursor-pointer" - > - -
- )} - {chat.thought && chat.thought !== "" && !hidden && ( -
setHidden((prev) => !prev)} - style={{ backgroundColor: nodeColors["thought"] }} - className=" text-start inline-block w-full pb-3 pt-3 px-5 cursor-pointer" - dangerouslySetInnerHTML={{ - __html: convert.toHtml(chat.thought), - }} - >
- )} - {chat.thought && chat.thought !== "" && !hidden &&

} -
- {chat.message} -
-
-
- ) : ( -
-
- {chat.message} -
-
- )} -
- ); + const [hidden, setHidden] = useState(true); + return ( +
+ {!chat.isSend ? ( +
+
+ {hidden && chat.thought && chat.thought !== "" && ( +
setHidden((prev) => !prev)} + className="absolute top-2 right-2 cursor-pointer" + > + +
+ )} + {chat.thought && chat.thought !== "" && !hidden && ( +
setHidden((prev) => !prev)} + style={{ backgroundColor: nodeColors["thought"] }} + className=" text-start inline-block w-full pb-3 pt-3 px-5 cursor-pointer" + dangerouslySetInnerHTML={{ + __html: convert.toHtml(chat.thought), + }} + >
+ )} + {chat.thought && chat.thought !== "" && !hidden &&

} +
+ {chat.message} +
+
+
+ ) : ( +
+
+ {chat.message} +
+
+ )} +
+ ); } diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index dc51c0fb7..61d0f35a1 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -7,26 +7,26 @@ import ChatModal from "../../modals/chatModal"; import _ from "lodash"; export default function Chat({ flow }: ChatType) { - const [open, setOpen] = useState(false); - useEffect(() => { - const handleKeyDown = (event: KeyboardEvent) => { - if ( - (event.key === "K" || event.key === "k") && - (event.metaKey || event.ctrlKey) - ) { - event.preventDefault(); - setOpen((oldState) => !oldState); - } - }; - document.addEventListener("keydown", handleKeyDown); - return () => { - document.removeEventListener("keydown", handleKeyDown); - }; - }, []); - return ( - <> - - - - ); + const [open, setOpen] = useState(false); + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if ( + (event.key === "K" || event.key === "k") && + (event.metaKey || event.ctrlKey) + ) { + event.preventDefault(); + setOpen((oldState) => !oldState); + } + }; + document.addEventListener("keydown", handleKeyDown); + return () => { + document.removeEventListener("keydown", handleKeyDown); + }; + }, []); + return ( + <> + + + + ); } diff --git a/src/frontend/src/components/codeAreaComponent/index.tsx b/src/frontend/src/components/codeAreaComponent/index.tsx index 2da5323e8..9bf256594 100644 --- a/src/frontend/src/components/codeAreaComponent/index.tsx +++ b/src/frontend/src/components/codeAreaComponent/index.tsx @@ -6,60 +6,60 @@ import TextAreaModal from "../../modals/textAreaModal"; import { TextAreaComponentType } from "../../types/components"; export default function CodeAreaComponent({ - value, - onChange, - disabled, + value, + onChange, + disabled, }: TextAreaComponentType) { - const [myValue, setMyValue] = useState(value); - const { openPopUp } = useContext(PopUpContext); - useEffect(() => { - if (disabled) { - setMyValue(""); - onChange(""); - } - }, [disabled, onChange]); - return ( -
-
- { - openPopUp( - { - setMyValue(t); - onChange(t); - }} - /> - ); - }} - className={ - "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + - (disabled ? " bg-gray-200" : "") - } - > - {myValue !== "" ? myValue : "Text empty"} - - -
-
- ); + const [myValue, setMyValue] = useState(value); + const { openPopUp } = useContext(PopUpContext); + useEffect(() => { + if (disabled) { + setMyValue(""); + onChange(""); + } + }, [disabled, onChange]); + return ( +
+
+ { + openPopUp( + { + setMyValue(t); + onChange(t); + }} + /> + ); + }} + className={ + "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + + (disabled ? " bg-gray-200" : "") + } + > + {myValue !== "" ? myValue : "Text empty"} + + +
+
+ ); } diff --git a/src/frontend/src/components/dropdownComponent/index.tsx b/src/frontend/src/components/dropdownComponent/index.tsx index 92085d8b8..bb4cd621c 100644 --- a/src/frontend/src/components/dropdownComponent/index.tsx +++ b/src/frontend/src/components/dropdownComponent/index.tsx @@ -5,90 +5,90 @@ import { DropDownComponentType } from "../../types/components"; import { classNames } from "../../utils"; export default function Dropdown({ - value, - options, - onSelect, + value, + options, + onSelect, }: DropDownComponentType) { - let [internalValue, setInternalValue] = useState( - value === "" || !value ? "Choose an option" : value - ); - return ( - <> - { - setInternalValue(value); - onSelect(value); - }} - > - {({ open }) => ( - <> -
- - {internalValue} - - - + let [internalValue, setInternalValue] = useState( + value === "" || !value ? "Choose an option" : value + ); + return ( + <> + { + setInternalValue(value); + onSelect(value); + }} + > + {({ open }) => ( + <> +
+ + {internalValue} + + + - - - {options.map((option, id) => ( - - classNames( - active - ? "text-white bg-indigo-600 dark:bg-indigo-500" - : "text-gray-900", - "relative cursor-default select-none py-2 pl-3 pr-9 dark:text-gray-300 dark:bg-gray-800" - ) - } - value={option} - > - {({ selected, active }) => ( - <> - - {option} - + + + {options.map((option, id) => ( + + classNames( + active + ? "text-white bg-indigo-600 dark:bg-indigo-500" + : "text-gray-900", + "relative cursor-default select-none py-2 pl-3 pr-9 dark:text-gray-300 dark:bg-gray-800" + ) + } + value={option} + > + {({ selected, active }) => ( + <> + + {option} + - {selected ? ( - - - ) : null} - - )} - - ))} - - -
- - )} -
- - ); + {selected ? ( + + + ) : null} + + )} + + ))} + + +
+ + )} +
+ + ); } diff --git a/src/frontend/src/components/floatComponent/index.tsx b/src/frontend/src/components/floatComponent/index.tsx index c09f3b9e0..f3678b0c1 100644 --- a/src/frontend/src/components/floatComponent/index.tsx +++ b/src/frontend/src/components/floatComponent/index.tsx @@ -3,39 +3,32 @@ import { FloatComponentType } from "../../types/components"; import { TabsContext } from "../../contexts/tabsContext"; export default function FloatComponent({ - value, - onChange, - disabled, + value, + onChange, + disabled, }: FloatComponentType) { - const [myValue, setMyValue] = useState(value ?? ""); - useEffect(() => { - if (disabled) { - setMyValue(""); - onChange(""); - } - }, [disabled, onChange]); - const {setDisableCopyPaste} = useContext(TabsContext) - return ( -
- { - setMyValue(e.target.value); - onChange(e.target.value); - }} - onBlur={() => { - setDisableCopyPaste(false) - }} - onFocus={() => { - setDisableCopyPaste(true) - }} - /> -
- ); + const [myValue, setMyValue] = useState(value ?? ""); + useEffect(() => { + if (disabled) { + setMyValue(""); + onChange(""); + } + }, [disabled, onChange]); + return ( +
+ { + setMyValue(e.target.value); + onChange(e.target.value); + }} + /> +
+ ); } diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx index b4f52902d..8f8f4c587 100644 --- a/src/frontend/src/components/inputComponent/index.tsx +++ b/src/frontend/src/components/inputComponent/index.tsx @@ -4,91 +4,84 @@ import { classNames } from "../../utils"; import { TabsContext } from "../../contexts/tabsContext"; export default function InputComponent({ - value, - onChange, - disabled, - password, + value, + onChange, + disabled, + password, }: InputComponentType) { - const [myValue, setMyValue] = useState(value ?? ""); - const [pwdVisible, setPwdVisible] = useState(false); - const {setDisableCopyPaste} = useContext(TabsContext) - useEffect(() => { - if (disabled) { - setMyValue(""); - onChange(""); - } - }, [disabled, onChange]); - return ( -
- { - setDisableCopyPaste(false) - }} - onFocus={() => { - setDisableCopyPaste(true) - }} - className={classNames( - "block w-full pr-12 form-input dark:bg-gray-900 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm", - disabled ? " bg-gray-200 dark:bg-gray-700" : "", - password && !pwdVisible && myValue !== "" ? "password" : "" - )} - placeholder="Type a text" - onChange={(e) => { - setMyValue(e.target.value); - onChange(e.target.value); - }} - /> - -
- ); + const [myValue, setMyValue] = useState(value ?? ""); + const [pwdVisible, setPwdVisible] = useState(false); + useEffect(() => { + if (disabled) { + setMyValue(""); + onChange(""); + } + }, [disabled, onChange]); + return ( +
+ { + setMyValue(e.target.value); + onChange(e.target.value); + }} + /> + +
+ ); } diff --git a/src/frontend/src/components/inputFileComponent/index.tsx b/src/frontend/src/components/inputFileComponent/index.tsx index 01a500f91..8b998c731 100644 --- a/src/frontend/src/components/inputFileComponent/index.tsx +++ b/src/frontend/src/components/inputFileComponent/index.tsx @@ -4,83 +4,83 @@ import { alertContext } from "../../contexts/alertContext"; import { FileComponentType } from "../../types/components"; export default function InputFileComponent({ - value, - onChange, - disabled, - suffixes, - fileTypes, - onFileChange, + value, + onChange, + disabled, + suffixes, + fileTypes, + onFileChange, }: FileComponentType) { - const [myValue, setMyValue] = useState(value); - const { setErrorData } = useContext(alertContext); - useEffect(() => { - if (disabled) { - setMyValue(""); - onChange(""); - onFileChange(""); - } - }, [disabled, onChange]); + const [myValue, setMyValue] = useState(value); + const { setErrorData } = useContext(alertContext); + useEffect(() => { + if (disabled) { + setMyValue(""); + onChange(""); + onFileChange(""); + } + }, [disabled, onChange]); - function attachFile(fileReadEvent: ProgressEvent) { - fileReadEvent.preventDefault(); - const file = fileReadEvent.target.result; - onFileChange(file as string); - } + function attachFile(fileReadEvent: ProgressEvent) { + fileReadEvent.preventDefault(); + const file = fileReadEvent.target.result; + onFileChange(file as string); + } - function checkFileType(fileName: string): boolean { - for (let index = 0; index < suffixes.length; index++) { - if (fileName.endsWith(suffixes[index])) { - return true; - } - } - return false; - } + function checkFileType(fileName: string): boolean { + for (let index = 0; index < suffixes.length; index++) { + if (fileName.endsWith(suffixes[index])) { + return true; + } + } + return false; + } - const handleButtonClick = () => { - const input = document.createElement("input"); - input.type = "file"; - input.accept = suffixes.join(","); - input.style.display = "none"; - input.multiple = false; - input.onchange = (e: Event) => { - const file = (e.target as HTMLInputElement).files?.[0]; - const fileData = new FileReader(); - fileData.onload = attachFile; - if (file && checkFileType(file.name)) { - fileData.readAsDataURL(file); - setMyValue(file.name); - onChange(file.name); - } else { - setErrorData({ - title: - "Please select a valid file. Only files this files are allowed:", - list: fileTypes, - }); - } - }; - input.click(); - }; + const handleButtonClick = () => { + const input = document.createElement("input"); + input.type = "file"; + input.accept = suffixes.join(","); + input.style.display = "none"; + input.multiple = false; + input.onchange = (e: Event) => { + const file = (e.target as HTMLInputElement).files?.[0]; + const fileData = new FileReader(); + fileData.onload = attachFile; + if (file && checkFileType(file.name)) { + fileData.readAsDataURL(file); + setMyValue(file.name); + onChange(file.name); + } else { + setErrorData({ + title: + "Please select a valid file. Only files this files are allowed:", + list: fileTypes, + }); + } + }; + input.click(); + }; - return ( -
-
- - {myValue !== "" ? myValue : "No file"} - - -
-
- ); + return ( +
+
+ + {myValue !== "" ? myValue : "No file"} + + +
+
+ ); } diff --git a/src/frontend/src/components/inputListComponent/index.tsx b/src/frontend/src/components/inputListComponent/index.tsx index 57ddd7a4e..ea47af8f9 100644 --- a/src/frontend/src/components/inputListComponent/index.tsx +++ b/src/frontend/src/components/inputListComponent/index.tsx @@ -6,79 +6,72 @@ import { TabsContext } from "../../contexts/tabsContext"; import _ from "lodash"; export default function InputListComponent({ - value, - onChange, - disabled, + value, + onChange, + disabled, }: InputListComponentType) { - const [inputList, setInputList] = useState(value ?? [""]); - useEffect(() => { - if (disabled) { - setInputList([""]); - onChange([""]); - } - }, [disabled, onChange]); - const {setDisableCopyPaste} = useContext(TabsContext) - return ( -
- {inputList.map((i, idx) => ( -
- { - setInputList((old) => { - let newInputList = _.cloneDeep(old); - newInputList[idx] = e.target.value; - return newInputList; - }); - onChange(inputList); - }} - onBlur={() => { - setDisableCopyPaste(false) - }} - onFocus={() => { - setDisableCopyPaste(true) - }} - /> - {idx === inputList.length - 1 ? ( - - ) : ( - - )} -
- ))} -
- ); + const [inputList, setInputList] = useState(value ?? [""]); + useEffect(() => { + if (disabled) { + setInputList([""]); + onChange([""]); + } + }, [disabled, onChange]); + return ( +
+ {inputList.map((i, idx) => ( +
+ { + setInputList((old) => { + let newInputList = _.cloneDeep(old); + newInputList[idx] = e.target.value; + return newInputList; + }); + onChange(inputList); + }} + /> + {idx === inputList.length - 1 ? ( + + ) : ( + + )} +
+ ))} +
+ ); } diff --git a/src/frontend/src/components/intComponent/index.tsx b/src/frontend/src/components/intComponent/index.tsx index c66f5e156..80f687924 100644 --- a/src/frontend/src/components/intComponent/index.tsx +++ b/src/frontend/src/components/intComponent/index.tsx @@ -3,56 +3,48 @@ import { FloatComponentType } from "../../types/components"; import { TabsContext } from "../../contexts/tabsContext"; export default function IntComponent({ - value, - onChange, - disabled, + value, + onChange, + disabled, }: FloatComponentType) { - const [myValue, setMyValue] = useState(value ?? ""); - useEffect(() => { - if (disabled) { - setMyValue(""); - onChange(""); - } - }, [disabled, onChange]); - const {setDisableCopyPaste} =useContext(TabsContext) - return ( -
- { - if ( - event.key !== "Backspace" && - event.key !== "Enter" && - event.key !== "Delete" && - event.key !== "ArrowLeft" && - event.key !== "ArrowRight" && - !/^[-]?\d*$/.test(event.key) - ) { - event.preventDefault(); - } - }} - type="number" - value={myValue} - className={ - "block w-full form-input dark:bg-gray-900 arrow-hide dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + - (disabled ? " bg-gray-200 dark:bg-gray-700" : "") - } - placeholder="Type a integer number" - onChange={(e) => { - setMyValue(e.target.value); - onChange(e.target.value); - }} - onBlur={() => { - setDisableCopyPaste(false) - }} - onFocus={() => { - setDisableCopyPaste(true) - }} - /> - -
- ); + const [myValue, setMyValue] = useState(value ?? ""); + useEffect(() => { + if (disabled) { + setMyValue(""); + onChange(""); + } + }, [disabled, onChange]); + return ( +
+ { + if ( + event.key !== "Backspace" && + event.key !== "Enter" && + event.key !== "Delete" && + event.key !== "ArrowLeft" && + event.key !== "ArrowRight" && + !/^[-]?\d*$/.test(event.key) + ) { + event.preventDefault(); + } + }} + type="number" + value={myValue} + className={ + "block w-full form-input dark:bg-gray-900 arrow-hide dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + + (disabled ? " bg-gray-200 dark:bg-gray-700" : "") + } + placeholder="Type a integer number" + onChange={(e) => { + setMyValue(e.target.value); + onChange(e.target.value); + }} + /> +
+ ); } diff --git a/src/frontend/src/components/loadingComponent/index.tsx b/src/frontend/src/components/loadingComponent/index.tsx index 43d6d9d75..42ad18c1e 100644 --- a/src/frontend/src/components/loadingComponent/index.tsx +++ b/src/frontend/src/components/loadingComponent/index.tsx @@ -1,28 +1,28 @@ type LoadingComponentProps = { - remSize: number; + remSize: number; }; export default function LoadingComponent({ remSize }: LoadingComponentProps) { - return ( -
- -

- Loading... -
- ); + return ( +
+ +

+ Loading... +
+ ); } diff --git a/src/frontend/src/components/promptComponent/index.tsx b/src/frontend/src/components/promptComponent/index.tsx index 842e5e7d8..10ac41281 100644 --- a/src/frontend/src/components/promptComponent/index.tsx +++ b/src/frontend/src/components/promptComponent/index.tsx @@ -4,63 +4,67 @@ import { PopUpContext } from "../../contexts/popUpContext"; import CodeAreaModal from "../../modals/codeAreaModal"; import TextAreaModal from "../../modals/textAreaModal"; import { TextAreaComponentType } from "../../types/components"; -import PromptAreaModal from "../../modals/promptModal"; +import GenericModal from "../../modals/genericModal"; export default function PromptAreaComponent({ - value, - onChange, - disabled, + value, + onChange, + disabled, }: TextAreaComponentType) { - const [myValue, setMyValue] = useState(value); - const { openPopUp } = useContext(PopUpContext); - useEffect(() => { - if (disabled) { - setMyValue(""); - onChange(""); - } - }, [disabled, onChange]); - return ( -
-
- { - openPopUp( - { - setMyValue(t); - onChange(t); - }} - /> - ); - }} - className={ - "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + - (disabled ? " bg-gray-200" : "") - } - > - {myValue !== "" ? myValue : "Text empty"} - - -
-
- ); + const [myValue, setMyValue] = useState(value); + const { openPopUp } = useContext(PopUpContext); + useEffect(() => { + if (disabled) { + setMyValue(""); + onChange(""); + } + }, [disabled, onChange]); + return ( +
+
+ { + openPopUp( + { + setMyValue(t); + onChange(t); + }} + /> + ); + }} + className={ + "truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + + (disabled ? " bg-gray-200" : "") + } + > + {myValue !== "" ? myValue : "Text empty"} + + +
+
+ ); } diff --git a/src/frontend/src/components/textAreaComponent/index.tsx b/src/frontend/src/components/textAreaComponent/index.tsx index 3737e02f0..b4ec85fe3 100644 --- a/src/frontend/src/components/textAreaComponent/index.tsx +++ b/src/frontend/src/components/textAreaComponent/index.tsx @@ -1,10 +1,14 @@ import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline"; import { useContext, useEffect, useState } from "react"; import { PopUpContext } from "../../contexts/popUpContext"; -import TextAreaModal from "../../modals/textAreaModal"; import { TextAreaComponentType } from "../../types/components"; +import GenericModal from "../../modals/genericModal"; -export default function TextAreaComponent({ value, onChange, disabled }:TextAreaComponentType) { +export default function TextAreaComponent({ + value, + onChange, + disabled, +}: TextAreaComponentType) { const [myValue, setMyValue] = useState(value); const { openPopUp } = useContext(PopUpContext); useEffect(() => { @@ -16,16 +20,43 @@ export default function TextAreaComponent({ value, onChange, disabled }:TextArea return (
- {openPopUp( {setMyValue(t); onChange(t);}}/>)}} + { + openPopUp( + { + setMyValue(t); + onChange(t); + }} + /> + ); + }} className={ "truncate block w-full text-gray-500 dark:text-gray-100 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + (disabled ? " bg-gray-200" : "") } > - {myValue !== "" ? myValue : 'Text empty'} + {myValue !== "" ? myValue : "Text empty"} -
diff --git a/src/frontend/src/components/toggleComponent/index.tsx b/src/frontend/src/components/toggleComponent/index.tsx index eed5bc278..f7140bdee 100644 --- a/src/frontend/src/components/toggleComponent/index.tsx +++ b/src/frontend/src/components/toggleComponent/index.tsx @@ -4,59 +4,57 @@ import { useEffect } from "react"; import { ToggleComponentType } from "../../types/components"; export default function ToggleComponent({ - enabled, - setEnabled, - disabled, + enabled, + setEnabled, + disabled, }: ToggleComponentType) { - useEffect(() => { - if (disabled) { - setEnabled(false); - } - }, [disabled, setEnabled]); - return ( -
- { - setEnabled(x); - }} - className={classNames( - enabled ? 'bg-indigo-600' : 'bg-gray-200', - 'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2' - )} - > - Use setting - - - - - -
- ); + useEffect(() => { + if (disabled) { + setEnabled(false); + } + }, [disabled, setEnabled]); + return ( +
+ { + setEnabled(x); + }} + className={classNames( + enabled ? "bg-indigo-600" : "bg-gray-200", + "relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" + )} + > + Use setting + + + + + +
+ ); } diff --git a/src/frontend/src/contexts/alertContext.tsx b/src/frontend/src/contexts/alertContext.tsx index ef18ade39..f85f858de 100644 --- a/src/frontend/src/contexts/alertContext.tsx +++ b/src/frontend/src/contexts/alertContext.tsx @@ -5,161 +5,161 @@ import _ from "lodash"; //types for alertContextType type alertContextType = { - errorData: { title: string; list?: Array }; - setErrorData: (newState: { title: string; list?: Array }) => void; - errorOpen: boolean; - setErrorOpen: (newState: boolean) => void; - noticeData: { title: string; link?: string }; - setNoticeData: (newState: { title: string; link?: string }) => void; - noticeOpen: boolean; - setNoticeOpen: (newState: boolean) => void; - successData: { title: string }; - setSuccessData: (newState: { title: string }) => void; - successOpen: boolean; - setSuccessOpen: (newState: boolean) => void; - notificationCenter: boolean; - setNotificationCenter: (newState: boolean) => void; - notificationList: Array; - pushNotificationList: (Object: AlertItemType) => void; - clearNotificationList: () => void; - removeFromNotificationList: (index: string) => void; + errorData: { title: string; list?: Array }; + setErrorData: (newState: { title: string; list?: Array }) => void; + errorOpen: boolean; + setErrorOpen: (newState: boolean) => void; + noticeData: { title: string; link?: string }; + setNoticeData: (newState: { title: string; link?: string }) => void; + noticeOpen: boolean; + setNoticeOpen: (newState: boolean) => void; + successData: { title: string }; + setSuccessData: (newState: { title: string }) => void; + successOpen: boolean; + setSuccessOpen: (newState: boolean) => void; + notificationCenter: boolean; + setNotificationCenter: (newState: boolean) => void; + notificationList: Array; + pushNotificationList: (Object: AlertItemType) => void; + clearNotificationList: () => void; + removeFromNotificationList: (index: string) => void; }; //initial values to alertContextType const initialValue: alertContextType = { - errorData: { title: "", list: [] }, - setErrorData: () => {}, - errorOpen: false, - setErrorOpen: () => {}, - noticeData: { title: "", link: "" }, - setNoticeData: () => {}, - noticeOpen: false, - setNoticeOpen: () => {}, - successData: { title: "" }, - setSuccessData: () => {}, - successOpen: false, - setSuccessOpen: () => {}, - notificationCenter: false, - setNotificationCenter: () => {}, - notificationList: [], - pushNotificationList: () => {}, - clearNotificationList: () => {}, - removeFromNotificationList: () => {}, + errorData: { title: "", list: [] }, + setErrorData: () => {}, + errorOpen: false, + setErrorOpen: () => {}, + noticeData: { title: "", link: "" }, + setNoticeData: () => {}, + noticeOpen: false, + setNoticeOpen: () => {}, + successData: { title: "" }, + setSuccessData: () => {}, + successOpen: false, + setSuccessOpen: () => {}, + notificationCenter: false, + setNotificationCenter: () => {}, + notificationList: [], + pushNotificationList: () => {}, + clearNotificationList: () => {}, + removeFromNotificationList: () => {}, }; export const alertContext = createContext(initialValue); export function AlertProvider({ children }: { children: ReactNode }) { - const [errorData, setErrorDataState] = useState<{ - title: string; - list?: Array; - }>({ title: "", list: [] }); - const [errorOpen, setErrorOpen] = useState(false); - const [noticeData, setNoticeDataState] = useState<{ - title: string; - link?: string; - }>({ title: "", link: "" }); - const [noticeOpen, setNoticeOpen] = useState(false); - const [successData, setSuccessDataState] = useState<{ title: string }>({ - title: "", - }); - const [successOpen, setSuccessOpen] = useState(false); - const [notificationCenter, setNotificationCenter] = useState(false); - const [notificationList, setNotificationList] = useState([]); - const pushNotificationList = (notification: AlertItemType) => { - setNotificationList((old) => { - let newNotificationList = _.cloneDeep(old); - newNotificationList.unshift(notification); - return newNotificationList; - }); - }; - /** - * Sets the error data state, opens the error dialog and pushes the new error notification to the notification list - * @param newState An object containing the new error data, including title and optional list of error messages - */ - function setErrorData(newState: { title: string; list?: Array }) { - setErrorDataState(newState); - setErrorOpen(true); - if (newState.title) { - setNotificationCenter(true); - pushNotificationList({ - type: "error", - title: newState.title, - list: newState.list, - id: _.uniqueId(), - }); - } - } - /** - * Sets the state of the notice data and opens the notice modal, also adds a new notice to the notification center if the title is defined. - * @param newState An object containing the title of the notice and optionally a link. - */ - function setNoticeData(newState: { title: string; link?: string }) { - setNoticeDataState(newState); - setNoticeOpen(true); - if (newState.title) { - // Add new notice to notification center - setNotificationCenter(true); - pushNotificationList({ - type: "notice", - title: newState.title, - link: newState.link, - id: _.uniqueId(), - }); - } - } - /** - * Update the success data state and show a success alert notification. - * @param newState - A state object with a "title" property to set in the success data state. - */ - function setSuccessData(newState: { title: string }) { - setSuccessDataState(newState); // update the success data state with the provided new state - setSuccessOpen(true); // open the success alert + const [errorData, setErrorDataState] = useState<{ + title: string; + list?: Array; + }>({ title: "", list: [] }); + const [errorOpen, setErrorOpen] = useState(false); + const [noticeData, setNoticeDataState] = useState<{ + title: string; + link?: string; + }>({ title: "", link: "" }); + const [noticeOpen, setNoticeOpen] = useState(false); + const [successData, setSuccessDataState] = useState<{ title: string }>({ + title: "", + }); + const [successOpen, setSuccessOpen] = useState(false); + const [notificationCenter, setNotificationCenter] = useState(false); + const [notificationList, setNotificationList] = useState([]); + const pushNotificationList = (notification: AlertItemType) => { + setNotificationList((old) => { + let newNotificationList = _.cloneDeep(old); + newNotificationList.unshift(notification); + return newNotificationList; + }); + }; + /** + * Sets the error data state, opens the error dialog and pushes the new error notification to the notification list + * @param newState An object containing the new error data, including title and optional list of error messages + */ + function setErrorData(newState: { title: string; list?: Array }) { + setErrorDataState(newState); + setErrorOpen(true); + if (newState.title) { + setNotificationCenter(true); + pushNotificationList({ + type: "error", + title: newState.title, + list: newState.list, + id: _.uniqueId(), + }); + } + } + /** + * Sets the state of the notice data and opens the notice modal, also adds a new notice to the notification center if the title is defined. + * @param newState An object containing the title of the notice and optionally a link. + */ + function setNoticeData(newState: { title: string; link?: string }) { + setNoticeDataState(newState); + setNoticeOpen(true); + if (newState.title) { + // Add new notice to notification center + setNotificationCenter(true); + pushNotificationList({ + type: "notice", + title: newState.title, + link: newState.link, + id: _.uniqueId(), + }); + } + } + /** + * Update the success data state and show a success alert notification. + * @param newState - A state object with a "title" property to set in the success data state. + */ + function setSuccessData(newState: { title: string }) { + setSuccessDataState(newState); // update the success data state with the provided new state + setSuccessOpen(true); // open the success alert - // If the new state has a "title" property, add a new success notification to the list - if (newState.title) { - setNotificationCenter(true); // show the notification center - pushNotificationList({ - // add the new notification to the list - type: "success", - title: newState.title, - id: _.uniqueId(), - }); - } - } - function clearNotificationList() { - setNotificationList([]); - } - function removeFromNotificationList(index: string) { - // set the notification list to a new array that filters out the alert with the matching id - setNotificationList((prevAlertsList) => - prevAlertsList.filter((alert) => alert.id !== index) - ); - } - return ( - - {children} - - ); + // If the new state has a "title" property, add a new success notification to the list + if (newState.title) { + setNotificationCenter(true); // show the notification center + pushNotificationList({ + // add the new notification to the list + type: "success", + title: newState.title, + id: _.uniqueId(), + }); + } + } + function clearNotificationList() { + setNotificationList([]); + } + function removeFromNotificationList(index: string) { + // set the notification list to a new array that filters out the alert with the matching id + setNotificationList((prevAlertsList) => + prevAlertsList.filter((alert) => alert.id !== index) + ); + } + return ( + + {children} + + ); } diff --git a/src/frontend/src/contexts/darkContext.tsx b/src/frontend/src/contexts/darkContext.tsx index c383fb1e3..f612fe381 100644 --- a/src/frontend/src/contexts/darkContext.tsx +++ b/src/frontend/src/contexts/darkContext.tsx @@ -1,34 +1,34 @@ import { createContext, useEffect, useState } from "react"; type darkContextType = { - dark: {}; - setDark: (newState: {}) => void; + dark: {}; + setDark: (newState: {}) => void; }; const initialValue = { - dark: {}, - setDark: () => {}, + dark: {}, + setDark: () => {}, }; export const darkContext = createContext(initialValue); export function DarkProvider({ children }) { - const [dark, setDark] = useState(false); - useEffect(() => { - if (dark) { - document.getElementById("body").classList.add("dark"); - } else { - document.getElementById("body").classList.remove("dark"); - } - }, [dark]); - return ( - - {children} - - ); + const [dark, setDark] = useState(false); + useEffect(() => { + if (dark) { + document.getElementById("body").classList.add("dark"); + } else { + document.getElementById("body").classList.remove("dark"); + } + }, [dark]); + return ( + + {children} + + ); } diff --git a/src/frontend/src/contexts/index.tsx b/src/frontend/src/contexts/index.tsx index bef4298e9..ab199368e 100644 --- a/src/frontend/src/contexts/index.tsx +++ b/src/frontend/src/contexts/index.tsx @@ -7,20 +7,20 @@ import { TabsProvider } from "./tabsContext"; import { TypesProvider } from "./typesContext"; export default function ContextWrapper({ children }: { children: ReactNode }) { - //element to wrap all context - return ( - <> - - - - - - {children} - - - - - - - ); + //element to wrap all context + return ( + <> + + + + + + {children} + + + + + + + ); } diff --git a/src/frontend/src/contexts/locationContext.tsx b/src/frontend/src/contexts/locationContext.tsx index a73db24fe..474062d69 100644 --- a/src/frontend/src/contexts/locationContext.tsx +++ b/src/frontend/src/contexts/locationContext.tsx @@ -2,78 +2,78 @@ import { createContext, ReactNode, useState } from "react"; //types for location context type locationContextType = { - current: Array; - setCurrent: (newState: Array) => void; - isStackedOpen: boolean; - setIsStackedOpen: (newState: boolean) => void; - showSideBar: boolean; - setShowSideBar: (newState: boolean) => void; - extraNavigation: { - title: string; - options?: Array<{ - name: string; - href: string; - icon: any; - children?: Array; - }>; - }; - setExtraNavigation: (newState: { - title: string; - options?: Array<{ - name: string; - href: string; - icon: any; - children?: Array; - }>; - }) => void; - extraComponent: any; - setExtraComponent: (newState: any) => void; + current: Array; + setCurrent: (newState: Array) => void; + isStackedOpen: boolean; + setIsStackedOpen: (newState: boolean) => void; + showSideBar: boolean; + setShowSideBar: (newState: boolean) => void; + extraNavigation: { + title: string; + options?: Array<{ + name: string; + href: string; + icon: any; + children?: Array; + }>; + }; + setExtraNavigation: (newState: { + title: string; + options?: Array<{ + name: string; + href: string; + icon: any; + children?: Array; + }>; + }) => void; + extraComponent: any; + setExtraComponent: (newState: any) => void; }; //initial value for location context const initialValue = { - //actual - current: window.location.pathname.replace(/\/$/g, "").split("/"), - isStackedOpen: - window.innerWidth > 1024 && window.location.pathname.split("/")[1] - ? true - : false, - setCurrent: () => {}, - setIsStackedOpen: () => {}, - showSideBar: window.location.pathname.split("/")[1] ? true : false, - setShowSideBar: () => {}, - extraNavigation: { title: "" }, - setExtraNavigation: () => {}, - extraComponent: <>, - setExtraComponent: () => {}, + //actual + current: window.location.pathname.replace(/\/$/g, "").split("/"), + isStackedOpen: + window.innerWidth > 1024 && window.location.pathname.split("/")[1] + ? true + : false, + setCurrent: () => {}, + setIsStackedOpen: () => {}, + showSideBar: window.location.pathname.split("/")[1] ? true : false, + setShowSideBar: () => {}, + extraNavigation: { title: "" }, + setExtraNavigation: () => {}, + extraComponent: <>, + setExtraComponent: () => {}, }; export const locationContext = createContext(initialValue); export function LocationProvider({ children }: { children: ReactNode }) { - const [current, setCurrent] = useState(initialValue.current); - const [isStackedOpen, setIsStackedOpen] = useState( - initialValue.isStackedOpen - ); - const [showSideBar, setShowSideBar] = useState(initialValue.showSideBar); - const [extraNavigation, setExtraNavigation] = useState({ title: "" }); - const [extraComponent, setExtraComponent] = useState(<>); - return ( - - {children} - - ); + const [current, setCurrent] = useState(initialValue.current); + const [isStackedOpen, setIsStackedOpen] = useState( + initialValue.isStackedOpen + ); + const [showSideBar, setShowSideBar] = useState(initialValue.showSideBar); + const [extraNavigation, setExtraNavigation] = useState({ title: "" }); + const [extraComponent, setExtraComponent] = useState(<>); + return ( + + {children} + + ); } diff --git a/src/frontend/src/contexts/popUpContext.tsx b/src/frontend/src/contexts/popUpContext.tsx index b8c47dea2..371aeefce 100644 --- a/src/frontend/src/contexts/popUpContext.tsx +++ b/src/frontend/src/contexts/popUpContext.tsx @@ -3,31 +3,31 @@ import React, { useState } from "react"; // context to set JSX element on the DOM export const PopUpContext = createContext({ - openPopUp: (popUpElement: JSX.Element) => {}, - closePopUp: () => {}, + openPopUp: (popUpElement: JSX.Element) => {}, + closePopUp: () => {}, }); interface PopUpProviderProps { - children: React.ReactNode; + children: React.ReactNode; } const PopUpProvider = ({ children }: PopUpProviderProps) => { - const [popUpElements, setPopUpElements] = useState([]); + const [popUpElements, setPopUpElements] = useState([]); - const openPopUp = (element: JSX.Element) => { - setPopUpElements((prevPopUps) => [element, ...prevPopUps]); - }; + const openPopUp = (element: JSX.Element) => { + setPopUpElements((prevPopUps) => [element, ...prevPopUps]); + }; - const closePopUp = () => { - setPopUpElements((prevPopUps) => prevPopUps.slice(1)); - }; + const closePopUp = () => { + setPopUpElements((prevPopUps) => prevPopUps.slice(1)); + }; - return ( - - {children} - {popUpElements[0]} - - ); + return ( + + {children} + {popUpElements[0]} + + ); }; export default PopUpProvider; diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index f34e1bc7a..2703631dd 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -1,10 +1,10 @@ import { - createContext, - useEffect, - useState, - useRef, - ReactNode, - useContext, + createContext, + useEffect, + useState, + useRef, + ReactNode, + useContext, } from "react"; import { FlowType, NodeType } from "../types/flow"; import { LangFlowState, TabsContextType } from "../types/tabs"; @@ -14,335 +14,341 @@ import { typesContext } from "./typesContext"; import { APITemplateType, TemplateVariableType } from "../types/api"; import { v4 as uuidv4 } from "uuid"; import { addEdge } from "reactflow"; +import _ from "lodash"; const TabsContextInitialValue: TabsContextType = { - save: () => {}, - tabIndex: 0, - setTabIndex: (index: number) => {}, - flows: [], - removeFlow: (id: string) => {}, - addFlow: (flowData?: any) => {}, - updateFlow: (newFlow: FlowType) => {}, - incrementNodeId: () => uuidv4(), - downloadFlow: (flow: FlowType) => {}, - uploadFlow: () => {}, - hardReset: () => {}, - disableCopyPaste:false, - setDisableCopyPaste:(state:boolean)=>{}, - getNodeId: () => "", - paste: (selection: {nodes: any, edges: any}, position: {x: number, y: number}) => {}, + save: () => {}, + tabIndex: 0, + setTabIndex: (index: number) => {}, + flows: [], + removeFlow: (id: string) => {}, + addFlow: (flowData?: any) => {}, + updateFlow: (newFlow: FlowType) => {}, + incrementNodeId: () => uuidv4(), + downloadFlow: (flow: FlowType) => {}, + uploadFlow: () => {}, + hardReset: () => {}, + disableCopyPaste: false, + setDisableCopyPaste: (state: boolean) => {}, + getNodeId: () => "", + paste: ( + selection: { nodes: any; edges: any }, + position: { x: number; y: number } + ) => {}, }; export const TabsContext = createContext( - TabsContextInitialValue + TabsContextInitialValue ); export function TabsProvider({ children }: { children: ReactNode }) { - const { setNoticeData } = useContext(alertContext); - const [tabIndex, setTabIndex] = useState(0); - const [flows, setFlows] = useState>([]); - const [id, setId] = useState(uuidv4()); - const { templates, reactFlowInstance } = useContext(typesContext); + const { setNoticeData } = useContext(alertContext); + const [tabIndex, setTabIndex] = useState(0); + const [flows, setFlows] = useState>([]); + const [id, setId] = useState(uuidv4()); + const { templates, reactFlowInstance } = useContext(typesContext); - const newNodeId = useRef(uuidv4()); - function incrementNodeId() { - newNodeId.current = uuidv4(); - return newNodeId.current; - } - function save() { - let Saveflows = [...flows]; - if (Saveflows.length !== 0) - Saveflows.forEach((flow) => { - if(flow.data && flow.data?.nodes) flow.data?.nodes.forEach((node) => { - console.log(node.data.type) - Object.keys(node.data.node.template).forEach((key) => { - console.log(node.data.node.template[key].type) - if(node.data.node.template[key].type==="file"){ - console.log(node.data.node.template[key]) - node.data.node.template[key].content = ""; - } - }) - }) - }) - window.localStorage.setItem( - "tabsData", - JSON.stringify({ tabIndex, flows:Saveflows, id}) - ); - } - useEffect(() => { - //save tabs locally - // console.log(id) - save(); - }, [flows, id, tabIndex, newNodeId]); + const newNodeId = useRef(uuidv4()); + function incrementNodeId() { + newNodeId.current = uuidv4(); + return newNodeId.current; + } + function save() { + // added clone deep to avoid mutating the original object + let Saveflows = _.cloneDeep(flows); + if (Saveflows.length !== 0) { + Saveflows.forEach((flow) => { + if (flow.data && flow.data?.nodes) + flow.data?.nodes.forEach((node) => { + console.log(node.data.type); + //looking for file fields to prevent saving the content and breaking the flow for exceeding the the data limite for local storage + Object.keys(node.data.node.template).forEach((key) => { + console.log(node.data.node.template[key].type); + if (node.data.node.template[key].type === "file") { + console.log(node.data.node.template[key]); + node.data.node.template[key].content = null; + node.data.node.template[key].value = ""; + } + }); + }); + }); + window.localStorage.setItem( + "tabsData", + JSON.stringify({ tabIndex, flows: Saveflows, id }) + ); + } + } - useEffect(() => { - //get tabs locally saved - let cookie = window.localStorage.getItem("tabsData"); - if (cookie && Object.keys(templates).length > 0) { - let cookieObject: LangFlowState = JSON.parse(cookie); - cookieObject.flows.forEach((flow) => { - flow.data.nodes.forEach((node) => { - if (Object.keys(templates[node.data.type]["template"]).length > 0) { - node.data.node.template = updateTemplate( - templates[node.data.type][ - "template" - ] as unknown as APITemplateType, + useEffect(() => { + //get tabs locally saved + let cookie = window.localStorage.getItem("tabsData"); + if (cookie && Object.keys(templates).length > 0) { + let cookieObject: LangFlowState = JSON.parse(cookie); + cookieObject.flows.forEach((flow) => { + flow.data.nodes.forEach((node) => { + if (Object.keys(templates[node.data.type]["template"]).length > 0) { + node.data.node.template = updateTemplate( + templates[node.data.type][ + "template" + ] as unknown as APITemplateType, - node.data.node.template as APITemplateType - ); - } - }); - }); - setTabIndex(cookieObject.tabIndex); - setFlows(cookieObject.flows); - setId(cookieObject.id); - } - }, [templates]); + node.data.node.template as APITemplateType + ); + } + }); + }); + setTabIndex(cookieObject.tabIndex); + setFlows(cookieObject.flows); + setId(cookieObject.id); + } + }, [templates]); - function hardReset() { - newNodeId.current = uuidv4(); - setTabIndex(0); - setFlows([]); - setId(uuidv4()); - } + useEffect(() => { + //save tabs locally + console.log(id); + save(); + }, [flows, id, tabIndex, newNodeId]); - /** - * Downloads the current flow as a JSON file - */ - function downloadFlow(flow: FlowType) { - // create a data URI with the current flow data - const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent( - JSON.stringify(flow) - )}`; + function hardReset() { + newNodeId.current = uuidv4(); + setTabIndex(0); + setFlows([]); + setId(uuidv4()); + } - // create a link element and set its properties - const link = document.createElement("a"); - link.href = jsonString; - link.download = `${flows[tabIndex].name}.json`; + /** + * Downloads the current flow as a JSON file + */ + function downloadFlow(flow: FlowType) { + // create a data URI with the current flow data + const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent( + JSON.stringify(flow) + )}`; - // simulate a click on the link element to trigger the download - link.click(); - setNoticeData({ - title: "Warning: Critical data,JSON file may including API keys.", - }); - } + // create a link element and set its properties + const link = document.createElement("a"); + link.href = jsonString; + link.download = `${flows[tabIndex].name}.json`; - function getNodeId() { - return `dndnode_` + incrementNodeId(); - } + // simulate a click on the link element to trigger the download + link.click(); + setNoticeData({ + title: "Warning: Critical data,JSON file may including API keys.", + }); + } - /** - * Creates a file input and listens to a change event to upload a JSON flow file. - * If the file type is application/json, the file is read and parsed into a JSON object. - * The resulting JSON object is passed to the addFlow function. - */ - function uploadFlow() { - // create a file input - const input = document.createElement("input"); - input.type = "file"; - // add a change event listener to the file input - input.onchange = (e: Event) => { - // check if the file type is application/json - if ((e.target as HTMLInputElement).files[0].type === "application/json") { - // get the file from the file input - const file = (e.target as HTMLInputElement).files[0]; - // read the file as text - file.text().then((text) => { - // parse the text into a JSON object - let flow: FlowType = JSON.parse(text); + function getNodeId() { + return `dndnode_` + incrementNodeId(); + } - addFlow(flow); - }); - } - }; - // trigger the file input click event to open the file dialog - input.click(); - } - /** - * Removes a flow from an array of flows based on its id. - * Updates the state of flows and tabIndex using setFlows and setTabIndex hooks. - * @param {string} id - The id of the flow to remove. - */ - function removeFlow(id: string) { - setFlows((prevState) => { - const newFlows = [...prevState]; - const index = newFlows.findIndex((flow) => flow.id === id); - if (index >= 0) { - if (index === tabIndex) { - setTabIndex(flows.length - 2); - newFlows.splice(index, 1); - } else { - let flowId = flows[tabIndex].id; - newFlows.splice(index, 1); - setTabIndex(newFlows.findIndex((flow) => flow.id === flowId)); - } - } - return newFlows; - }); - } - /** - * Add a new flow to the list of flows. - * @param flow Optional flow to add. - */ + /** + * Creates a file input and listens to a change event to upload a JSON flow file. + * If the file type is application/json, the file is read and parsed into a JSON object. + * The resulting JSON object is passed to the addFlow function. + */ + function uploadFlow() { + // create a file input + const input = document.createElement("input"); + input.type = "file"; + // add a change event listener to the file input + input.onchange = (e: Event) => { + // check if the file type is application/json + if ((e.target as HTMLInputElement).files[0].type === "application/json") { + // get the file from the file input + const file = (e.target as HTMLInputElement).files[0]; + // read the file as text + file.text().then((text) => { + // parse the text into a JSON object + let flow: FlowType = JSON.parse(text); - function paste(selectionInstance, position){ - console.log(position); - console.log(selectionInstance) - let minimumX = Infinity; - let minimumY = Infinity; - let idsMap = {}; - let nodes = reactFlowInstance.getNodes(); - let edges = reactFlowInstance.getEdges(); - selectionInstance.nodes.forEach((n) => { - if (n.position.y < minimumY) { - minimumY = n.position.y; - } - if (n.position.x < minimumX) { - minimumX = n.position.x; - } - }); + addFlow(flow); + }); + } + }; + // trigger the file input click event to open the file dialog + input.click(); + } + /** + * Removes a flow from an array of flows based on its id. + * Updates the state of flows and tabIndex using setFlows and setTabIndex hooks. + * @param {string} id - The id of the flow to remove. + */ + function removeFlow(id: string) { + setFlows((prevState) => { + const newFlows = [...prevState]; + const index = newFlows.findIndex((flow) => flow.id === id); + if (index >= 0) { + if (index === tabIndex) { + setTabIndex(flows.length - 2); + newFlows.splice(index, 1); + } else { + let flowId = flows[tabIndex].id; + newFlows.splice(index, 1); + setTabIndex(newFlows.findIndex((flow) => flow.id === flowId)); + } + } + return newFlows; + }); + } + /** + * Add a new flow to the list of flows. + * @param flow Optional flow to add. + */ - const insidePosition = reactFlowInstance.project(position); - - selectionInstance.nodes.forEach((n) => { - // Generate a unique node ID - let newId = getNodeId(); - idsMap[n.id] = newId; - - // Create a new node object - const newNode: NodeType = { - id: newId, - type: "genericNode", - position: { - x: insidePosition.x + n.position.x - minimumX, - y: insidePosition.y + n.position.y - minimumY, - }, - data: { - ...n.data, - id: newId, - }, - }; - - // Add the new node to the list of nodes in state - nodes = nodes - .map((e) => ({ ...e, selected: false })) - .concat({ ...newNode, selected: false }) - console.log(nodes); - }); - reactFlowInstance.setNodes(nodes); - - selectionInstance.edges.forEach((e) => { - let source = idsMap[e.source]; - let target = idsMap[e.target]; - let sourceHandleSplitted = e.sourceHandle.split("|"); - let sourceHandle = - sourceHandleSplitted[0] + - "|" + - source + - "|" + - sourceHandleSplitted.slice(2).join("|"); - let targetHandleSplitted = e.targetHandle.split("|"); - let targetHandle = - targetHandleSplitted.slice(0, -1).join("|") + "|" + target; - let id = - "reactflow__edge-" + - source + - sourceHandle + - "-" + - target + - targetHandle; - edges = addEdge( - { - source, - target, - sourceHandle, - targetHandle, - id, - className: "animate-pulse", - selected: false, - }, - edges.map((e) => ({ ...e, selected: false })) - ); - console.log(edges); - }); - reactFlowInstance.setEdges(edges); - }; - - function addFlow(flow?: FlowType) { - // Get data from the flow or set it to null if there's no flow provided. - const data = flow?.data ? flow.data : null; - const description = flow?.description ? flow.description : ""; + function paste(selectionInstance, position) { + let minimumX = Infinity; + let minimumY = Infinity; + let idsMap = {}; + let nodes = reactFlowInstance.getNodes(); + let edges = reactFlowInstance.getEdges(); + selectionInstance.nodes.forEach((n) => { + if (n.position.y < minimumY) { + minimumY = n.position.y; + } + if (n.position.x < minimumX) { + minimumX = n.position.x; + } + }); - if (data) { - data.nodes.forEach((node) => { - if (Object.keys(templates[node.data.type]["template"]).length > 0) { - node.data.node.template = updateTemplate( - templates[node.data.type]["template"] as unknown as APITemplateType, - node.data.node.template as APITemplateType - ); - } - }); - } - // Create a new flow with a default name if no flow is provided. - let newFlow: FlowType = { - description, - name: flow?.name ?? "New Flow", - id: uuidv4(), - data, - }; + const insidePosition = reactFlowInstance.project(position); - // Increment the ID counter. - setId(uuidv4()); + selectionInstance.nodes.forEach((n) => { + // Generate a unique node ID + let newId = getNodeId(); + idsMap[n.id] = newId; - // Add the new flow to the list of flows. - - setFlows((prevState) => { - const newFlows = [...prevState, newFlow]; - return newFlows; - }); + // Create a new node object + const newNode: NodeType = { + id: newId, + type: "genericNode", + position: { + x: insidePosition.x + n.position.x - minimumX, + y: insidePosition.y + n.position.y - minimumY, + }, + data: { + ...n.data, + id: newId, + }, + }; - // Set the tab index to the new flow. - setTabIndex(flows.length); - } - /** - * Updates an existing flow with new data - * @param newFlow - The new flow object containing the updated data - */ - function updateFlow(newFlow: FlowType) { - setFlows((prevState) => { - const newFlows = [...prevState]; - const index = newFlows.findIndex((flow) => flow.id === newFlow.id); - if (index !== -1) { - newFlows[index].description = newFlow.description ?? ""; - newFlows[index].data = newFlow.data; - newFlows[index].name = newFlow.name; - } - return newFlows; - }); - } - const [disableCopyPaste, setDisableCopyPaste] = useState(false); + // Add the new node to the list of nodes in state + nodes = nodes + .map((e) => ({ ...e, selected: false })) + .concat({ ...newNode, selected: false }); + }); + reactFlowInstance.setNodes(nodes); - return ( - - {children} - - ); -} \ No newline at end of file + selectionInstance.edges.forEach((e) => { + let source = idsMap[e.source]; + let target = idsMap[e.target]; + let sourceHandleSplitted = e.sourceHandle.split("|"); + let sourceHandle = + sourceHandleSplitted[0] + + "|" + + source + + "|" + + sourceHandleSplitted.slice(2).join("|"); + let targetHandleSplitted = e.targetHandle.split("|"); + let targetHandle = + targetHandleSplitted.slice(0, -1).join("|") + "|" + target; + let id = + "reactflow__edge-" + + source + + sourceHandle + + "-" + + target + + targetHandle; + edges = addEdge( + { + source, + target, + sourceHandle, + targetHandle, + id, + className: "animate-pulse", + selected: false, + }, + edges.map((e) => ({ ...e, selected: false })) + ); + }); + reactFlowInstance.setEdges(edges); + } + + function addFlow(flow?: FlowType) { + // Get data from the flow or set it to null if there's no flow provided. + const data = flow?.data ? flow.data : null; + const description = flow?.description ? flow.description : ""; + + if (data) { + data.nodes.forEach((node) => { + if (Object.keys(templates[node.data.type]["template"]).length > 0) { + node.data.node.template = updateTemplate( + templates[node.data.type]["template"] as unknown as APITemplateType, + node.data.node.template as APITemplateType + ); + } + }); + } + // Create a new flow with a default name if no flow is provided. + let newFlow: FlowType = { + description, + name: flow?.name ?? "New Flow", + id: uuidv4(), + data, + }; + + // Increment the ID counter. + setId(uuidv4()); + + // Add the new flow to the list of flows. + + setFlows((prevState) => { + const newFlows = [...prevState, newFlow]; + return newFlows; + }); + + // Set the tab index to the new flow. + setTabIndex(flows.length); + } + /** + * Updates an existing flow with new data + * @param newFlow - The new flow object containing the updated data + */ + function updateFlow(newFlow: FlowType) { + setFlows((prevState) => { + const newFlows = [...prevState]; + const index = newFlows.findIndex((flow) => flow.id === newFlow.id); + if (index !== -1) { + newFlows[index].description = newFlow.description ?? ""; + newFlows[index].data = newFlow.data; + newFlows[index].name = newFlow.name; + } + return newFlows; + }); + } + const [disableCopyPaste, setDisableCopyPaste] = useState(false); + + return ( + + {children} + + ); +} diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 9a93a9b36..f6f46404b 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -4,40 +4,40 @@ import axios, { AxiosResponse } from "axios"; import { FlowType } from "../../types/flow"; export async function getAll(): Promise> { - return await axios.get(`/all`); + return await axios.get(`/all`); } export async function sendAll(data: sendAllProps) { - return await axios.post(`/predict`, data); + return await axios.post(`/predict`, data); } export async function checkCode( - code: string + code: string ): Promise> { - return await axios.post("/validate/code", { code }); + return await axios.post("/validate/code", { code }); } export async function checkPrompt( - template: string + template: string ): Promise> { - return await axios.post("/validate/prompt", { template }); + return await axios.post("/validate/prompt", { template }); } export async function getExamples(): Promise { - const url = - "https://api.github.com/repos/logspace-ai/langflow_examples/contents/examples"; - const response = await axios.get(url); + const url = + "https://api.github.com/repos/logspace-ai/langflow_examples/contents/examples"; + const response = await axios.get(url); - const jsonFiles = response.data.filter((file: any) => { - return file.name.endsWith(".json"); - }); + const jsonFiles = response.data.filter((file: any) => { + return file.name.endsWith(".json"); + }); - const contentsPromises = jsonFiles.map(async (file: any) => { - const contentResponse = await axios.get(file.download_url); - return contentResponse.data; - }); + const contentsPromises = jsonFiles.map(async (file: any) => { + const contentResponse = await axios.get(file.download_url); + return contentResponse.data; + }); - const contents = await Promise.all(contentsPromises); + const contents = await Promise.all(contentsPromises); - return contents; + return contents; } diff --git a/src/frontend/src/index.tsx b/src/frontend/src/index.tsx index 5857efd9a..088db15a8 100644 --- a/src/frontend/src/index.tsx +++ b/src/frontend/src/index.tsx @@ -5,16 +5,16 @@ import reportWebVitals from "./reportWebVitals"; import { BrowserRouter } from "react-router-dom"; import ContextWrapper from "./contexts"; -import './index.css'; +import "./index.css"; const root = ReactDOM.createRoot( - document.getElementById("root") as HTMLElement + document.getElementById("root") as HTMLElement ); root.render( - - - - - + + + + + ); reportWebVitals(); diff --git a/src/frontend/src/modals/ApiModal/index.tsx b/src/frontend/src/modals/ApiModal/index.tsx index f14b190f5..daeafe6bb 100644 --- a/src/frontend/src/modals/ApiModal/index.tsx +++ b/src/frontend/src/modals/ApiModal/index.tsx @@ -1,6 +1,10 @@ import { Dialog, Transition } from "@headlessui/react"; -import { IconCheck, IconClipboard, IconDownload } from '@tabler/icons-react'; -import { XMarkIcon, CommandLineIcon, CodeBracketSquareIcon } from "@heroicons/react/24/outline"; +import { IconCheck, IconClipboard, IconDownload } from "@tabler/icons-react"; +import { + XMarkIcon, + CommandLineIcon, + CodeBracketSquareIcon, +} from "@heroicons/react/24/outline"; import { Fragment, useContext, useRef, useState } from "react"; import { PopUpContext } from "../../contexts/popUpContext"; import "ace-builds/src-noconflict/mode-python"; @@ -9,42 +13,40 @@ import "ace-builds/src-noconflict/theme-twilight"; import "ace-builds/src-noconflict/ext-language_tools"; // import "ace-builds/webpack-resolver"; import { darkContext } from "../../contexts/darkContext"; -import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; -import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'; - - +import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; +import { oneDark } from "react-syntax-highlighter/dist/cjs/styles/prism"; export default function ApiModal({ flowName }) { - const [open, setOpen] = useState(true); - const { dark } = useContext(darkContext); - const { closePopUp } = useContext(PopUpContext); - const [activeTab, setActiveTab] = useState(0); - const ref = useRef(); - const [isCopied, setIsCopied] = useState(false); + const [open, setOpen] = useState(true); + const { dark } = useContext(darkContext); + const { closePopUp } = useContext(PopUpContext); + const [activeTab, setActiveTab] = useState(0); + const ref = useRef(); + const [isCopied, setIsCopied] = useState(false); - const copyToClipboard = () => { - if (!navigator.clipboard || !navigator.clipboard.writeText) { - return; - } + const copyToClipboard = () => { + if (!navigator.clipboard || !navigator.clipboard.writeText) { + return; + } - navigator.clipboard.writeText(tabs[activeTab].code).then(() => { - setIsCopied(true); + navigator.clipboard.writeText(tabs[activeTab].code).then(() => { + setIsCopied(true); - setTimeout(() => { - setIsCopied(false); - }, 2000); - }); - }; - function setModalOpen(x: boolean) { - setOpen(x); - if (x === false) { - setTimeout(() => { - closePopUp(); - }, 300); - } - } + setTimeout(() => { + setIsCopied(false); + }, 2000); + }); + }; + function setModalOpen(x: boolean) { + setOpen(x); + if (x === false) { + setTimeout(() => { + closePopUp(); + }, 300); + } + } - const pythonApiCode = `import requests + const pythonApiCode = `import requests import json API_URL = "${window.location.protocol}//${window.location.host}/predict" @@ -58,130 +60,142 @@ def predict(message): print(predict("Your message"))`; - const pythonCode = `from langflow import load_flow_from_json + const pythonCode = `from langflow import load_flow_from_json flow = load_flow_from_json("${flowName}.json") # Now you can use it like any chain flow("Hey, have you heard of LangFlow?")`; - const tabs = [ - { - name: "Python API", - mode: "python", - image: "https://images.squarespace-cdn.com/content/v1/5df3d8c5d2be5962e4f87890/1628015119369-OY4TV3XJJ53ECO0W2OLQ/Python+API+Training+Logo.png?format=1000w", - code: pythonApiCode, - }, - { - name: "Python Code", - mode: "python", - image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png", - code: pythonCode, - }, + const tabs = [ + { + name: "Python API", + mode: "python", + image: + "https://images.squarespace-cdn.com/content/v1/5df3d8c5d2be5962e4f87890/1628015119369-OY4TV3XJJ53ECO0W2OLQ/Python+API+Training+Logo.png?format=1000w", + code: pythonApiCode, + }, + { + name: "Python Code", + mode: "python", + image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png", + code: pythonCode, + }, + ]; + return ( + + + +
+ - ] - return ( - - - -
- - -
-
- - -
- -
-
-
-
-
-
- - Code - -
-
-
-
-
- {tabs.map((tab, index) => ( - - ))} -
-
-
- - Export your flow to use it with this code. - - -
- - {tabs[activeTab].code} - -
-
-
-
-
-
-
-
-
-
- ); +
+
+ + +
+ +
+
+
+
+
+
+ + Code + +
+
+
+
+
+ {tabs.map((tab, index) => ( + + ))} +
+
+
+ + Export your flow to use it with this code. + + +
+ + {tabs[activeTab].code} + +
+
+
+
+
+
+
+
+
+
+ ); } diff --git a/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx b/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx index 049131e6b..0c19b9611 100644 --- a/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx +++ b/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx @@ -13,154 +13,154 @@ import CodeAreaComponent from "../../../../components/codeAreaComponent"; import { classNames } from "../../../../utils"; export default function ModalField({ data, title, required, id, name, type }) { - const { save } = useContext(TabsContext); - const [enabled, setEnabled] = useState( - data.node.template[name]?.value ?? false - ); - const display = - type === "str" || - type === "int" || - type === "prompt" || - type === "bool" || - type === "float" || - type === "file" || - type === "code"; + const { save } = useContext(TabsContext); + const [enabled, setEnabled] = useState( + data.node.template[name]?.value ?? false + ); + const display = + type === "str" || + type === "int" || + type === "prompt" || + type === "bool" || + type === "float" || + type === "file" || + type === "code"; - return ( -
- {display && ( -
- {title} - {required ? " *" : ""} -
- )} + return ( +
+ {display && ( +
+ {title} + {required ? " *" : ""} +
+ )} - {type === "str" && !data.node.template[name].options ? ( -
- {data.node.template[name].list ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : data.node.template[name].multiline ? ( - { - data.node.template[name].value = t; - save(); - }} - /> - ) : ( - { - data.node.template[name].value = t; - save(); - }} - /> - )} -
- ) : type === "bool" ? ( -
- {" "} - { - data.node.template[name].value = t; - setEnabled(t); - save(); - }} - /> -
- ) : type === "float" ? ( -
- { - data.node.template[name].value = t; - save(); - }} - /> -
- ) : type === "str" && data.node.template[name].options ? ( -
- (data.node.template[name].value = newValue)} - value={data.node.template[name].value ?? "Choose an option"} - > -
- ) : type === "int" ? ( -
- { - data.node.template[name].value = t; - save(); - }} - /> -
- ) : type === "file" ? ( -
- { - data.node.template[name].value = t; - }} - fileTypes={data.node.template[name].fileTypes} - suffixes={data.node.template[name].suffixes} - onFileChange={(t: string) => { - data.node.template[name].content = t; - save(); - }} - > -
- ) : type === "prompt" ? ( -
- { - data.node.template[name].value = t; - save(); - }} - /> -
- ) : type === "code" ? ( -
- { - data.node.template[name].value = t; - save(); - }} - /> -
- ) : ( -
- )} -
- ); + {type === "str" && !data.node.template[name].options ? ( +
+ {data.node.template[name].list ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : data.node.template[name].multiline ? ( + { + data.node.template[name].value = t; + save(); + }} + /> + ) : ( + { + data.node.template[name].value = t; + save(); + }} + /> + )} +
+ ) : type === "bool" ? ( +
+ {" "} + { + data.node.template[name].value = t; + setEnabled(t); + save(); + }} + /> +
+ ) : type === "float" ? ( +
+ { + data.node.template[name].value = t; + save(); + }} + /> +
+ ) : type === "str" && data.node.template[name].options ? ( +
+ (data.node.template[name].value = newValue)} + value={data.node.template[name].value ?? "Choose an option"} + > +
+ ) : type === "int" ? ( +
+ { + data.node.template[name].value = t; + save(); + }} + /> +
+ ) : type === "file" ? ( +
+ { + data.node.template[name].value = t; + }} + fileTypes={data.node.template[name].fileTypes} + suffixes={data.node.template[name].suffixes} + onFileChange={(t: string) => { + data.node.template[name].content = t; + save(); + }} + > +
+ ) : type === "prompt" ? ( +
+ { + data.node.template[name].value = t; + save(); + }} + /> +
+ ) : type === "code" ? ( +
+ { + data.node.template[name].value = t; + save(); + }} + /> +
+ ) : ( +
+ )} +
+ ); } diff --git a/src/frontend/src/modals/NodeModal/index.tsx b/src/frontend/src/modals/NodeModal/index.tsx index 1bc73af6f..257ccffa4 100644 --- a/src/frontend/src/modals/NodeModal/index.tsx +++ b/src/frontend/src/modals/NodeModal/index.tsx @@ -8,138 +8,138 @@ import { typesContext } from "../../contexts/typesContext"; import ModalField from "./components/ModalField"; export default function NodeModal({ data }: { data: NodeDataType }) { - const [open, setOpen] = useState(true); - const { closePopUp } = useContext(PopUpContext); - const { types } = useContext(typesContext); - const ref = useRef(); - function setModalOpen(x: boolean) { - setOpen(x); - if (x === false) { - setTimeout(() => { - closePopUp(); - }, 300); - } - } - const Icon = nodeIcons[types[data.type]]; - return ( - - - -
- + const [open, setOpen] = useState(true); + const { closePopUp } = useContext(PopUpContext); + const { types } = useContext(typesContext); + const ref = useRef(); + function setModalOpen(x: boolean) { + setOpen(x); + if (x === false) { + setTimeout(() => { + closePopUp(); + }, 300); + } + } + const Icon = nodeIcons[types[data.type]]; + return ( + + + +
+ -
-
- - -
- -
-
-
- -
- - {data.type} - -
-
-
-
-
-
- {Object.keys(data.node.template) - .filter( - (t) => - t.charAt(0) !== "_" && - data.node.template[t].advanced && - data.node.template[t].show - ) - .map((t: string, idx) => { - return ( - - ); - })} -
-
-
-
-
- -
-
-
-
-
-
-
-
- ); +
+
+ + +
+ +
+
+
+ +
+ + {data.type} + +
+
+
+
+
+
+ {Object.keys(data.node.template) + .filter( + (t) => + t.charAt(0) !== "_" && + data.node.template[t].advanced && + data.node.template[t].show + ) + .map((t: string, idx) => { + return ( + + ); + })} +
+
+
+
+
+ +
+
+
+
+
+
+
+
+ ); } diff --git a/src/frontend/src/modals/chatModal/chatInput/index.tsx b/src/frontend/src/modals/chatModal/chatInput/index.tsx index 5cddb9c14..5a979499a 100644 --- a/src/frontend/src/modals/chatModal/chatInput/index.tsx +++ b/src/frontend/src/modals/chatModal/chatInput/index.tsx @@ -17,8 +17,6 @@ export default function ChatInput({ } }, [chatValue]); - const { setDisableCopyPaste } = useContext(TabsContext); - return (
-
+
+
+ + +
+ +
+
+
+
+
+
+ + Export as + +
+
+
+
+ + { + if (event.target.value != "") { + let newFlow = flows[tabIndex]; + newFlow.name = event.target.value; + setName(event.target.value); + updateFlow(newFlow); + } else { + setName(event.target.value); + } + }} + type="text" + name="name" + value={name ?? null} + placeholder="File name" + id="name" + className="focus:border focus:border-blue block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500 text-gray-900 dark:text-gray-100" + /> +
+
+ + +
-
- -
-
- -
-
-
-
-
-
-
- - - ); +
+ +
+
+ +
+
+ + + + + + + + ); } diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx new file mode 100644 index 000000000..b804803ea --- /dev/null +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -0,0 +1,160 @@ +import { Dialog, Transition } from "@headlessui/react"; +import { XMarkIcon, DocumentTextIcon } from "@heroicons/react/24/outline"; +import { Fragment, useContext, useRef, useState } from "react"; +import { PopUpContext } from "../../contexts/popUpContext"; +import { darkContext } from "../../contexts/darkContext"; +import { checkPrompt } from "../../controllers/API"; +import { alertContext } from "../../contexts/alertContext"; +export default function PromptAreaModal({ + value, + setValue, + buttonText, + modalTitle, +}: { + setValue: (value: string) => void; + value: string; + buttonText: string; + modalTitle: string; +}) { + const [myButtonText, setmyButtonText] = useState(buttonText); + const [myModalTitle, setMyModalTitle] = useState(modalTitle); + const [open, setOpen] = useState(true); + const [myValue, setMyValue] = useState(value); + const { dark } = useContext(darkContext); + const { setErrorData, setSuccessData } = useContext(alertContext); + const { closePopUp } = useContext(PopUpContext); + const ref = useRef(); + function setModalOpen(x: boolean) { + setOpen(x); + if (x === false) { + setTimeout(() => { + closePopUp(); + }, 300); + } + } + + return ( + + + +
+ + +
+
+ + +
+ +
+
+
+
+
+
+ + {myModalTitle} + +
+
+
+
+
+