Merge remote-tracking branch 'origin/dev' into fix/minor_bugs

This commit is contained in:
Lucas Oliveira 2024-05-31 20:55:38 -03:00
commit 81f61201be
435 changed files with 9714 additions and 13063 deletions

View file

@ -1,7 +0,0 @@
.venv/
**/aws
node_modules
**/node_modules/
dist/
**/build/
src/backend/langflow/frontend

View file

@ -77,7 +77,12 @@ runs:
POETRY_VERSION: ${{ inputs.poetry-version }}
PYTHON_VERSION: ${{ inputs.python-version }}
# Install poetry using the python version installed by setup-python step.
run: pipx install "poetry==$POETRY_VERSION" --python '${{ steps.setup-python.outputs.python-path }}' --verbose
run: |
pipx install "poetry==$POETRY_VERSION" --python '${{ steps.setup-python.outputs.python-path }}' --verbose
pipx ensurepath
# Ensure the poetry binary is available in the PATH.
# Test that the poetry binary is available.
poetry --version
- name: Restore pip and poetry cached dependencies
uses: actions/cache@v4

64
.github/workflows/create-release.yml vendored Normal file
View file

@ -0,0 +1,64 @@
name: Create Release
on:
workflow_dispatch:
inputs:
version:
description: "Version to release"
required: true
type: string
release_type:
description: "Type of release (base or main)"
required: true
type: choice
options:
- base
- main
env:
POETRY_VERSION: "1.8.2"
jobs:
release:
name: Build Langflow
runs-on: ubuntu-latest
outputs:
version: ${{ steps.check-version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Install poetry
run: pipx install poetry==$POETRY_VERSION
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "poetry"
- name: Build project for distribution
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
make build base=true
else
make build main=true
fi
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: dist${{ inputs.release_type }}
path: ${{ inputs.release_type == 'base' && 'src/backend/base/dist' || 'dist' }}
create_release:
name: Create Release Job
runs-on: ubuntu-latest
needs: release
steps:
- uses: actions/download-artifact@v4
with:
name: dist${{ inputs.release_type }}
path: dist
- name: Create Release Notes
uses: ncipollo/release-action@v1
with:
artifacts: "dist/*"
token: ${{ secrets.GITHUB_TOKEN }}
draft: false
generateReleaseNotes: true
prerelease: true
tag: v${{ inputs.version }}
commit: dev

63
.github/workflows/docker-build.yml vendored Normal file
View file

@ -0,0 +1,63 @@
name: Docker Build and Push
on:
workflow_call:
inputs:
version:
required: true
type: string
release_type:
required: true
type: string
workflow_dispatch:
inputs:
version:
required: true
type: string
release_type:
required: true
type: choice
options:
- base
- main
jobs:
docker_build:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set Dockerfile and Tags
id: set-vars
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
echo "DOCKERFILE=./docker/build_and_push_base.Dockerfile" >> $GITHUB_ENV
echo "TAGS=langflowai/langflow:base-${{ inputs.version }}" >> $GITHUB_ENV
else
echo "DOCKERFILE=./docker/build_and_push.Dockerfile" >> $GITHUB_ENV
echo "TAGS=langflowai/langflow:${{ inputs.version }},langflowai/langflow:1.0-alpha" >> $GITHUB_ENV
fi
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
file: ${{ env.DOCKERFILE }}
tags: ${{ env.TAGS }}
- name: Wait for Docker Hub to propagate
run: sleep 120
- name: Restart HuggingFace Spaces Build
# There's a script in ./scripts/factory_reset_space.py that will reset the build
# using the HUGGINGFACE_API_TOKEN secret
run: |
python ./scripts/factory_restart_space.py
env:
HUGGINGFACE_API_TOKEN: ${{ secrets.HUGGINGFACE_API_TOKEN }}

View file

@ -72,6 +72,6 @@ jobs:
with:
context: .
push: true
file: ./build_and_push_base.Dockerfile
file: ./docker/build_and_push_base.Dockerfile
tags: |
langflowai/langflow:base-${{ needs.release.outputs.version }}

View file

@ -78,7 +78,7 @@ jobs:
with:
context: .
push: true
file: ./build_and_push.Dockerfile
file: ./docker/build_and_push.Dockerfile
tags: |
langflowai/langflow:${{ needs.release.outputs.version }}
langflowai/langflow:1.0-alpha

104
.github/workflows/pre-release.yml vendored Normal file
View file

@ -0,0 +1,104 @@
name: Langflow Pre-release (Unified)
run-name: Langflow (${{inputs.release_type}}) Pre-release by @${{ github.actor }}
on:
workflow_dispatch:
inputs:
release_package:
description: "Release package"
required: true
type: boolean
default: false
release_type:
description: "Type of release (base or main)"
required: true
type: choice
options:
- base
- main
env:
POETRY_VERSION: "1.8.2"
jobs:
release:
name: Release Langflow
if: inputs.release_package == true
runs-on: ubuntu-latest
outputs:
version: ${{ steps.check-version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Install poetry
run: pipx install poetry==$POETRY_VERSION
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "poetry"
- name: Check Version
id: check-version
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
version=$(cd src/backend/base && poetry version --short)
last_released_version=$(curl -s "https://pypi.org/pypi/langflow-base/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
else
version=$(poetry version --short)
last_released_version=$(curl -s "https://pypi.org/pypi/langflow/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
fi
if [ "$version" = "$last_released_version" ]; then
echo "Version $version is already released. Skipping release."
exit 1
else
echo version=$version >> $GITHUB_OUTPUT
fi
- name: Build project for distribution
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
make build base=true
else
make build main=true
fi
- name: Publish to PyPI
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
make publish base=true
else
make publish main=true
fi
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: dist${{ inputs.release_type }}
path: ${{ inputs.release_type == 'base' && 'src/backend/base/dist' || 'dist' }}
call_docker_build:
name: Call Docker Build Workflow
needs: release
uses: langflow-ai/langflow/.github/workflows/docker-build.yml@dev
with:
version: ${{ needs.release.outputs.version }}
release_type: ${{ inputs.release_type }}
secrets: inherit
create_release:
name: Create Release
runs-on: ubuntu-latest
needs: [release]
if: ${{ inputs.release_type == 'main' }}
steps:
- uses: actions/download-artifact@v4
with:
name: dist${{ inputs.release_type }}
path: dist
- name: Create Release
uses: ncipollo/release-action@v1
with:
artifacts: "dist/*"
token: ${{ secrets.GITHUB_TOKEN }}
draft: false
generateReleaseNotes: true
prerelease: true
tag: v${{ needs.release.outputs.version }}
commit: dev

View file

@ -50,7 +50,7 @@ jobs:
with:
context: .
push: true
file: ./build_and_push.Dockerfile
file: ./docker/build_and_push.Dockerfile
tags: |
langflowai/langflow:${{ steps.check-version.outputs.version }}
langflowai/langflow:latest

View file

@ -19,8 +19,8 @@ jobs:
strategy:
fail-fast: false
matrix:
shardIndex: [1]
shardTotal: [1]
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- name: Checkout code
uses: actions/checkout@v4
@ -30,7 +30,15 @@ jobs:
id: setup-node
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Cache Node.js dependencies
uses: actions/cache@v4
id: npm-cache
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Node.js dependencies
run: |
@ -80,7 +88,7 @@ jobs:
- name: Run Playwright Tests
run: |
cd src/frontend
npx playwright test
npx playwright test --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2
- name: Upload blob report to GitHub Actions Artifacts
if: always()

View file

@ -18,17 +18,13 @@ repos:
hooks:
- id: check-case-conflict
- id: end-of-file-fixer
# python, js and ts only
files: \.(py|js|ts)$
- id: mixed-line-ending
files: \.(py|js|ts)$
args:
- --fix=lf
- id: trailing-whitespace
- id: pretty-format-json
exclude: ^tsconfig.*.json
args:
- --autofix
- --indent=4
- --no-sort-keys
- id: check-merge-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.2

View file

@ -1,31 +0,0 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# You can also specify other tool versions:
# nodejs: "19"
# rust: "1.64"
# golang: "1.19"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/conf.py
# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
# python:
# install:
# - requirements: docs/requirements.txt

103
README.md
View file

@ -1,21 +1,49 @@
<!-- markdownlint-disable MD030 -->
# [![Langflow](https://github.com/langflow-ai/langflow/blob/dev/docs/static/img/hero.png)](https://www.langflow.org)
# [![Langflow](./docs/static/img/hero.png)](https://www.langflow.org)
### [Langflow](https://www.langflow.org) is a new, visual way to build, iterate and deploy AI apps.
<p align="center"><strong>
A visual framework for building multi-agent and RAG applications
</strong></p>
<p align="center" style="font-size: 12px;">
Open-source, Python-powered, fully customizable, LLM and vector store agnostic
</p>
# ⚡️ Documentation and Community
<p align="center" style="font-size: 12px;">
<a href="https://docs.langflow.org" style="text-decoration: underline;">Docs</a> -
<a href="https://discord.com/invite/EqksyE2EX9" style="text-decoration: underline;">Join our Discord</a> -
<a href="https://twitter.com/langflow_ai" style="text-decoration: underline;">Follow us on X</a> -
<a href="https://huggingface.co/spaces/Langflow/Langflow-Preview" style="text-decoration: underline;">Live demo</a>
</p>
- [Documentation](https://docs.langflow.org)
- [Discord](https://discord.com/invite/EqksyE2EX9)
<p align="center">
<a href="https://github.com/langflow-ai/langflow">
<img src="https://img.shields.io/github/stars/langflow-ai/langflow">
</a>
<a href="https://discord.com/invite/EqksyE2EX9">
<img src="https://img.shields.io/discord/1116803230643527710?label=Discord">
</a>
</p>
# 📦 Installation
<p align="center">
<img src="./docs/static/img/langflow_basic_howto.gif" alt="Your GIF" style="border: 3px solid #211C43;">
</p>
# 📝 Content
- [Get Started](#-get-started)
- [Create Flows](#-create-flows)
- [Deploy](#deploy)
- [Command Line Interface (CLI)](#-command-line-interface-cli)
- [Contribute](#-contribute)
# 📦 Get Started
You can install Langflow with pip:
```shell
# Make sure you have Python 3.10 installed on your system.
# Install the pre-release version
# Make sure you have >=Python 3.10 installed on your system.
# Install the pre-release version (recommended for the latest updates)
python -m pip install langflow --pre --force-reinstall
# or stable version
@ -28,9 +56,9 @@ Then, run Langflow with:
python -m langflow run
```
You can also preview Langflow in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview). [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true), to create your own Langflow workspace in minutes.
You can also preview Langflow in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview). [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
# 🎨 Creating Flows
# 🎨 Create Flows
Creating flows with Langflow is easy. Simply drag components from the sidebar onto the canvas and connect them to start building your application.
@ -46,6 +74,32 @@ from langflow.load import run_flow_from_json
results = run_flow_from_json("path/to/flow.json", input_value="Hello, World!")
```
# Deploy
## Deploy Langflow on Google Cloud Platform
Follow our step-by-step guide to deploy Langflow on Google Cloud Platform (GCP) using Google Cloud Shell. The guide is available in the [**Langflow in Google Cloud Platform**](https://github.com/langflow-ai/langflow/blob/dev/docs/docs/deployment/gcp-deployment.md) document.
Alternatively, click the **"Open in Cloud Shell"** button below to launch Google Cloud Shell, clone the Langflow repository, and start an **interactive tutorial** that will guide you through the process of setting up the necessary resources and deploying Langflow on your GCP project.
[![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.svg)](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/langflow-ai/langflow&working_dir=scripts/gcp&shellonly=true&tutorial=walkthroughtutorial_spot.md)
## Deploy on Railway
Use this template to deploy Langflow 1.0 Preview on Railway:
[![Deploy 1.0 Preview on Railway](https://railway.app/button.svg)](https://railway.app/template/UsJ1uB?referralCode=MnPSdg)
Or this one to deploy Langflow 0.6.x:
[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/JMXEWp?referralCode=MnPSdg)
## Deploy on Render
<a href="https://render.com/deploy?repo=https://github.com/langflow-ai/langflow/tree/main">
<img src="https://render.com/images/deploy-to-render-button.svg" alt="Deploy to Render" />
</a>
# 🖥️ Command Line Interface (CLI)
Langflow provides a command-line interface (CLI) for easy management and configuration.
@ -65,7 +119,6 @@ Each option is detailed below:
- `--workers`: Sets the number of worker processes. Can be set using the `LANGFLOW_WORKERS` environment variable. The default is `1`.
- `--timeout`: Sets the worker timeout in seconds. The default is `60`.
- `--port`: Sets the port to listen on. Can be set using the `LANGFLOW_PORT` environment variable. The default is `7860`.
- `--config`: Defines the path to the configuration file. The default is `config.yaml`.
- `--env-file`: Specifies the path to the .env file containing environment variables. The default is `.env`.
- `--log-level`: Defines the logging level. Can be set using the `LANGFLOW_LOG_LEVEL` environment variable. The default is `critical`.
- `--components-path`: Specifies the path to the directory containing custom components. Can be set using the `LANGFLOW_COMPONENTS_PATH` environment variable. The default is `langflow/components`.
@ -88,33 +141,7 @@ You can configure many of the CLI options using environment variables. These can
A sample `.env` file named `.env.example` is included with the project. Copy this file to a new file named `.env` and replace the example values with your actual settings. If you're setting values in both your OS and the `.env` file, the `.env` settings will take precedence.
# Deployment
## Deploy Langflow on Google Cloud Platform
Follow our step-by-step guide to deploy Langflow on Google Cloud Platform (GCP) using Google Cloud Shell. The guide is available in the [**Langflow in Google Cloud Platform**](GCP_DEPLOYMENT.md) document.
Alternatively, click the **"Open in Cloud Shell"** button below to launch Google Cloud Shell, clone the Langflow repository, and start an **interactive tutorial** that will guide you through the process of setting up the necessary resources and deploying Langflow on your GCP project.
[![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.svg)](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/langflow-ai/langflow&working_dir=scripts/gcp&shellonly=true&tutorial=walkthroughtutorial_spot.md)
## Deploy on Railway
Use this template to deploy Langflow 1.0 Preview on Railway:
[![Deploy 1.0 Preview on Railway](https://railway.app/button.svg)](https://railway.app/template/UsJ1uB?referralCode=MnPSdg)
Or this one to deploy Langflow 0.6.x:
[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/JMXEWp?referralCode=MnPSdg)
## Deploy on Render
<a href="https://render.com/deploy?repo=https://github.com/langflow-ai/langflow/tree/main">
<img src="https://render.com/images/deploy-to-render-button.svg" alt="Deploy to Render" />
</a>
# 👋 Contributing
# 👋 Contribute
We welcome contributions from developers of all levels to our open-source project on GitHub. If you'd like to contribute, please check our [contributing guidelines](./CONTRIBUTING.md) and help make Langflow more accessible.

View file

@ -1,99 +0,0 @@
# syntax=docker/dockerfile:1
# Keep this syntax directive! It's used to enable Docker BuildKit
# Based on https://github.com/python-poetry/poetry/discussions/1879?sort=top#discussioncomment-216865
# but I try to keep it updated (see history)
################################
# PYTHON-BASE
# Sets up all our shared environment variables
################################
FROM python:3.10-slim as python-base
# python
ENV PYTHONUNBUFFERED=1 \
# prevents python creating .pyc files
PYTHONDONTWRITEBYTECODE=1 \
\
# pip
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
\
# poetry
# https://python-poetry.org/docs/configuration/#using-environment-variables
POETRY_VERSION=1.8.2 \
# make poetry install to this location
POETRY_HOME="/opt/poetry" \
# make poetry create the virtual environment in the project's root
# it gets named `.venv`
POETRY_VIRTUALENVS_IN_PROJECT=true \
# do not ask any interactive question
POETRY_NO_INTERACTION=1 \
\
# paths
# this is where our requirements + virtual environment will live
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"
# prepend poetry and venv to path
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"
################################
# BUILDER-BASE
# Used to build deps + create our virtual environment
################################
FROM python-base as builder-base
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
# deps for installing poetry
curl \
# deps for building python deps
build-essential
# install poetry - respects $POETRY_VERSION & $POETRY_HOME
# The --mount will mount the buildx cache directory to where
# Poetry and Pip store their cache so that they can reuse it
RUN --mount=type=cache,target=/root/.cache \
curl -sSL https://install.python-poetry.org | python3 -
# copy project requirement files here to ensure they will be cached.
WORKDIR $PYSETUP_PATH
# Copy just one file to avoid rebuilding the whole image
COPY poetry.lock pyproject.toml ./
COPY ./src/backend/langflow ./src/backend/langflow
COPY ./src/backend/base/pyproject.toml ./src/backend/base/pyproject.toml
# Copy README.md to the build context
COPY README.md .
# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally
RUN --mount=type=cache,target=/root/.cache \
poetry install --without dev --extras deploy
################################
# DEVELOPMENT
# Image used during development / testing
################################
FROM python-base as development
WORKDIR $PYSETUP_PATH
# copy in our built poetry + venv
COPY --from=builder-base $POETRY_HOME $POETRY_HOME
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
# Copy just one file to avoid rebuilding the whole image
COPY ./src/backend/langflow ./src/backend/langflow
# quicker install as runtime deps are already installed
RUN --mount=type=cache,target=/root/.cache \
poetry install --with=dev --extras deploy
# copy in our app code
COPY ./src/backend ./src/backend
RUN --mount=type=cache,target=/root/.cache \
poetry install --with=dev --extras deploy
COPY ./tests ./tests=

View file

@ -1,33 +0,0 @@
version: "3.4"
services:
backend:
volumes:
- ./:/app
build:
context: ./
dockerfile: ./dev.Dockerfile
command:
[
"sh",
"-c",
"pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload --loop asyncio",
]
ports:
- 7860:7860
- 5678:5678
restart: on-failure
frontend:
build:
context: ./src/frontend
dockerfile: ./dev.Dockerfile
args:
- BACKEND_URL=http://backend:7860
ports:
- "3000:3000"
volumes:
- ./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

9
docker/.dockerignore Normal file
View file

@ -0,0 +1,9 @@
.venv/
**/aws
node_modules
**/node_modules/
dist/
**/build/
src/backend/langflow/frontend
**/langflow-pre.db
**/langflow.db

View file

@ -72,15 +72,21 @@ COPY Makefile ./
COPY README.md ./
RUN --mount=type=cache,target=/root/.cache \
curl -sSL https://install.python-poetry.org | python3 -
RUN useradd -m -u 1000 user && \
mkdir -p /app/langflow && \
chown -R user:user /app && \
chmod -R u+w /app/langflow
# Update PATH with home/user/.local/bin
ENV PATH="/home/user/.local/bin:${PATH}"
RUN python -m pip install requests && cd ./scripts && python update_dependencies.py
RUN $POETRY_HOME/bin/poetry lock
RUN $POETRY_HOME/bin/poetry build
# Copy virtual environment and built .tar.gz from builder base
RUN useradd -m -u 1000 user
USER user
# Install the package from the .tar.gz
RUN python -m pip install /app/dist/*.tar.gz
RUN python -m pip install /app/dist/*.tar.gz --user
ENTRYPOINT ["python", "-m", "langflow", "run"]
CMD ["--host", "0.0.0.0", "--port", "7860"]

View file

@ -78,13 +78,20 @@ RUN cd src/frontend && npm run build
COPY src/backend ./src/backend
RUN cp -r src/frontend/build src/backend/base/langflow/frontend
RUN rm -rf src/backend/base/dist
RUN useradd -m -u 1000 user && \
mkdir -p /app/langflow && \
chown -R user:user /app && \
chmod -R u+w /app/langflow
# Update PATH with home/user/.local/bin
ENV PATH="/home/user/.local/bin:${PATH}"
RUN cd src/backend/base && $POETRY_HOME/bin/poetry build
# Copy virtual environment and built .tar.gz from builder base
RUN useradd -m -u 1000 user
USER user
# Install the package from the .tar.gz
RUN python -m pip install /app/src/backend/base/dist/*.tar.gz
RUN python -m pip install /app/src/backend/base/dist/*.tar.gz --user
ENTRYPOINT ["python", "-m", "langflow", "run"]

View file

@ -10,9 +10,9 @@ services:
environment:
- LANGFLOW_DATABASE_URL=postgresql://langflow:langflow@postgres:5432/langflow
# This variable defines where the logs, file storage, monitor data and secret keys are stored.
- LANGFLOW_CONFIG_DIR=/var/lib/langflow
- LANGFLOW_CONFIG_DIR=app/langflow
volumes:
- langflow-data:/var/lib/langflow
- langflow-data:/app/langflow
postgres:
image: postgres:16

View file

@ -4,15 +4,15 @@ import Admonition from "@theme/Admonition";
# API Keys
## Introduction
Langflow offers an API Key functionality that allows users to access their individual components and flows without going through traditional login authentication. The API Key is a user-specific token that can be included in the request's header or query parameter to authenticate API calls. The following documentation outlines how to generate, use, and manage these API Keys in Langflow.
Langflow provides an API key functionality that allows users to access their individual components and flows without traditional login authentication. The API key is a user-specific token that can be included in the request header or query parameter to authenticate API calls. This documentation outlines how to generate, use, and manage API keys in Langflow.
<Admonition type="warning">
This feature requires the `LANGFLOW_AUTO_LOGIN` environment variable to be set
to `False`. The default user and password are set using _`LANGFLOW_SUPERUSER`_
and _`LANGFLOW_SUPERUSER_PASSWORD`_ environment variables. Default values are
_`langflow`_ and _`langflow`_ respectively.
The default user and password are set using the LANGFLOW_SUPERUSER and
LANGFLOW_SUPERUSER_PASSWORD environment variables.
The default values are
langflow and langflow, respectively.
</Admonition>
## Generating an API Key
@ -93,7 +93,7 @@ print(run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS, apiKey=api_key))
### Using the Query Parameter
Alternatively, you can include the API key as a query parameter in the URL:
Include the API key as a query parameter in the URL:
```bash
curl -X POST \
@ -146,9 +146,9 @@ print(run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS, apiKey=api_key))
## Security Considerations
- **Visibility**: The API key won't be retrievable again through the UI for security reasons.
- **Scope**: The key only allows access to the flows and components of the specific user to whom it was issued.
- **Visibility**: For security reasons, the API key cannot be retrieved again through the UI.
- **Scope**: The key allows access only to the flows and components of the specific user to whom it was issued.
## Revoking an API Key
To revoke an API key, simply delete it from the UI. This will immediately invalidate the key and prevent it from being used again.
To revoke an API key, delete it from the UI. This action immediately invalidates the key and prevents it from being used again.

View file

@ -1,4 +1,4 @@
# 🖥️ Command Line Interface (CLI)
# Command Line Interface (CLI)
## Overview
@ -7,19 +7,18 @@ Langflow's Command Line Interface (CLI) is a powerful tool that allows you to in
Running the CLI without any arguments will display a list of available commands and options.
```bash
python -m langflow --help
python -m langflow run --help
# or
python -m langflow
python -m langflow run
```
Each option is detailed below:
Each option for `run` command are detailed below:
- `--help`: Displays all available options.
- `--host`: Defines the host to bind the server to. Can be set using the `LANGFLOW_HOST` environment variable. The default is `127.0.0.1`.
- `--workers`: Sets the number of worker processes. Can be set using the `LANGFLOW_WORKERS` environment variable. The default is `1`.
- `--timeout`: Sets the worker timeout in seconds. The default is `60`.
- `--port`: Sets the port to listen on. Can be set using the `LANGFLOW_PORT` environment variable. The default is `7860`.
- `--config`: Defines the path to the configuration file. The default is `config.yaml`.
- `--env-file`: Specifies the path to the .env file containing environment variables. The default is `.env`.
- `--log-level`: Defines the logging level. Can be set using the `LANGFLOW_LOG_LEVEL` environment variable. The default is `critical`.
- `--components-path`: Specifies the path to the directory containing custom components. Can be set using the `LANGFLOW_COMPONENTS_PATH` environment variable. The default is `langflow/components`.
@ -36,6 +35,41 @@ Each option is detailed below:
These parameters are important for users who need to customize the behavior of Langflow, especially in development or specialized deployment scenarios.
### API Key Command
The `api-key` command allows you to create an API key for accessing Langflow's API when `LANGFLOW_AUTO_LOGIN` is set to `True`.
```bash
python -m langflow api-key --help
Usage: langflow api-key [OPTIONS]
Creates an API key for the default superuser if AUTO_LOGIN is enabled.
Args: log_level (str, optional): Logging level. Defaults to "error".
Returns: None
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --log-level TEXT Logging level. [env var: LANGFLOW_LOG_LEVEL] [default: error] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```
Once you run the `api-key` command, it will create an API key for the default superuser if `LANGFLOW_AUTO_LOGIN` is set to `True`.
```bash
python -m langflow api-key
╭─────────────────────────────────────────────────────────────────────╮
│ API Key Created Successfully: │
│ │
│ sk-O0elzoWID1izAH8RUKrnnvyyMwIzHi2Wk-uXWoNJ2Ro │
│ │
│ This is the only time the API key will be displayed. │
│ Make sure to store it in a secure location. │
│ │
│ The API key has been copied to your clipboard. Cmd + V to paste it. │
╰─────────────────────────────────────────────────────────────────────╯
```
### Environment Variables
You can configure many of the CLI options using environment variables. These can be exported in your operating system or added to a `.env` file and loaded using the `--env-file` option.

View file

@ -74,11 +74,6 @@ class DocumentProcessor(CustomComponent):
</div>
<Admonition type="tip">
Check out [FlowRunner Component](../examples/flow-runner) for a more complex
example.
</Admonition>
---
## Rules
@ -391,13 +386,13 @@ The recommended way to load custom components is to set the _`LANGFLOW_COMPONENT
```bash
export LANGFLOW_COMPONENTS_PATH='["/path/to/components"]'
langflow
langflow run
```
Alternatively, you can specify the path to your custom components using the _`--components-path`_ argument when running the Langflow CLI, as shown below:
```bash
langflow --components-path /path/to/components
langflow run --components-path /path/to/components
```
Langflow will attempt to load all of the components found in the specified directory. If a component fails to load due to errors in the component's code, Langflow will print an error message to the console but will continue loading the rest of the components.

View file

@ -1,7 +1,8 @@
import ZoomableImage from "/src/theme/ZoomableImage.js";
import Admonition from "@theme/Admonition";
import ReactPlayer from "react-player";
# Global environment variables
# Global Environment Variables
Langflow 1.0 alpha includes the option to add **Global Environment Variables** for your application.
@ -43,3 +44,11 @@ You now have a `openai_api_key` global environment variable for your Langflow pr
4. To view and manage your project's global environment variables, visit **Settings** > **Variables and Secrets**.
For more on variables in HuggingFace Spaces, see [Managing Secrets](https://huggingface.co/docs/hub/spaces-overview#managing-secrets).
## Video
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_global_variables.mp4" />
</div>

View file

@ -1,49 +0,0 @@
# Integrating Langfuse with Langflow
## Introduction
Langfuse is an open-source tracing and analytics tool designed for LLM applications. Integrating Langfuse with Langflow provides detailed production traces and granular insights into quality, cost, and latency. This integration allows you to monitor and debug your Langflow's chat or APIs easily.
## Step-by-Step Instructions
### Step 1: Create a Langfuse account
1. Go to [Langfuse](https://langfuse.com) and click on the "Sign In" button in the top right corner.
2. Click on the "Sign Up" button and create an account.
3. Once logged in, click on "Settings" and then on "Create new API keys."
4. Copy the Public key and the Secret Key and save them somewhere safe.
{/* Add these keys to your environment variables in the following step. */}
### Step 2: Set up Langfuse in Langflow
1. **Export the Environment Variables**: You'll need to export the environment variables `LANGFLOW_LANGFUSE_SECRET_KEY` and `LANGFLOW_LANGFUSE_PUBLIC_KEY` with the values obtained in Step 1.
You can do this by executing the following commands in your terminal:
```bash
export LANGFLOW_LANGFUSE_SECRET_KEY=<your secret key>
export LANGFLOW_LANGFUSE_PUBLIC_KEY=<your public key>
```
Alternatively, you can run the Langflow CLI command:
```bash
LANGFLOW_LANGFUSE_SECRET_KEY=<your secret key> LANGFLOW_LANGFUSE_PUBLIC_KEY=<your public key> langflow
```
If you are self-hosting Langfuse, you can also set the environment variable `LANGFLOW_LANGFUSE_HOST` to point to your Langfuse instance. By default, Langfuse points to the cloud instance at `https://cloud.langfuse.com`.
2. **Verify Integration**: Ensure that the environment variables are set correctly by checking their existence in your environment, for example by running:
```bash
echo $LANGFLOW_LANGFUSE_SECRET_KEY
echo $LANGFLOW_LANGFUSE_PUBLIC_KEY
```
3. **Monitor Langflow**: Now, whenever you use Langflow's chat or API, you will be able to see the tracing of your conversations in Langfuse.
That's it! You have successfully integrated Langfuse with Langflow, enhancing observability and debugging capabilities for your LLM application.
---
Note: For more details or customized configurations, please refer to the official [Langfuse documentation](https://langfuse.com/docs/integrations/langchain).

View file

@ -4,7 +4,7 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Sign up and Sign in
# Sign Up and Sign In
## Introduction

View file

@ -14,7 +14,7 @@ It even works for flows hosted on the Langflow store!
As long as you have a flow's environment variables set, you can run it by clicking the **Playground** button.
1. From your **Collections** page, click **Playground** in one of your flows.
1. From your **Collections** page, click the **![Playground icon](/logos/botmessage.svg)Playground** in one of your flows.
The **Playground** window opens.
<ZoomableImage
@ -27,3 +27,11 @@ As long as you have a flow's environment variables set, you can run it by clicki
/>
2. Chat with your bot as you normally would, all without having to open the editor.
## Video
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_playground.mp4" />
</div>

View file

@ -3,7 +3,8 @@ import Admonition from "@theme/Admonition";
# Custom Components
<Admonition type="info" label="Tip">
Read the [Custom Component Guidelines](../administration/custom-component) for detailed information on custom components.
Read the [Custom Component Guidelines](../administration/custom-component) for
detailed information on custom components.
</Admonition>
Custom components let you extend Langflow by creating reusable and configurable components from a Python script.
@ -31,57 +32,60 @@ This class is the foundation for creating custom components. It allows users to
The following types are supported in the build method:
| Supported Types |
| --------------------------------------------------------- |
| _`str`_, _`int`_, _`float`_, _`bool`_, _`list`_, _`dict`_ |
| _`langflow.field_typing.NestedDict`_ |
| _`langflow.field_typing.Prompt`_ |
| _`langchain.chains.base.Chain`_ |
| _`langchain.PromptTemplate`_ |
| Supported Types |
| ----------------------------------------------------------------- |
| _`str`_, _`int`_, _`float`_, _`bool`_, _`list`_, _`dict`_ |
| _`langflow.field_typing.NestedDict`_ |
| _`langflow.field_typing.Prompt`_ |
| _`langchain.chains.base.Chain`_ |
| _`langchain.PromptTemplate`_ |
| _`from langchain.schema.language_model import BaseLanguageModel`_ |
| _`langchain.Tool`_ |
| _`langchain.document_loaders.base.BaseLoader`_ |
| _`langchain.schema.Document`_ |
| _`langchain.text_splitters.TextSplitter`_ |
| _`langchain.vectorstores.base.VectorStore`_ |
| _`langchain.embeddings.base.Embeddings`_ |
| _`langchain.schema.BaseRetriever`_ |
| _`langchain.Tool`_ |
| _`langchain.document_loaders.base.BaseLoader`_ |
| _`langchain.schema.Document`_ |
| _`langchain.text_splitters.TextSplitter`_ |
| _`langchain.vectorstores.base.VectorStore`_ |
| _`langchain.embeddings.base.Embeddings`_ |
| _`langchain.schema.BaseRetriever`_ |
The difference between _`dict`_ and _`langflow.field_typing.NestedDict`_ is that one adds a simple key-value pair field, while the other opens a more robust dictionary editor.
<Admonition type="info">
Use the `Prompt` type by adding **kwargs to the build method.
If you want to add the values of the variables to the template you defined, format the `PromptTemplate` inside the `CustomComponent` class.
Use the `Prompt` type by adding **kwargs to the build method. If you want to
add the values of the variables to the template you defined, format the
`PromptTemplate` inside the `CustomComponent` class.
</Admonition>
<Admonition type="info">
Use base Python types without a handle by default. To add handles, use the `input_types` key in the `build_config` method.
Use base Python types without a handle by default. To add handles, use the
`input_types` key in the `build_config` method.
</Admonition>
**build_config:** Defines the configuration fields of the component. This method returns a dictionary where each key represents a field name and each value defines the field's behavior.
Supported keys for configuring fields:
| Key | Description |
| --------------------- | --------------------------------------------------- |
| `is_list` | Boolean indicating if the field can hold multiple values. |
| `options` | Dropdown menu options. |
| `multiline` | Boolean indicating if a field allows multiline input. |
| `input_types` | Allows connection handles for string fields. |
| `display_name` | Field name displayed in the UI. |
| `advanced` | Hides the field in the default UI view. |
| `password` | Masks input, useful for sensitive data. |
| `required` | Overrides the default behavior to make a field mandatory. |
| `info` | Tooltip for the field. |
| `file_types` | Accepted file types, useful for file fields. |
| `range_spec` | Defines valid ranges for float fields. |
| `title_case` | Boolean that controls field name capitalization. |
| `refresh_button` | Adds a refresh button that updates field values. |
| `real_time_refresh` | Updates the configuration as field values change. |
| `field_type` | Automatically set based on the build method's type hint. |
| Key | Description |
| ------------------- | --------------------------------------------------------- |
| `is_list` | Boolean indicating if the field can hold multiple values. |
| `options` | Dropdown menu options. |
| `multiline` | Boolean indicating if a field allows multiline input. |
| `input_types` | Allows connection handles for string fields. |
| `display_name` | Field name displayed in the UI. |
| `advanced` | Hides the field in the default UI view. |
| `password` | Masks input, useful for sensitive data. |
| `required` | Overrides the default behavior to make a field mandatory. |
| `info` | Tooltip for the field. |
| `file_types` | Accepted file types, useful for file fields. |
| `range_spec` | Defines valid ranges for float fields. |
| `title_case` | Boolean that controls field name capitalization. |
| `refresh_button` | Adds a refresh button that updates field values. |
| `real_time_refresh` | Updates the configuration as field values change. |
| `field_type` | Automatically set based on the build method's type hint. |
<Admonition type="info" label="Tip">
Use the `update_build_config` method to dynamically update configurations based on field values.
Use the `update_build_config` method to dynamically update configurations
based on field values.
</Admonition>
## Additional methods and attributes
@ -99,8 +103,3 @@ The `CustomComponent` class also provides helpful methods for specific tasks (e.
- `status`: Shows values from the `build` method, useful for debugging.
- `field_order`: Controls the display order of fields.
- `icon`: Sets the canvas display icon.
<Admonition type="info" label="Tip">
Check out the [FlowRunner](../examples/flow-runner) example to understand how to call a flow from a custom component.
</Admonition>

View file

@ -1,6 +1,6 @@
import ZoomableImage from "/src/theme/ZoomableImage.js";
# How to contribute components?
# How to Contribute Components?
As of Langflow 1.0 alpha, new components are added as objects of the [CustomComponent](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/interface/custom/custom_component/custom_component.py) class and any dependencies are added to the [pyproject.toml](https://github.com/langflow-ai/langflow/blob/dev/pyproject.toml#L27) file.

View file

@ -1,35 +0,0 @@
import Admonition from "@theme/Admonition";
# Buffer Memory
For certain applications, retaining past interactions is crucial. For that, chains and agents may accept a memory component as one of their input parameters. The `ConversationBufferMemory` component is one of them. It stores messages and extracts them into variables.
## ⛓️ Langflow Example
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/buffer-memory.png",
dark: "img/buffer-memory.png",
}}
style={{
width: "80%",
margin: "20px auto",
display: "flex",
justifyContent: "center",
}}
/>
#### <a target="\_blank" href="json_files/Buffer_Memory.json" download>Download Flow</a>
<Admonition type="note" title="LangChain Components 🦜🔗">
- [`ConversationBufferMemory`](https://python.langchain.com/docs/modules/memory/types/buffer)
- [`ConversationChain`](https://python.langchain.com/docs/modules/chains/)
- [`ChatOpenAI`](https://python.langchain.com/docs/modules/model_io/models/chat/integrations/openai)
</Admonition>

View file

@ -0,0 +1,17 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Chat Memory
The **Chat Memory** component restores previous messages given a Session ID, which can be any string.
This component is available under the **Helpers** tab of the Langflow preview.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/chat_memory.mp4" />
</div>

View file

@ -0,0 +1,21 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Combine Text
With LLM pipelines, combining text from different sources may be as important as splitting text.
The **Combine Text** component concatenates two text inputs into a single chunk using a specified delimiter, such as whitespace or a newline.
Also, check out **Combine Texts (Unsorted)** as a similar alternative.
This component is available under the **Helpers** tab of the Langflow preview.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/combine_text.mp4" />
</div>

View file

@ -1,41 +0,0 @@
import Admonition from "@theme/Admonition";
# Conversation Chain
This example shows how to instantiate a simple `ConversationChain` component using a Language Model (LLM). Once the Node Status turns green 🟢, the chat will be ready to take in user messages. Here, we used `ChatOpenAI` to act as the required LLM input, but you can use any LLM for this purpose.
<Admonition type="info">
Make sure to always get the API key from the provider.
</Admonition>
## ⛓️ Langflow Example
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/basic-chat.png",
dark: "img/basic-chat.png",
}}
style={{
width: "80%",
margin: "20px auto",
display: "flex",
justifyContent: "center",
}}
/>
#### <a target="\_blank" href="json_files/Basic_Chat.json" download>Download Flow</a>
<Admonition type="note" title="LangChain Components 🦜🔗">
- [`ConversationChain`](https://python.langchain.com/docs/modules/chains/)
- [`ChatOpenAI`](https://python.langchain.com/docs/modules/model_io/models/chat/integrations/openai)
</Admonition>

View file

@ -0,0 +1,17 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Create Record
In Langflow, a `Record` has a structure very similar to a Python dictionary. It is a key-value pair data structure.
The **Create Record** component allows you to dynamically create a `Record` from a specified number of inputs. You can add as many key-value pairs as you want (as long as it is less than 15 😅). Once you've chosen the number of `Records`, add keys and fill up values, or pass on values from other components to the component using the input handles.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/create_record.mp4" />
</div>

View file

@ -1,57 +0,0 @@
import Admonition from "@theme/Admonition";
# CSV Loader
The `VectoStoreAgent` component retrieves information from one or more vector stores. This example shows a `VectoStoreAgent` connected to a CSV file through the `Chroma` vector store. Process description:
- The `CSVLoader` loads a CSV file into a list of documents.
- The extracted data is then processed by the `CharacterTextSplitter`, which splits the text into small, meaningful chunks (usually sentences).
- These chunks feed the `Chroma` vector store, which converts them into vectors and stores them for fast indexing.
- Finally, the agent accesses the information of the vector store through the `VectorStoreInfo` tool.
<Admonition type="info">
The vector store is used for efficient semantic search, while
`VectorStoreInfo` carries information about it, such as its name and
description. Embeddings are a way to represent words, phrases, or any entities
in a vector space. Learn more about them
[here](https://platform.openai.com/docs/guides/embeddings/what-are-embeddings).
</Admonition>
<Admonition type="tip">
Once you build this flow, ask questions about the data in the chat interface
(e.g., number of rows or columns).
</Admonition>
## ⛓️ Langflow Example
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/csv-loader.png",
dark: "img/csv-loader.png",
}}
style={{
width: "80%",
margin: "20px auto",
display: "flex",
justifyContent: "center",
}}
/>
#### <a target="\_blank" href="json_files/CSV_Loader.json" download>Download Flow</a>
<Admonition type="note" title="LangChain Components 🦜🔗">
- [`CSVLoader`](https://python.langchain.com/docs/integrations/document_loaders/csv)
- [`CharacterTextSplitter`](https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/character_text_splitter)
- [`OpenAIEmbedding`](https://python.langchain.com/docs/integrations/text_embedding/openai)
- [`Chroma`](https://python.langchain.com/docs/integrations/vectorstores/chroma)
- [`VectorStoreInfo`](https://python.langchain.com/docs/modules/data_connection/vectorstores/)
- [`OpenAI`](https://python.langchain.com/docs/modules/model_io/models/llms/integrations/openai)
- [`VectorStoreAgent`](https://js.langchain.com/docs/modules/agents/tools/how_to/agents_with_vectorstores)
</Admonition>

View file

@ -1,368 +0,0 @@
---
description: Custom Components
hide_table_of_contents: true
---
# FlowRunner Component
The CustomComponent class allows us to create components that interact with Langflow itself. In this example, we will make a component that runs other flows available in "My Collection".
<ZoomableImage
alt="Document Processor Component"
sources={{
light: "img/flow_runner.png",
dark: "img/flow_runner.png",
}}
style={{
width: "30%",
margin: "20px auto",
display: "flex",
justifyContent: "center",
}}
/>
We will cover how to:
- List Collection flows using the _`list_flows`_ method.
- Load a flow using the _`load_flow`_ method.
- Configure a dropdown input field using the _`options`_ parameter.
<details open>
<summary>Example Code</summary>
```python
from langflow.custom import CustomComponent
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
flows = self.list_flows()
flow_names = [f.name for f in flows]
return {"flow_name": {"options": flow_names,
"display_name": "Flow Name",
},
"document": {"display_name": "Document"}
}
def build(self, flow_name: str, document: Document) -> Document:
# List the flows
flows = self.list_flows()
# Get the flow that matches the selected name
# You can also get the flow by id
# using self.get_flow(flow_id=flow_id)
tweaks = {}
flow = self.get_flow(flow_name=flow_name, tweaks=tweaks)
# Get the page_content from the document
if document and isinstance(document, list):
document = document[0]
page_content = document.page_content
# Use it in the flow
result = flow(page_content)
return Document(page_content=str(result))
```
</details>
<CH.Scrollycoding rows={20} className={""}>
```python
from langflow.custom import CustomComponent
class MyComponent(CustomComponent):
display_name = "Custom Component"
description = "This is a custom component"
def build_config(self):
...
def build(self):
...
```
The typical structure of a Custom Component is composed of _`display_name`_ and _`description`_ attributes, _`build`_ and _`build_config`_ methods.
---
```python
from langflow.custom import CustomComponent
# focus
class FlowRunner(CustomComponent):
# focus
display_name = "Flow Runner"
# focus
description = "Run other flows"
def build_config(self):
...
def build(self):
...
```
Let's start by defining our component's _`display_name`_ and _`description`_.
---
```python
from langflow.custom import CustomComponent
# focus
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
...
def build(self):
...
```
Second, we will import _`Document`_ from the [_langchain.schema_](https://docs.langchain.com/docs/components/schema/) module. This will be the return type of the _`build`_ method.
---
```python
from langflow.custom import CustomComponent
# focus
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
...
# focus
def build(self, flow_name: str, document: Document) -> Document:
...
```
Now, let's add the [parameters](focus://11[20:55]) and the [return type](focus://11[60:69]) to the _`build`_ method. The parameters added are:
- _`flow_name`_ is the name of the flow we want to run.
- _`document`_ is the input document to be passed to that flow.
- Since _`Document`_ is a Langchain type, it will add an input [handle](../administration/components) to the component ([see more](../components/custom)).
---
```python focus=13:14
from langflow.custom import CustomComponent
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
...
def build(self, flow_name: str, document: Document) -> Document:
# List the flows
flows = self.list_flows()
```
We can now start writing the _`build`_ method. Let's list available flows in "My Collection" using the _`list_flows`_ method.
---
```python focus=15:18
from langflow.custom import CustomComponent
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
...
def build(self, flow_name: str, document: Document) -> Document:
# List the flows
flows = self.list_flows()
# Get the flow that matches the selected name
# You can also get the flow by id
# using self.get_flow(flow_id=flow_id)
tweaks = {}
flow = self.get_flow(flow_name=flow_name, tweaks=tweaks)
```
And retrieve a flow that matches the selected name (we'll make a dropdown input field for the user to choose among flow names).
<Admonition type="caution">
From version 0.4.0, names are unique, which was not the case in previous
versions. This might lead to unexpected results if using flows with the same
name.
</Admonition>
---
```python
from langflow.custom import CustomComponent
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
...
def build(self, flow_name: str, document: Document) -> Document:
# List the flows
flows = self.list_flows()
# Get the flow that matches the selected name
# You can also get the flow by id
# using self.get_flow(flow_id=flow_id)
tweaks = {}
flow = self.get_flow(flow_name=flow_name, tweaks=tweaks)
```
You can load this flow using _`get_flow`_ and set a _`tweaks`_ dictionary to customize it. Find more about tweaks in our [features guidelines](../administration/features#code).
---
```python
from langflow.custom import CustomComponent
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
...
def build(self, flow_name: str, document: Document) -> Document:
# List the flows
flows = self.list_flows()
# Get the flow that matches the selected name
# You can also get the flow by id
# using self.get_flow(flow_id=flow_id)
tweaks = {}
flow = self.get_flow(flow_name=flow_name, tweaks=tweaks)
# Get the page_content from the document
if document and isinstance(document, list):
document = document[0]
page_content = document.page_content
# Use it in the flow
result = flow(page_content)
return Document(page_content=str(result))
```
We are using a _`Document`_ as input because it is a straightforward way to pass text data in Langflow (specifically because you can connect it to many [loaders](../components/loaders)).
Generally, a flow will take a string or a dictionary as input because that's what LangChain components expect.
In case you are passing a dictionary, you need to build it according to the needs of the flow you are using.
The content of a document can be extracted using the _`page_content`_ attribute, which is a string, and passed as an argument to the selected flow.
---
```python focus=9:16
from langflow.custom import CustomComponent
from langchain.schema import Document
class FlowRunner(CustomComponent):
display_name = "Flow Runner"
description = "Run other flows using a document as input."
def build_config(self):
flows = self.list_flows()
flow_names = [f.name for f in flows]
return {"flow_name": {"options": flow_names,
"display_name": "Flow Name",
},
"document": {"display_name": "Document"}
}
def build(self, flow_name: str, document: Document) -> Document:
# List the flows
flows = self.list_flows()
# Get the flow that matches the selected name
# You can also get the flow by id
# using self.get_flow(flow_id=flow_id)
tweaks = {}
flow = self.get_flow(flow_name=flow_name, tweaks=tweaks)
# Get the page_content from the document
if document and isinstance(document, list):
document = document[0]
page_content = document.page_content
# Use it in the flow
result = flow(page_content)
return Document(page_content=str(result))
```
Finally, we can add field customizations through the _`build_config`_ method. Here we added the _`options`_ key to make the _`flow_name`_ field a dropdown menu. Check out the [custom component reference](../components/custom) for a list of available keys.
<Admonition type="caution">
Make sure that the field type is _`str`_ and _`options`_ values are strings.
</Admonition>
</CH.Scrollycoding>
Done! This is what our script and custom component looks like:
<div style={{
display: "flex",
justifyContent: "center",
}}>
<ZoomableImage
alt="Document Processor Code"
sources={{
light: "img/flow_runner_code.png",
dark: "img/flow_runner_code.png",
}}
style={{
maxWidth: "100%",
margin: "0 auto",
display: "flex",
justifyContent: "center",
}}
/>
<ZoomableImage
alt="Document Processor Component"
sources={{
light: "img/flow_runner.png",
dark: "img/flow_runner.png",
}}
style={{
width: "40%",
margin: "0 auto",
display: "flex",
justifyContent: "center",
}}
/>
</div>
import ZoomableImage from "/src/theme/ZoomableImage.js";
import Admonition from "@theme/Admonition";

View file

@ -0,0 +1,17 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Pass
Sometimes all you need to do is… nothing!
The **Pass** component enables you to ignore one input and move forward with another one. This is super helpful to swap routes for A/B testing!
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/pass.mp4" />
</div>

View file

@ -1,62 +0,0 @@
import Admonition from "@theme/Admonition";
# Python Function
Langflow allows you to create a customized tool using the `PythonFunction` connected to a `Tool` component. In this example, Regex is used in Python to validate a pattern.
```python
import re
def is_brazilian_zipcode(zipcode: str) -> bool:
pattern = r"\d{5}-?\d{3}"
# Check if the zip code matches the pattern
if re.match(pattern, zipcode):
return True
return False
```
<Admonition type="tip">
When a tool is called, it is often desirable to have its output returned
directly to the user. You can do this by setting the **return_direct** flag
for a tool to be True.
</Admonition>
The `AgentInitializer` component is a quick way to construct an agent from the model and tools.
<Admonition type="info">
The `PythonFunction` is a custom component that uses the LangChain 🦜🔗 tool
decorator. Learn more about it
[here](https://python.langchain.com/docs/modules/agents/tools/custom_tools).
</Admonition>
## ⛓️ Langflow Example
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/python-function.png",
dark: "img/python-function.png",
}}
style={{
width: "80%",
margin: "20px auto",
display: "flex",
justifyContent: "center",
}}
/>
#### <a target="\_blank" href="json_files/Python_Function.json" download>Download Flow</a>
<Admonition type="note" title="LangChain Components 🦜🔗">
- [`PythonFunctionTool`](https://python.langchain.com/docs/modules/agents/tools/custom_tools)
- [`ChatOpenAI`](https://python.langchain.com/docs/modules/model_io/models/chat/integrations/openai)
- [`AgentInitializer`](https://python.langchain.com/docs/modules/agents/)
</Admonition>

View file

@ -1,52 +0,0 @@
import Admonition from "@theme/Admonition";
# SearchApi Tool
The [SearchApi](https://www.searchapi.io/) allows developers to retrieve results from search engines such as Google, Google Scholar, YouTube, YouTube transcripts, and more, and can be used as in Langflow through the `SearchApi` tool.
<Admonition type="info">
To use the SearchApi, you must first obtain an API key by registering at [SearchApi's website](https://www.searchapi.io/).
</Admonition>
In the given example, we specify `engine` as `youtube_transcripts` and provide a `video_id`.
<Admonition type="info">
All engines and parameters can be found in [SearchApi documentation](https://www.searchapi.io/docs/google).
</Admonition>
The `RetrievalQA` chain processes a `Document` along with a user's question to return an answer.
<Admonition type="tip">
In this example, we used [`ChatOpenAI`](https://platform.openai.com/) as the
LLM, but feel free to experiment with other Language Models!
</Admonition>
The `RetrievalQA` takes `CombineDocsChain` and `SearchApi` tool as inputs, using the tool as a `Document` to answer questions.
<Admonition type="info">
Learn more about the SearchApi
[here](https://python.langchain.com/docs/integrations/tools/searchapi).
</Admonition>
## ⛓️ Langflow Example
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/searchapi-tool.png",
}}
/>
#### <a target="\_blank" href="json_files/SearchApi_Tool.json" download>Download Flow</a>
<Admonition type="note" title="LangChain Components 🦜🔗">
- [`OpenAI`](https://python.langchain.com/docs/modules/model_io/models/llms/integrations/openai)
- [`SearchApiAPIWrapper`](https://python.langchain.com/docs/integrations/providers/searchapi#wrappers)
- [`ZeroShotAgent`](https://python.langchain.com/docs/modules/agents/how_to/custom_mrkl_agent)
</Admonition>

View file

@ -1,58 +0,0 @@
import Admonition from "@theme/Admonition";
# Serp API Tool
The [Serp API](https://serpapi.com/) (Search Engine Results Page) allows developers to scrape results from search engines such as Google, Bing and Yahoo, and can be used as in Langflow through the `Search` component.
<Admonition type="info">
To use the Serp API, you first need to sign up [Serp
API](https://serpapi.com/) for an API key on the provider's website.
</Admonition>
Here, the `ZeroShotPrompt` component specifies a prompt template for the `ZeroShotAgent`. Set a _Prefix_ and _Suffix_ with rules for the agent to obey. In the example, we used default templates.
The `LLMChain` is a simple chain that takes in a prompt template, formats it with the user input, and returns the response from an LLM.
<Admonition type="tip">
In this example, we used [`ChatOpenAI`](https://platform.openai.com/) as the
LLM, but feel free to experiment with other Language Models!
</Admonition>
The `ZeroShotAgent` takes the `LLMChain` and the `Search` tool as inputs, using the tool to find information when necessary.
<Admonition type="info">
Learn more about the Serp API
[here](https://python.langchain.com/docs/integrations/providers/serpapi ).
</Admonition>
## ⛓️ Langflow Example
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/serp-api-tool.png",
dark: "img/serp-api-tool.png",
}}
style={{
width: "80%",
margin: "20px auto",
display: "flex",
justifyContent: "center",
}}
/>
#### <a target="\_blank" href="json_files/SerpAPI_Tool.json" download>Download Flow</a>
<Admonition type="note" title="LangChain Components 🦜🔗">
- [`ZeroShotPrompt`](https://python.langchain.com/docs/modules/model_io/prompts/prompt_templates/)
- [`OpenAI`](https://python.langchain.com/docs/modules/model_io/models/llms/integrations/openai)
- [`LLMChain`](https://python.langchain.com/docs/modules/chains/foundational/llm_chain)
- [`Search`](https://python.langchain.com/docs/integrations/providers/serpapi)
- [`ZeroShotAgent`](https://python.langchain.com/docs/modules/agents/how_to/custom_mrkl_agent)
</Admonition>

View file

@ -0,0 +1,17 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Store Message
The **Store Message** component allows you to save information under a specified Session ID and sender type.
The **Message History** component can then be used to retrieve stored messages.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/store_message.mp4" />
</div>

View file

@ -0,0 +1,15 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Sub Flow
The **Sub Flow** component enables a user to select a previously built flow and dynamically generate a component out of it.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/sub_flow.mp4" />
</div>

View file

@ -0,0 +1,15 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Text Operator
The **Text Operator** component simplifies logic. It evaluates the results from another component (for example, if the input text exactly equals `Tuna`) and runs another component based on the results. Basically, the text operator is an if/else component for your flow.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/text_operator.mp4" />
</div>

View file

@ -0,0 +1,282 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# 🎨 Langflow Canvas
The **Langflow canvas** is the central hub of Langflow, where you'll assemble new flows from components, run them, and see the results.
To get a feel for the canvas, we'll examine a basic prompting flow.
You can either build this flow yourself, or select **New Project** > **Basic prompting** to open a canvas with the flow pre-built.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/basic-prompting.png",
dark: "img/basic-prompting.png",
}}
style={{ width: "30%", margin: "20px auto" }}
/>
## Flows, components, collections, and projects
A [flow](#flow) is a pipeline of components connected together in the Langflow canvas.
A [component](#component) is a single building block within a flow. A component has inputs, outputs, and parameters that define its functionality.
A [collection](#collection) is a snapshot of the flows available in your database. Collections can be downloaded to local storage and uploaded for future use.
A [project](#project) can be a component or a flow. Projects are saved as part of your collection.
For example, the **OpenAI LLM** is a **component** of the **Basic prompting** flow, and the **flow** is stored in a **collection**.
## Flow
A **flow** is a pipeline of components connected together in the Langflow canvas.
For example, the [Basic prompting](../starter-projects/basic-prompting.mdx) flow is a pipeline of four components:
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/basic-prompting.png",
dark: "img/basic-prompting.png",
}}
style={{ width: "80%", margin: "20px auto" }}
/>
In this flow, the **OpenAI LLM component** receives input (left side) and produces output (right side) - in this case, receiving input from the **Chat Input** and **Prompt** components and producing output to the **Chat Output** component.
## Component
Components are the building blocks of flows. They consist of inputs, outputs, and parameters that define their functionality. These elements provide a convenient and straightforward way to compose LLM-based applications. Learn more about components and how they work in the LangChain [documentation](https://python.langchain.com/docs/integrations/components).
<div style={{ marginBottom: "20px" }}>
During the flow creation process, you will notice handles (colored circles)
attached to one or both sides of a component. These handles represent the
availability to connect to other components. Hover over a handle to see
connection details.
</div>
<div style={{ marginBottom: "20px" }}>
For example, if you select a <code>ConversationChain</code> component, you
will see orange <span style={{ color: "orange" }}>o</span> and purple{" "}
<span style={{ color: "purple" }}>o</span> input handles. They indicate that
this component accepts an LLM and a Memory component as inputs. The red
asterisk <span style={{ color: "red" }}>*</span> means that at least one input
of that type is required.
</div>
{" "}
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: useBaseUrl("img/single-component.png"),
dark: useBaseUrl("img/single-component.png"),
}}
style={{ width: "50%", maxWidth: "800px", margin: "20px auto" }}
/>
<div style={{ marginBottom: "20px" }}>
In the top right corner of the component, you'll find the component status icon (![Status icon](/logos/playbutton.svg)).
Build the flow by clicking the **![Playground icon](/logos/botmessage.svg)Playground** at the bottom right of the canvas.
Once the validation is complete, the status of each validated component should turn green (![Status icon](/logos/greencheck.svg)).
To debug, hover over the component status to see the outputs.
</div>
---
### Component Parameters
Langflow components can be edited by clicking the component settings button. Hide parameters to reduce complexity and keep the canvas clean and intuitive for experimentation.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_parameters.mp4" />
</div>
### Component menu
Each component is a little unique, but they will all have a menu bar on top that looks something like this.
The menu options are **Code**, **Save**, **Duplicate**, and **More**.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/chat-input-with-menu.png",
dark: "img/chat-input-with-menu.png",
}}
style={{ width: "30%", margin: "20px auto" }}
/>
### Code menu
The **Code** button displays your component's Python code.
You can modify the code and save it.
#### Save
Save your component to the **Saved** components folder for re-use.
#### Duplicate
Duplicate your component in the canvas.
#### More
**Advanced** - modify the parameters of your component.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_parameters.mp4" />
</div>
**Copy** - copy your component.
**Share** - share your component to the Langflow store.
**Docs** - view documentation for your component.
**Delete** - delete your component.
### Group multiple components
Components without input or output nodes can be grouped into a single component for re-use.
This is useful for combining large flows into single components (like RAG with a vector database, for example) and saves space in the canvas.
1. Hold **Shift** and drag to select the **Prompt** and **OpenAI** components.
2. Select **Group**.
3. The components merge into a single component.
4. To save the new component, select **Save**. It can now be re-used from the **Saved** components folder.
## Playground
Run your flow by clicking the **![Playground icon](/logos/botmessage.svg)Playground** button.
For more, see [Playground](../administration/playground.mdx).
## API
The **API** button opens the API window, where Langflow presents code for integrating your flow into external applications.
Modify the call's parameters in the **Tweaks** window, click the **Copy Code** or **Download** buttons, and paste your code where you want to use it.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/api-window.png",
dark: "img/api-window.png",
}}
style={{ width: "50%", margin: "20px auto" }}
/>
### curl
The **curl** tab displays sample code for posting a query to your flow.
Modify the `input_value` to change your input message.
```curl
curl -X POST \
http://127.0.0.1:7863/api/v1/run/f2eefd80-bb91-4190-9279-0d6ffafeaac4\?stream\=false \
-H 'Content-Type: application/json'\
-d '{"input_value": "is anybody there?",
"output_type": "chat",
"input_type": "chat",
"tweaks": {
"Prompt-uxBqP": {},
"OpenAIModel-k39HS": {},
"ChatOutput-njtka": {},
"ChatInput-P3fgL": {}
}}'
```
Result:
```
{"session_id":"f2eefd80-bb91-4190-9279-0d6ffafeaac4:53856a772b8e1cfcb3dd2e71576b5215399e95bae318d3c02101c81b7c252da3","outputs":[{"inputs":{"input_value":"is anybody there?"},"outputs":[{"results":{"result":"Arrr, me hearties! Aye, this be Captain [Your Name] speakin'. What be ye needin', matey?"},"artifacts":{"message":"Arrr, me hearties! Aye, this be Captain [Your Name] speakin'. What be ye needin', matey?","sender":"Machine","sender_name":"AI"},"messages":[{"message":"Arrr, me hearties! Aye, this be Captain [Your Name] speakin'. What be ye needin', matey?","sender":"Machine","sender_name":"AI","component_id":"ChatOutput-njtka"}],"component_display_name":"Chat Output","component_id":"ChatOutput-njtka"}]}]}%
```
### Python API
The **Python API** tab displays code to interact with your flow using the Python HTTP requests library.
### Python Code
The **Python Code** tab displays code to interact with your flow's `.json` file using the Langflow runtime.
### Chat Widget HTML
The **Chat Widget HTML** tab displays code that can be inserted in the `<body>` of your HTML to interact with your flow.
For more, see the [Chat widget documentation](../administration/chat-widget.mdx).
### Tweaks
The **Tweaks** tab displays the available parameters for your flow.
Modifying the parameters changes the code parameters across all windows.
For example, changing the **Chat Input** component's `input_value` will change that value across all API calls.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_api.mp4" />
</div>
## Collection
A collection is a snapshot of flows available in a database.
Collections can be downloaded to local storage and uploaded for future use.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_collection.mp4" />
</div>
## Project
A **Project** can be a flow or a component. To view your saved projects, select **My Collection**.
Your **Projects** are displayed.
Click the **![Playground icon](/logos/botmessage.svg) Playground** button to run a flow from the **My Collection** screen.
In the top left corner of the screen are options for **Download Collection**, **Upload Collection**, and **New Project**.
Select **Download Collection** to save your project to your local machine. This downloads all flows and components as a `.json` file.
Select **Upload Collection** to upload a flow or component `.json` file from your local machine.
Select **New Project** to create a new project. In addition to a blank canvas, [starter projects](../starter-projects/basic-prompting.mdx) are also available.
## Project options menu
To see options for your project, in the upper left corner of the canvas, select the dropdown menu.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/project-options-menu.png",
dark: "img/project-options-menu.png",
}}
style={{ width: "30%", margin: "20px auto" }}
/>
**New** - Start a new project.
**Duplicate** - Duplicate the current flow as a new project.
**Settings** - Modify the project's **Name** or **Description**.
**Import** - Upload a flow `.json` file from your local machine.
**Export** - Download your current project to your local machine as a `.json` file.
**Undo** or **Redo** - Undo or redo your last action.

View file

@ -0,0 +1,20 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
# 🖥️ Flows, components, collections, and projects
## TL;DR
A [flow](#flow) is a pipeline of components connected together in the Langflow canvas.
A [component](#component) is a single building block within a flow. A component has inputs, outputs, and parameters that define its functionality.
A [collection](#collection) is a snapshot of the flows available in your database. Collections can be downloaded to local storage and uploaded for future use.
A [project](#project) can be a component or a flow. Projects are saved as part of your collection.
For example, the **OpenAI LLM** is a **component** of the **Basic prompting** flow, and the **flow** is stored in a **collection**.
## Component

View file

@ -1,38 +0,0 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import Admonition from "@theme/Admonition";
# 🤗 HuggingFace Spaces
HuggingFace provides a great alternative for running Langflow in their Spaces environment. This means you can run Langflow without any local installation required.
In a Chromium-based browser, go to the [Langflow Space](https://huggingface.co/spaces/Langflow/Langflow?duplicate=true) or [Langflow v1.0 alpha Preview Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true).
You'll be presented with the following screen:
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/duplicate-space.png",
dark: "img/duplicate-space.png",
}}
style={{ width: "100%", margin: "20px auto" }}
/>
Name your Space, define the visibility (Public or Private), and click on **Duplicate Space** to start the installation process. When installation is finished, you'll be redirected to the Space's main page to start using Langflow right away!
## Run a starter project
Langflow provides a range of example flows to help you get started.
Once you get Langflow running in your Space, click on **New Project** in the top right corner of the screen.
Select a starter project from the list, set up your API keys, and click ⚡ Run. This will open up Langflow's Interaction Panel with the chat console, text inputs, and outputs ready to go.
For more information on the starter projects, see the guides below:
* [Basic prompting](/starter-projects/basic-prompting.mdx)
* [Memory chatbot](/starter-projects/memory-chatbot.mdx)
* [Blog writer](/starter-projects/blog-writer.mdx)
* [Document QA](/starter-projects/document-qa.mdx)

View file

@ -6,35 +6,40 @@ import Admonition from "@theme/Admonition";
# 📦 Install Langflow
<Admonition type="info">
Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](./huggingface-spaces) to install it locally.
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true),
to create your own Langflow workspace in minutes.
</Admonition>
Langflow requires [Python 3.10](https://www.python.org/downloads/release/python-3100/) and [pip](https://pypi.org/project/pip/) or [pipx](https://pipx.pypa.io/stable/installation/) to be installed on your system.
Langflow requires [Python >=3.10](https://www.python.org/downloads/release/python-3100/) and [pip](https://pypi.org/project/pip/) or [pipx](https://pipx.pypa.io/stable/installation/) to be installed on your system.
Install Langflow with pip:
```bash
python -m pip install langflow -U
```
Install Langflow with pipx:
```bash
pipx install langflow --python python3.10 --fetch-missing-python
```
Pipx can fetch the missing Python version for you with `--fetch-missing-python`, but you can also install the Python version manually.
Pipx can fetch the missing Python version for you with `--fetch-missing-python`, but you can also install the Python version manually.
## Install Langflow pre-release
To install a pre-release version of Langflow:
pip:
```bash
python -m pip install langflow --pre --force-reinstall
```
pipx:
```bash
pipx install langflow --python python3.10 --fetch-missing-python --pip-args="--pre --force-reinstall"
```
@ -54,11 +59,13 @@ python -m langflow --help
## ⛓️ Run Langflow
1. To run Langflow, enter the following command.
```bash
python -m langflow run
```
2. Confirm that a local Langflow instance starts by visiting `http://127.0.0.1:7860` in a Chromium-based browser.
```bash
│ Welcome to ⛓ Langflow │
│ │
@ -66,4 +73,23 @@ python -m langflow run
│ Collaborate, and contribute at our GitHub Repo 🚀 │
```
3. Continue on to the [Quickstart](./quickstart.mdx).
3. Continue on to the [Quickstart](./quickstart.mdx).
## HuggingFace Spaces
HuggingFace provides a great alternative for running Langflow in their Spaces environment. This means you can run Langflow without any local installation required.
In a Chromium-based browser, go to the [Langflow Space](https://huggingface.co/spaces/Langflow/Langflow?duplicate=true) or [Langflow v1.0 alpha Preview Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true).
You'll be presented with the following screen:
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/duplicate-space.png",
dark: "img/duplicate-space.png",
}}
style={{ width: "100%", margin: "20px auto" }}
/>
Name your Space, define the visibility (Public or Private), and click on **Duplicate Space** to start the installation process. When installation is finished, you'll be redirected to the Space's main page to start using Langflow right away!

View file

@ -10,12 +10,15 @@ This guide demonstrates how to build a basic prompt flow and modify that prompt
## Prerequisites
* [Langflow installed](./install-langflow.mdx)
- [Langflow installed and running](./install-langflow.mdx)
* [OpenAI API key](https://platform.openai.com)
- [OpenAI API key](https://platform.openai.com)
<Admonition type="info">
Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](./huggingface-spaces) to install it locally.
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true)
to create your own Langflow workspace in minutes.
</Admonition>
## Hello World - Basic Prompting
@ -44,25 +47,25 @@ Examine the **Prompt** component. The **Template** field instructs the LLM to `A
This should be interesting...
4. To create an environment variable for the **OpenAI** component, in the **OpenAI API Key** field, click the **Globe** button, and then click **Add New Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
## Run the basic prompting flow
1. Click the **Run** button.
The **Interaction Panel** opens, where you can chat with your bot.
The **Interaction Panel** opens, where you can chat with your bot.
2. Type a message and press Enter.
And... Ahoy! 🏴‍☠️
The bot responds in a piratical manner!
And... Ahoy! 🏴‍☠️
The bot responds in a piratical manner!
## Modify the prompt for a different result
1. To modify your prompt results, in the **Prompt** template, click the **Template** field.
The **Edit Prompt** window opens.
The **Edit Prompt** window opens.
2. Change `Answer the user as if you were a pirate` to a different character, perhaps `Answer the user as if you were Harold Abelson.`
3. Run the basic prompting flow again.
The response will be markedly different.
The response will be markedly different.
## Next steps
@ -72,8 +75,6 @@ By adding Langflow components to your flow, you can create all sorts of interest
Here are a couple of examples:
* [Memory chatbot](/starter-projects/memory-chatbot.mdx)
* [Blog writer](/starter-projects/blog-writer.mdx)
* [Document QA](/starter-projects/document-qa.mdx)
- [Memory chatbot](/starter-projects/memory-chatbot.mdx)
- [Blog writer](/starter-projects/blog-writer.mdx)
- [Document QA](/starter-projects/document-qa.mdx)

View file

@ -26,9 +26,14 @@ Its intuitive interface allows for easy manipulation of AI building blocks, enab
- [Quickstart](/getting-started/quickstart) - Create a flow and run it.
- [HuggingFace Spaces](/getting-started/huggingface-spaces) - Duplicate the Langflow preview space and try it out before you install.
- [Langflow Canvas](/getting-started/canvas) - Learn more about the Langflow canvas.
- [New to LLMs?](/getting-started/new-to-llms) - Learn more about LLMs, prompting, and more at [promptingguide.ai](https://promptingguide.ai).
<Admonition type="info">
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true)
to create your own Langflow workspace in minutes.
</Admonition>
## Learn more about Langflow 1.0

View file

@ -0,0 +1,138 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# Add Content To Page
The `AddContentToPage` component converts markdown text to Notion blocks and appends them to a Notion page.
[Notion Reference](https://developers.notion.com/reference/patch-block-children)
<Admonition type="tip" title="Component Functionality">
The `AddContentToPage` component enables you to:
- Convert markdown text to Notion blocks.
- Append the converted blocks to a specified Notion page.
- Seamlessly integrate Notion content creation into Langflow workflows.
</Admonition>
## Component Usage
To use the `AddContentToPage` component in a Langflow flow:
1. **Add the `AddContentToPage` component** to your flow.
2. **Configure the component** by providing:
- `markdown_text`: The markdown text to convert.
- `block_id`: The ID of the Notion page/block to append the content.
- `notion_secret`: The Notion integration token for authentication.
3. **Connect the component** to other nodes in your flow as needed.
4. **Run the flow** to convert the markdown text and append it to the specified Notion page.
## Component Python Code
```python
import json
from typing import Optional
import requests
from langflow.custom import CustomComponent
class NotionPageCreator(CustomComponent):
display_name = "Create Page [Notion]"
description = "A component for creating Notion pages."
documentation: str = "https://docs.langflow.org/integrations/notion/add-content-to-page"
icon = "NotionDirectoryLoader"
def build_config(self):
return {
"database_id": {
"display_name": "Database ID",
"field_type": "str",
"info": "The ID of the Notion database.",
},
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
"properties": {
"display_name": "Properties",
"field_type": "str",
"info": "The properties of the new page. Depending on your database setup, this can change. E.G: {'Task name': {'id': 'title', 'type': 'title', 'title': [{'type': 'text', 'text': {'content': 'Send Notion Components to LF', 'link': null}}]}}",
},
}
def build(
self,
database_id: str,
notion_secret: str,
properties: str = '{"Task name": {"id": "title", "type": "title", "title": [{"type": "text", "text": {"content": "Send Notion Components to LF", "link": null}}]}}',
) -> str:
if not database_id or not properties:
raise ValueError("Invalid input. Please provide 'database_id' and 'properties'.")
headers = {
"Authorization": f"Bearer {notion_secret}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
}
data = {
"parent": {"database_id": database_id},
"properties": json.loads(properties),
}
response = requests.post("https://api.notion.com/v1/pages", headers=headers, json=data)
if response.status_code == 200:
page_id = response.json()["id"]
self.status = f"Successfully created Notion page with ID: {page_id}\n {str(response.json())}"
return response.json()
else:
error_message = f"Failed to create Notion page. Status code: {response.status_code}, Error: {response.text}"
self.status = error_message
raise Exception(error_message)
```
## Example Usage
<Admonition type="info" title="Example Usage">
Example of using the `AddContentToPage` component in a Langflow flow using Markdown as input:
<ZoomableImage
alt="NotionDatabaseProperties Flow Example"
sources={{
light: "img/notion/AddContentToPage_flow_example.png",
dark: "img/notion/AddContentToPage_flow_example.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
In this example, the `AddContentToPage` component connects to a `MarkdownLoader` component to provide the markdown text input. The converted Notion blocks are appended to the specified Notion page using the provided `block_id` and `notion_secret`.
</Admonition>
## Best Practices
When using the `AddContentToPage` component:
- Ensure markdown text is well-formatted.
- Verify the `block_id` corresponds to the right Notion page/block.
- Keep your Notion integration token secure.
- Test with sample markdown text before production use.
The `AddContentToPage` component is a powerful tool for integrating Notion content creation into Langflow workflows, facilitating easy conversion of markdown text to Notion blocks and appending them to specific pages.
## Troubleshooting
If you encounter any issues while using the `AddContentToPage` component, consider the following:
- Verify the Notion integration tokens validity and permissions.
- Check the Notion API documentation for updates.
- Ensure markdown text is properly formatted.
- Double-check the `block_id` for correctness.

View file

@ -0,0 +1,43 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# Introduction to Notion in Langflow
The Notion integration in Langflow enables seamless connectivity with Notion databases, pages, and users, facilitating automation and improving productivity.
<ZoomableImage
alt="Notion Components in Langflow"
sources={{
light: "img/notion/notion_bundle.jpg",
dark: "img/notion/notion_bundle.jpg",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
#### <a target="\_blank" href="json_files/Notion_Components_bundle.json" download>Download Notion Components Bundle</a>
### Key Features of Notion Integration in Langflow
- **List Pages**: Retrieve a list of pages from a Notion database and access data stored in your Notion workspace.
- **List Database Properties**: Obtain insights into the properties of a Notion database, allowing for easy understanding of its structure and metadata.
- **Add Page Content**: Programmatically add new content to a Notion page, simplifying the creation and updating of pages.
- **List Users**: Retrieve a list of users with access to a Notion workspace, aiding in user management and collaboration.
- **Update Property**: Update the value of a specific property in a Notion page, enabling easy modification and maintenance of Notion data.
### Potential Use Cases for Notion Integration in Langflow
- **Task Automation**: Automate task creation in Notion using Langflow's AI capabilities. Describe the required tasks, and they will be automatically created and updated in Notion.
- **Context Extraction from Meetings**: Leverage AI to analyze meeting contexts, extract key points, and update the relevant Notion pages automatically.
- **Content Creation**: Utilize AI to generate ideas, suggest templates, and populate Notion pages with relevant data, enhancing content management efficiency.
### Getting Started with Notion Integration in Langflow
1. **Set Up Notion Integration**: Follow the guide [Setting up a Notion App](./setup) to set up a Notion integration in your workspace.
2. **Configure Notion Components**: Provide the necessary authentication details and parameters to configure the Notion components in your Langflow flows.
3. **Connect Components**: Integrate Notion components with other Langflow components to build your workflow.
4. **Test and Refine**: Ensure your Langflow flow operates as intended by testing and refining it.
5. **Deploy and Run**: Deploy your Langflow flow to automate Notion-related tasks and processes.
The Notion integration in Langflow offers a powerful toolset for automation and productivity enhancement. Whether managing tasks, extracting meeting insights, or creating content, Langflow and Notion provide robust solutions for streamlining workflows.

View file

@ -0,0 +1,117 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# Database Properties
The `NotionDatabaseProperties` component retrieves properties of a Notion database. It provides a convenient way to integrate Notion database information into your Langflow workflows.
[Notion Reference](https://developers.notion.com/reference/post-database-query)
<Admonition type="tip" title="Component Functionality">
The `NotionDatabaseProperties` component enables you to:
- Retrieve properties of a Notion database
- Access the retrieved properties in your Langflow flows
- Integrate Notion database information seamlessly into your workflows
</Admonition>
## Component Usage
To use the `NotionDatabaseProperties` component in a Langflow flow, follow these steps:
1. Add the `NotionDatabaseProperties` component to your flow.
2. Configure the component by providing the required inputs:
- `database_id`: The ID of the Notion database you want to retrieve properties from.
- `notion_secret`: The Notion integration token for authentication.
3. Connect the output of the `NotionDatabaseProperties` component to other components in your flow as needed.
## Component Python code
```python
import requests
from typing import Dict
from langflow import CustomComponent
from langflow.schema import Record
class NotionDatabaseProperties(CustomComponent):
display_name = "List Database Properties [Notion]"
description = "Retrieve properties of a Notion database."
documentation: str = "https://docs.langflow.org/integrations/notion/list-database-properties"
icon = "NotionDirectoryLoader"
def build_config(self):
return {
"database_id": {
"display_name": "Database ID",
"field_type": "str",
"info": "The ID of the Notion database.",
},
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
}
def build(
self,
database_id: str,
notion_secret: str,
) -> Record:
url = f"https://api.notion.com/v1/databases/{database_id}"
headers = {
"Authorization": f"Bearer {notion_secret}",
"Notion-Version": "2022-06-28", # Use the latest supported version
}
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
properties = data.get("properties", {})
record = Record(text=str(response.json()), data=properties)
self.status = f"Retrieved {len(properties)} properties from the Notion database.\n {record.text}"
return record
```
## Example Usage
<Admonition type="info" title="Example Usage">
Here's an example of how you can use the `NotionDatabaseProperties` component in a Langflow flow:
<ZoomableImage
alt="NotionDatabaseProperties Flow Example"
sources={{
light: "img/notion/NotionDatabaseProperties_flow_example.png",
dark: "img/notion/NotionDatabaseProperties_flow_example_dark.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
In this example, the `NotionDatabaseProperties` component retrieves the properties of a Notion database, and the retrieved properties are then used as input for subsequent components in the flow.
</Admonition>
## Best Practices
When using the `NotionDatabaseProperties` component, consider the following best practices:
- Ensure that you have a valid Notion integration token with the necessary permissions to access the desired database.
- Double-check the database ID to avoid retrieving properties from the wrong database.
- Handle potential errors gracefully by checking the response status and providing appropriate error messages.
The `NotionDatabaseProperties` component simplifies the process of retrieving properties from a Notion database and integrating them into your Langflow workflows. By leveraging this component, you can easily access and utilize Notion database information in your flows, enabling powerful integrations and automations.
Feel free to explore the capabilities of the `NotionDatabaseProperties` component and experiment with different use cases to enhance your Langflow workflows!
## Troubleshooting
If you encounter any issues while using the `NotionDatabaseProperties` component, consider the following:
- Verify that the Notion integration token is valid and has the required permissions.
- Check the database ID to ensure it matches the intended Notion database.
- Inspect the response from the Notion API for any error messages or status codes that may indicate the cause of the issue.

View file

@ -0,0 +1,179 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# List Pages
The `NotionListPages` component queries a Notion database with filtering and sorting. It provides a convenient way to integrate Notion database querying capabilities into your Langflow workflows.
[Notion Reference](https://developers.notion.com/reference/post-database-query)
<Admonition type="tip" title="Component Functionality">
The `NotionListPages` component enables you to:
- Query a Notion database with custom filters and sorting options
- Retrieve specific pages from a Notion database based on the provided criteria
- Integrate Notion database data seamlessly into your Langflow workflows
</Admonition>
## Component Usage
To use the `NotionListPages
` component in a Langflow flow, follow these steps:
1. **Add the `NotionListPages
` component to your flow.**
2. **Configure the component by providing the required parameters:**
- `notion_secret`: The Notion integration token for authentication.
- `database_id`: The ID of the Notion database you want to query.
- `query_payload`: A JSON string containing the filters and sorting options for the query.
3. **Connect the `NotionListPages
` component to other components in your flow as needed.**
## Component Python code
```python
import requests
import json
from typing import Dict, Any, List
from langflow.custom import CustomComponent
from langflow.schema import Record
class NotionListPages(CustomComponent):
display_name = "List Pages [Notion]"
description = (
"Query a Notion database with filtering and sorting. "
"The input should be a JSON string containing the 'filter' and 'sorts' objects. "
"Example input:\n"
'{"filter": {"property": "Status", "select": {"equals": "Done"}}, "sorts": [{"timestamp": "created_time", "direction": "descending"}]}'
)
documentation: str = "https://docs.langflow.org/integrations/notion/list-pages"
icon = "NotionDirectoryLoader"
field_order = [
"notion_secret",
"database_id",
"query_payload",
]
def build_config(self):
return {
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
"database_id": {
"display_name": "Database ID",
"field_type": "str",
"info": "The ID of the Notion database to query.",
},
"query_payload": {
"display_name": "Database query",
"field_type": "str",
"info": "A JSON string containing the filters that will be used for querying the database. EG: {'filter': {'property': 'Status', 'status': {'equals': 'In progress'}}}",
},
}
def build(
self,
notion_secret: str,
database_id: str,
query_payload: str = "{}",
) -> List[Record]:
try:
query_data = json.loads(query_payload)
filter_obj = query_data.get("filter")
sorts = query_data.get("sorts", [])
url = f"https://api.notion.com/v1/databases/{database_id}/query"
headers = {
"Authorization": f"Bearer {notion_secret}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
}
data = {
"sorts": sorts,
}
if filter_obj:
data["filter"] = filter_obj
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
results = response.json()
records = []
combined_text = f"Pages found: {len(results['results'])}\n\n"
for page in results['results']:
page_data = {
'id': page['id'],
'url': page['url'],
'created_time': page['created_time'],
'last_edited_time': page['last_edited_time'],
'properties': page['properties'],
}
text = (
f"id: {page['id']}\n"
f"url: {page['url']}\n"
f"created_time: {page['created_time']}\n"
f"last_edited_time: {page['last_edited_time']}\n"
f"properties: {json.dumps(page['properties'], indent=2)}\n\n"
)
combined_text += text
records.append(Record(text=text, data=page_data))
self.status = combined_text.strip()
return records
except Exception as e:
self.status = f"An error occurred: {str(e)}"
return [Record(text=self.status, data=[])]
```
<Admonition type="info" title="Example Usage">
## Example Usage
Here's an example of how you can use the `NotionListPages` component in a Langflow flow and passing to the Prompt component:
<ZoomableImage
alt="NotionListPages
Flow Example"
sources={{
light: "img/notion/NotionListPages_flow_example.png",
dark: "img/notion/NotionListPages_flow_example_dark.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
In this example, the `NotionListPages` component is used to retrieve specific pages from a Notion database based on the provided filters and sorting options. The retrieved data can then be processed further in the subsequent components of the flow.
</Admonition>
## Best Practices
When using the `NotionListPages
` component, consider the following best practices:
- Ensure that you have a valid Notion integration token with the necessary permissions to query the desired database.
- Construct the `query_payload` JSON string carefully, following the Notion API documentation for filtering and sorting options.
The `NotionListPages
` component provides a powerful way to integrate Notion database querying capabilities into your Langflow workflows. By leveraging this component, you can easily retrieve specific pages from a Notion database based on custom filters and sorting options, enabling you to build more dynamic and data-driven flows.
We encourage you to explore the capabilities of the `NotionListPages
` component further and experiment with different querying scenarios to unlock the full potential of integrating Notion databases into your Langflow workflows.
## Troubleshooting
If you encounter any issues while using the `NotionListPages` component, consider the following:
- Double-check that the `notion_secret` and `database_id` are correct and valid.
- Verify that the `query_payload` JSON string is properly formatted and contains valid filtering and sorting options.
- Check the Notion API documentation for any updates or changes that may affect the component's functionality.

View file

@ -0,0 +1,127 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# User List
The `NotionUserList` component retrieves users from Notion. It provides a convenient way to integrate Notion user data into your Langflow workflows.
[Notion Reference](https://developers.notion.com/reference/get-users)
<Admonition type="tip" title="Component Functionality">
The `NotionUserList` component enables you to:
- Retrieve user data from Notion
- Access user information such as ID, type, name, and avatar URL
- Integrate Notion user data seamlessly into your Langflow workflows
</Admonition>
## Component Usage
To use the `NotionUserList` component in a Langflow flow, follow these steps:
1. Add the `NotionUserList` component to your flow.
2. Configure the component by providing the required Notion secret token.
3. Connect the component to other nodes in your flow as needed.
## Component Python code
```python
import requests
from typing import List
from langflow import CustomComponent
from langflow.schema import Record
class NotionUserList(CustomComponent):
display_name = "List Users [Notion]"
description = "Retrieve users from Notion."
documentation: str = "https://docs.langflow.org/integrations/notion/list-users"
icon = "NotionDirectoryLoader"
def build_config(self):
return {
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
}
def build(
self,
notion_secret: str,
) -> List[Record]:
url = "https://api.notion.com/v1/users"
headers = {
"Authorization": f"Bearer {notion_secret}",
"Notion-Version": "2022-06-28",
}
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
results = data['results']
records = []
for user in results:
id = user['id']
type = user['type']
name = user.get('name', '')
avatar_url = user.get('avatar_url', '')
record_data = {
"id": id,
"type": type,
"name": name,
"avatar_url": avatar_url,
}
output = "User:\n"
for key, value in record_data.items():
output += f"{key.replace('_', ' ').title()}: {value}\n"
output += "________________________\n"
record = Record(text=output, data=record_data)
records.append(record)
self.status = "\n".join(record.text for record in records)
return records
```
## Example Usage
<Admonition type="info" title="Example Usage">
Here's an example of how you can use the `NotionUserList` component in a Langflow flow and passing the outputs to the Prompt component:
<ZoomableImage
alt="NotionUserList Flow Example"
sources={{
light: "img/notion/NotionUserList_flow_example.png",
dark: "img/notion/NotionUserList_flow_example_dark.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
</Admonition>
## Best Practices
When using the `NotionUserList` component, consider the following best practices:
- Ensure that you have a valid Notion integration token with the necessary permissions to retrieve user data.
- Handle the retrieved user data securely and in compliance with Notion's API usage guidelines.
The `NotionUserList` component provides a seamless way to integrate Notion user data into your Langflow workflows. By leveraging this component, you can easily retrieve and utilize user information from Notion, enhancing the capabilities of your Langflow applications. Feel free to explore and experiment with the `NotionUserList` component to unlock new possibilities in your Langflow projects!
## Troubleshooting
If you encounter any issues while using the `NotionUserList` component, consider the following:
- Double-check that your Notion integration token is valid and has the required permissions.
- Verify that you have installed the necessary dependencies (`requests`) for the component to function properly.
- Check the Notion API documentation for any updates or changes that may affect the component's functionality.

View file

@ -0,0 +1,142 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# Page Content
The `NotionPageContent` component retrieves the content of a Notion page as plain text. It provides a convenient way to integrate Notion page content into your Langflow workflows.
[Notion Reference](https://developers.notion.com/reference/get-page)
<Admonition type="tip" title="Component Functionality">
The `NotionPageContent` component enables you to:
- Retrieve the content of a Notion page as plain text
- Extract text from various block types, including paragraphs, headings, lists, and more
- Integrate Notion page content seamlessly into your Langflow workflows
</Admonition>
## Component Usage
To use the `NotionPageContent` component in a Langflow flow, follow these steps:
1. Add the `NotionPageContent` component to your flow.
2. Configure the component by providing the required inputs:
- `page_id`: The ID of the Notion page you want to retrieve.
- `notion_secret`: Your Notion integration token for authentication.
3. Connect the output of the `NotionPageContent` component to other components in your flow as needed.
## Component Python code
```python
import requests
from typing import Dict, Any
from langflow import CustomComponent
from langflow.schema import Record
class NotionPageContent(CustomComponent):
display_name = "Page Content Viewer [Notion]"
description = "Retrieve the content of a Notion page as plain text."
documentation: str = "https://docs.langflow.org/integrations/notion/page-content-viewer"
icon = "NotionDirectoryLoader"
def build_config(self):
return {
"page_id": {
"display_name": "Page ID",
"field_type": "str",
"info": "The ID of the Notion page to retrieve.",
},
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
}
def build(
self,
page_id: str,
notion_secret: str,
) -> Record:
blocks_url = f"https://api.notion.com/v1/blocks/{page_id}/children?page_size=100"
headers = {
"Authorization": f"Bearer {notion_secret}",
"Notion-Version": "2022-06-28", # Use the latest supported version
}
# Retrieve the child blocks
blocks_response = requests.get(blocks_url, headers=headers)
blocks_response.raise_for_status()
blocks_data = blocks_response.json()
# Parse the blocks and extract the content as plain text
content = self.parse_blocks(blocks_data["results"])
self.status = content
return Record(data={"content": content}, text=content)
def parse_blocks(self, blocks: list) -> str:
content = ""
for block in blocks:
block_type = block["type"]
if block_type in ["paragraph", "heading_1", "heading_2", "heading_3", "quote"]:
content += self.parse_rich_text(block[block_type]["rich_text"]) + "\n\n"
elif block_type in ["bulleted_list_item", "numbered_list_item"]:
content += self.parse_rich_text(block[block_type]["rich_text"]) + "\n"
elif block_type == "to_do":
content += self.parse_rich_text(block["to_do"]["rich_text"]) + "\n"
elif block_type == "code":
content += self.parse_rich_text(block["code"]["rich_text"]) + "\n\n"
elif block_type == "image":
content += f"[Image: {block['image']['external']['url']}]\n\n"
elif block_type == "divider":
content += "---\n\n"
return content.strip()
def parse_rich_text(self, rich_text: list) -> str:
text = ""
for segment in rich_text:
text += segment["plain_text"]
return text
```
## Example Usage
<Admonition type="info" title="Example Usage">
Here's an example of how you can use the `NotionPageContent` component in a Langflow flow:
<ZoomableImage
alt="NotionPageContent Flow Example"
sources={{
light: "img/notion/NotionPageContent_flow_example.png",
dark: "img/notion/NotionPageContent_flow_example_dark.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
</Admonition>
## Best Practices
When using the `NotionPageContent` component, consider the following best practices:
- Ensure that you have the necessary permissions to access the Notion page you want to retrieve.
- Keep your Notion integration token secure and avoid sharing it publicly.
- Be mindful of the content you retrieve and ensure that it aligns with your intended use case.
The `NotionPageContent` component provides a seamless way to integrate Notion page content into your Langflow workflows. By leveraging this component, you can easily retrieve and process the content of Notion pages, enabling you to build powerful and dynamic applications. Explore the capabilities of the `NotionPageContent` component and unlock new possibilities in your Langflow projects!
## Troubleshooting
If you encounter any issues while using the `NotionPageContent` component, consider the following:
- Double-check that you have provided the correct Notion page ID.
- Verify that your Notion integration token is valid and has the necessary permissions.
- Check the Notion API documentation for any updates or changes that may affect the component's functionality.

View file

@ -0,0 +1,131 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# Page Create
The `NotionPageCreator` component creates pages in a Notion database. It provides a convenient way to integrate Notion page creation into your Langflow workflows.
[Notion Reference](https://developers.notion.com/reference/patch-block-children)
<Admonition type="tip" title="Component Functionality">
The `NotionPageCreator` component enables you to:
- Create new pages in a specified Notion database
- Set custom properties for the created pages
- Retrieve the ID and URL of the newly created pages
</Admonition>
## Component Usage
To use the `NotionPageCreator` component in a Langflow flow, follow these steps:
1. Add the `NotionPageCreator` component to your flow.
2. Configure the component by providing the required inputs:
- `database_id`: The ID of the Notion database where the pages will be created.
- `notion_secret`: The Notion integration token for authentication.
- `properties`: The properties of the new page, specified as a JSON string.
3. Connect the component to other components in your flow as needed.
4. Run the flow to create Notion pages based on the configured inputs.
## Component Python Code
```python
import json
from typing import Optional
import requests
from langflow.custom import CustomComponent
class NotionPageCreator(CustomComponent):
display_name = "Create Page [Notion]"
description = "A component for creating Notion pages."
documentation: str = "https://docs.langflow.org/integrations/notion/page-create"
icon = "NotionDirectoryLoader"
def build_config(self):
return {
"database_id": {
"display_name": "Database ID",
"field_type": "str",
"info": "The ID of the Notion database.",
},
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
"properties": {
"display_name": "Properties",
"field_type": "str",
"info": "The properties of the new page. Depending on your database setup, this can change. E.G: {'Task name': {'id': 'title', 'type': 'title', 'title': [{'type': 'text', 'text': {'content': 'Send Notion Components to LF', 'link': null}}]}}",
},
}
def build(
self,
database_id: str,
notion_secret: str,
properties: str = '{"Task name": {"id": "title", "type": "title", "title": [{"type": "text", "text": {"content": "Send Notion Components to LF", "link": null}}]}}',
) -> str:
if not database_id or not properties:
raise ValueError("Invalid input. Please provide 'database_id' and 'properties'.")
headers = {
"Authorization": f"Bearer {notion_secret}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
}
data = {
"parent": {"database_id": database_id},
"properties": json.loads(properties),
}
response = requests.post("https://api.notion.com/v1/pages", headers=headers, json=data)
if response.status_code == 200:
page_id = response.json()["id"]
self.status = f"Successfully created Notion page with ID: {page_id}\n {str(response.json())}"
return response.json()
else:
error_message = f"Failed to create Notion page. Status code: {response.status_code}, Error: {response.text}"
self.status = error_message
raise Exception(error_message)
```
## Example Usage
<Admonition type="info" title="Example Usage">
Here's an example of how to use the `NotionPageCreator` component in a Langflow flow:
<ZoomableImage
alt="NotionPageCreator Flow Example"
sources={{
light: "img/notion/NotionPageCreator_flow_example.png",
dark: "img/notion/NotionPageCreator_flow_example_dark.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
</Admonition>
## Best Practices
When using the `NotionPageCreator` component, consider the following best practices:
- Ensure that you have a valid Notion integration token with the necessary permissions to create pages in the specified database.
- Properly format the `properties` input as a JSON string, matching the structure and field types of your Notion database.
- Handle any errors or exceptions that may occur during the page creation process and provide appropriate error messages.
- To avoid the hassle of messing with JSON, we recommend using the LLM to create the JSON for you as input.
The `NotionPageCreator` component simplifies the process of creating pages in a Notion database directly from your Langflow workflows. By leveraging this component, you can seamlessly integrate Notion page creation functionality into your automated processes, saving time and effort. Feel free to explore the capabilities of the `NotionPageCreator` component and adapt it to suit your specific requirements.
## Troubleshooting
If you encounter any issues while using the `NotionPageCreator` component, consider the following:
- Double-check that the `database_id` and `notion_secret` inputs are correct and valid.
- Verify that the `properties` input is properly formatted as a JSON string and matches the structure of your Notion database.
- Check the Notion API documentation for any updates or changes that may affect the component's functionality.

View file

@ -0,0 +1,138 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# Page Update
The `NotionPageUpdate` component updates the properties of a Notion page. It provides a convenient way to integrate updating Notion page properties into your Langflow workflows.
[Notion Reference](https://developers.notion.com/reference/patch-page)
## Component Usage
To use the `NotionPageUpdate` component in your Langflow flow:
1. Drag and drop the `NotionPageUpdate` component onto the canvas.
2. Double-click the component to open its configuration.
3. Provide the required parameters as defined in the component's `build_config` method.
4. Connect the component to other nodes in your flow as needed.
## Component Python Code
```python
import json
import requests
from typing import Dict, Any
from langflow import CustomComponent
from langflow.schema import Record
class NotionPageUpdate(CustomComponent):
display_name = "Update Page Property [Notion]"
description = "Update the properties of a Notion page."
documentation: str = "https://docs.langflow.org/integrations/notion/page-update"
icon = "NotionDirectoryLoader"
def build_config(self):
return {
"page_id": {
"display_name": "Page ID",
"field_type": "str",
"info": "The ID of the Notion page to update.",
},
"properties": {
"display_name": "Properties",
"field_type": "str",
"info": "The properties to update on the page (as a JSON string).",
"multiline": True,
},
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
}
def build(
self,
page_id: str,
properties: str,
notion_secret: str,
) -> Record:
url = f"https://api.notion.com/v1/pages/{page_id}"
headers = {
"Authorization": f"Bearer {notion_secret}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28", # Use the latest supported version
}
try:
parsed_properties = json.loads(properties)
except json.JSONDecodeError as e:
raise ValueError("Invalid JSON format for properties") from e
data = {
"properties": parsed_properties
}
response = requests.patch(url, headers=headers, json=data)
response.raise_for_status()
updated_page = response.json()
output = "Updated page properties:\n"
for prop_name, prop_value in updated_page["properties"].items():
output += f"{prop_name}: {prop_value}\n"
self.status = output
return Record(data=updated_page)
```
Let's break down the key parts of this component:
- The `build_config` method defines the configuration fields for the component. It specifies the required parameters and their properties, such as display names, field types, and any additional information or validation.
- The `build` method contains the main logic of the component. It takes the configured parameters as input and performs the necessary operations to update the properties of a Notion page.
- The component interacts with the Notion API to update the page properties. It constructs the API URL, headers, and request data based on the provided parameters.
- The processed data is returned as a `Record` object, which can be connected to other components in the Langflow flow. The `Record` object contains the updated page data.
- The component also stores the updated page properties in the `status` attribute for logging and debugging purposes.
## Example Usage
<Admonition type="info" title="Example Usage">
Here's an example of how to use the `NotionPageUpdate` component in a Langflow flow using:
<ZoomableImage
alt="NotionPageUpdate Flow Example"
sources={{
light: "img/notion/NotionPageUpdate_flow_example.png",
dark: "img/notion/NotionPageUpdate_flow_example_dark.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
</Admonition>
## Best Practices
When using the `NotionPageUpdate` component, consider the following best practices:
- Ensure that you have a valid Notion integration token with the necessary permissions to update page properties.
- Handle edge cases and error scenarios gracefully, such as invalid JSON format for properties or API request failures.
- We recommend using an LLM to generate the inputs for this component, to allow flexibilty
By leveraging the `NotionPageUpdate` component in Langflow, you can easily integrate updating Notion page properties into your language model workflows and build powerful applications that extend Langflow's capabilities.
## Troubleshooting
If you encounter any issues while using the `NotionPageUpdate` component, consider the following:
- Double-check that you have correctly configured the component with the required parameters, including the page ID, properties JSON, and Notion integration token.
- Verify that your Notion integration token has the necessary permissions to update page properties.
- Check the Langflow logs for any error messages or exceptions related to the component, such as invalid JSON format or API request failures.
- Consult the [Notion API Documentation](https://developers.notion.com/reference/patch-page) for specific troubleshooting steps or common issues related to updating page properties.

View file

@ -0,0 +1,184 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# Notion Search
The `NotionSearch` component is designed to search all pages and databases that have been shared with an integration in Notion. It provides a convenient way to integrate Notion search capabilities into your Langflow workflows.
[Notion Reference](https://developers.notion.com/reference/search)
<Admonition type="tip" title="Component Functionality">
The `NotionSearch` component enables you to:
- Search for pages and databases in Notion that have been shared with an integration
- Filter the search results based on object type (pages or databases)
- Sort the search results in ascending or descending order based on the last edited time
</Admonition>
## Component Usage
To use the `NotionSearch` component in a Langflow flow, follow these steps:
1. **Add the `NotionSearch` component to your flow.**
2. **Configure the component by providing the required parameters:**
- `notion_secret`: The Notion integration token for authentication.
- `query`: The text to search for in page and database titles.
- `filter_value`: The type of objects to include in the search results (pages or databases).
- `sort_direction`: The direction to sort the search results (ascending or descending).
3. **Connect the `NotionSearch` component to other components in your flow as needed.**
## Component Python Code
```python
import requests
from typing import Dict, Any, List
from langflow.custom import CustomComponent
from langflow.schema import Record
class NotionSearch(CustomComponent):
display_name = "Search Notion"
description = (
"Searches all pages and databases that have been shared with an integration."
)
documentation: str = "https://docs.langflow.org/integrations/notion/search"
icon = "NotionDirectoryLoader"
field_order = [
"notion_secret",
"query",
"filter_value",
"sort_direction",
]
def build_config(self):
return {
"notion_secret": {
"display_name": "Notion Secret",
"field_type": "str",
"info": "The Notion integration token.",
"password": True,
},
"query": {
"display_name": "Search Query",
"field_type": "str",
"info": "The text that the API compares page and database titles against.",
},
"filter_value": {
"display_name": "Filter Type",
"field_type": "str",
"info": "Limits the results to either only pages or only databases.",
"options": ["page", "database"],
"default_value": "page",
},
"sort_direction": {
"display_name": "Sort Direction",
"field_type": "str",
"info": "The direction to sort the results.",
"options": ["ascending", "descending"],
"default_value": "descending",
},
}
def build(
self,
notion_secret: str,
query: str = "",
filter_value: str = "page",
sort_direction: str = "descending",
) -> List[Record]:
try:
url = "https://api.notion.com/v1/search"
headers = {
"Authorization": f"Bearer {notion_secret}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
}
data = {
"query": query,
"filter": {
"value": filter_value,
"property": "object"
},
"sort":{
"direction": sort_direction,
"timestamp": "last_edited_time"
}
}
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
results = response.json()
records = []
combined_text = f"Results found: {len(results['results'])}\n\n"
for result in results['results']:
result_data = {
'id': result['id'],
'type': result['object'],
'last_edited_time': result['last_edited_time'],
}
if result['object'] == 'page':
result_data['title_or_url'] = result['url']
text = f"id: {result['id']}\ntitle_or_url: {result['url']}\n"
elif result['object'] == 'database':
if 'title' in result and isinstance(result['title'], list) and len(result['title']) > 0:
result_data['title_or_url'] = result['title'][0]['plain_text']
text = f"id: {result['id']}\ntitle_or_url: {result['title'][0]['plain_text']}\n"
else:
result_data['title_or_url'] = "N/A"
text = f"id: {result['id']}\ntitle_or_url: N/A\n"
text += f"type: {result['object']}\nlast_edited_time: {result['last_edited_time']}\n\n"
combined_text += text
records.append(Record(text=text, data=result_data))
self.status = combined_text
return records
except Exception as e:
self.status = f"An error occurred: {str(e)}"
return [Record(text=self.status, data=[])]
```
## Example Usage
<Admonition type="info" title="Example Usage">
Here's an example of how you can use the `NotionSearch` component in a Langflow flow:
<ZoomableImage
alt="NotionSearch Flow Example"
sources={{
light: "img/notion/NotionSearch_flow_example.png",
dark: "img/notion/NotionSearch_flow_example_dark.png",
}}
style={{ width: "100%", margin: "20px 0" }}
/>
In this example, the `NotionSearch` component is used to search for pages and databases in Notion based on the provided query and filter criteria. The retrieved data can then be processed further in the subsequent components of the flow.
</Admonition>
## Best Practices
When using the `NotionSearch` component, consider these best practices:
- Ensure you have a valid Notion integration token with the necessary permissions to search for pages and databases.
- Provide a meaningful search query to narrow down the results to the desired pages or databases.
- Choose the appropriate filter type (`page` or `database`) based on your search requirements.
- Consider the sorting direction (`ascending` or `descending`) to organize the search results effectively.
The `NotionSearch` component provides a powerful way to integrate Notion search capabilities into your Langflow workflows. By leveraging this component, you can easily search for pages and databases in Notion based on custom queries and filters, enabling you to build more dynamic and data-driven flows.
We encourage you to explore the capabilities of the `NotionSearch` component further and experiment with different search scenarios to unlock the full potential of integrating Notion search into your Langflow workflows.
## Troubleshooting
If you encounter any issues while using the `NotionSearch` component, consider the following:
- Double-check that the `notion_secret` is correct and valid.
- Verify that the Notion integration has the necessary permissions to access the desired pages and databases.
- Check the Notion API documentation for any updates or changes that may affect the component's functionality.

View file

@ -0,0 +1,78 @@
import Admonition from "@theme/Admonition";
# Setting up a Notion App
To use Notion components in Langflow, you first need to create a Notion integration and configure it with the necessary capabilities. This guide will walk you through the process of setting up a Notion integration and granting it access to your Notion databases.
## Prerequisites
- A Notion account with access to the workspace where you want to use the integration.
- Admin permissions in the Notion workspace to create and manage integrations.
## Step 1: Create a Notion Integration
1. Go to the [Notion Integrations](https://www.notion.com/my-integrations) page.
2. Click on the "New integration" button.
3. Give your integration a name and select the workspace where you want to use it.
4. Click "Submit" to create the integration.
<Admonition type="info" title="Integration Capabilities">
When creating the integration, make sure to enable the necessary capabilities based on your requirements. Refer to the [Notion Integration Capabilities](https://developers.notion.com/reference/capabilities) documentation for more information on each capability.
</Admonition>
## Step 2: Configure Integration Capabilities
After creating the integration, you need to configure its capabilities to define what actions it can perform and what data it can access.
1. In the integration settings page, go to the **Capabilities** tab.
2. Enable the required capabilities for your integration. For example:
- If your integration needs to read data from Notion, enable the "Read content" capability.
- If your integration needs to create new content in Notion, enable the "Insert content" capability.
- If your integration needs to update existing content in Notion, enable the "Update content" capability.
3. Configure the user information access level based on your integration's requirements.
4. Save the changes.
## Step 3: Obtain Integration Token
To authenticate your integration with Notion, you need to obtain an integration token.
1. In the integration settings page, go to the "Secrets" tab.
2. Copy the "Internal Integration Token" value. This token will be used to authenticate your integration with Notion.
<Admonition type="warning" title="Keep Your Token Secure">
Your integration token is a sensitive piece of information. Make sure to keep it secure and never share it publicly. Store it safely in your Langflow configuration or environment variables.
</Admonition>
## Step 4: Grant Integration Access to Notion Databases
For your integration to interact with Notion databases, you need to grant it access to the specific databases it will be working with.
1. Open the Notion database that you want your integration to access.
2. Click on the "Share" button in the top-right corner of the page.
3. In the "Invite" section, select your integration from the list.
4. Click "Invite" to grant the integration access to the database.
<Admonition type="info" title="Nested Databases">
If your database contains references to other databases, you need to grant the integration access to those referenced databases as well. Repeat step 4 for each referenced database to ensure your integration has the necessary access.
</Admonition>
## Using Notion Components in Langflow
Once you have set up your Notion integration and granted it access to the required databases, you can start using the Notion components in Langflow.
Langflow provides the following Notion components:
- **List Pages**: Retrieves a list of pages from a Notion database.
- **List Database Properties**: Retrieves the properties of a Notion database.
- **Add Page Content**: Adds content to a Notion page.
- **List Users**: Retrieves a list of users with access to a Notion workspace.
- **Update Property**: Updates the value of a property in a Notion page.
Refer to the individual component documentation for more details on how to use each component in your Langflow flows.
## Additional Resources
- [Notion API Documentation](https://developers.notion.com/docs/getting-started)
- [Notion Integration Capabilities](https://developers.notion.com/reference/capabilities)
If you encounter any issues or have questions, please reach out to our support team or consult the Langflow community forums.

View file

@ -105,6 +105,8 @@ The default list at the moment is:
- PINECONE_API_KEY
- SEARCHAPI_API_KEY
- SERPAPI_API_KEY
- UPSTASH_VECTOR_REST_URL
- UPSTASH_VECTOR_REST_TOKEN
- VECTARA_CUSTOMER_ID
- VECTARA_CORPUS_ID
- VECTARA_API_KEY

View file

@ -1,4 +1,4 @@
# Common Installation Issues
# ❗️ Common Installation Issues
This is a list of possible issues that you may encounter when installing Langflow 1.0 alpha and how to solve them.
@ -25,11 +25,11 @@ ModuleNotFoundError: No module named 'langflow.__main__'
There are two possible reasons for this error:
1. You've installed Langflow using _`pip install langflow`_ but you already had a previous version of Langflow installed in your system.
In this case, you might be running the wrong executable.
To solve this issue, run the correct executable by running _`python -m langflow run`_ instead of _`langflow run`_.
If that doesn't work, try uninstalling and reinstalling Langflow with _`python -m pip install langflow --pre -U`_.
In this case, you might be running the wrong executable.
To solve this issue, run the correct executable by running _`python -m langflow run`_ instead of _`langflow run`_.
If that doesn't work, try uninstalling and reinstalling Langflow with _`python -m pip install langflow --pre -U`_.
2. Some version conflicts might have occurred during the installation process.
Run _`python -m pip install langflow --pre -U --force-reinstall`_ to reinstall Langflow and its dependencies.
Run _`python -m pip install langflow --pre -U --force-reinstall`_ to reinstall Langflow and its dependencies.
## _`Something went wrong running migrations. Please, run 'langflow migration --fix'`_
@ -45,4 +45,3 @@ There are two possible reasons for this error:
This error can occur during Langflow upgrades when the new version can't override `langflow-pre.db` in `.cache/langflow/`. Clearing the cache removes this file but will also erase your settings.
If you wish to retain your files, back them up before clearing the folder.

View file

@ -4,7 +4,7 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Basic prompting
# Basic Prompting
Prompts serve as the inputs to a large language model (LLM), acting as the interface between human instructions and computational tasks.
@ -14,36 +14,17 @@ This article demonstrates how to use Langflow's prompt tools to issue basic prom
## Prerequisites
1. Install Langflow.
```bash
python -m pip install langflow --pre
```
- [Langflow installed and running](../getting-started/install-langflow.mdx)
2. Start a local Langflow instance with the Langflow CLI:
```bash
langflow run
```
Or start Langflow with Python:
```bash
python -m langflow run
```
Result:
```
│ Welcome to ⛓ Langflow │
│ │
│ Access http://127.0.0.1:7860 │
│ Collaborate, and contribute at our GitHub Repo 🚀 │
```
- [OpenAI API key created](https://platform.openai.com)
<Admonition type="info">
Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true)
to create your own Langflow workspace in minutes.
</Admonition>
3. Create an [OpenAI API key](https://platform.openai.com).
## Create the basic prompting project
1. From the Langflow dashboard, click **New Project**.
@ -64,25 +45,21 @@ Examine the **Prompt** component. The **Template** field instructs the LLM to `A
This should be interesting...
4. To create an environment variable for the **OpenAI** component, in the **OpenAI API Key** field, click the **Globe** button, and then click **Add New Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
## Run the basic prompting flow
1. Click the **Run** button.
The **Interaction Panel** opens, where you can converse with your bot.
The **Interaction Panel** opens, where you can converse with your bot.
2. Type a message and press Enter.
The bot responds in a markedly piratical manner!
The bot responds in a markedly piratical manner!
## Modify the prompt for a different result
1. To modify your prompt results, in the **Prompt** template, click the **Template** field.
The **Edit Prompt** window opens.
The **Edit Prompt** window opens.
2. Change `Answer the user as if you were a pirate` to a different character, perhaps `Answer the user as if you were Harold Abelson.`
3. Run the basic prompting flow again.
The response will be markedly different.
The response will be markedly different.

View file

@ -4,42 +4,23 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Blog writer
# Blog Writer
Build a blog writer with OpenAI that uses URLs for reference content.
## Prerequisites
1. Install Langflow.
```bash
python -m pip install langflow --pre
```
- [Langflow installed and running](../getting-started/install-langflow.mdx)
2. Start a local Langflow instance with the Langflow CLI:
```bash
langflow run
```
Or start Langflow with Python:
```bash
python -m langflow run
```
Result:
```bash
│ Welcome to ⛓ Langflow │
│ │
│ Access http://127.0.0.1:7860 │
│ Collaborate, and contribute at our GitHub Repo 🚀 │
```
- [OpenAI API key created](https://platform.openai.com)
<Admonition type="info">
Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true)
to create your own Langflow workspace in minutes.
</Admonition>
3. Create an [OpenAI API key](https://platform.openai.com).
## Create the Blog Writer project
1. From the Langflow dashboard, click **New Project**.
@ -58,6 +39,7 @@ Result:
This flow creates a one-shot prompt flow with **Prompt**, **OpenAI**, and **Chat Output** components, and augments the flow with reference content and instructions from the **URL** and **Instructions** components.
The **Prompt** component's default **Template** field looks like this:
```bash
Reference 1:
@ -81,16 +63,16 @@ The `{instructions}` value is received from the **Value** field of the **Instruc
The `reference_1` and `reference_2` values are received from the **URL** fields of the **URL** components.
4. To create an environment variable for the **OpenAI** component, in the **OpenAI API Key** field, click the **Globe** button, and then click **Add New Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
## Run the Blog Writer flow
1. Click the **Run** button.
The **Interaction Panel** opens, where you can run your one-shot flow.
The **Interaction Panel** opens, where you can run your one-shot flow.
2. Click the **Lighting Bolt** icon to run your flow.
3. The **OpenAI** component constructs a blog post with the **URL** items as context.
The default **URL** values are for web pages at `promptingguide.ai`, so your blog post will be about prompting LLMs.
The default **URL** values are for web pages at `promptingguide.ai`, so your blog post will be about prompting LLMs.
To write about something different, change the values in the **URL** components, and see what the LLM constructs.
To write about something different, change the values in the **URL** components, and see what the LLM constructs.

View file

@ -10,36 +10,17 @@ Build a question-and-answer chatbot with a document loaded from local memory.
## Prerequisites
1. Install Langflow.
```bash
python -m pip install langflow --pre
```
- [Langflow installed and running](../getting-started/install-langflow.mdx)
2. Start a local Langflow instance with the Langflow CLI:
```bash
langflow run
```
Or start Langflow with Python:
```bash
python -m langflow run
```
Result:
```
│ Welcome to ⛓ Langflow │
│ │
│ Access http://127.0.0.1:7860 │
│ Collaborate, and contribute at our GitHub Repo 🚀 │
```
- [OpenAI API key created](https://platform.openai.com)
<Admonition type="info">
Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true)
to create your own Langflow workspace in minutes.
</Admonition>
3. Create an [OpenAI API key](https://platform.openai.com).
## Create the Document QA project
1. From the Langflow dashboard, click **New Project**.
@ -61,24 +42,27 @@ The **Prompt** component is instructed to answer questions based on the contents
Including a file with the prompt gives the **OpenAI** component context it may not otherwise have access to.
4. To create an environment variable for the **OpenAI** component, in the **OpenAI API Key** field, click the **Globe** button, and then click **Add New Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
5. To select a document to load, in the **Files** component, click within the **Path** field.
1. Select a local file, and then click **Open**.
2. The file name appears in the field.
<Admonition type="tip">
The file must be of an extension type listed [here](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/base/data/utils.py#L13).
</Admonition>
1. Select a local file, and then click **Open**.
2. The file name appears in the field.
<Admonition type="tip">
The file must be of an extension type listed
[here](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/base/data/utils.py#L13).
</Admonition>
## Run the Document QA flow
1. Click the **Run** button.
The **Interaction Panel** opens, where you can converse with your bot.
The **Interaction Panel** opens, where you can converse with your bot.
2. Type a message and press Enter.
For this example, we loaded an error log `.txt` file and asked, "What went wrong?"
The bot responded:
For this example, we loaded an error log `.txt` file and asked, "What went wrong?"
The bot responded:
```
The issue occurred during the execution of migrations in the application. Specifically, an error was raised by the Alembic library, indicating that new upgrade operations were detected that had not been accounted for in the existing migration scripts. The operation in question involved modifying the nullable property of a column (apikey, created_at) in the database, with details about the existing type (DATETIME()), existing server default, and other properties.
```

View file

@ -4,42 +4,23 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Memory chatbot
# Memory Chatbot
This flow extends the [basic prompting flow](./basic-prompting.mdx) to include chat memory for unique SessionIDs.
## Prerequisites
1. Install Langflow.
```bash
python -m pip install langflow --pre
```
- [Langflow installed and running](../getting-started/install-langflow.mdx)
2. Start a local Langflow instance with the Langflow CLI:
```bash
langflow run
```
Or start Langflow with Python:
```bash
python -m langflow run
```
Result:
```
│ Welcome to ⛓ Langflow │
│ │
│ Access http://127.0.0.1:7860 │
│ Collaborate, and contribute at our GitHub Repo 🚀 │
```
- [OpenAI API key created](https://platform.openai.com)
<Admonition type="info">
Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true)
to create your own Langflow workspace in minutes.
</Admonition>
3. Create an [OpenAI API key](https://platform.openai.com).
## Create the memory chatbot project
1. From the Langflow dashboard, click **New Project**.
@ -65,16 +46,16 @@ This chatbot is augmented with the **Chat Memory** component, which stores messa
The **Chat History** component gives the **OpenAI** component a memory of previous questions.
4. To create an environment variable for the **OpenAI** component, in the **OpenAI API Key** field, click the **Globe** button, and then click **Add New Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
## Run the memory chatbot flow
1. Click the **Run** button.
The **Interaction Panel** opens, where you can converse with your bot.
The **Interaction Panel** opens, where you can converse with your bot.
2. Type a message and press Enter.
The bot will respond according to the template in the **Prompt** component.
The bot will respond according to the template in the **Prompt** component.
3. Type more questions. In the **Outputs** log, your queries are logged in order. Up to 5 queries are stored by default. Try asking `What is the first subject I asked you about?` to see where the LLM's memory disappears.
## Modify the Session ID field to have multiple conversations
@ -87,11 +68,11 @@ You can demonstrate this by modifying the **Session ID** value to switch between
1. In the **Session ID** field of the **Chat Memory** and **Chat Input** components, change the **Session ID** value from `MySessionID` to `AnotherSessionID`.
2. Click the **Run** button to run your flow.
In the **Interaction Panel**, you will have a new conversation. (You may need to clear the cache with the **Eraser** button).
In the **Interaction Panel**, you will have a new conversation. (You may need to clear the cache with the **Eraser** button).
3. Type a few questions to your bot.
4. In the **Session ID** field of the **Chat Memory** and **Chat Input** components, change the **Session ID** value back to `MySessionID`.
5. Run your flow.
The **Outputs** log of the **Interaction Panel** displays the history from your initial chat with `MySessionID`.
The **Outputs** log of the **Interaction Panel** displays the history from your initial chat with `MySessionID`.
## Store Session ID as a Langflow variable
@ -101,4 +82,3 @@ To store **Session ID** as a Langflow variable, in the **Session ID** field, cli
2. In the **Value** field, enter a value like `1B5EBD79-6E9C-4533-B2C8-7E4FF29E983B`.
3. Click **Save Variable**.
4. Apply this variable to **Chat Input**.

View file

@ -4,7 +4,7 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# Vector store RAG
# Vector Store RAG
Retrieval Augmented Generation, or RAG, is a pattern for training LLMs on your data and querying it.
@ -17,16 +17,19 @@ We've chosen [Astra DB](https://astra.datastax.com/signup?utm_source=langflow-pr
## Prerequisites
<Admonition type="info">
Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](../getting-started/huggingface-spaces) to install it locally.
Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space
using this
link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true)
to create your own Langflow workspace in minutes.
</Admonition>
* [Langflow installed](../getting-started/install-langflow.mdx)
- [Langflow installed and running](../getting-started/install-langflow.mdx)
* [OpenAI API key](https://platform.openai.com)
- [OpenAI API key](https://platform.openai.com)
* [An Astra DB vector database created](https://docs.datastax.com/en/astra-db-serverless/get-started/quickstart.html) with:
* Application token (`AstraCS:WSnyFUhRxsrg…`)
* API endpoint (`https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com`)
- [An Astra DB vector database created](https://docs.datastax.com/en/astra-db-serverless/get-started/quickstart.html) with:
- Application token (`AstraCS:WSnyFUhRxsrg…`)
- API endpoint (`https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com`)
## Create the vector store RAG project
@ -49,38 +52,40 @@ The **ingestion** flow (bottom of the screen) populates the vector store with da
It ingests data from a file (**File**), splits it into chunks (**Recursive Character Text Splitter**), indexes it in Astra DB (**Astra DB**), and computes embeddings for the chunks (**OpenAI Embeddings**).
This forms a "brain" for the query flow.
The **query** flow (top of the screen) allows users to chat with the embedded vector store data. It's a little more complex:
The **query** flow (top of the screen) allows users to chat with the embedded vector store data. It's a little more complex:
* **Chat Input** component defines where to put the user input coming from the Playground.
* **OpenAI Embeddings** component generates embeddings from the user input.
* **Astra DB Search** component retrieves the most relevant Records from the Astra DB database.
* **Text Output** component turns the Records into Text by concatenating them and also displays it in the Playground.
* **Prompt** component takes in the user input and the retrieved Records as text and builds a prompt for the OpenAI model.
* **OpenAI** component generates a response to the prompt.
* **Chat Output** component displays the response in the Playground.
- **Chat Input** component defines where to put the user input coming from the Playground.
- **OpenAI Embeddings** component generates embeddings from the user input.
- **Astra DB Search** component retrieves the most relevant Records from the Astra DB database.
- **Text Output** component turns the Records into Text by concatenating them and also displays it in the Playground.
- **Prompt** component takes in the user input and the retrieved Records as text and builds a prompt for the OpenAI model.
- **OpenAI** component generates a response to the prompt.
- **Chat Output** component displays the response in the Playground.
4. To create an environment variable for the **OpenAI** component, in the **OpenAI API Key** field, click the **Globe** button, and then click **Add New Variable**.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
4. To create environment variables for the **Astra DB** and **Astra DB Search** components:
1. In the **Token** field, click the **Globe** button, and then click **Add New Variable**.
2. In the **Variable Name** field, enter `astra_token`.
3. In the **Value** field, paste your Astra application token (`AstraCS:WSnyFUhRxsrg…`).
4. Click **Save Variable**.
5. Repeat the above steps for the **API Endpoint** field, pasting your Astra API Endpoint instead (`https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com`).
6. Add the global variable to both the **Astra DB** and **Astra DB Search** components.
1. In the **Variable Name** field, enter `openai_api_key`.
2. In the **Value** field, paste your OpenAI API Key (`sk-...`).
3. Click **Save Variable**.
5. To create environment variables for the **Astra DB** and **Astra DB Search** components:
1. In the **Token** field, click the **Globe** button, and then click **Add New Variable**.
2. In the **Variable Name** field, enter `astra_token`.
3. In the **Value** field, paste your Astra application token (`AstraCS:WSnyFUhRxsrg…`).
4. Click **Save Variable**.
5. Repeat the above steps for the **API Endpoint** field, pasting your Astra API Endpoint instead (`https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com`).
6. Add the global variable to both the **Astra DB** and **Astra DB Search** components.
## Run the vector store RAG flow
1. Click the **Playground** button.
The **Playground** opens, where you can chat with your data.
The **Playground** opens, where you can chat with your data.
2. Type a message and press Enter. (Try something like "What topics do you know about?")
3. The bot will respond with a summary of the data you've embedded.
For example, we embedded a PDF of an engine maintenance manual and asked, "How do I change the oil?"
The bot responds:
```
To change the oil in the engine, follow these steps:
@ -102,7 +107,3 @@ You should use a 3/8 inch wrench to remove the oil drain cap.
```
This is the size the engine manual lists as well. This confirms our flow works, because the query returns the unique knowledge we embedded from the Astra vector store.

View file

@ -3,7 +3,7 @@ import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
# Building chatbots with System Message
# Building Chatbots with System Message
## Overview

View file

@ -3,7 +3,7 @@ import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
# Integrating documents with prompt variables
# Integrating Documents with Prompt Variables
## Overview

View file

@ -14,7 +14,8 @@ module.exports = {
"index",
"getting-started/install-langflow",
"getting-started/quickstart",
"getting-started/huggingface-spaces",
"getting-started/canvas",
"migration/possible-installation-issues",
"getting-started/new-to-llms",
],
},
@ -35,15 +36,12 @@ module.exports = {
label: "Administration",
collapsed: false,
items: [
"administration/login",
"administration/api",
"administration/login",
"administration/cli",
"administration/playground",
"administration/global-env",
"administration/components",
"administration/collection",
"administration/prompt-customization",
"administration/langfuse_integration",
"administration/chat-widget",
],
},
{
@ -82,13 +80,13 @@ module.exports = {
label: "Example Components",
collapsed: true,
items: [
"examples/flow-runner",
"examples/conversation-chain",
"examples/buffer-memory",
"examples/csv-loader",
"examples/searchapi-tool",
"examples/serp-api-tool",
"examples/python-function",
"examples/chat-memory",
"examples/combine-text",
"examples/create-record",
"examples/pass",
"examples/store-message",
"examples/sub-flow",
"examples/text-operator",
],
},
{
@ -131,5 +129,28 @@ module.exports = {
"contributing/contribute-component",
],
},
{
type: "category",
label: "Integrations",
collapsed: false,
items: [
{
type: "category",
label: "Notion",
items: [
"integrations/notion/intro",
"integrations/notion/setup",
"integrations/notion/search",
"integrations/notion/list-database-properties",
"integrations/notion/list-pages",
"integrations/notion/list-users",
"integrations/notion/page-create",
"integrations/notion/add-content-to-page",
"integrations/notion/page-update",
"integrations/notion/page-content-viewer",
],
},
],
},
],
};

View file

@ -532,10 +532,10 @@
"advanced": false,
"dynamic": false,
"info": "",
"load_from_db": false,
"load_from_db": true,
"title_case": false,
"input_types": ["Text"],
"value": ""
"value": "OPENAI_API_KEY"
},
"openai_api_type": {
"type": "str",

BIN
docs/static/img/api-window.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

BIN
docs/static/img/chat-input-with-menu.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

BIN
docs/static/img/langflow_basic_howto.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
docs/static/img/notion/notion_bundle.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
docs/static/img/project-options-menu.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
docs/static/img/single-component.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

File diff suppressed because one or more lines are too long

8
docs/static/logos/botmessage.svg vendored Normal file
View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bot-message-square">
<path d="M12 6V2H8" />
<path d="m8 18-4 4V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2Z" />
<path d="M2 12h2" />
<path d="M9 11v2" />
<path d="M15 11v2" />
<path d="M20 12h2" />
</svg>

After

Width:  |  Height:  |  Size: 417 B

Some files were not shown because too many files have changed in this diff Show more