diff --git a/gitlab/client.py b/gitlab/client.py index 4ad6c8fb6..36d4ae21e 100644 --- a/gitlab/client.py +++ b/gitlab/client.py @@ -8,7 +8,6 @@ import requests import requests.utils -from requests_toolbelt.multipart.encoder import MultipartEncoder # type: ignore import gitlab import gitlab.config @@ -637,38 +636,6 @@ def _check_redirects(result: requests.Response) -> None: ) ) - @staticmethod - def _prepare_send_data( - files: Optional[Dict[str, Any]] = None, - post_data: Optional[Union[Dict[str, Any], bytes]] = None, - raw: bool = False, - ) -> Tuple[ - Optional[Union[Dict[str, Any], bytes]], - Optional[Union[Dict[str, Any], MultipartEncoder]], - str, - ]: - if files: - if post_data is None: - post_data = {} - else: - # booleans does not exists for data (neither for MultipartEncoder): - # cast to string int to avoid: 'bool' object has no attribute 'encode' - if TYPE_CHECKING: - assert isinstance(post_data, dict) - for k, v in post_data.items(): - if isinstance(v, bool): - post_data[k] = str(int(v)) - post_data["file"] = files.get("file") - post_data["avatar"] = files.get("avatar") - - data = MultipartEncoder(post_data) - return (None, data, data.content_type) - - if raw and post_data: - return (None, post_data, "application/octet-stream") - - return (post_data, None, "application/json") - def http_request( self, verb: str, @@ -746,7 +713,9 @@ def http_request( retry_transient_errors = self.retry_transient_errors # We need to deal with json vs. data when uploading files - json, data, content_type = self._prepare_send_data(files, post_data, raw) + json, data, content_type = self.http_backend.prepare_send_data( + files, post_data, raw + ) opts["headers"]["Content-type"] = content_type cur_retries = 0 diff --git a/gitlab/http_backends/requests_backend.py b/gitlab/http_backends/requests_backend.py index 0b310abc8..60309fc69 100644 --- a/gitlab/http_backends/requests_backend.py +++ b/gitlab/http_backends/requests_backend.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING, Union import requests from requests.structures import CaseInsensitiveDict @@ -39,6 +39,38 @@ def __init__(self, session: Optional[requests.Session] = None) -> None: def client(self) -> requests.Session: return self._client + @staticmethod + def prepare_send_data( + files: Optional[Dict[str, Any]] = None, + post_data: Optional[Union[Dict[str, Any], bytes]] = None, + raw: bool = False, + ) -> Tuple[ + Optional[Union[Dict[str, Any], bytes]], + Optional[Union[Dict[str, Any], MultipartEncoder]], + str, + ]: + if files: + if post_data is None: + post_data = {} + else: + # booleans does not exists for data (neither for MultipartEncoder): + # cast to string int to avoid: 'bool' object has no attribute 'encode' + if TYPE_CHECKING: + assert isinstance(post_data, dict) + for k, v in post_data.items(): + if isinstance(v, bool): + post_data[k] = str(int(v)) + post_data["file"] = files.get("file") + post_data["avatar"] = files.get("avatar") + + data = MultipartEncoder(post_data) + return (None, data, data.content_type) + + if raw and post_data: + return (None, post_data, "application/octet-stream") + + return (post_data, None, "application/json") + def http_request( self, method: str,