1- from dataclasses import asdict , dataclass
2-
3- from django .db import DatabaseError
4- from django .http import JsonResponse
51from rest_framework .decorators import action
62from rest_framework .request import Request
73from rest_framework .response import Response
84from rest_framework .viewsets import ModelViewSet
5+ from rest_framework .status import HTTP_201_CREATED , HTTP_200_OK
96
10- from langpro_annotator .logger import logger
117from problem .problem_details import (
128 get_filters ,
139 get_related_problem_ids ,
1410)
1511from problem .models import KnowledgeBase , Problem , Sentence
16- from problem .serializers import ProblemSerializer
17-
18- @dataclass
19- class SaveProblemResponse :
20- id : int | None = None
21- error : str | None = None
22-
23- def json_response (self , status = 200 ) -> JsonResponse :
24- return JsonResponse (asdict (self ), status = status )
12+ from problem .serializers import ProblemInputSerializer , ProblemSerializer
2513
2614
2715class ProblemView (ModelViewSet ):
@@ -40,10 +28,9 @@ def list(self, request: Request) -> Response:
4028 qs = qs .filter (filters )
4129
4230 serializer = self .get_serializer (qs , many = True )
43- return Response (serializer .data , status = 200 )
31+ return Response (serializer .data , status = HTTP_200_OK )
4432
45-
46- @action (detail = False , methods = ['get' ], url_path = 'first' )
33+ @action (detail = False , methods = ["get" ], url_path = "first" )
4734 def first (self , request : Request ) -> Response :
4835 """
4936 Retrieves the first problem from the queryset.
@@ -85,72 +72,49 @@ def _get_problem_response(self, request: Request, pk: int | None) -> Response:
8572
8673 serializer = self .get_serializer (problem )
8774
88- return Response ({
89- "problem" : serializer .data ,
90- "index" : problem_index ,
91- "first" : related_problem_ids .first ,
92- "previous" : related_problem_ids .previous ,
93- "next" : related_problem_ids .next ,
94- "last" : related_problem_ids .last ,
95- "total" : related_problem_ids .total ,
96- }, status = 200 )
97-
98- def post (self , request : Request , problem_id : int | None = None ) -> JsonResponse :
75+ return Response (
76+ {
77+ "problem" : serializer .data ,
78+ "index" : problem_index ,
79+ "first" : related_problem_ids .first ,
80+ "previous" : related_problem_ids .previous ,
81+ "next" : related_problem_ids .next ,
82+ "last" : related_problem_ids .last ,
83+ "total" : related_problem_ids .total ,
84+ },
85+ status = HTTP_200_OK ,
86+ )
87+
88+ def create (self , request : Request ) -> Response :
89+ """
90+ Creates a new Problem from the provided input data.
91+ """
92+ return self ._handle_update_create_problem (request , problem_id = None )
93+
94+ def partial_update (self , request : Request , pk : int ) -> Response :
9995 """
100- If the Problem ID is None, attempts to create a new Problem;
101- else the associated Problem is updated.
96+ Updates an existing user-created Problem with the provided input data.
10297 """
98+ return self ._handle_update_create_problem (request , pk )
99+
100+ def _handle_update_create_problem (
101+ self , request : Request , problem_id : int | None
102+ ) -> Response :
103103 input_data = request .data
104104
105- try :
106- problem = save_problem (input_data , problem_id )
107- except ValueError as ve :
108- logger .error (f"Validation error saving problem: { ve } " )
109- return SaveProblemResponse (id = problem_id , error = str (ve )).json_response (
110- status = 400
111- )
112- except Problem .DoesNotExist as pne :
113- logger .error (f"Problem not found: { pne } " )
114- return SaveProblemResponse (
115- id = problem_id , error = "Problem not found."
116- ).json_response (status = 404 )
117- except KnowledgeBase .DoesNotExist as kbne :
118- logger .error (f"Knowledge base item not found: { kbne } " )
119- return SaveProblemResponse (
120- id = problem_id , error = "Knowledge base item not found."
121- ).json_response (status = 404 )
122- except DatabaseError as dbe :
123- logger .error (f"Database error saving problem: { dbe } " )
124- return SaveProblemResponse (
125- id = problem_id , error = "Database error saving problem."
126- ).json_response (status = 500 )
127- except Exception as e :
128- logger .exception (f"Unexpected error saving problem: { e } " )
129- return SaveProblemResponse (
130- id = problem_id , error = "Error saving problem."
131- ).json_response (status = 500 )
132-
133- return SaveProblemResponse (id = problem .pk ).json_response (status = 200 )
134-
135-
136- def save_problem (input_data : dict , problem_id : int | None ) -> Problem :
137- serializer = ProblemInputSerializer (data = input_data )
138-
139- if not serializer .is_valid ():
140- raise ValueError ("Input data is not valid." )
141-
142- validated_input : dict = serializer .validated_data # type: ignore
143-
144- problem : Problem | None = None
145- if problem_id is None :
146- problem = create_problem_from_input (validated_input )
147- else :
148- problem = update_problem_from_input (validated_input )
149-
150- if problem is None :
151- raise ValueError ("Problem could not be saved." )
105+ serializer = ProblemInputSerializer (data = input_data )
106+ serializer .is_valid (raise_exception = True )
107+ validated_input : dict = serializer .validated_data # type: ignore
108+ validated_input ["id" ] = problem_id
152109
153- return problem
110+ if problem_id is None :
111+ problem = create_problem_from_input (validated_input )
112+ status = HTTP_201_CREATED
113+ else :
114+ problem = update_problem_from_input (validated_input )
115+ status = HTTP_200_OK
116+
117+ return Response ({"id" : problem .pk }, status = status )
154118
155119
156120def create_problem_from_input (parse_input : dict ) -> Problem :
@@ -185,7 +149,7 @@ def create_problem_from_input(parse_input: dict) -> Problem:
185149def update_or_create_kb_items (problem : Problem , kb_items : list [dict ]) -> None :
186150 kb_ids : list [str ] = []
187151 for item in kb_items :
188- id = item [ "id" ]
152+ id = getattr ( item , "id" , None )
189153 entity1 = item ["entity1" ]
190154 relationship = item ["relationship" ]
191155 entity2 = item ["entity2" ]
0 commit comments