Skip to content

Commit 48afd2c

Browse files
author
Liora Milbaum
committed
refactor: Migrate MultipartEncoder to RequestsBackend
1 parent 18f4148 commit 48afd2c

File tree

3 files changed

+50
-52
lines changed

3 files changed

+50
-52
lines changed

gitlab/client.py

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import requests
1010
import requests.utils
11-
from requests_toolbelt.multipart.encoder import MultipartEncoder # type: ignore
1211

1312
import gitlab
1413
import gitlab.config
@@ -637,38 +636,6 @@ def _check_redirects(result: requests.Response) -> None:
637636
)
638637
)
639638

640-
@staticmethod
641-
def _prepare_send_data(
642-
files: Optional[Dict[str, Any]] = None,
643-
post_data: Optional[Union[Dict[str, Any], bytes]] = None,
644-
raw: bool = False,
645-
) -> Tuple[
646-
Optional[Union[Dict[str, Any], bytes]],
647-
Optional[Union[Dict[str, Any], MultipartEncoder]],
648-
str,
649-
]:
650-
if files:
651-
if post_data is None:
652-
post_data = {}
653-
else:
654-
# booleans does not exists for data (neither for MultipartEncoder):
655-
# cast to string int to avoid: 'bool' object has no attribute 'encode'
656-
if TYPE_CHECKING:
657-
assert isinstance(post_data, dict)
658-
for k, v in post_data.items():
659-
if isinstance(v, bool):
660-
post_data[k] = str(int(v))
661-
post_data["file"] = files.get("file")
662-
post_data["avatar"] = files.get("avatar")
663-
664-
data = MultipartEncoder(post_data)
665-
return (None, data, data.content_type)
666-
667-
if raw and post_data:
668-
return (None, post_data, "application/octet-stream")
669-
670-
return (post_data, None, "application/json")
671-
672639
def http_request(
673640
self,
674641
verb: str,
@@ -746,7 +713,9 @@ def http_request(
746713
retry_transient_errors = self.retry_transient_errors
747714

748715
# We need to deal with json vs. data when uploading files
749-
json, data, content_type = self._prepare_send_data(files, post_data, raw)
716+
json, data, content_type = self.http_backend.prepare_send_data(
717+
files, post_data, raw
718+
)
750719
opts["headers"]["Content-type"] = content_type
751720

752721
cur_retries = 0
@@ -779,46 +748,42 @@ def http_request(
779748
if 200 <= result.status_code < 300:
780749
return result.response
781750

782-
if (429 == result.response.status_code and obey_rate_limit) or (
783-
result.response.status_code
784-
in gitlab.const.RETRYABLE_TRANSIENT_ERROR_CODES
751+
if (429 == result.status_code and obey_rate_limit) or (
752+
result.status_code in gitlab.const.RETRYABLE_TRANSIENT_ERROR_CODES
785753
and retry_transient_errors
786754
):
787755
# Response headers documentation:
788756
# https://docs.gitlab.com/ee/user/admin_area/settings/user_and_ip_rate_limits.html#response-headers
789757
if max_retries == -1 or cur_retries < max_retries:
790758
wait_time = 2**cur_retries * 0.1
791-
if "Retry-After" in result.response.headers:
792-
wait_time = int(result.response.headers["Retry-After"])
793-
elif "RateLimit-Reset" in result.response.headers:
794-
wait_time = (
795-
int(result.response.headers["RateLimit-Reset"])
796-
- time.time()
797-
)
759+
if "Retry-After" in result.headers:
760+
wait_time = int(result.headers["Retry-After"])
761+
elif "RateLimit-Reset" in result.headers:
762+
wait_time = int(result.headers["RateLimit-Reset"]) - time.time()
798763
cur_retries += 1
799764
time.sleep(wait_time)
800765
continue
801766

802-
error_message = result.response.content
767+
error_message = result.content
803768
try:
804-
error_json = result.response.json()
769+
error_json = result.json()
805770
for k in ("message", "error"):
806771
if k in error_json:
807772
error_message = error_json[k]
808773
except (KeyError, ValueError, TypeError):
809774
pass
810775

811-
if result.response.status_code == 401:
776+
if result.status_code == 401:
812777
raise gitlab.exceptions.GitlabAuthenticationError(
813-
response_code=result.response.status_code,
778+
response_code=result.status_code,
814779
error_message=error_message,
815-
response_body=result.response.content,
780+
response_body=result.content,
816781
)
817782

818783
raise gitlab.exceptions.GitlabHttpError(
819-
response_code=result.response.status_code,
784+
response_code=result.status_code,
820785
error_message=error_message,
821-
response_body=result.response.content,
786+
response_body=result.content,
822787
)
823788

824789
def http_get(

gitlab/http_backends/requests_backend.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, Dict, Optional, Union
3+
from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING, Union
44

55
import requests
66
from requests.structures import CaseInsensitiveDict
@@ -39,6 +39,38 @@ def __init__(self, session: Optional[requests.Session] = None) -> None:
3939
def client(self) -> requests.Session:
4040
return self._client
4141

42+
@staticmethod
43+
def prepare_send_data(
44+
files: Optional[Dict[str, Any]] = None,
45+
post_data: Optional[Union[Dict[str, Any], bytes]] = None,
46+
raw: bool = False,
47+
) -> Tuple[
48+
Optional[Union[Dict[str, Any], bytes]],
49+
Optional[Union[Dict[str, Any], MultipartEncoder]],
50+
str,
51+
]:
52+
if files:
53+
if post_data is None:
54+
post_data = {}
55+
else:
56+
# booleans does not exists for data (neither for MultipartEncoder):
57+
# cast to string int to avoid: 'bool' object has no attribute 'encode'
58+
if TYPE_CHECKING:
59+
assert isinstance(post_data, dict)
60+
for k, v in post_data.items():
61+
if isinstance(v, bool):
62+
post_data[k] = str(int(v))
63+
post_data["file"] = files.get("file")
64+
post_data["avatar"] = files.get("avatar")
65+
66+
data = MultipartEncoder(post_data)
67+
return (None, data, data.content_type)
68+
69+
if raw and post_data:
70+
return (None, post_data, "application/octet-stream")
71+
72+
return (post_data, None, "application/json")
73+
4274
def http_request(
4375
self,
4476
method: str,

tests/functional/api/test_import_export.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def test_project_remote_import_s3(gl):
9393
"remote-project",
9494
"root",
9595
)
96+
print(err_info, flush=True)
9697
assert err_info.value.response_code == 400
9798
assert (
9899
"Failed to open 'aws-file-key' in 'aws-bucket-name'"

0 commit comments

Comments
 (0)