From af35ae315e8843dbb2c617e789d983b92627fe88 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 26 Sep 2023 19:34:50 -0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20docs(async-api.mdx):=20update=20?= =?UTF-8?q?endpoint=20path=20for=20checking=20task=20status=20to=20improve?= =?UTF-8?q?=20consistency=20and=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🐛 fix(endpoints.py): update endpoint path for checking task status to match the updated path in the documentation 🐛 fix(schemas.py): add TaskResponse schema to properly handle task response data 🐛 fix(locustfile.py): update endpoint path for polling task status to match the updated path in the endpoints 🐛 fix(test_endpoints.py): update helper function and test cases to use the new task response structure and endpoint path for polling task status --- docs/docs/guidelines/async-api.mdx | 4 ++-- src/backend/langflow/api/v1/endpoints.py | 11 +++++++++-- src/backend/langflow/api/v1/schemas.py | 9 ++++++++- tests/locust/locustfile.py | 2 +- tests/test_endpoints.py | 20 ++++++++++++++------ 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/docs/docs/guidelines/async-api.mdx b/docs/docs/guidelines/async-api.mdx index 582a5e1c8..9ef836704 100644 --- a/docs/docs/guidelines/async-api.mdx +++ b/docs/docs/guidelines/async-api.mdx @@ -29,11 +29,11 @@ curl -X POST \ ## Checking Task Status -You can check the status of an asynchronous task by making a GET request to the `/task/{task_id}/status` endpoint. +You can check the status of an asynchronous task by making a GET request to the `/task/{task_id}` endpoint. ```bash curl -X GET \ - http://localhost:3000/api/v1/task//status \ + http://localhost:3000/api/v1/task/ \ -H 'x-api-key: ' ``` diff --git a/src/backend/langflow/api/v1/endpoints.py b/src/backend/langflow/api/v1/endpoints.py index ff5e0541e..864467f9b 100644 --- a/src/backend/langflow/api/v1/endpoints.py +++ b/src/backend/langflow/api/v1/endpoints.py @@ -20,6 +20,7 @@ from langflow.interface.custom.custom_component import CustomComponent from langflow.api.v1.schemas import ( ProcessResponse, + TaskResponse, TaskStatusResponse, UploadFileResponse, CustomComponentCode, @@ -145,9 +146,15 @@ async def process_flow( session_id, ) task_result = task.status + + if task_id: + task_response = TaskResponse(id=task_id, href=f"api/v1/task/{task_id}") + else: + task_response = None + return ProcessResponse( result=task_result, - id=task_id, + task=task_response, session_id=session_id, backend=str(type(task_service.backend)), ) @@ -173,7 +180,7 @@ async def process_flow( raise HTTPException(status_code=500, detail=str(e)) from e -@router.get("/task/{task_id}/status", response_model=TaskStatusResponse) +@router.get("/task/{task_id}", response_model=TaskStatusResponse) async def get_task_status(task_id: str): task_service = get_task_service() task = task_service.get_task(task_id) diff --git a/src/backend/langflow/api/v1/schemas.py b/src/backend/langflow/api/v1/schemas.py index 519bc534e..9c6ac6d60 100644 --- a/src/backend/langflow/api/v1/schemas.py +++ b/src/backend/langflow/api/v1/schemas.py @@ -47,11 +47,18 @@ class UpdateTemplateRequest(BaseModel): template: dict +class TaskResponse(BaseModel): + """Task response schema.""" + + id: Optional[str] = Field(None) + href: Optional[str] = Field(None) + + class ProcessResponse(BaseModel): """Process response schema.""" result: Any - id: Optional[str] = None + task: Optional[TaskResponse] = None session_id: Optional[str] = None backend: Optional[str] = None diff --git a/tests/locust/locustfile.py b/tests/locust/locustfile.py index 000c3456d..aca0d1de9 100644 --- a/tests/locust/locustfile.py +++ b/tests/locust/locustfile.py @@ -19,7 +19,7 @@ class NameTest(FastHttpUser): while True: with self.rest( "GET", - f"/task/{task_id}/status", + f"/task/{task_id}", name="task_status", headers=self.headers, ) as response: diff --git a/tests/test_endpoints.py b/tests/test_endpoints.py index 43a68580a..1de7c9deb 100644 --- a/tests/test_endpoints.py +++ b/tests/test_endpoints.py @@ -25,10 +25,10 @@ def run_post(client, flow_id, headers, post_data): # Helper function to poll task status -def poll_task_status(client, headers, task_id, max_attempts=20, sleep_time=1): +def poll_task_status(client, headers, href, max_attempts=20, sleep_time=1): for _ in range(max_attempts): task_status_response = client.get( - f"api/v1/task/{task_id}/status", + href, headers=headers, ) if ( @@ -544,11 +544,15 @@ def test_async_task_processing(distributed_client, added_flow, created_api_key): assert response.status_code == 200, response.json() # Extract the task ID from the response - task_id = response.json().get("id") + task = response.json().get("task") + task_id = task.get("id") + task_href = task.get("href") assert task_id is not None + assert task_href is not None + assert task_href == f"api/v1/task/{task_id}" # Polling the task status using the helper function - task_status_json = poll_task_status(distributed_client, headers, task_id) + task_status_json = poll_task_status(distributed_client, headers, task_href) assert task_status_json is not None, "Task did not complete in time" # Validate that the task completed successfully and the result is as expected @@ -576,11 +580,15 @@ def test_async_task_processing_vector_store( assert "FAILURE" not in response.json()["result"] # Extract the task ID from the response - task_id = response.json().get("id") + task = response.json().get("task") + task_id = task.get("id") + task_href = task.get("href") assert task_id is not None + assert task_href is not None + assert task_href == f"api/v1/task/{task_id}" # Polling the task status using the helper function - task_status_json = poll_task_status(client, headers, task_id, max_attempts=40) + task_status_json = poll_task_status(client, headers, task_href) assert task_status_json is not None, "Task did not complete in time" # Validate that the task completed successfully and the result is as expected