Skip to content

Commit b27f4ee

Browse files
chore: add http_patch method
In order to support some new API calls we need to support the HTTP `PATCH` method. Closes: #2469
1 parent 0867564 commit b27f4ee

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

docs/api-levels.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ The available methods are:
6060
* ``http_get()``
6161
* ``http_post()``
6262
* ``http_put()``
63+
* ``http_patch()``
6364
* ``http_delete()``
6465
* ``http_list()`` (a wrapper around ``http_get`` handling pagination, including with lazy generators)
6566
* ``http_head()`` (only returns the header dictionary)

gitlab/client.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,54 @@ def http_put(
10941094
error_message="Failed to parse the server message"
10951095
) from e
10961096

1097+
def http_patch(
1098+
self,
1099+
path: str,
1100+
*,
1101+
query_data: Optional[Dict[str, Any]] = None,
1102+
post_data: Optional[Union[Dict[str, Any], bytes]] = None,
1103+
raw: bool = False,
1104+
**kwargs: Any,
1105+
) -> Union[Dict[str, Any], requests.Response]:
1106+
"""Make a PATCH request to the Gitlab server.
1107+
1108+
Args:
1109+
path: Path or full URL to query ('/projects' or
1110+
'http://whatever/v4/api/projecs')
1111+
query_data: Data to send as query parameters
1112+
post_data: Data to send in the body (will be converted to
1113+
json by default)
1114+
raw: If True, do not convert post_data to json
1115+
**kwargs: Extra options to send to the server (e.g. sudo)
1116+
1117+
Returns:
1118+
The parsed json returned by the server.
1119+
1120+
Raises:
1121+
GitlabHttpError: When the return code is not 2xx
1122+
GitlabParsingError: If the json data could not be parsed
1123+
"""
1124+
query_data = query_data or {}
1125+
post_data = post_data or {}
1126+
1127+
result = self.http_request(
1128+
"patch",
1129+
path,
1130+
query_data=query_data,
1131+
post_data=post_data,
1132+
raw=raw,
1133+
**kwargs,
1134+
)
1135+
try:
1136+
json_result = result.json()
1137+
if TYPE_CHECKING:
1138+
assert isinstance(json_result, dict)
1139+
return json_result
1140+
except Exception as e:
1141+
raise gitlab.exceptions.GitlabParsingError(
1142+
error_message="Failed to parse the server message"
1143+
) from e
1144+
10971145
def http_delete(self, path: str, **kwargs: Any) -> requests.Response:
10981146
"""Make a DELETE request to the Gitlab server.
10991147

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ disable = [
5858
"too-many-instance-attributes",
5959
"too-many-lines",
6060
"too-many-locals",
61+
"too-many-public-methods",
6162
"too-many-statements",
6263
"unsubscriptable-object",
6364
]

tests/unit/test_gitlab_http_methods.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,56 @@ def test_put_request_invalid_data(gl):
809809
assert responses.assert_call_count(url, 1) is True
810810

811811

812+
@responses.activate
813+
def test_patch_request(gl):
814+
url = "http://localhost/api/v4/projects"
815+
responses.add(
816+
method=responses.PATCH,
817+
url=url,
818+
json={"name": "project1"},
819+
status=200,
820+
match=helpers.MATCH_EMPTY_QUERY_PARAMS,
821+
)
822+
823+
result = gl.http_patch("/projects")
824+
assert isinstance(result, dict)
825+
assert result["name"] == "project1"
826+
assert responses.assert_call_count(url, 1) is True
827+
828+
829+
@responses.activate
830+
def test_patch_request_404(gl):
831+
url = "http://localhost/api/v4/not_there"
832+
responses.add(
833+
method=responses.PATCH,
834+
url=url,
835+
json=[],
836+
status=404,
837+
match=helpers.MATCH_EMPTY_QUERY_PARAMS,
838+
)
839+
840+
with pytest.raises(GitlabHttpError):
841+
gl.http_patch("/not_there")
842+
assert responses.assert_call_count(url, 1) is True
843+
844+
845+
@responses.activate
846+
def test_patch_request_invalid_data(gl):
847+
url = "http://localhost/api/v4/projects"
848+
responses.add(
849+
method=responses.PATCH,
850+
url=url,
851+
body='["name": "project1"]',
852+
content_type="application/json",
853+
status=200,
854+
match=helpers.MATCH_EMPTY_QUERY_PARAMS,
855+
)
856+
857+
with pytest.raises(GitlabParsingError):
858+
gl.http_patch("/projects")
859+
assert responses.assert_call_count(url, 1) is True
860+
861+
812862
@responses.activate
813863
def test_delete_request(gl):
814864
url = "http://localhost/api/v4/projects"

0 commit comments

Comments
 (0)