merge fix

This commit is contained in:
Cristhian Zanforlin Lousa 2023-07-07 11:46:13 -03:00
commit fbc9eb6d1b
97 changed files with 2357 additions and 575 deletions

View file

@ -1,6 +1,6 @@
from importlib import metadata
from langflow.cache import cache_manager
from langflow.processing.process import load_flow_from_json
from langflow.cache import cache_manager # noqa: E402
from langflow.processing.process import load_flow_from_json # noqa: E402
try:
__version__ = metadata.version(__package__)
@ -9,4 +9,5 @@ except metadata.PackageNotFoundError:
__version__ = ""
del metadata # optional, avoids polluting the results of dir(__package__)
__all__ = ["load_flow_from_json", "cache_manager"]

View file

@ -1,3 +1,4 @@
import os
import sys
import time
import httpx
@ -33,6 +34,10 @@ def update_settings(
remove_api_keys: bool = False,
):
"""Update the settings from a config file."""
# Check for database_url in the environment variables
database_url = database_url or os.getenv("langflow_database_url")
if config:
settings.update_from_yaml(config, dev=dev)
if database_url:
@ -43,6 +48,26 @@ def update_settings(
settings.update_settings(cache=cache)
def load_params():
"""
Load the parameters from the environment variables.
"""
global_vars = globals()
for key, value in global_vars.items():
env_key = f"LANGFLOW_{key.upper()}"
if env_key in os.environ:
if isinstance(value, bool):
# Handle booleans
global_vars[key] = os.getenv(env_key, str(value)).lower() == "true"
elif isinstance(value, int):
# Handle integers
global_vars[key] = int(os.getenv(env_key, str(value)))
elif isinstance(value, str) or value is None:
# Handle strings and None values
global_vars[key] = os.getenv(env_key, str(value))
def serve_on_jcloud():
"""
Deploy Langflow server on Jina AI Cloud
@ -91,19 +116,27 @@ def serve_on_jcloud():
@app.command()
def serve(
host: str = typer.Option("127.0.0.1", help="Host to bind the server to."),
workers: int = typer.Option(1, help="Number of worker processes."),
host: str = typer.Option(
"127.0.0.1", help="Host to bind the server to.", envvar="LANGFLOW_HOST"
),
workers: int = typer.Option(
1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"
),
timeout: int = typer.Option(60, help="Worker timeout in seconds."),
port: int = typer.Option(7860, help="Port to listen on."),
port: int = typer.Option(7860, help="Port to listen on.", envvar="LANGFLOW_PORT"),
config: str = typer.Option("config.yaml", help="Path to the configuration file."),
# .env file param
env_file: Path = typer.Option(
".env", help="Path to the .env file containing environment variables."
),
log_level: str = typer.Option("critical", help="Logging level."),
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."),
cache: str = typer.Argument(
envvar="LANGCHAIN_CACHE",
log_level: str = typer.Option(
"critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"
),
log_file: Path = typer.Option(
"logs/langflow.log", help="Path to the log file.", envvar="LANGFLOW_LOG_FILE"
),
cache: str = typer.Option(
envvar="LANGFLOW_LANGCHAIN_CACHE",
help="Type of cache to use. (InMemoryCache, SQLiteCache)",
default="SQLiteCache",
),
@ -112,27 +145,35 @@ def serve(
database_url: str = typer.Option(
None,
help="Database URL to connect to. If not provided, a local SQLite database will be used.",
envvar="LANGFLOW_DATABASE_URL",
),
path: str = typer.Option(
None,
help="Path to the frontend directory containing build files. This is for development purposes only.",
envvar="LANGFLOW_FRONTEND_PATH",
),
open_browser: bool = typer.Option(
True, help="Open the browser after starting the server."
True,
help="Open the browser after starting the server.",
envvar="LANGFLOW_OPEN_BROWSER",
),
remove_api_keys: bool = typer.Option(
False, help="Remove API keys from the projects saved in the database."
False,
help="Remove API keys from the projects saved in the database.",
envvar="LANGFLOW_REMOVE_API_KEYS",
),
):
"""
Run the Langflow server.
"""
# override env variables with .env file
if env_file:
load_dotenv(env_file, override=True)
load_params()
if jcloud:
return serve_on_jcloud()
load_dotenv(env_file)
configure(log_level=log_level, log_file=log_file)
update_settings(
config,
@ -224,7 +265,7 @@ def get_free_port(port):
def print_banner(host, port):
# console = Console()
word = "LangFlow"
word = "Langflow"
colors = ["#3300cc"]
styled_word = ""

View file

@ -23,7 +23,7 @@ class GraphData(BaseModel):
class ExportedFlow(BaseModel):
"""Exported flow from LangFlow."""
"""Exported flow from Langflow."""
description: str
name: str

View file

@ -2,17 +2,34 @@ from langflow.settings import settings
from sqlmodel import SQLModel, Session, create_engine
from langflow.utils.logger import logger
if settings.database_url.startswith("sqlite"):
if settings.database_url and settings.database_url.startswith("sqlite"):
connect_args = {"check_same_thread": False}
else:
connect_args = {}
if not settings.database_url:
raise RuntimeError("No database_url provided")
engine = create_engine(settings.database_url, connect_args=connect_args)
def create_db_and_tables():
logger.debug("Creating database and tables")
SQLModel.metadata.create_all(engine)
logger.debug("Database and tables created")
try:
SQLModel.metadata.create_all(engine)
except Exception as exc:
logger.error(f"Error creating database and tables: {exc}")
raise RuntimeError("Error creating database and tables") from exc
# Now check if the table Flow exists, if not, something went wrong
# and we need to create the tables again.
from sqlalchemy import inspect
inspector = inspect(engine)
if "flow" not in inspector.get_table_names():
logger.error("Something went wrong creating the database and tables.")
logger.error("Please check your database settings.")
raise RuntimeError("Something went wrong creating the database and tables.")
else:
logger.debug("Database and tables created successfully")
def get_session():

View file

@ -217,7 +217,7 @@ class Vertex:
self.edges.append(edge)
def __repr__(self) -> str:
return f"Node(id={self.id}, data={self.data})"
return f"Vertex(id={self.id}, data={self.data})"
def __eq__(self, __o: object) -> bool:
return self.id == __o.id if isinstance(__o, Vertex) else False

View file

@ -66,17 +66,24 @@ def extract_input_variables_from_prompt(prompt: str) -> list[str]:
def setup_llm_caching():
"""Setup LLM caching."""
from langflow.settings import settings
try:
import langchain
from langflow.settings import settings
from langflow.interface.importing.utils import import_class
cache_class = import_class(f"langchain.cache.{settings.cache}")
logger.debug(f"Setting up LLM caching with {cache_class.__name__}")
langchain.llm_cache = cache_class()
logger.info(f"LLM caching setup with {cache_class.__name__}")
set_langchain_cache(settings)
except ImportError:
logger.warning(f"Could not import {settings.cache}. ")
except Exception as exc:
logger.warning(f"Could not setup LLM caching. Error: {exc}")
# TODO Rename this here and in `setup_llm_caching`
def set_langchain_cache(settings):
import langchain
from langflow.interface.importing.utils import import_class
cache_type = os.getenv("LANGFLOW_LANGCHAIN_CACHE")
cache_class = import_class(f"langchain.cache.{cache_type or settings.cache}")
logger.debug(f"Setting up LLM caching with {cache_class.__name__}")
langchain.llm_cache = cache_class()
logger.info(f"LLM caching setup with {cache_class.__name__}")

View file

@ -1,16 +1,15 @@
# This file is used by lc-serve to load the mounted app and serve it.
from pathlib import Path
import os
from fastapi.staticfiles import StaticFiles
# Use the JCLOUD_WORKSPACE for db URL if it's provided by JCloud.
if 'JCLOUD_WORKSPACE' in os.environ:
os.environ[
'LANGFLOW_DATABASE_URL'
] = f"sqlite:///{os.environ['JCLOUD_WORKSPACE']}/langflow.db"
from langflow.main import create_app
from langflow.main import setup_app
from langflow.utils.logger import configure
app = create_app()
path = Path(__file__).parent
static_files_dir = path / "frontend"
app.mount(
"/",
StaticFiles(directory=static_files_dir, html=True),
name="static",
)
configure(log_level="DEBUG")
app = setup_app()

View file

@ -61,7 +61,7 @@ def setup_static_files(app: FastAPI, static_files_dir: Path):
# app = create_app()
# setup_static_files(app, static_files_dir)
def setup_app(static_files_dir: Optional[Path]) -> FastAPI:
def setup_app(static_files_dir: Optional[Path] = None) -> FastAPI:
"""Setup the FastAPI app."""
# get the directory of the current file
if not static_files_dir:

View file

@ -1,4 +1,5 @@
import os
from typing import Optional
import yaml
from pydantic import BaseSettings, root_validator
@ -22,16 +23,18 @@ class Settings(BaseSettings):
utilities: dict = {}
output_parsers: dict = {}
dev: bool = False
database_url: str
database_url: Optional[str] = None
cache: str = "InMemoryCache"
remove_api_keys: bool = False
@root_validator(pre=True)
def set_database_url(cls, values):
if "database_url" not in values:
logger.debug("No database_url provided, trying DATABASE_URL env variable")
if database_url := os.getenv("DATABASE_URL"):
values["database_url"] = database_url
logger.debug(
"No database_url provided, trying LANGFLOW_DATABASE_URL env variable"
)
if langflow_database_url := os.getenv("LANGFLOW_DATABASE_URL"):
values["database_url"] = langflow_database_url
else:
logger.debug("No DATABASE_URL env variable, using sqlite database")
values["database_url"] = "sqlite:///./langflow.db"
@ -40,7 +43,6 @@ class Settings(BaseSettings):
class Config:
validate_assignment = True
extra = "ignore"
env_prefix = "LANGFLOW_"
@root_validator(allow_reuse=True)
def validate_lists(cls, values):

View file

@ -33,7 +33,6 @@ class DocumentLoaderFrontNode(FrontendNode):
"SlackDirectoryLoader": build_file_field(suffixes=[".zip"], fileTypes=["zip"]),
"EverNoteLoader": build_file_field(suffixes=[".xml"], fileTypes=["xml"]),
"FacebookChatLoader": build_file_field(suffixes=[".json"], fileTypes=["json"]),
"GutenbergLoader": build_file_field(suffixes=[".txt"], fileTypes=["txt"]),
"BSHTMLLoader": build_file_field(suffixes=[".html"], fileTypes=["html"]),
"UnstructuredHTMLLoader": build_file_field(
suffixes=[".html"], fileTypes=["html"]
@ -116,8 +115,11 @@ class DocumentLoaderFrontNode(FrontendNode):
"HNLoader",
"IFixitLoader",
"IMSDbLoader",
"GutenbergLoader",
}:
name = "web_path"
elif self.template.type_name in {"GutenbergLoader"}:
name = "file_path"
elif self.template.type_name in {"GitbookLoader"}:
name = "web_page"
elif self.template.type_name in {

View file

@ -65,6 +65,7 @@ class VectorStoreFrontendNode(FrontendNode):
show=True,
advanced=True,
multiline=False,
password=True,
value="",
)
extra_field2 = TemplateField(
@ -142,6 +143,7 @@ class VectorStoreFrontendNode(FrontendNode):
show=True,
advanced=True,
multiline=False,
password=True,
value="",
)
extra_fields.extend((extra_field, extra_field2, extra_field3, extra_field4))