Skip to content

Commit b375a1a

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

File tree

2 files changed

+49
-52
lines changed

2 files changed

+49
-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,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy