|
.PHONY: all init format lint build build_frontend install_frontend run_frontend run_backend dev help tests coverage clean_python_cache clean_npm_cache clean_all |
|
|
|
# Configurations |
|
VERSION=$(shell grep "^version" pyproject.toml | sed 's/.*\"\(.*\)\"$$/\1/') |
|
DOCKERFILE=docker/build_and_push.Dockerfile |
|
DOCKERFILE_BACKEND=docker/build_and_push_backend.Dockerfile |
|
DOCKERFILE_FRONTEND=docker/frontend/build_and_push_frontend.Dockerfile |
|
DOCKER_COMPOSE=docker_example/docker-compose.yml |
|
PYTHON_REQUIRED=$(shell grep '^requires-python[[:space:]]*=' pyproject.toml | sed -n 's/.*"\([^"]*\)".*/\1/p') |
|
RED=\033[0;31m |
|
NC=\033[0m # No Color |
|
GREEN=\033[0;32m |
|
|
|
log_level ?= debug |
|
host ?= 0.0.0.0 |
|
port ?= 7860 |
|
env ?= .env |
|
open_browser ?= true |
|
path = src/backend/base/langflow/frontend |
|
workers ?= 1 |
|
async ?= true |
|
lf ?= false |
|
ff ?= true |
|
all: help |
|
|
|
###################### |
|
# UTILITIES |
|
###################### |
|
|
|
# increment the patch version of the current package |
|
patch: ## bump the version in langflow and langflow-base |
|
@echo 'Patching the version' |
|
@poetry version patch |
|
@echo 'Patching the version in langflow-base' |
|
@cd src/backend/base && poetry version patch |
|
@make lock |
|
|
|
# check for required tools |
|
check_tools: |
|
@command -v uv >/dev/null 2>&1 || { echo >&2 "$(RED)uv is not installed. Aborting.$(NC)"; exit 1; } |
|
@command -v npm >/dev/null 2>&1 || { echo >&2 "$(RED)NPM is not installed. Aborting.$(NC)"; exit 1; } |
|
@echo "$(GREEN)All required tools are installed.$(NC)" |
|
|
|
|
|
help: ## show this help message |
|
@echo '----' |
|
@grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | \ |
|
awk -F ':.*##' '{printf "\033[36mmake %s\033[0m: %s\n", $$1, $$2}' | \ |
|
column -c2 -t -s : |
|
@echo '----' |
|
|
|
###################### |
|
# INSTALL PROJECT |
|
###################### |
|
|
|
reinstall_backend: ## forces reinstall all dependencies (no caching) |
|
@echo 'Installing backend dependencies' |
|
@uv sync -n --reinstall --frozen |
|
|
|
install_backend: ## install the backend dependencies |
|
@echo 'Installing backend dependencies' |
|
@uv sync --frozen |
|
|
|
install_frontend: ## install the frontend dependencies |
|
@echo 'Installing frontend dependencies' |
|
@cd src/frontend && npm install > /dev/null 2>&1 |
|
|
|
build_frontend: ## build the frontend static files |
|
@echo 'Building frontend static files' |
|
@cd src/frontend && CI='' npm run build > /dev/null 2>&1 |
|
@rm -rf src/backend/base/langflow/frontend |
|
@cp -r src/frontend/build src/backend/base/langflow/frontend |
|
|
|
init: check_tools clean_python_cache clean_npm_cache ## initialize the project |
|
@make install_backend |
|
@make install_frontend |
|
@make build_frontend |
|
@echo "$(GREEN)All requirements are installed.$(NC)" |
|
@uv run langflow run |
|
|
|
###################### |
|
# CLEAN PROJECT |
|
###################### |
|
|
|
clean_python_cache: |
|
@echo "Cleaning Python cache..." |
|
find . -type d -name '__pycache__' -exec rm -r {} + |
|
find . -type f -name '*.py[cod]' -exec rm -f {} + |
|
find . -type f -name '*~' -exec rm -f {} + |
|
find . -type f -name '.*~' -exec rm -f {} + |
|
find . -type d -empty -delete |
|
@echo "$(GREEN)Python cache cleaned.$(NC)" |
|
|
|
clean_npm_cache: |
|
@echo "Cleaning npm cache..." |
|
cd src/frontend && npm cache clean --force |
|
rm -rf src/frontend/node_modules src/frontend/build src/backend/base/langflow/frontend src/frontend/package-lock.json |
|
@echo "$(GREEN)NPM cache and frontend directories cleaned.$(NC)" |
|
|
|
clean_all: clean_python_cache clean_npm_cache # clean all caches and temporary directories |
|
@echo "$(GREEN)All caches and temporary directories cleaned.$(NC)" |
|
|
|
setup_uv: ## install poetry using pipx |
|
pipx install uv |
|
|
|
add: |
|
@echo 'Adding dependencies' |
|
ifdef devel |
|
@cd src/backend/base && uv add --group dev $(devel) |
|
endif |
|
|
|
ifdef main |
|
@uv add $(main) |
|
endif |
|
|
|
ifdef base |
|
@cd src/backend/base && uv add $(base) |
|
endif |
|
|
|
|
|
|
|
###################### |
|
# CODE TESTS |
|
###################### |
|
|
|
coverage: ## run the tests and generate a coverage report |
|
@uv run coverage run |
|
@uv run coverage erase |
|
|
|
unit_tests: ## run unit tests |
|
@uv sync --extra dev --frozen |
|
@EXTRA_ARGS="" |
|
@if [ "$(async)" = "true" ]; then \ |
|
EXTRA_ARGS="$$EXTRA_ARGS --instafail -n auto"; \ |
|
fi; \ |
|
if [ "$(lf)" = "true" ]; then \ |
|
EXTRA_ARGS="$$EXTRA_ARGS --lf"; \ |
|
fi; \ |
|
if [ "$(ff)" = "true" ]; then \ |
|
EXTRA_ARGS="$$EXTRA_ARGS --ff"; \ |
|
fi; \ |
|
uv run pytest src/backend/tests --ignore=src/backend/tests/integration $$EXTRA_ARGS --instafail -ra -m 'not api_key_required' --durations-path src/backend/tests/.test_durations --splitting-algorithm least_duration $(args) |
|
|
|
unit_tests_looponfail: |
|
@make unit_tests args="-f" |
|
|
|
integration_tests: |
|
uv run pytest src/backend/tests/integration \ |
|
--instafail -ra \ |
|
$(args) |
|
|
|
integration_tests_no_api_keys: |
|
uv run pytest src/backend/tests/integration \ |
|
--instafail -ra -m "not api_key_required" \ |
|
$(args) |
|
|
|
integration_tests_api_keys: |
|
uv run pytest src/backend/tests/integration \ |
|
--instafail -ra -m "api_key_required" \ |
|
$(args) |
|
|
|
tests: ## run unit, integration, coverage tests |
|
@echo 'Running Unit Tests...' |
|
make unit_tests |
|
@echo 'Running Integration Tests...' |
|
make integration_tests |
|
@echo 'Running Coverage Tests...' |
|
make coverage |
|
|
|
###################### |
|
# CODE QUALITY |
|
###################### |
|
|
|
codespell: ## run codespell to check spelling |
|
@poetry install --with spelling |
|
poetry run codespell --toml pyproject.toml |
|
|
|
fix_codespell: ## run codespell to fix spelling errors |
|
@poetry install --with spelling |
|
poetry run codespell --toml pyproject.toml --write |
|
|
|
format: ## run code formatters |
|
@uv run ruff check . --fix |
|
@uv run ruff format . --config pyproject.toml |
|
@cd src/frontend && npm run format |
|
|
|
unsafe_fix: |
|
@uv run ruff check . --fix --unsafe-fixes |
|
|
|
lint: install_backend ## run linters |
|
@uv run mypy --namespace-packages -p "langflow" |
|
|
|
install_frontendci: |
|
@cd src/frontend && npm ci > /dev/null 2>&1 |
|
|
|
install_frontendc: |
|
@cd src/frontend && rm -rf node_modules package-lock.json && npm install > /dev/null 2>&1 |
|
|
|
run_frontend: ## run the frontend |
|
@-kill -9 `lsof -t -i:3000` |
|
@cd src/frontend && npm start |
|
|
|
tests_frontend: ## run frontend tests |
|
ifeq ($(UI), true) |
|
@cd src/frontend && npx playwright test --ui --project=chromium |
|
else |
|
@cd src/frontend && npx playwright test --project=chromium |
|
endif |
|
|
|
run_cli: install_frontend install_backend build_frontend ## run the CLI |
|
@echo 'Running the CLI' |
|
@uv run langflow run \ |
|
--frontend-path $(path) \ |
|
--log-level $(log_level) \ |
|
--host $(host) \ |
|
--port $(port) \ |
|
$(if $(env),--env-file $(env),) \ |
|
$(if $(filter false,$(open_browser)),--no-open-browser) |
|
|
|
run_cli_debug: |
|
@echo 'Running the CLI in debug mode' |
|
@make install_frontend > /dev/null |
|
@echo 'Building the frontend' |
|
@make build_frontend > /dev/null |
|
@echo 'Install backend dependencies' |
|
@make install_backend > /dev/null |
|
ifdef env |
|
@make start env=$(env) host=$(host) port=$(port) log_level=debug |
|
else |
|
@make start host=$(host) port=$(port) log_level=debug |
|
endif |
|
|
|
|
|
setup_devcontainer: ## set up the development container |
|
make install_backend |
|
make install_frontend |
|
make build_frontend |
|
uv run langflow --frontend-path src/frontend/build |
|
|
|
setup_env: ## set up the environment |
|
@sh ./scripts/setup/setup_env.sh |
|
|
|
frontend: install_frontend ## run the frontend in development mode |
|
make run_frontend |
|
|
|
frontendc: install_frontendc |
|
make run_frontend |
|
|
|
|
|
backend: setup_env install_backend ## run the backend in development mode |
|
@-kill -9 $$(lsof -t -i:7860) || true |
|
ifdef login |
|
@echo "Running backend autologin is $(login)"; |
|
LANGFLOW_AUTO_LOGIN=$(login) uv run uvicorn \ |
|
--factory langflow.main:create_app \ |
|
--host 0.0.0.0 \ |
|
--port $(port) \ |
|
$(if $(filter-out 1,$(workers)),, --reload) \ |
|
--env-file $(env) \ |
|
--loop asyncio \ |
|
$(if $(workers),--workers $(workers),) |
|
else |
|
@echo "Running backend respecting the $(env) file"; |
|
uv run uvicorn \ |
|
--factory langflow.main:create_app \ |
|
--host 0.0.0.0 \ |
|
--port $(port) \ |
|
$(if $(filter-out 1,$(workers)),, --reload) \ |
|
--env-file $(env) \ |
|
--loop asyncio \ |
|
$(if $(workers),--workers $(workers),) |
|
endif |
|
|
|
build_and_run: setup_env ## build the project and run it |
|
rm -rf dist |
|
rm -rf src/backend/base/dist |
|
make build |
|
uv run pip install dist |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|