feat: improve CLI parameter handling and cleanup unused code (#4002)
* chore: remove envvar parameter from CLI option * chore: add show_default=False flag to CLI option * chore: update argument type to accept None * feat: add missing Settings to CLI options * feat: add default path value for components * chore: rename CLI parameters to match Settings * feat: update function to enforce parameter hierarchy CLI > specific env_file > default env_file * fix: adjust CLI parameter code to pass unit tests * fix: mypy error arg-type * fix: little ajustments
This commit is contained in:
parent
b8e7a77d78
commit
ed7ec6a332
3 changed files with 90 additions and 61 deletions
6
Makefile
6
Makefile
|
|
@ -243,7 +243,7 @@ start:
|
||||||
|
|
||||||
ifeq ($(open_browser),false)
|
ifeq ($(open_browser),false)
|
||||||
@make install_backend && uv run langflow run \
|
@make install_backend && uv run langflow run \
|
||||||
--path $(path) \
|
--frontend-path $(path) \
|
||||||
--log-level $(log_level) \
|
--log-level $(log_level) \
|
||||||
--host $(host) \
|
--host $(host) \
|
||||||
--port $(port) \
|
--port $(port) \
|
||||||
|
|
@ -251,7 +251,7 @@ ifeq ($(open_browser),false)
|
||||||
--no-open-browser
|
--no-open-browser
|
||||||
else
|
else
|
||||||
@make install_backend && uv run langflow run \
|
@make install_backend && uv run langflow run \
|
||||||
--path $(path) \
|
--frontend-path $(path) \
|
||||||
--log-level $(log_level) \
|
--log-level $(log_level) \
|
||||||
--host $(host) \
|
--host $(host) \
|
||||||
--port $(port) \
|
--port $(port) \
|
||||||
|
|
@ -262,7 +262,7 @@ setup_devcontainer: ## set up the development container
|
||||||
make install_backend
|
make install_backend
|
||||||
make install_frontend
|
make install_frontend
|
||||||
make build_frontend
|
make build_frontend
|
||||||
uv run langflow --path src/frontend/build
|
uv run langflow --frontend-path src/frontend/build
|
||||||
|
|
||||||
setup_env: ## set up the environment
|
setup_env: ## set up the environment
|
||||||
@sh ./scripts/setup/setup_env.sh
|
@sh ./scripts/setup/setup_env.sh
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import inspect
|
||||||
import platform
|
import platform
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -28,7 +29,6 @@ from langflow.services.database.utils import session_getter
|
||||||
from langflow.services.deps import get_db_service, get_settings_service, session_scope
|
from langflow.services.deps import get_db_service, get_settings_service, session_scope
|
||||||
from langflow.services.settings.constants import DEFAULT_SUPERUSER
|
from langflow.services.settings.constants import DEFAULT_SUPERUSER
|
||||||
from langflow.services.utils import initialize_services
|
from langflow.services.utils import initialize_services
|
||||||
from langflow.utils.util import update_settings
|
|
||||||
from langflow.utils.version import fetch_latest_version, get_version_info
|
from langflow.utils.version import fetch_latest_version, get_version_info
|
||||||
from langflow.utils.version import is_pre_release as langflow_is_pre_release
|
from langflow.utils.version import is_pre_release as langflow_is_pre_release
|
||||||
|
|
||||||
|
|
@ -79,69 +79,73 @@ def set_var_for_macos_issue():
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
def run(
|
def run(
|
||||||
host: str = typer.Option("127.0.0.1", help="Host to bind the server to.", envvar="LANGFLOW_HOST"),
|
host: str | None = typer.Option(None, help="Host to bind the server to.", show_default=False),
|
||||||
workers: int = typer.Option(1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"),
|
workers: int | None = typer.Option(None, help="Number of worker processes.", show_default=False),
|
||||||
timeout: int = typer.Option(300, help="Worker timeout in seconds.", envvar="LANGFLOW_WORKER_TIMEOUT"),
|
worker_timeout: int | None = typer.Option(None, help="Worker timeout in seconds.", show_default=False),
|
||||||
port: int = typer.Option(7860, help="Port to listen on.", envvar="LANGFLOW_PORT"),
|
port: int | None = typer.Option(None, help="Port to listen on.", show_default=False),
|
||||||
components_path: Path | None = typer.Option(
|
components_path: Path | None = typer.Option(
|
||||||
Path(__file__).parent / "components",
|
Path(__file__).parent / "components",
|
||||||
help="Path to the directory containing custom components.",
|
help="Path to the directory containing custom components.",
|
||||||
envvar="LANGFLOW_COMPONENTS_PATH",
|
show_default=False,
|
||||||
),
|
),
|
||||||
# .env file param
|
# .env file param
|
||||||
env_file: Path = typer.Option(None, help="Path to the .env file containing environment variables."),
|
env_file: Path | None = typer.Option(
|
||||||
log_level: str = typer.Option("critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"),
|
None,
|
||||||
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file.", envvar="LANGFLOW_LOG_FILE"),
|
help="Path to the .env file containing environment variables.",
|
||||||
cache: str | None = typer.Option(
|
show_default=False,
|
||||||
envvar="LANGFLOW_LANGCHAIN_CACHE",
|
|
||||||
help="Type of cache to use. (InMemoryCache, SQLiteCache)",
|
|
||||||
default=None,
|
|
||||||
),
|
),
|
||||||
dev: bool = typer.Option(False, help="Run in development mode (may contain bugs)"),
|
log_level: str | None = typer.Option(None, help="Logging level.", show_default=False),
|
||||||
path: str = typer.Option(
|
log_file: Path | None = typer.Option(None, help="Path to the log file.", show_default=False),
|
||||||
|
cache: str | None = typer.Option(
|
||||||
|
None,
|
||||||
|
help="Type of cache to use. (InMemoryCache, SQLiteCache)",
|
||||||
|
show_default=False,
|
||||||
|
),
|
||||||
|
dev: bool | None = typer.Option(None, help="Run in development mode (may contain bugs)", show_default=False),
|
||||||
|
frontend_path: str | None = typer.Option(
|
||||||
None,
|
None,
|
||||||
help="Path to the frontend directory containing build files. This is for development purposes only.",
|
help="Path to the frontend directory containing build files. This is for development purposes only.",
|
||||||
envvar="LANGFLOW_FRONTEND_PATH",
|
show_default=False,
|
||||||
),
|
),
|
||||||
open_browser: bool = typer.Option(
|
open_browser: bool | None = typer.Option(
|
||||||
True,
|
None,
|
||||||
help="Open the browser after starting the server.",
|
help="Open the browser after starting the server.",
|
||||||
envvar="LANGFLOW_OPEN_BROWSER",
|
show_default=False,
|
||||||
),
|
),
|
||||||
remove_api_keys: bool = typer.Option(
|
remove_api_keys: bool | None = typer.Option(
|
||||||
False,
|
None,
|
||||||
help="Remove API keys from the projects saved in the database.",
|
help="Remove API keys from the projects saved in the database.",
|
||||||
envvar="LANGFLOW_REMOVE_API_KEYS",
|
show_default=False,
|
||||||
),
|
),
|
||||||
backend_only: bool = typer.Option(
|
backend_only: bool | None = typer.Option(
|
||||||
False,
|
None,
|
||||||
help="Run only the backend server without the frontend.",
|
help="Run only the backend server without the frontend.",
|
||||||
envvar="LANGFLOW_BACKEND_ONLY",
|
show_default=False,
|
||||||
),
|
),
|
||||||
store: bool = typer.Option(
|
store: bool | None = typer.Option(
|
||||||
True,
|
None,
|
||||||
help="Enables the store features.",
|
help="Enables the store features.",
|
||||||
envvar="LANGFLOW_STORE",
|
show_default=False,
|
||||||
),
|
),
|
||||||
auto_saving: bool = typer.Option(
|
auto_saving: bool | None = typer.Option(
|
||||||
True,
|
None,
|
||||||
help="Defines if the auto save is enabled.",
|
help="Defines if the auto save is enabled.",
|
||||||
envvar="LANGFLOW_AUTO_SAVING",
|
show_default=False,
|
||||||
),
|
),
|
||||||
auto_saving_interval: int = typer.Option(
|
auto_saving_interval: int | None = typer.Option(
|
||||||
1000,
|
None,
|
||||||
help="Defines the debounce time for the auto save.",
|
help="Defines the debounce time for the auto save.",
|
||||||
envvar="LANGFLOW_AUTO_SAVING_INTERVAL",
|
show_default=False,
|
||||||
),
|
),
|
||||||
health_check_max_retries: bool = typer.Option(
|
health_check_max_retries: bool | None = typer.Option(
|
||||||
True,
|
None,
|
||||||
help="Defines the number of retries for the health check.",
|
help="Defines the number of retries for the health check.",
|
||||||
envvar="LANGFLOW_HEALTH_CHECK_MAX_RETRIES",
|
show_default=False,
|
||||||
),
|
),
|
||||||
max_file_size_upload: int = typer.Option(
|
max_file_size_upload: int | None = typer.Option(
|
||||||
100,
|
None,
|
||||||
help="Defines the maximum file size for the upload in MB.",
|
help="Defines the maximum file size for the upload in MB.",
|
||||||
envvar="LANGFLOW_MAX_FILE_SIZE_UPLOAD",
|
show_default=False,
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
|
@ -153,33 +157,44 @@ def run(
|
||||||
|
|
||||||
if env_file:
|
if env_file:
|
||||||
load_dotenv(env_file, override=True)
|
load_dotenv(env_file, override=True)
|
||||||
|
logger.debug(f"Loading config from file: '{env_file}'")
|
||||||
|
|
||||||
update_settings(
|
|
||||||
dev=dev,
|
|
||||||
remove_api_keys=remove_api_keys,
|
|
||||||
cache=cache,
|
|
||||||
components_path=components_path,
|
|
||||||
store=store,
|
|
||||||
auto_saving=auto_saving,
|
|
||||||
auto_saving_interval=auto_saving_interval,
|
|
||||||
health_check_max_retries=health_check_max_retries,
|
|
||||||
max_file_size_upload=max_file_size_upload,
|
|
||||||
)
|
|
||||||
# create path object if path is provided
|
|
||||||
static_files_dir: Path | None = Path(path) if path else None
|
|
||||||
settings_service = get_settings_service()
|
settings_service = get_settings_service()
|
||||||
settings_service.set("backend_only", backend_only)
|
|
||||||
|
frame = inspect.currentframe()
|
||||||
|
valid_args: list = []
|
||||||
|
values: dict = {}
|
||||||
|
if frame is not None:
|
||||||
|
arguments, _, _, values = inspect.getargvalues(frame)
|
||||||
|
valid_args = [arg for arg in arguments if values[arg] is not None]
|
||||||
|
|
||||||
|
for arg in valid_args:
|
||||||
|
if arg == "components_path":
|
||||||
|
settings_service.settings.update_settings(components_path=components_path)
|
||||||
|
elif hasattr(settings_service.settings, arg):
|
||||||
|
settings_service.set(arg, values[arg])
|
||||||
|
logger.debug(f"Loading config from cli parameter '{arg}': '{values[arg]}'")
|
||||||
|
|
||||||
|
host = settings_service.settings.host
|
||||||
|
port = settings_service.settings.port
|
||||||
|
workers = settings_service.settings.workers
|
||||||
|
worker_timeout = settings_service.settings.worker_timeout
|
||||||
|
log_level = settings_service.settings.log_level
|
||||||
|
frontend_path = settings_service.settings.frontend_path
|
||||||
|
backend_only = settings_service.settings.backend_only
|
||||||
|
|
||||||
|
# create path object if frontend_path is provided
|
||||||
|
static_files_dir: Path | None = Path(frontend_path) if frontend_path else None
|
||||||
|
|
||||||
app = setup_app(static_files_dir=static_files_dir, backend_only=backend_only)
|
app = setup_app(static_files_dir=static_files_dir, backend_only=backend_only)
|
||||||
# check if port is being used
|
# check if port is being used
|
||||||
if is_port_in_use(port, host):
|
if is_port_in_use(port, host):
|
||||||
port = get_free_port(port)
|
port = get_free_port(port)
|
||||||
|
|
||||||
settings_service.set("worker_timeout", timeout)
|
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
"bind": f"{host}:{port}",
|
"bind": f"{host}:{port}",
|
||||||
"workers": get_number_of_workers(workers),
|
"workers": get_number_of_workers(workers),
|
||||||
"timeout": timeout,
|
"timeout": worker_timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Define an env variable to know if we are just testing the server
|
# Define an env variable to know if we are just testing the server
|
||||||
|
|
@ -472,7 +487,7 @@ def migration(
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
def api_key(
|
def api_key(
|
||||||
log_level: str = typer.Option("error", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"),
|
log_level: str = typer.Option("error", help="Logging level."),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Creates an API key for the default superuser if AUTO_LOGIN is enabled.
|
Creates an API key for the default superuser if AUTO_LOGIN is enabled.
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,20 @@ class Settings(BaseSettings):
|
||||||
"""If set to True, Langflow will keep track of each vertex builds (outputs) in the UI for any flow."""
|
"""If set to True, Langflow will keep track of each vertex builds (outputs) in the UI for any flow."""
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
|
host: str = "127.0.0.1"
|
||||||
|
"""The host on which Langflow will run."""
|
||||||
|
port: int = 7860
|
||||||
|
"""The port on which Langflow will run."""
|
||||||
|
workers: int = 1
|
||||||
|
"""The number of workers to run."""
|
||||||
|
log_level: str = "critical"
|
||||||
|
"""The log level for Langflow."""
|
||||||
|
log_file: str | None = "logs/langflow.log"
|
||||||
|
"""The path to log file for Langflow."""
|
||||||
|
frontend_path: str | None = None
|
||||||
|
"""The path to the frontend directory containing build files. This is for development purposes only.."""
|
||||||
|
open_browser: bool = False
|
||||||
|
"""If set to True, Langflow will open the browser on startup."""
|
||||||
auto_saving: bool = True
|
auto_saving: bool = True
|
||||||
"""If set to True, Langflow will auto save flows."""
|
"""If set to True, Langflow will auto save flows."""
|
||||||
auto_saving_interval: int = 1000
|
auto_saving_interval: int = 1000
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue