From b588ac071a88befffd2430e1ed95a229e86fcb13 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 19 Aug 2024 19:32:17 -0300 Subject: [PATCH] feat: add endpoint to get starter projects (#3370) * feat(api): Add endpoint to get list of starter projects with error handling. * feat: Add test for getting starter projects with valid API key. * [autofix.ci] apply automated fixes * refactor(langflow): Update function name from get_all_graphs_dump to get_starter_projects_dump. * bug: fixes route collision * bug: fixes serialization * chore: move endpoint to new file * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: italojohnny --- src/backend/base/langflow/api/router.py | 2 ++ src/backend/base/langflow/api/v1/__init__.py | 2 ++ src/backend/base/langflow/api/v1/flows.py | 10 +++---- .../base/langflow/api/v1/starter_projects.py | 26 +++++++++++++++++++ .../base/langflow/graph/vertex/base.py | 8 +++++- src/backend/tests/test_endpoints.py | 6 +++++ 6 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 src/backend/base/langflow/api/v1/starter_projects.py diff --git a/src/backend/base/langflow/api/router.py b/src/backend/base/langflow/api/router.py index d5d709738..8e5ce927f 100644 --- a/src/backend/base/langflow/api/router.py +++ b/src/backend/base/langflow/api/router.py @@ -14,6 +14,7 @@ from langflow.api.v1 import ( validate_router, variables_router, folders_router, + starter_projects_router, ) router = APIRouter( @@ -31,3 +32,4 @@ router.include_router(variables_router) router.include_router(files_router) router.include_router(monitor_router) router.include_router(folders_router) +router.include_router(starter_projects_router) diff --git a/src/backend/base/langflow/api/v1/__init__.py b/src/backend/base/langflow/api/v1/__init__.py index efc55cba8..25b042a19 100644 --- a/src/backend/base/langflow/api/v1/__init__.py +++ b/src/backend/base/langflow/api/v1/__init__.py @@ -10,6 +10,7 @@ from langflow.api.v1.users import router as users_router from langflow.api.v1.validate import router as validate_router from langflow.api.v1.variable import router as variables_router from langflow.api.v1.folders import router as folders_router +from langflow.api.v1.starter_projects import router as starter_projects_router __all__ = [ "chat_router", @@ -24,4 +25,5 @@ __all__ = [ "monitor_router", "files_router", "folders_router", + "starter_projects_router", ] diff --git a/src/backend/base/langflow/api/v1/flows.py b/src/backend/base/langflow/api/v1/flows.py index c036ff287..ce03013f1 100644 --- a/src/backend/base/langflow/api/v1/flows.py +++ b/src/backend/base/langflow/api/v1/flows.py @@ -1,17 +1,15 @@ import io import json import re +import zipfile from datetime import datetime, timezone from typing import List from uuid import UUID -import zipfile -from fastapi.responses import StreamingResponse -from langflow.services.database.models.transactions.crud import get_transactions_by_flow_id -from langflow.services.database.models.vertex_builds.crud import get_vertex_builds_by_flow_id import orjson from fastapi import APIRouter, Depends, File, HTTPException, UploadFile from fastapi.encoders import jsonable_encoder +from fastapi.responses import StreamingResponse from loguru import logger from sqlmodel import Session, and_, col, select @@ -20,10 +18,12 @@ from langflow.api.v1.schemas import FlowListCreate from langflow.initial_setup.setup import STARTER_FOLDER_NAME from langflow.services.auth.utils import get_current_active_user from langflow.services.database.models.flow import Flow, FlowCreate, FlowRead, FlowUpdate -from langflow.services.database.models.flow.utils import get_webhook_component_in_flow, delete_flow_by_id +from langflow.services.database.models.flow.utils import delete_flow_by_id, get_webhook_component_in_flow from langflow.services.database.models.folder.constants import DEFAULT_FOLDER_NAME from langflow.services.database.models.folder.model import Folder +from langflow.services.database.models.transactions.crud import get_transactions_by_flow_id from langflow.services.database.models.user.model import User +from langflow.services.database.models.vertex_builds.crud import get_vertex_builds_by_flow_id from langflow.services.deps import get_session, get_settings_service from langflow.services.settings.service import SettingsService diff --git a/src/backend/base/langflow/api/v1/starter_projects.py b/src/backend/base/langflow/api/v1/starter_projects.py new file mode 100644 index 000000000..215e76175 --- /dev/null +++ b/src/backend/base/langflow/api/v1/starter_projects.py @@ -0,0 +1,26 @@ +from typing import List + +from fastapi import APIRouter, Depends, HTTPException +from loguru import logger + +from langflow.graph.graph.schema import GraphDump +from langflow.services.database.models.user.model import User +from langflow.services.auth.utils import get_current_active_user +from langflow.initial_setup.load import get_starter_projects_dump + + +router = APIRouter(prefix="/starter-projects", tags=["Flows"]) + + +@router.get("/", response_model=List[GraphDump], status_code=200) +def get_starter_projects( + *, + current_user: User = Depends(get_current_active_user), +): + """Get a list of starter projects.""" + try: + flows = get_starter_projects_dump() + return flows + except Exception as exc: + logger.error(exc) + raise HTTPException(status_code=500, detail=str(exc)) from exc diff --git a/src/backend/base/langflow/graph/vertex/base.py b/src/backend/base/langflow/graph/vertex/base.py index c2135600e..d6cad40bb 100644 --- a/src/backend/base/langflow/graph/vertex/base.py +++ b/src/backend/base/langflow/graph/vertex/base.py @@ -4,6 +4,7 @@ import inspect import os import traceback import types +import json from enum import Enum from typing import TYPE_CHECKING, Any, AsyncIterator, Callable, Dict, Iterator, List, Mapping, Optional, Set @@ -103,7 +104,12 @@ class Vertex: self._custom_component._set_input_value(name, value) def to_data(self): - return self._data + try: + data = json.loads(json.dumps(self._data, default=str)) + except TypeError: + data = self._data + + return data def add_component_instance(self, component_instance: "Component"): component_instance.set_vertex(self) diff --git a/src/backend/tests/test_endpoints.py b/src/backend/tests/test_endpoints.py index a57e06802..130abed93 100644 --- a/src/backend/tests/test_endpoints.py +++ b/src/backend/tests/test_endpoints.py @@ -671,3 +671,9 @@ def test_invalid_flow_id(client, created_api_key): response = client.post(f"/api/v1/run/{flow_id}", headers=headers) assert response.status_code == status.HTTP_404_NOT_FOUND, response.text # Check if the error detail is as expected + + +def test_starter_projects(client, created_api_key): + headers = {"x-api-key": created_api_key.api_key} + response = client.get("/api/v1/starter-projects/", headers=headers) + assert response.status_code == status.HTTP_200_OK, response.text