From 41f6aecda4e2358cd8e428fe9debff550c5eadc7 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 13 Jun 2023 17:21:45 -0300 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=94=80=20refactor(chat.py):=20import?= =?UTF-8?q?=20InitResponse=20and=20BuiltResponse=20from=20schemas=20module?= =?UTF-8?q?=20=F0=9F=9A=80=20feat(chat.py):=20add=20response=20models=20to?= =?UTF-8?q?=20/build/init=20and=20/build/{flow=5Fid}/status=20endpoints=20?= =?UTF-8?q?The=20InitResponse=20and=20BuiltResponse=20models=20are=20now?= =?UTF-8?q?=20imported=20from=20the=20schemas=20module=20to=20improve=20co?= =?UTF-8?q?de=20organization.=20The=20/build/init=20and=20/build/{flow=5Fi?= =?UTF-8?q?d}/status=20endpoints=20now=20have=20response=20models=20to=20p?= =?UTF-8?q?rovide=20a=20clear=20understanding=20of=20the=20expected=20resp?= =?UTF-8?q?onse.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 21 ++++++++++++--------- src/backend/langflow/api/v1/schemas.py | 8 ++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 5ce1ff2ab..52c8e9a67 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -6,7 +6,8 @@ from fastapi import ( WebSocketException, status, ) -from fastapi.responses import StreamingResponse, JSONResponse +from fastapi.responses import StreamingResponse +from langflow.api.v1.schemas import BuiltResponse, InitResponse from langflow.chat.manager import ChatManager from langflow.graph.graph.base import Graph @@ -31,7 +32,7 @@ async def chat(client_id: str, websocket: WebSocket): await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) -@router.post("/build/init") +@router.post("/build/init", response_model=InitResponse) async def init_build(graph_data: dict): """Initialize the build by storing graph data and returning a unique session ID.""" @@ -39,19 +40,21 @@ async def init_build(graph_data: dict): flow_data_store[flow_id] = graph_data - return JSONResponse(content={"flowId": flow_id}) + return InitResponse(flowId=flow_id) -@router.get("/build/{flow_id}/status") +@router.get("/build/{flow_id}/status", response_model=BuiltResponse) async def build_status(flow_id: str): """Check the flow_id is in the flow_data_store.""" try: - if flow_id in flow_data_store and not isinstance( + built = flow_id in flow_data_store and not isinstance( flow_data_store[flow_id], dict - ): - return JSONResponse(content={"built": True}) - else: - return JSONResponse(content={"built": False}) + ) + + return BuiltResponse( + built=built, + ) + except Exception as exc: logger.error(exc) return HTTPException(status_code=500, detail=str(exc)) diff --git a/src/backend/langflow/api/v1/schemas.py b/src/backend/langflow/api/v1/schemas.py index f73b0642d..161704738 100644 --- a/src/backend/langflow/api/v1/schemas.py +++ b/src/backend/langflow/api/v1/schemas.py @@ -68,3 +68,11 @@ class FileResponse(ChatMessage): if v not in ["image", "csv"]: raise ValueError("data_type must be image or csv") return v + + +class InitResponse(BaseModel): + flowId: str + + +class BuiltResponse(BaseModel): + built: bool From 52baae64e6991ecb7ae1906b0df55ded99f251ff Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 13 Jun 2023 18:05:11 -0300 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=94=A8=20refactor(chatComponent):=20r?= =?UTF-8?q?emove=20unused=20imports=20and=20variables,=20and=20extract=20p?= =?UTF-8?q?ostBuildInit=20function=20to=20API=20controller=20=E2=9C=A8=20f?= =?UTF-8?q?eat(API):=20add=20postBuildInit=20function=20to=20handle=20POST?= =?UTF-8?q?=20requests=20to=20/api/v1/build/init=20The=20chatComponent=20f?= =?UTF-8?q?ile=20had=20unused=20imports=20and=20variables=20that=20were=20?= =?UTF-8?q?removed=20to=20improve=20code=20readability.=20The=20postBuildI?= =?UTF-8?q?nit=20function=20was=20extracted=20to=20the=20API=20controller?= =?UTF-8?q?=20to=20improve=20code=20organization=20and=20maintainability.?= =?UTF-8?q?=20The=20function=20handles=20POST=20requests=20to=20/api/v1/bu?= =?UTF-8?q?ild/init.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatComponent/buildTrigger/index.tsx | 36 ++++++++++--------- src/frontend/src/controllers/API/index.ts | 17 ++++++--- src/frontend/src/types/api/index.ts | 4 +++ src/frontend/vite.config.ts | 13 +++---- 4 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx index d447780e1..c09d2bb82 100644 --- a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx +++ b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx @@ -1,16 +1,13 @@ -import { useState, useContext, useRef, useEffect } from "react"; +import { useState, useContext } from "react"; import { Transition } from "@headlessui/react"; -import { Bars3CenterLeftIcon } from "@heroicons/react/24/outline"; import { Zap } from "lucide-react"; -import { nodeColors, validateNodes } from "../../../utils"; -import { PopUpContext } from "../../../contexts/popUpContext"; -import ChatModal from "../../../modals/chatModal"; +import { validateNodes } from "../../../utils"; import { FlowType } from "../../../types/flow"; import Loading from "../../../components/ui/loading"; import { useSSE } from "../../../contexts/SSEContext"; -import axios from "axios"; import { typesContext } from "../../../contexts/typesContext"; import { alertContext } from "../../../contexts/alertContext"; +import { postBuildInit } from "../../../controllers/API"; export default function BuildTrigger({ open, @@ -26,21 +23,24 @@ export default function BuildTrigger({ const [isBuilding, setIsBuilding] = useState(false); const { updateSSEData } = useSSE(); - const {reactFlowInstance} = useContext(typesContext); - const {setErrorData} = useContext(alertContext) + const { reactFlowInstance } = useContext(typesContext); + const { setErrorData } = useContext(alertContext); async function handleBuild(flow: FlowType) { - const errors = validateNodes(reactFlowInstance) - if(errors.length > 0) { - setErrorData({title: "Oops! Looks like you missed something", list: errors}) - return + const errors = validateNodes(reactFlowInstance); + if (errors.length > 0) { + setErrorData({ + title: "Oops! Looks like you missed something", + list: errors, + }); + return; } const minimumLoadingTime = 200; // in milliseconds const startTime = Date.now(); setIsBuilding(true); try { - const allNodesValid = await streamNodeData(`/build/init`, flow); + const allNodesValid = await streamNodeData(flow); await enforceMinimumLoadingTime(startTime, minimumLoadingTime); setIsBuilt(allNodesValid); } catch (error) { @@ -50,15 +50,15 @@ export default function BuildTrigger({ } } - async function streamNodeData(apiUrl: string, flow: FlowType) { + async function streamNodeData(flow: FlowType) { // Step 1: Make a POST request to send the flow data and receive a unique session ID - const response = await axios.post(apiUrl, flow); + const response = await postBuildInit(flow); const { flowId } = response.data; // Step 2: Use the session ID to establish an SSE connection using EventSource let validationResults = []; let finished = false; - apiUrl = `/build/stream/${flowId}`; + const apiUrl = `/build/stream/${flowId}`; const eventSource = new EventSource(apiUrl); eventSource.onmessage = (event) => { @@ -128,7 +128,9 @@ export default function BuildTrigger({
{if(!isBuilding) handleBuild(flow)}} + onClick={() => { + if (!isBuilding) handleBuild(flow); + }} >