fix: set folder id on flows imported on startup (#4018)

* set folder id on flows imported on startup
---------

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
Jordan Frazier 2024-10-04 10:19:08 -07:00 committed by GitHub
commit 7fe478e4b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 41 additions and 2 deletions

View file

@ -20,7 +20,10 @@ from langflow.graph.graph.base import Graph
from langflow.services.auth.utils import create_super_user
from langflow.services.database.models.flow.model import Flow, FlowCreate
from langflow.services.database.models.folder.model import Folder, FolderCreate
from langflow.services.database.models.folder.utils import create_default_folder_if_it_doesnt_exist
from langflow.services.database.models.folder.utils import (
create_default_folder_if_it_doesnt_exist,
get_default_folder_id,
)
from langflow.services.database.models.user.crud import get_user_by_username
from langflow.services.deps import get_settings_service, get_storage_service, get_variable_service, session_scope
from langflow.template.field.prompt import DEFAULT_PROMPT_INTUT_TYPES
@ -497,6 +500,12 @@ def _is_valid_uuid(val):
def load_flows_from_directory():
"""
On langflow startup, this loads all flows from the directory specified in the settings.
All flows are uploaded into the default folder for the superuser.
Note that this feature currently only works if AUTO_LOGIN is enabled in the settings.
"""
settings_service = get_settings_service()
flows_path = settings_service.settings.load_flows_path
if not flows_path:
@ -522,6 +531,7 @@ def load_flows_from_directory():
existing = find_existing_flow(session, flow_id, flow_endpoint_name)
if existing:
logger.debug(f"Found existing flow: {existing.name}")
logger.info(f"Updating existing flow: {flow_id} with endpoint name {flow_endpoint_name}")
for key, value in flow.items():
if hasattr(existing, key):
@ -529,10 +539,23 @@ def load_flows_from_directory():
setattr(existing, key, value)
existing.updated_at = datetime.now(tz=timezone.utc).astimezone()
existing.user_id = user_id
# Generally, folder_id should not be None, but we must check this due to the previous
# behavior where flows could be added and folder_id was None, orphaning
# them within Langflow.
if existing.folder_id is None:
folder_id = get_default_folder_id(session, user_id)
existing.folder_id = folder_id
session.add(existing)
else:
logger.info(f"Creating new flow: {flow_id} with endpoint name {flow_endpoint_name}")
# Current behavior loads all new flows into default folder
folder_id = get_default_folder_id(session, user_id)
flow["user_id"] = user_id
flow["folder_id"] = folder_id
flow = Flow.model_validate(flow, from_attributes=True)
flow.updated_at = datetime.now(tz=timezone.utc).astimezone()
session.add(flow)
@ -540,11 +563,14 @@ def load_flows_from_directory():
def find_existing_flow(session, flow_id, flow_endpoint_name):
if flow_endpoint_name:
logger.debug(f"flow_endpoint_name: {flow_endpoint_name}")
stmt = select(Flow).where(Flow.endpoint_name == flow_endpoint_name)
if existing := session.exec(stmt).first():
logger.debug(f"Found existing flow by endpoint name: {existing.name}")
return existing
stmt = select(Flow).where(Flow.id == flow_id)
if existing := session.exec(stmt).first():
logger.debug(f"Found existing flow by id: {flow_id}")
return existing
return None

View file

@ -11,7 +11,11 @@ from .model import Folder
def create_default_folder_if_it_doesnt_exist(session: Session, user_id: UUID):
folder = session.exec(select(Folder).where(Folder.user_id == user_id)).first()
if not folder:
folder = Folder(name=DEFAULT_FOLDER_NAME, user_id=user_id, description=DEFAULT_FOLDER_DESCRIPTION)
folder = Folder(
name=DEFAULT_FOLDER_NAME,
user_id=user_id,
description=DEFAULT_FOLDER_DESCRIPTION,
)
session.add(folder)
session.commit()
session.refresh(folder)
@ -27,3 +31,10 @@ def create_default_folder_if_it_doesnt_exist(session: Session, user_id: UUID):
)
session.commit()
return folder
def get_default_folder_id(session: Session, user_id: UUID):
folder = session.exec(select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME, Folder.user_id == user_id)).first()
if not folder:
folder = create_default_folder_if_it_doesnt_exist(session, user_id)
return folder.id

View file

@ -423,11 +423,13 @@ async def test_load_flows(client: TestClient, load_flows_dir):
response = await client.get("api/v1/flows/c54f9130-f2fa-4a3e-b22a-3856d946351b")
assert response.status_code == 200
assert response.json()["name"] == "BasicExample"
assert response.json()["folder_id"] is not None
# re-run to ensure updates work well
load_flows_from_directory()
response = await client.get("api/v1/flows/c54f9130-f2fa-4a3e-b22a-3856d946351b")
assert response.status_code == 200
assert response.json()["name"] == "BasicExample"
assert response.json()["folder_id"] is not None
def test_sqlite_pragmas():