diff --git a/src/backend/langflow/api/v1/endpoints.py b/src/backend/langflow/api/v1/endpoints.py index 48a7a6261..7104a2002 100644 --- a/src/backend/langflow/api/v1/endpoints.py +++ b/src/backend/langflow/api/v1/endpoints.py @@ -1,3 +1,6 @@ +import random + +from http import HTTPStatus from typing import Optional from langflow.cache.utils import save_uploaded_file from langflow.database.models.flow import Flow @@ -15,6 +18,7 @@ from langflow.api.v1.schemas import ( ProcessResponse, UploadFileResponse, CustomComponentCode, + CustomComponentResponseError, ) from langflow.interface.types import ( @@ -70,7 +74,7 @@ async def process_flow( raise HTTPException(status_code=500, detail=str(e)) from e -@router.post("/upload/{flow_id}", response_model=UploadFileResponse, status_code=201) +@router.post("/upload/{flow_id}", response_model=UploadFileResponse, status_code=HTTPStatus.CREATED) async def create_upload_file(file: UploadFile, flow_id: str): # Cache file try: @@ -93,11 +97,9 @@ def get_version(): return {"version": __version__} -# @router.post("/custom_component", response_model=CustomComponentResponse, status_code=200) -@router.post("/custom_component", status_code=200) -def custom_component( +@router.post("/custom_component", status_code=HTTPStatus.OK) +async def custom_component( raw_code: CustomComponentCode, - session: Session = Depends(get_session), ): extractor = ClassCodeExtractor(raw_code.code) data = extractor.extract_class_info() @@ -110,3 +112,28 @@ def custom_component( function_args, function_return_type ) + + +# TODO: Just for test - will be remove +@router.get("/custom_component_error", + response_model=CustomComponentResponseError, + status_code=HTTPStatus.BAD_REQUEST) +async def custom_component_error(): + error1 = { + "detail": "'int' object has no attribute 'get'", + "traceback": "Traceback (most recent call last):\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/errors.py\", line 162, in __call__\n await self.app(scope, receive, _send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/cors.py\", line 83, in __call__\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py\", line 79, in __call__\n raise exc\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py\", line 68, in __call__\n await self.app(scope, receive, sender)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py\", line 20, in __call__\n raise e\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py\", line 17, in __call__\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 718, in __call__\n await route.handle(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 276, in handle\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 66, in app\n response = await func(request)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/routing.py\", line 241, in app\n raw_response = await run_endpoint_function(\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/routing.py\", line 167, in run_endpoint_function\n return await dependant.call(**values)\n File \"/Users/gustavopoa/Documents/Langspace/langflow/src/backend/langflow/api/v1/endpoints.py\", line 124, in custom_component_error\n c = x.get(\"a\")\nAttributeError: 'int' object has no attribute 'get'\n" + } + + error2 = { + "detail": "division by zero", + "traceback": "Traceback (most recent call last):\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/errors.py\", line 162, in __call__\n await self.app(scope, receive, _send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/cors.py\", line 83, in __call__\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py\", line 79, in __call__\n raise exc\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py\", line 68, in __call__\n await self.app(scope, receive, sender)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py\", line 20, in __call__\n raise e\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py\", line 17, in __call__\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 718, in __call__\n await route.handle(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 276, in handle\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 66, in app\n response = await func(request)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/routing.py\", line 241, in app\n raw_response = await run_endpoint_function(\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/routing.py\", line 167, in run_endpoint_function\n return await dependant.call(**values)\n File \"/Users/gustavopoa/Documents/Langspace/langflow/src/backend/langflow/api/v1/endpoints.py\", line 130, in custom_component_error\n return 1/0\nZeroDivisionError: division by zero\n" + } + + error3 = { + "detail": "name 'CreateObject' is not defined", + "traceback": "Traceback (most recent call last):\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/errors.py\", line 162, in __call__\n await self.app(scope, receive, _send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/cors.py\", line 83, in __call__\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py\", line 79, in __call__\n raise exc\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py\", line 68, in __call__\n await self.app(scope, receive, sender)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py\", line 20, in __call__\n raise e\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py\", line 17, in __call__\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 718, in __call__\n await route.handle(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 276, in handle\n await self.app(scope, receive, send)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/starlette/routing.py\", line 66, in app\n response = await func(request)\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/routing.py\", line 241, in app\n raw_response = await run_endpoint_function(\n File \"/Users/gustavopoa/Library/Caches/pypoetry/virtualenvs/langflow-3LyDxlRJ-py3.10/lib/python3.10/site-packages/fastapi/routing.py\", line 167, in run_endpoint_function\n return await dependant.call(**values)\n File \"/Users/gustavopoa/Documents/Langspace/langflow/src/backend/langflow/api/v1/endpoints.py\", line 130, in custom_component_error\n error3 = CreateObject()\nNameError: name 'CreateObject' is not defined\n" + } + + error = [error1, error2, error3] + + return error[random.randint(0, 2)] diff --git a/src/backend/langflow/api/v1/schemas.py b/src/backend/langflow/api/v1/schemas.py index eac732575..1d38998b2 100644 --- a/src/backend/langflow/api/v1/schemas.py +++ b/src/backend/langflow/api/v1/schemas.py @@ -111,3 +111,8 @@ class StreamData(BaseModel): class CustomComponentCode(BaseModel): code: str + + +class CustomComponentResponseError(BaseModel): + detail: str + traceback: str diff --git a/src/backend/langflow/main.py b/src/backend/langflow/main.py index 12d70bfb4..e6594742c 100644 --- a/src/backend/langflow/main.py +++ b/src/backend/langflow/main.py @@ -5,238 +5,12 @@ from langflow.api import router from langflow.database.base import create_db_and_tables from langflow.interface.utils import setup_llm_caching -template_node = { - "template": { - "code": { - "required": True, - "placeholder": "", - "show": True, - "multiline": True, - "value": "\ndef my_user_python_function(text: str) -> str:\n \"\"\"This is a default python function that returns the input text\"\"\"\n return text.upper()\n", - "password": False, - "name": "code", - "advanced": False, - "type": "code", - "list": False - }, - "lc_kwargs": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "password": False, - "name": "lc_kwargs", - "advanced": True, - "type": "code", - "list": False - }, - "verbose": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "value": False, - "password": False, - "name": "verbose", - "advanced": False, - "type": "bool", - "list": False - }, - "callbacks": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "password": False, - "name": "callbacks", - "advanced": False, - "type": "langchain.callbacks.base.BaseCallbackHandler", - "list": True - }, - "tags": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "password": False, - "name": "tags", - "advanced": False, - "type": "str", - "list": True - }, - "client": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "password": False, - "name": "client", - "advanced": False, - "type": "Any", - "list": False - }, - "model_name": { - "required": False, - "placeholder": "", - "show": True, - "multiline": False, - "value": "gpt-3.5-turbo", - "password": False, - "options": [ - "gpt-3.5-turbo-0613", - "gpt-3.5-turbo", - "gpt-3.5-turbo-16k-0613", - "gpt-3.5-turbo-16k", - "gpt-4-0613", - "gpt-4-32k-0613", - "gpt-4", - "gpt-4-32k" - ], - "name": "model_name", - "advanced": False, - "type": "str", - "list": True - }, - "temperature": { - "required": False, - "placeholder": "", - "show": True, - "multiline": False, - "value": 0.7, - "password": False, - "name": "temperature", - "advanced": False, - "type": "float", - "list": False - }, - "model_kwargs": { - "required": False, - "placeholder": "", - "show": True, - "multiline": False, - "password": False, - "name": "model_kwargs", - "advanced": True, - "type": "code", - "list": False - }, - "openai_api_key": { - "required": False, - "placeholder": "", - "show": True, - "multiline": False, - "value": "", - "password": True, - "name": "openai_api_key", - "display_name": "OpenAI API Key", - "advanced": False, - "type": "str", - "list": False - }, - "openai_api_base": { - "required": False, - "placeholder": "", - "show": True, - "multiline": False, - "password": False, - "name": "openai_api_base", - "display_name": "OpenAI API Base", - "advanced": False, - "type": "str", - "list": False - }, - "openai_organization": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "password": False, - "name": "openai_organization", - "display_name": "OpenAI Organization", - "advanced": False, - "type": "str", - "list": False - }, - "openai_proxy": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "password": False, - "name": "openai_proxy", - "display_name": "OpenAI Proxy", - "advanced": False, - "type": "str", - "list": False - }, - "request_timeout": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "password": False, - "name": "request_timeout", - "advanced": False, - "type": "float", - "list": False - }, - "max_retries": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "value": 6, - "password": False, - "name": "max_retries", - "advanced": False, - "type": "int", - "list": False - }, - "streaming": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "value": False, - "password": False, - "name": "streaming", - "advanced": False, - "type": "bool", - "list": False - }, - "n": { - "required": False, - "placeholder": "", - "show": False, - "multiline": False, - "value": 1, - "password": False, - "name": "n", - "advanced": False, - "type": "int", - "list": False - }, - "max_tokens": { - "required": False, - "placeholder": "", - "show": True, - "multiline": False, - "password": True, - "name": "max_tokens", - "advanced": False, - "type": "int", - "list": False - }, - "_type": "ChatOpenAI" - }, - "base_classes": [ - "BaseChatModel", - "Serializable", - "BaseLanguageModel", - "ChatOpenAI" - ], - "description": "Wrapper around OpenAI Chat large language models." -} +from pydantic import BaseModel + + +class ErrorMessage(BaseModel): + detail: str + traceback: str def create_app(): @@ -252,10 +26,6 @@ def create_app(): def get_health(): return {"status": "OK"} - @app.get("/dynamic_node") - def get_dynamic_nome(): - return template_node - app.add_middleware( CORSMiddleware, allow_origins=origins,