Import random module and HTTPStatus from http module in endpoints.py. Add CustomComponentResponseError to the import in schemas.py. Change the status_code in create_upload_file endpoint to use the HTTPStatus.CREATED constant. Change the status_code in custom_component endpoint to use the HTTPStatus.OK constant. Add a new endpoint for custom_component_error that returns a random error response.

This commit is contained in:
gustavoschaedler 2023-06-28 17:37:48 +01:00
commit cd4c73ac28
3 changed files with 43 additions and 241 deletions

View file

@ -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)]

View file

@ -111,3 +111,8 @@ class StreamData(BaseModel):
class CustomComponentCode(BaseModel):
code: str
class CustomComponentResponseError(BaseModel):
detail: str
traceback: str

View file

@ -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,