fix APIError signature and DELETE body for dmr 0.6.0

This commit is contained in:
straitz 2026-06-03 05:55:39 +09:00
parent 8e44c4501a
commit 98214393a6
2 changed files with 25 additions and 16 deletions

View file

@ -56,6 +56,15 @@ from .validators import base64_to_curve
User = get_user_model()
def _api_error(status_code, body, headers=None):
"""Adapter for DMR's APIError(raw_data, *, status_code, ...) signature.
Lets call sites keep the (status_code=, body=) style; the body is DMR's
first positional ``raw_data`` argument.
"""
return APIError(body, status_code=status_code, headers=headers)
def _resolve_related(model, pk, field_name):
"""Resolve a related object by PK (was PrimaryKeyRelatedField(queryset=...)).
@ -66,7 +75,7 @@ def _resolve_related(model, pk, field_name):
return None
obj = model.objects.filter(pk=pk).first()
if obj is None:
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_REQUEST,
body={field_name: [f'Invalid pk "{pk}" - object does not exist.']},
)
@ -92,7 +101,7 @@ class PredictionCollectionController(Controller[PydanticSerializer]):
try:
prediction_result = TawhiriClient.get_prediction(parsed_body.model_dump())
except requests.RequestException as exc:
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_GATEWAY,
body={'error': f'Tawhiri error: {str(exc)}'},
)
@ -135,7 +144,7 @@ class PredictionListUserController(Controller[PydanticSerializer]):
filters['created_at__lte'] = parse_datetime(parsed_query.created_till)
if parsed_query.satellite_id:
if not user.satellites.filter(id=parsed_query.satellite_id).exists():
raise APIError(status_code=HTTPStatus.FORBIDDEN, body={'detail': 'Access denied'})
raise _api_error(status_code=HTTPStatus.FORBIDDEN, body={'detail': 'Access denied'})
filters['satellite_id'] = parsed_query.satellite_id
queryset = Prediction.objects.filter(**filters)
@ -157,7 +166,7 @@ class PredictionDetailController(Controller[PydanticSerializer]):
prediction = Prediction.objects.filter(
user=self.request.user, pk=parsed_path.pk).first()
if prediction is None:
raise APIError(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found'})
raise _api_error(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found'})
return PredictionDetailOut.model_validate(prediction)
@ -169,7 +178,7 @@ class PredictionDeleteController(Controller[PydanticSerializer]):
prediction = Prediction.objects.filter(
user=self.request.user, pk=parsed_path.pk).first()
if prediction is None:
raise APIError(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found'})
raise _api_error(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found'})
prediction.delete()
@ -260,14 +269,14 @@ class LoginController(Controller[PydanticSerializer]):
password = data.get('password')
if username is None or password is None:
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_REQUEST,
body={'detail': 'Please provide username and password.'},
)
user = authenticate(username=username, password=password)
if user is None:
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_REQUEST,
body={'detail': 'Invalid credentials.'},
)
@ -284,7 +293,7 @@ class LogoutController(Controller[PydanticSerializer]):
@modify(status_code=HTTPStatus.OK)
def post(self) -> DetailResponse:
if not self.request.user.is_authenticated:
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_REQUEST,
body={'detail': "You're not logged in."},
)
@ -302,7 +311,7 @@ def _check_saved_point_unique(user, name, exclude_pk=None):
if exclude_pk is not None:
qs = qs.exclude(pk=exclude_pk)
if qs.exists():
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_REQUEST,
body={'non_field_errors': [_SAVED_POINT_DUPLICATE]},
)
@ -330,7 +339,7 @@ class SavedPointDetailController(Controller[PydanticSerializer]):
# matching DRF's get_object() over a user-scoped queryset.
obj = SavedPoint.objects.filter(user=self.request.user, pk=pk).first()
if obj is None:
raise APIError(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found.'})
raise _api_error(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found.'})
return obj
def get(self, parsed_path: Path[PkPath]) -> SavedPointOut:
@ -383,7 +392,7 @@ class PredictionTemplateDetailController(Controller[PydanticSerializer]):
def _get_object(self, pk: int):
obj = PreditctionTemplate.objects.filter(user=self.request.user, pk=pk).first()
if obj is None:
raise APIError(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found.'})
raise _api_error(status_code=HTTPStatus.NOT_FOUND, body={'detail': 'Not found.'})
return obj
def get(self, parsed_path: Path[PkPath]) -> PredictionTemplateOut:
@ -432,7 +441,7 @@ class ChangePasswordController(Controller[PydanticSerializer]):
user = self.request.user
if not user.check_password(parsed_body.old_password):
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_REQUEST,
body={'detail': 'Old password is incorrect'},
)
@ -454,12 +463,12 @@ class DeleteAccountController(Controller[PydanticSerializer]):
try:
parsed_body = DeleteAccountIn(**json.loads(self.request.body or b'{}'))
except ValidationError as exc:
raise APIError(status_code=HTTPStatus.BAD_REQUEST, body=json.loads(exc.json()))
raise _api_error(status_code=HTTPStatus.BAD_REQUEST, body=json.loads(exc.json()))
except ValueError:
raise APIError(status_code=HTTPStatus.BAD_REQUEST, body={'detail': 'Invalid request body.'})
raise _api_error(status_code=HTTPStatus.BAD_REQUEST, body={'detail': 'Invalid request body.'})
if not user.check_password(parsed_body.password):
raise APIError(
raise _api_error(
status_code=HTTPStatus.BAD_REQUEST,
body={'detail': 'Incorrect password'},
)