From 05440e0596b29fea24c8acbd9eb9e78459d67c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=B6pf?= Date: Fri, 16 Dec 2022 15:48:17 +0100 Subject: [PATCH] step 2/2 of parallel dev on task controller --- backend/app/api/v1/api.py | 4 +- backend/app/api/v1/tasks.py | 116 ++++++++++++------- backend/app/api/v1/tasks2.py | 210 ----------------------------------- 3 files changed, 76 insertions(+), 254 deletions(-) delete mode 100644 backend/app/api/v1/tasks2.py diff --git a/backend/app/api/v1/api.py b/backend/app/api/v1/api.py index 277e92f3..afcb9677 100644 --- a/backend/app/api/v1/api.py +++ b/backend/app/api/v1/api.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- -from app.api.v1 import tasks, tasks2 +from app.api.v1 import tasks from fastapi import APIRouter api_router = APIRouter() api_router.include_router(tasks.router, prefix="/tasks", tags=["tasks"]) - -api_router.include_router(tasks2.router, prefix="/task2", tags=["task2"]) # temporary diff --git a/backend/app/api/v1/tasks.py b/backend/app/api/v1/tasks.py index fab75569..6032c0b3 100644 --- a/backend/app/api/v1/tasks.py +++ b/backend/app/api/v1/tasks.py @@ -4,6 +4,7 @@ from typing import Any from uuid import UUID from app.api import deps +from app.prompt_repository import PromptRepository, TaskPayload from app.schemas import protocol as protocol_schema from fastapi import APIRouter, Depends, HTTPException from fastapi.security.api_key import APIKey @@ -135,11 +136,14 @@ def request_task( """ Create new task. """ - deps.api_auth(api_key, db) + api_client = deps.api_auth(api_key, db) try: task = generate_task(request) - # TODO: store task in database + + pr = PromptRepository(db, api_client, request.user) + pr.store_task(task) + except Exception: logger.exception("Failed to generate task.") raise HTTPException( @@ -159,10 +163,21 @@ def acknowledge_task( """ The frontend acknowledges a task. """ - deps.api_auth(api_key, db) - logger.info(f"Frontend acknowledges task {task_id=}, {ack_request=}.") - # here we would store the post id in the database for the task + api_client = deps.api_auth(api_key, db) + + try: + pr = PromptRepository(db, api_client, user=None) + + # here we store the post id in the database for the task + pr.bind_frontend_post_id(task_id=task_id, post_id=ack_request.post_id) + logger.info(f"Frontend acknowledges task {task_id=}, {ack_request=}.") + + except Exception: + logger.exception("Failed to acknowledge task.") + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + ) return {} @@ -194,40 +209,59 @@ def post_interaction( """ The frontend reports an interaction. """ - deps.api_auth(api_key, db) + api_client = deps.api_auth(api_key, db) - match type(interaction): - case protocol_schema.TextReplyToPost: - logger.info( - f"Frontend reports text reply to {interaction.post_id=} with {interaction.text=} by {interaction.user=}." - ) - # here we would store the text reply in the database - return protocol_schema.TaskDone( - reply_to_post_id=interaction.user_post_id, - addressed_user=interaction.user, - ) - case protocol_schema.PostRating: - logger.info( - f"Frontend reports rating of {interaction.post_id=} with {interaction.rating=} by {interaction.user=}." - ) - # check if rating in range - # here we would store the rating in the database - return protocol_schema.TaskDone( - reply_to_post_id=interaction.post_id, - addressed_user=interaction.user, - ) - case protocol_schema.PostRanking: - logger.info( - f"Frontend reports ranking of {interaction.post_id=} with {interaction.ranking=} by {interaction.user=}." - ) - # TODO: check if the ranking is valid - # here we would store the ranking in the database - return protocol_schema.TaskDone( - reply_to_post_id=interaction.post_id, - addressed_user=interaction.user, - ) - case _: - raise HTTPException( - status_code=HTTP_400_BAD_REQUEST, - detail="Invalid response type.", - ) + try: + pr = PromptRepository(db, api_client, user=interaction.user) + + match type(interaction): + case protocol_schema.TextReplyToPost: + logger.info( + f"Frontend reports text reply to {interaction.post_id=} with {interaction.text=} by {interaction.user=}." + ) + + work_package = pr.fetch_workpackage_by_postid(interaction.post_id) + work_payload: TaskPayload = work_package.payload.payload + logger.info(f"found task work package in db: {work_payload}") + + # here we store the text reply in the database + # ToDo: role user or agent? + pr.store_text_reply(interaction, role="unknown") + + return protocol_schema.TaskDone( + reply_to_post_id=interaction.user_post_id, + addressed_user=interaction.user, + ) + case protocol_schema.PostRating: + logger.info( + f"Frontend reports rating of {interaction.post_id=} with {interaction.rating=} by {interaction.user=}." + ) + + # here we store the rating in the database + pr.store_rating(interaction) + + return protocol_schema.TaskDone( + reply_to_post_id=interaction.post_id, + addressed_user=interaction.user, + ) + case protocol_schema.PostRanking: + logger.info( + f"Frontend reports ranking of {interaction.post_id=} with {interaction.ranking=} by {interaction.user=}." + ) + # TODO: check if the ranking is valid + # here we would store the ranking in the database + return protocol_schema.TaskDone( + reply_to_post_id=interaction.post_id, + addressed_user=interaction.user, + ) + case _: + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + detail="Invalid response type.", + ) + + except Exception: + logger.exception("Interaction request failed.") + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + ) diff --git a/backend/app/api/v1/tasks2.py b/backend/app/api/v1/tasks2.py deleted file mode 100644 index 8fd8ac48..00000000 --- a/backend/app/api/v1/tasks2.py +++ /dev/null @@ -1,210 +0,0 @@ -# -*- coding: utf-8 -*- -import random -from typing import Any -from uuid import UUID - -from app.api import deps -from app.prompt_repository import PromptRepository, RateSummaryPayload, TaskPayload -from app.schemas import protocol as protocol_schema -from fastapi import APIRouter, Depends, HTTPException -from fastapi.security.api_key import APIKey -from loguru import logger -from sqlmodel import Session -from starlette.status import HTTP_400_BAD_REQUEST - -router = APIRouter() - - -def generate_task(request: protocol_schema.TaskRequest) -> protocol_schema.Task: - match (request.type): - case protocol_schema.TaskRequestType.random: - logger.info("Frontend requested a random task.") - while request.type == protocol_schema.TaskRequestType.random: - request.type = random.choice(list(protocol_schema.TaskRequestType)).value - return generate_task(request) - case protocol_schema.TaskRequestType.summarize_story: - logger.info("Generating a SummarizeStoryTask.") - task = protocol_schema.SummarizeStoryTask( - story="This is a story. A very long story. So long, it needs to be summarized.", - ) - case protocol_schema.TaskRequestType.rate_summary: - logger.info("Generating a RateSummaryTask.") - task = protocol_schema.RateSummaryTask( - full_text="This is a story. A very long story. So long, it needs to be summarized.", - summary="This is a summary.", - scale=protocol_schema.RatingScale(min=1, max=5), - ) - case protocol_schema.TaskRequestType.initial_prompt: - logger.info("Generating an InitialPromptTask.") - task = protocol_schema.InitialPromptTask( - hint="Ask the assistant about a current event." # this is optional - ) - case protocol_schema.TaskRequestType.user_reply: - logger.info("Generating a UserReplyTask.") - task = protocol_schema.UserReplyTask( - conversation=protocol_schema.Conversation( - messages=[ - protocol_schema.ConversationMessage( - text="Hey, assistant, what's going on in the world?", - is_assistant=False, - ), - protocol_schema.ConversationMessage( - text="I'm not sure I understood correctly, could you rephrase that?", - is_assistant=True, - ), - ], - ) - ) - case protocol_schema.TaskRequestType.assistant_reply: - logger.info("Generating a AssistantReplyTask.") - task = protocol_schema.AssistantReplyTask( - conversation=protocol_schema.Conversation( - messages=[ - protocol_schema.ConversationMessage( - text="Hey, assistant, write me an English essay about water.", - is_assistant=False, - ), - ], - ) - ) - case _: - raise HTTPException( - status_code=HTTP_400_BAD_REQUEST, - detail="Invalid request type.", - ) - logger.info(f"Generated {task=}.") - if request.user is not None: - task.addressed_user = request.user - - return task - - -@router.post("/", response_model=protocol_schema.AnyTask) # work with Union once more types are added -def request_task( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - request: protocol_schema.TaskRequest, -) -> Any: - """ - Create new task. - """ - api_client = deps.api_auth(api_key, db) - - try: - task = generate_task(request) - - pr = PromptRepository(db, api_client, request.user) - pr.store_task(task) - - except Exception: - logger.exception("Failed to generate task.") - raise HTTPException( - status_code=HTTP_400_BAD_REQUEST, - ) - return task - - -@router.post("/{task_id}/ack") -def acknowledge_task( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - task_id: UUID, - ack_request: protocol_schema.TaskAck, -) -> Any: - """ - The frontend acknowledges a task. - """ - api_client = deps.api_auth(api_key, db) - pr = PromptRepository(db, api_client, user=None) - - logger.info(f"Frontend acknowledges task {task_id=}, {ack_request=}.") - # here we store the post id in the database for the task - try: - pr.bind_frontend_post_id(task_id=task_id, post_id=ack_request.post_id) - except Exception as err: - logger.warning(err) - raise - return {} - - -@router.post("/{task_id}/nack") -def acknowledge_task_failure( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - task_id: UUID, - nack_request: protocol_schema.TaskNAck, -) -> Any: - """ - The frontend reports failure to implement a task. - """ - deps.api_auth(api_key, db) - - logger.info(f"Frontend reports failure to implement task {task_id=}, {nack_request=}.") - # here we would store the post id in the database for the task - return {} - - -@router.post("/interaction") -def post_interaction( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - interaction: protocol_schema.AnyInteraction, -) -> Any: - """ - The frontend reports an interaction. - """ - api_client = deps.api_auth(api_key, db) - pr = PromptRepository(db, api_client, user=interaction.user) - - match (type(interaction)): - case protocol_schema.TextReplyToPost: - logger.info( - f"Frontend reports text reply to {interaction.post_id=} with {interaction.text=} by {interaction.user=}." - ) - - work_package = pr.fetch_workpackage_by_postid(interaction.post_id) - work_payload: TaskPayload = work_package.payload.payload - logger.info(f"found task work package in db: {work_payload}") - - # here we store the text reply in the database - # ToDo: role user or agent? - pr.store_text_reply(interaction, role="unknown") - - return protocol_schema.TaskDone( - reply_to_post_id=interaction.user_post_id, - addressed_user=interaction.user, - ) - case protocol_schema.PostRating: - logger.info( - f"Frontend reports rating of {interaction.post_id=} with {interaction.rating=} by {interaction.user=}." - ) - # check if rating in range - - work_package = pr.fetch_workpackage_by_postid(interaction.post_id) - work_payload: RateSummaryPayload = work_package.payload.payload - if ( - type(work_payload) != RateSummaryPayload - or interaction.rating < work_payload.scale.min - or interaction.rating > work_payload.scale.max - ): - raise HTTPException( - status_code=HTTP_400_BAD_REQUEST, - detail="Invalid response type.", - ) - - pr.store_rating(interaction) - - # here we would store the rating in the database - return protocol_schema.TaskDone( - reply_to_post_id=interaction.post_id, - addressed_user=interaction.user, - ) - case _: - raise HTTPException( - status_code=HTTP_400_BAD_REQUEST, - detail="Invalid response type.", - )