Skip to content

Commit

Permalink
fix: allow DELETE to have a body
Browse files Browse the repository at this point in the history
The Keycloak Admin doesn't follow the HTTP spec, and
expects a body in some delete calls. For example:

DELETE
/admin/realms/{realm}/users/{user-id}/role-mappings/clients/{client-id}

This commit changes the DELETE signature to match a POST.
  • Loading branch information
derlin committed Dec 29, 2024
1 parent 33588c8 commit 4cab8aa
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/02-making-calls.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ information):
* :python:`.post(data=None, files=None, **kwargs)`
* :python:`.patch(data=None, files=None, **kwargs)`
* :python:`.put(data=None, files=None, **kwargs)`
* :python:`.delete(**kwargs)`
* :python:`.delete(data=None, files=None, **kwargs)`

The ``kwargs`` can be used to add query parameters to the URL. The ``data`` and ``files`` parameters
can be used to add a payload to the request. See :py:meth:`requests.Session.request` for more
Expand Down
16 changes: 13 additions & 3 deletions mantelo/internal/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,25 @@ def put(
"PUT", data=data, files=files, params=kwargs
)

def delete(self, **kwargs: Any) -> bool | tuple[requests.Response, bool]:
def delete(
self,
data: dict | None = None,
files: dict | None = None,
**kwargs: Any,
) -> bool | tuple[requests.Response, bool]:
"""
Do a DELETE request.
Parameters are the same as :func:`post`.
*Note*: some APIs such as the Keycloak Admin REST Api do not follow the HTTP spec and expect
a body in the request (e.g.
``DELETE /admin/realms/{realm}/users/{user-id}/role-mappings/clients/{client-id}``).
:param kwargs: The query parameters to send with the request.
:return: True if the request was successful, False for 3xx status codes.
:rtype: bool
"""
resp = self._request("DELETE", params=kwargs)
resp = self._request("DELETE", data=data, files=files, params=kwargs)
# TODO: isn't this stupid?
# The only other possible statues are 3xx...
response = 200 <= resp.status_code <= 299
Expand Down
6 changes: 4 additions & 2 deletions tests/internal/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,11 @@ def test_resource_delete(mock_store, raw, status_code, expected):
resource = _api.Resource(mock_store.evolve(raw=raw))
resource._request = Mock(return_value=mock_response)

response = resource.delete(foo="bar")
response = resource.delete(data="data", files="files", foo="bar")

resource._request.assert_called_with("DELETE", params={"foo": "bar"})
resource._request.assert_called_with(
"DELETE", data="data", files="files", params={"foo": "bar"}
)

if raw:
assert response == (mock_response, expected)
Expand Down

0 comments on commit 4cab8aa

Please sign in to comment.