Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 6 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/backend/base/langflow/initial_setup/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
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
Expand Down Expand Up @@ -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:
Expand All @@ -522,29 +531,46 @@ 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):
# flow dict from json and db representation are not 100% the same
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

ogabrielluiz marked this conversation as resolved.
Show resolved Hide resolved
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)


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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
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)
Expand All @@ -31,3 +35,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
2 changes: 2 additions & 0 deletions src/backend/tests/unit/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
Loading