diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68e4b9c11..98dddaa84 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,9 +43,11 @@ the system we use to tag our issues and pull requests. You can develop LangFlow using docker compose, or locally. #### **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:5003`. +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 docker compose up --build +# or +make dev build=1 ``` #### **Locally** @@ -58,7 +60,6 @@ Before you start, make sure you have the following installed: For the backend, you will need to install the dependencies and start the development server. ```bash poetry install -# Port 5003 is required for the backend to work with the frontend make run_backend ``` For the frontend, you will need to install the dependencies and start the development server. diff --git a/Makefile b/Makefile index e0548f006..70407436b 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,17 @@ build: poetry build --format sdist rm -rf src/backend/langflow/frontend +dev: + make install_frontend +ifeq ($(build),1) + @echo 'Running docker compose up with build' + docker compose up --build +else + @echo 'Running docker compose up without build' + docker compose up +endif + + publish: make build poetry publish @@ -49,4 +60,8 @@ help: @echo 'lint - run linters' @echo 'install_frontend - install the frontend dependencies' @echo 'build_frontend - build the frontend static files' - @echo 'build - build the frontend static files and package the project' \ No newline at end of file + @echo 'run_frontend - run the frontend in development mode' + @echo 'run_backend - run the backend in development mode' + @echo 'build - build the frontend static files and package the project' + @echo 'publish - build the frontend static files and package the project and publish it to PyPI' + @echo 'dev - run the project in development mode with docker compose' diff --git a/README.md b/README.md index 60693f0b1..8de32742a 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,18 @@ Creating flows with LangFlow is easy. Simply drag sidebar components onto the ca Explore by editing prompt parameters, link chains and agents, track an agent's thought process, and export your flow. +Once you're done, you can export your flow as a JSON file to use with LangChain. +To do so, click the "Export" button in the top right corner of the canvas, then +in Python, you can load the flow with: + +```python +from langflow import load_flow_from_json + +flow = load_flow_from_json("path/to/flow.json") +# Now you can use it like any chain +flow("Hey, have you heard of LangFlow?") +``` + ## 👋 Contributing diff --git a/dev.Dockerfile b/dev.Dockerfile index b8a37bd4f..0f559a0cf 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -3,7 +3,7 @@ FROM python:3.10-slim WORKDIR /app # Install Poetry -RUN apt-get update && apt-get install -y curl +RUN apt-get update && apt-get install gcc curl -y RUN curl -sSL https://install.python-poetry.org | python3 - # # Add Poetry to PATH ENV PATH="${PATH}:/root/.local/bin" diff --git a/docker-compose.yml b/docker-compose.yml index c7aa27a65..d9ba84030 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,12 +15,12 @@ services: build: context: ./src/frontend dockerfile: ./dev.Dockerfile + args: + - BACKEND_URL=http://backend:7860 ports: - "3000:3000" volumes: - - ./src/frontend:/app - # Set process.env.BACKEND to the backend service - environment: - - BACKEND_HOST="http://backend" - - BACKEND_PORT="7860" - restart: on-failure + - ./src/frontend/public:/home/node/app/public + - ./src/frontend/src:/home/node/app/src + - ./src/frontend/package.json:/home/node/app/package.json + restart: on-failure \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index fd7eeb17e..b989234e1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -594,19 +594,19 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] [[package]] name = "fastapi" -version = "0.91.0" +version = "0.92.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "fastapi-0.91.0-py3-none-any.whl", hash = "sha256:8dc18f860755159b3c4b30577c61c821b98f382acfeb6d5a849f9fa6a5369789"}, - {file = "fastapi-0.91.0.tar.gz", hash = "sha256:ff2fa93af3f2f982b07b5f96e8512565b3ef0e5f8f02469dbfd6bc27f6fd9a9e"}, + {file = "fastapi-0.92.0-py3-none-any.whl", hash = "sha256:ae7b97c778e2f2ec3fb3cb4fb14162129411d99907fb71920f6d69a524340ebf"}, + {file = "fastapi-0.92.0.tar.gz", hash = "sha256:023a0f5bd2c8b2609014d3bba1e14a1d7df96c6abea0a73070621c9862b9a4de"}, ] [package.dependencies] pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" -starlette = ">=0.24.0,<0.25.0" +starlette = ">=0.25.0,<0.26.0" [package.extras] all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] @@ -950,14 +950,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.0.0" +version = "6.1.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"}, - {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"}, + {file = "importlib_metadata-6.1.0-py3-none-any.whl", hash = "sha256:ff80f3b5394912eb1b108fcfd444dc78b7f1f3e16b16188054bd01cb9cb86f09"}, + {file = "importlib_metadata-6.1.0.tar.gz", hash = "sha256:43ce9281e097583d758c2c708c4376371261a02c34682491a8e98352365aad20"}, ] [package.dependencies] @@ -1378,13 +1378,14 @@ files = [ [[package]] name = "openai" -version = "0.26.5" +version = "0.27.2" description = "Python client library for the OpenAI API" category = "main" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-0.26.5.tar.gz", hash = "sha256:2882a59c67ae33c2716a04389a6e6680d061f073424953732f917fde219addfd"}, + {file = "openai-0.27.2-py3-none-any.whl", hash = "sha256:6df674cf257e9e0504f1fd191c333d3f6a2442b13218d0eccf06230eb24d320e"}, + {file = "openai-0.27.2.tar.gz", hash = "sha256:5869fdfa34b0ec66c39afa22f4a0fb83a135dff81f6505f52834c6ab3113f762"}, ] [package.dependencies] @@ -1395,7 +1396,7 @@ tqdm = "*" [package.extras] datalib = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] dev = ["black (>=21.6b0,<22.0)", "pytest (>=6.0.0,<7.0.0)", "pytest-asyncio", "pytest-mock"] -embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "sklearn", "tenacity (>=8.0.1)"] +embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "scipy", "tenacity (>=8.0.1)"] wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "wandb"] [[package]] @@ -1993,53 +1994,53 @@ files = [ [[package]] name = "sqlalchemy" -version = "1.4.46" +version = "1.4.47" description = "Database Abstraction Library" category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "SQLAlchemy-1.4.46-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:7001f16a9a8e06488c3c7154827c48455d1c1507d7228d43e781afbc8ceccf6d"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c7a46639ba058d320c9f53a81db38119a74b8a7a1884df44d09fbe807d028aaf"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27m-win32.whl", hash = "sha256:c04144a24103135ea0315d459431ac196fe96f55d3213bfd6d39d0247775c854"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27m-win_amd64.whl", hash = "sha256:7b81b1030c42b003fc10ddd17825571603117f848814a344d305262d370e7c34"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:939f9a018d2ad04036746e15d119c0428b1e557470361aa798e6e7d7f5875be0"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b7f4b6aa6e87991ec7ce0e769689a977776db6704947e562102431474799a857"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbf17ac9a61e7a3f1c7ca47237aac93cabd7f08ad92ac5b96d6f8dea4287fc1"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7f8267682eb41a0584cf66d8a697fef64b53281d01c93a503e1344197f2e01fe"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64cb0ad8a190bc22d2112001cfecdec45baffdf41871de777239da6a28ed74b6"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-win32.whl", hash = "sha256:5f752676fc126edc1c4af0ec2e4d2adca48ddfae5de46bb40adbd3f903eb2120"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-win_amd64.whl", hash = "sha256:31de1e2c45e67a5ec1ecca6ec26aefc299dd5151e355eb5199cd9516b57340be"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d68e1762997bfebf9e5cf2a9fd0bcf9ca2fdd8136ce7b24bbd3bbfa4328f3e4a"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d112b0f3c1bc5ff70554a97344625ef621c1bfe02a73c5d97cac91f8cd7a41e"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69fac0a7054d86b997af12dc23f581cf0b25fb1c7d1fed43257dee3af32d3d6d"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-win32.whl", hash = "sha256:887865924c3d6e9a473dc82b70977395301533b3030d0f020c38fd9eba5419f2"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-win_amd64.whl", hash = "sha256:984ee13543a346324319a1fb72b698e521506f6f22dc37d7752a329e9cd00a32"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:9167d4227b56591a4cc5524f1b79ccd7ea994f36e4c648ab42ca995d28ebbb96"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d61e9ecc849d8d44d7f80894ecff4abe347136e9d926560b818f6243409f3c86"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3ec187acf85984263299a3f15c34a6c0671f83565d86d10f43ace49881a82718"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9883f5fae4fd8e3f875adc2add69f8b945625811689a6c65866a35ee9c0aea23"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-win32.whl", hash = "sha256:535377e9b10aff5a045e3d9ada8a62d02058b422c0504ebdcf07930599890eb0"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-win_amd64.whl", hash = "sha256:18cafdb27834fa03569d29f571df7115812a0e59fd6a3a03ccb0d33678ec8420"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:a1ad90c97029cc3ab4ffd57443a20fac21d2ec3c89532b084b073b3feb5abff3"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4847f4b1d822754e35707db913396a29d874ee77b9c3c3ef3f04d5a9a6209618"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5a99282848b6cae0056b85da17392a26b2d39178394fc25700bcf967e06e97a"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4b1cc7835b39835c75cf7c20c926b42e97d074147c902a9ebb7cf2c840dc4e2"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-win32.whl", hash = "sha256:c522e496f9b9b70296a7675272ec21937ccfc15da664b74b9f58d98a641ce1b6"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-win_amd64.whl", hash = "sha256:ae067ab639fa499f67ded52f5bc8e084f045d10b5ac7bb928ae4ca2b6c0429a5"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e3c1808008124850115a3f7e793a975cfa5c8a26ceeeb9ff9cbb4485cac556df"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d164df3d83d204c69f840da30b292ac7dc54285096c6171245b8d7807185aa"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b33ffbdbbf5446cf36cd4cc530c9d9905d3c2fe56ed09e25c22c850cdb9fac92"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d94682732d1a0def5672471ba42a29ff5e21bb0aae0afa00bb10796fc1e28dd"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-win32.whl", hash = "sha256:f8cb80fe8d14307e4124f6fad64dfd87ab749c9d275f82b8b4ec84c84ecebdbe"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-win_amd64.whl", hash = "sha256:07e48cbcdda6b8bc7a59d6728bd3f5f574ffe03f2c9fb384239f3789c2d95c2e"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1b1e5e96e2789d89f023d080bee432e2fef64d95857969e70d3cadec80bd26f0"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3714e5b33226131ac0da60d18995a102a17dddd42368b7bdd206737297823ad"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:955162ad1a931fe416eded6bb144ba891ccbf9b2e49dc7ded39274dd9c5affc5"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6e4cb5c63f705c9d546a054c60d326cbde7421421e2d2565ce3e2eee4e1a01f"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-win32.whl", hash = "sha256:51e1ba2884c6a2b8e19109dc08c71c49530006c1084156ecadfaadf5f9b8b053"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-win_amd64.whl", hash = "sha256:315676344e3558f1f80d02535f410e80ea4e8fddba31ec78fe390eff5fb8f466"}, - {file = "SQLAlchemy-1.4.46.tar.gz", hash = "sha256:6913b8247d8a292ef8315162a51931e2b40ce91681f1b6f18f697045200c4a30"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:dcfb480bfc9e1fab726003ae00a6bfc67a29bad275b63a4e36d17fe7f13a624e"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:28fda5a69d6182589892422c5a9b02a8fd1125787aab1d83f1392aa955bf8d0a"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-win32.whl", hash = "sha256:45e799c1a41822eba6bee4e59b0e38764e1a1ee69873ab2889079865e9ea0e23"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-win_amd64.whl", hash = "sha256:10edbb92a9ef611f01b086e271a9f6c1c3e5157c3b0c5ff62310fb2187acbd4a"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7a4df53472c9030a8ddb1cce517757ba38a7a25699bbcabd57dcc8a5d53f324e"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:511d4abc823152dec49461209607bbfb2df60033c8c88a3f7c93293b8ecbb13d"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbe57f39f531c5d68d5594ea4613daa60aba33bb51a8cc42f96f17bbd6305e8d"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ca8ab6748e3ec66afccd8b23ec2f92787a58d5353ce9624dccd770427ee67c82"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299b5c5c060b9fbe51808d0d40d8475f7b3873317640b9b7617c7f988cf59fda"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-win32.whl", hash = "sha256:684e5c773222781775c7f77231f412633d8af22493bf35b7fa1029fdf8066d10"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-win_amd64.whl", hash = "sha256:2bba39b12b879c7b35cde18b6e14119c5f1a16bd064a48dd2ac62d21366a5e17"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:795b5b9db573d3ed61fae74285d57d396829e3157642794d3a8f72ec2a5c719b"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:989c62b96596b7938cbc032e39431e6c2d81b635034571d6a43a13920852fb65"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3b67bda733da1dcdccaf354e71ef01b46db483a4f6236450d3f9a61efdba35a"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-win32.whl", hash = "sha256:9a198f690ac12a3a807e03a5a45df6a30cd215935f237a46f4248faed62e69c8"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-win_amd64.whl", hash = "sha256:03be6f3cb66e69fb3a09b5ea89d77e4bc942f3bf84b207dba84666a26799c166"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:16ee6fea316790980779268da47a9260d5dd665c96f225d28e7750b0bb2e2a04"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:557675e0befafa08d36d7a9284e8761c97490a248474d778373fb96b0d7fd8de"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb2797fee8a7914fb2c3dc7de404d3f96eb77f20fc60e9ee38dc6b0ca720f2c2"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28297aa29e035f29cba6b16aacd3680fbc6a9db682258d5f2e7b49ec215dbe40"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-win32.whl", hash = "sha256:998e782c8d9fd57fa8704d149ccd52acf03db30d7dd76f467fd21c1c21b414fa"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-win_amd64.whl", hash = "sha256:dde4d02213f1deb49eaaf8be8a6425948963a7af84983b3f22772c63826944de"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e98ef1babe34f37f443b7211cd3ee004d9577a19766e2dbacf62fce73c76245a"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14a3879853208a242b5913f3a17c6ac0eae9dc210ff99c8f10b19d4a1ed8ed9b"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7120a2f72599d4fed7c001fa1cbbc5b4d14929436135768050e284f53e9fbe5e"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:048509d7f3ac27b83ad82fd96a1ab90a34c8e906e4e09c8d677fc531d12c23c5"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-win32.whl", hash = "sha256:6572d7c96c2e3e126d0bb27bfb1d7e2a195b68d951fcc64c146b94f088e5421a"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-win_amd64.whl", hash = "sha256:a6c3929df5eeaf3867724003d5c19fed3f0c290f3edc7911616616684f200ecf"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:71d4bf7768169c4502f6c2b0709a02a33703544f611810fb0c75406a9c576ee1"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd45c60cc4f6d68c30d5179e2c2c8098f7112983532897566bb69c47d87127d3"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fdbb8e9d4e9003f332a93d6a37bca48ba8095086c97a89826a136d8eddfc455"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f216a51451a0a0466e082e163591f6dcb2f9ec182adb3f1f4b1fd3688c7582c"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-win32.whl", hash = "sha256:bd988b3362d7e586ef581eb14771bbb48793a4edb6fcf62da75d3f0f3447060b"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-win_amd64.whl", hash = "sha256:32ab09f2863e3de51529aa84ff0e4fe89a2cb1bfbc11e225b6dbc60814e44c94"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:07764b240645627bc3e82596435bd1a1884646bfc0721642d24c26b12f1df194"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e2a42017984099ef6f56438a6b898ce0538f6fadddaa902870c5aa3e1d82583"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b6d807c76c20b4bc143a49ad47782228a2ac98bdcdcb069da54280e138847fc"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a94632ba26a666e7be0a7d7cc3f7acab622a04259a3aa0ee50ff6d44ba9df0d"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-win32.whl", hash = "sha256:f80915681ea9001f19b65aee715115f2ad310730c8043127cf3e19b3009892dd"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-win_amd64.whl", hash = "sha256:fc700b862e0a859a37faf85367e205e7acaecae5a098794aff52fdd8aea77b12"}, + {file = "SQLAlchemy-1.4.47.tar.gz", hash = "sha256:95fc02f7fc1f3199aaa47a8a757437134cf618e9d994c84effd53f530c38586f"}, ] [package.dependencies] @@ -2088,14 +2089,14 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "starlette" -version = "0.24.0" +version = "0.25.0" description = "The little ASGI library that shines." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "starlette-0.24.0-py3-none-any.whl", hash = "sha256:75e2b24d71ff4f7cb9a3338f83d234c2d4135bf80f52aeb105c02a01d72a5df1"}, - {file = "starlette-0.24.0.tar.gz", hash = "sha256:7925947f177a19e906c6ace10f07c64c4f9fdf7d509caaac6589f7cc0cfd95f3"}, + {file = "starlette-0.25.0-py3-none-any.whl", hash = "sha256:774f1df1983fd594b9b6fb3ded39c2aa1979d10ac45caac0f4255cbe2acb8628"}, + {file = "starlette-0.25.0.tar.gz", hash = "sha256:854c71e73736c429c2bdb07801f2c76c9cba497e7c3cf4988fde5e95fe4cdb3c"}, ] [package.dependencies] @@ -2406,4 +2407,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "de85751ffee58e67b57ed3fedd5ec3115a65c8fdb0fcd1e904d96ecb3ce2b803" +content-hash = "ebc0a8ca9ea284d8e986306a10f13ff91e7e8aae18341c83329f5b1e1bcc66bd" diff --git a/pyproject.toml b/pyproject.toml index a202a22cc..239ab37a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "0.0.40" +version = "0.0.44" description = "A Python package with a built-in web application" authors = ["Logspace "] packages = [ @@ -15,8 +15,7 @@ langflow = "langflow.__main__:main" [tool.poetry.dependencies] python = "^3.9" -openai = "^0.26.5" -fastapi = "^0.91.0" +fastapi = "^0.92.0" uvicorn = "^0.20.0" beautifulsoup4 = "^4.11.2" google-search-results = "^2.4.1" @@ -24,6 +23,7 @@ google-api-python-client = "^2.79.0" typer = "^0.7.0" gunicorn = "^20.1.0" langchain = "^0.0.113" +openai = "^0.27.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 c93de7667..cf2a2f8a0 100644 --- a/src/backend/langflow/__main__.py +++ b/src/backend/langflow/__main__.py @@ -7,6 +7,9 @@ from langflow.main import create_app import typer from fastapi.staticfiles import StaticFiles from pathlib import Path +import logging + +logger = logging.getLogger(__name__) def get_number_of_workers(workers=None): @@ -23,7 +26,14 @@ def replace_port(static_files_dir, host, port): # we need to set the base url to the port that the server is running on # so that the frontend can make requests to the backend # This is a hacky way to do it, but it works - new_string = f'setItem("port","http://{host}:{port}")' + + # Check if the host is http or https + logger.info(f"host: {host}") + logger.info(f"port: {port}") + url = f"{host}:{port}" if "http" in host else f"http://{host}:{port}" + logger.info(f"url: {url}") + new_string = f'setItem("port","{url}")' + with open(static_files_dir / "index.html", "r") as f: index_html = f.read() # using regex to replace the port diff --git a/src/backend/langflow/interface/custom_lists.py b/src/backend/langflow/interface/custom_lists.py new file mode 100644 index 000000000..10f0e9e53 --- /dev/null +++ b/src/backend/langflow/interface/custom_lists.py @@ -0,0 +1,6 @@ +from langchain import llms +from langchain.llms.openai import OpenAIChat + + +llm_type_to_cls_dict = llms.type_to_cls_dict +llm_type_to_cls_dict["openai-chat"] = OpenAIChat diff --git a/src/backend/langflow/interface/listing.py b/src/backend/langflow/interface/listing.py index 9d2c99b91..1df2d25e7 100644 --- a/src/backend/langflow/interface/listing.py +++ b/src/backend/langflow/interface/listing.py @@ -1,4 +1,5 @@ -from langchain import chains, agents, prompts, llms +from langchain import chains, agents, prompts +from langflow.interface.custom_lists import llm_type_to_cls_dict from langflow.custom import customs from langflow.utils import util, allowed_components from langchain.agents.load_tools import get_all_tool_names @@ -55,7 +56,7 @@ def list_llms(): """List all llm types""" return [ llm.__name__ - for llm in llms.type_to_cls_dict.values() + for llm in llm_type_to_cls_dict.values() if llm.__name__ in allowed_components.LLMS ] diff --git a/src/backend/langflow/interface/signature.py b/src/backend/langflow/interface/signature.py index 89a10a0f7..baa2956dc 100644 --- a/src/backend/langflow/interface/signature.py +++ b/src/backend/langflow/interface/signature.py @@ -1,5 +1,6 @@ from typing import Dict, Any # noqa: F401 -from langchain import agents, chains, llms, prompts +from langchain import agents, chains, prompts +from langflow.interface.custom_lists import llm_type_to_cls_dict from langchain.agents.load_tools import ( _BASE_TOOLS, _EXTRA_LLM_TOOLS, @@ -56,7 +57,7 @@ def get_prompt_signature(name: str): def get_llm_signature(name: str): """Get the signature of an llm.""" try: - return util.build_template_from_class(name, llms.type_to_cls_dict) + return util.build_template_from_class(name, llm_type_to_cls_dict) except ValueError as exc: raise ValueError("LLM not found") from exc diff --git a/src/backend/langflow/utils/allowed_components.py b/src/backend/langflow/utils/allowed_components.py index 6e2ac1bc6..f304a3d15 100644 --- a/src/backend/langflow/utils/allowed_components.py +++ b/src/backend/langflow/utils/allowed_components.py @@ -4,6 +4,6 @@ AGENTS = ["ZeroShotAgent"] PROMPTS = ["PromptTemplate", "FewShotPromptTemplate"] -LLMS = ["OpenAI"] +LLMS = ["OpenAI", "OpenAIChat"] TOOLS = ["Search", "PAL-MATH", "Calculator", "Serper Search"] diff --git a/src/backend/langflow/utils/util.py b/src/backend/langflow/utils/util.py index d023fbc3e..5d13e931d 100644 --- a/src/backend/langflow/utils/util.py +++ b/src/backend/langflow/utils/util.py @@ -297,6 +297,8 @@ def format_dict(d, name: Optional[str] = None): # Add options to openai if name == "OpenAI" and key == "model_name": value["options"] = ["text-davinci-003", "text-davinci-002"] + elif name == "OpenAIChat" and key == "model_name": + value["options"] = ["gpt-3.5-turbo", "gpt-4"] return d diff --git a/src/frontend/dev.Dockerfile b/src/frontend/dev.Dockerfile index 90766088c..df5f7f5dc 100644 --- a/src/frontend/dev.Dockerfile +++ b/src/frontend/dev.Dockerfile @@ -1,6 +1,23 @@ -FROM node:19-alpine as frontend_build -ARG BACKEND -WORKDIR /app -COPY . /app -RUN npm install +#baseline +FROM node:19-bullseye-slim AS base +RUN mkdir -p /home/node/app +RUN chown -R node:node /home/node && chmod -R 770 /home/node +RUN apt-get update && apt-get install -y jq +WORKDIR /home/node/app + +# client build +FROM base AS builder-client +ARG BACKEND_URL +ENV BACKEND_URL $BACKEND_URL +RUN echo "BACKEND_URL: $BACKEND_URL" + +WORKDIR /home/node/app +COPY --chown=node:node . ./ + +COPY ./set_proxy.sh . +RUN chmod +x set_proxy.sh && ./set_proxy.sh + +USER node + +RUN npm install --loglevel warn CMD ["npm", "start"] \ No newline at end of file diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index a3bd7c1d9..dffaa4665 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "langflow", - "version": "0.1.1", + "version": "0.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "langflow", - "version": "0.1.1", + "version": "0.1.2", "dependencies": { "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", @@ -17080,9 +17080,9 @@ } }, "node_modules/webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "version": "5.76.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.2.tgz", + "integrity": "sha512-Th05ggRm23rVzEOlX8y67NkYCHa9nTNcwHPBhdg+lKG+mtiW7XgggjAeeLnADAe7mLjJ6LUNfgHAuRRh+Z6J7w==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", diff --git a/src/frontend/package.json b/src/frontend/package.json index 494db2ed3..01be61167 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -1,6 +1,6 @@ { "name": "langflow", - "version": "0.1.1", + "version": "0.1.2", "private": true, "dependencies": { "@emotion/react": "^11.10.5", @@ -53,5 +53,6 @@ "last 1 firefox version", "last 1 safari version" ] - } + }, + "proxy": "http://localhost:7860" } \ No newline at end of file diff --git a/src/frontend/public/index.html b/src/frontend/public/index.html index c1953d6b8..1aa066669 100644 --- a/src/frontend/public/index.html +++ b/src/frontend/public/index.html @@ -14,4 +14,4 @@
- \ No newline at end of file + diff --git a/src/frontend/set_proxy.sh b/src/frontend/set_proxy.sh new file mode 100755 index 000000000..e9ad9f109 --- /dev/null +++ b/src/frontend/set_proxy.sh @@ -0,0 +1,10 @@ +#! /bin/bash +# Edit package.json to set proxy +backend_url=$BACKEND_URL +echo "Setting proxy to $backend_url" +# Load package.json file and edit proxy +packagejson=$(cat package.json) + +packagejson=$(echo "$packagejson" | jq ".proxy = \"$backend_url\"") + +echo "$packagejson" > package.json diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 0ae55a4ea..c1a6d5f5f 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -39,7 +39,6 @@ export default function ParameterComponent({ const [enabled, setEnabled] = useState( data.node.template[name]?.value ?? false ); - console.log(data.node.template[name]); const { reactFlowInstance } = useContext(typesContext); let disabled = reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false; diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 8e0773681..acbdde477 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -80,8 +80,8 @@ export default function GenericNode({ data, selected}:{data:NodeDataType,selecte data={data} color={nodeColors[types[data.type]]} title={data.type} - tooltipTitle={"Type: str"} - id={data.type + "|" + data.id + data.node.base_classes.map((b) => ("|" + b))} + tooltipTitle={`Type: ${data.node.base_classes.join(' | ')}`} + id={[data.type, data.id, ...data.node.base_classes].join('|')} type={'str'} left={false} /> diff --git a/src/frontend/src/alerts/alertDropDown/components/singleAlertComponent/index.tsx b/src/frontend/src/alerts/alertDropDown/components/singleAlertComponent/index.tsx index 61965929d..576dfb0b8 100644 --- a/src/frontend/src/alerts/alertDropDown/components/singleAlertComponent/index.tsx +++ b/src/frontend/src/alerts/alertDropDown/components/singleAlertComponent/index.tsx @@ -7,7 +7,6 @@ import { SingleAlertComponentType } from "../../../../types/alerts"; export default function SingleAlert({ dropItem, removeAlert}:SingleAlertComponentType) { const [show, setShow] = useState(true); const type = dropItem.type; - console.log(dropItem.id) return ( { let newChat = _.cloneDeep(old); if(JSON.stringify(flow.chat) !==JSON.stringify(old)){ - console.log(old,flow.chat) tabsChange = true return old } @@ -43,7 +42,6 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) { return newChat; }); if(tabsChange){ - console.log(flow.chat) if(thought){ updateFlow({..._.cloneDeep(flow),chat:[...flow.chat,{isSend,message,thought}]}) } @@ -98,11 +96,9 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) { let message = chatValue; setChatValue(""); addChatHistory(message, true); - console.log({ ...reactFlowInstance.toObject(), message, chatHistory }); sendAll({ ...reactFlowInstance.toObject(), message, chatHistory}) .then((r) => { - console.log(r.data); addChatHistory(r.data.result, false, r.data.thought); setLockChat(false); }) diff --git a/src/frontend/src/controllers/NodesServices/index.ts b/src/frontend/src/controllers/NodesServices/index.ts index 40e98821c..f0257ea00 100644 --- a/src/frontend/src/controllers/NodesServices/index.ts +++ b/src/frontend/src/controllers/NodesServices/index.ts @@ -1,13 +1,10 @@ import { APIObjectType, sendAllProps } from '../../types/api/index'; import axios, { AxiosResponse } from "axios"; -const backendUrl = window.sessionStorage.getItem('port') || "http://localhost:7860"; - export async function getAll():Promise> { - return await axios.get(`${backendUrl}/all`); + return await axios.get(`/all`); } export async function sendAll(data:sendAllProps) { - console.log(data); - return await axios.post(`${backendUrl}/predict`, data); + return await axios.post(`/predict`, data); } \ No newline at end of file diff --git a/src/frontend/src/pages/FlowPage/components/tabsManagerComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/tabsManagerComponent/index.tsx index 6b2e05b08..6396b753f 100644 --- a/src/frontend/src/pages/FlowPage/components/tabsManagerComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/tabsManagerComponent/index.tsx @@ -4,17 +4,24 @@ import TabComponent from "../tabComponent"; import { TabsContext } from "../../../../contexts/tabsContext"; import FlowPage from "../.."; import { darkContext } from "../../../../contexts/darkContext"; -import { BellIcon, MoonIcon, SunIcon } from "@heroicons/react/24/outline"; +import { + ArrowDownTrayIcon, + ArrowUpTrayIcon, + BellIcon, + MoonIcon, + SunIcon, +} from "@heroicons/react/24/outline"; import { PopUpContext } from "../../../../contexts/popUpContext"; import AlertDropdown from "../../../../alerts/alertDropDown"; import { alertContext } from "../../../../contexts/alertContext"; export default function TabsManagerComponent() { - const { flows, addFlow, tabIndex, setTabIndex } = useContext(TabsContext); + const { flows, addFlow, tabIndex, setTabIndex, uploadFlow, downloadFlow } = useContext(TabsContext); const { openPopUp } = useContext(PopUpContext); - const AlertWidth = 256 + const AlertWidth = 256; const { dark, setDark } = useContext(darkContext); - const {notificationCenter, setNotificationCenter} = useContext(alertContext) + const { notificationCenter, setNotificationCenter } = + useContext(alertContext); useEffect(() => { //create the first flow if (flows.length === 0) { @@ -43,6 +50,12 @@ export default function TabsManagerComponent() { flow={null} />
+ +
diff --git a/src/frontend/src/pages/FlowPage/index.tsx b/src/frontend/src/pages/FlowPage/index.tsx index 2cf11574f..6471621af 100644 --- a/src/frontend/src/pages/FlowPage/index.tsx +++ b/src/frontend/src/pages/FlowPage/index.tsx @@ -182,17 +182,6 @@ export default function FlowPage({ flow }:{flow:FlowType}) { > - uploadFlow()} - > - - - - downloadFlow()} - > - -