@@ -394,15 +394,9 @@ def enable_debug(self) -> None:
394394 requests_log .setLevel (logging .DEBUG )
395395 requests_log .propagate = True
396396
397- def _create_headers (self , content_type : Optional [str ] = None ) -> Dict [str , Any ]:
398- request_headers = self .headers .copy ()
399- if content_type is not None :
400- request_headers ["Content-type" ] = content_type
401- return request_headers
402-
403- def _get_session_opts (self , content_type : str ) -> Dict [str , Any ]:
397+ def _get_session_opts (self ) -> Dict [str , Any ]:
404398 return {
405- "headers" : self ._create_headers ( content_type ),
399+ "headers" : self .headers . copy ( ),
406400 "auth" : self ._http_auth ,
407401 "timeout" : self .timeout ,
408402 "verify" : self .ssl_verify ,
@@ -442,12 +436,39 @@ def _check_redirects(self, result: requests.Response) -> None:
442436 if location and location .startswith ("https://" ):
443437 raise gitlab .exceptions .RedirectError (REDIRECT_MSG )
444438
439+ def _prepare_send_data (
440+ self ,
441+ files : Dict [str , Any ] = None ,
442+ post_data : Dict [str , Any ] = None ,
443+ raw : Optional [bool ] = False ,
444+ ) -> Tuple :
445+ if files :
446+ if post_data is None :
447+ post_data = {}
448+ else :
449+ # booleans does not exists for data (neither for MultipartEncoder):
450+ # cast to string int to avoid: 'bool' object has no attribute 'encode'
451+ for k , v in post_data .items ():
452+ if isinstance (v , bool ):
453+ post_data [k ] = str (int (v ))
454+ post_data ["file" ] = files .get ("file" )
455+ post_data ["avatar" ] = files .get ("avatar" )
456+
457+ data = MultipartEncoder (post_data )
458+ return (None , data , data .content_type )
459+
460+ if raw and post_data :
461+ return (None , post_data , "application/octet-stream" )
462+
463+ return (post_data , None , "application/json" )
464+
445465 def http_request (
446466 self ,
447467 verb : str ,
448468 path : str ,
449469 query_data : Optional [Dict [str , Any ]] = None ,
450470 post_data : Optional [Dict [str , Any ]] = None ,
471+ raw : Optional [bool ] = False ,
451472 streamed : bool = False ,
452473 files : Optional [Dict [str , Any ]] = None ,
453474 timeout : Optional [float ] = None ,
@@ -465,7 +486,8 @@ def http_request(
465486 'http://whatever/v4/api/projecs')
466487 query_data (dict): Data to send as query parameters
467488 post_data (dict): Data to send in the body (will be converted to
468- json)
489+ json by default)
490+ raw (bool): If True, do not convert post_data to json
469491 streamed (bool): Whether the data should be streamed
470492 files (dict): The files to send to the server
471493 timeout (float): The timeout, in seconds, for the request
@@ -504,7 +526,7 @@ def http_request(
504526 else :
505527 utils .copy_dict (params , kwargs )
506528
507- opts = self ._get_session_opts (content_type = "application/json" )
529+ opts = self ._get_session_opts ()
508530
509531 verify = opts .pop ("verify" )
510532 opts_timeout = opts .pop ("timeout" )
@@ -513,23 +535,8 @@ def http_request(
513535 timeout = opts_timeout
514536
515537 # We need to deal with json vs. data when uploading files
516- if files :
517- json = None
518- if post_data is None :
519- post_data = {}
520- else :
521- # booleans does not exists for data (neither for MultipartEncoder):
522- # cast to string int to avoid: 'bool' object has no attribute 'encode'
523- for k , v in post_data .items ():
524- if isinstance (v , bool ):
525- post_data [k ] = str (int (v ))
526- post_data ["file" ] = files .get ("file" )
527- post_data ["avatar" ] = files .get ("avatar" )
528- data = MultipartEncoder (post_data )
529- opts ["headers" ]["Content-type" ] = data .content_type
530- else :
531- json = post_data
532- data = None
538+ json , data , content_type = self ._prepare_send_data (files , post_data , raw )
539+ opts ["headers" ]["Content-type" ] = content_type
533540
534541 # Requests assumes that `.` should not be encoded as %2E and will make
535542 # changes to urls using this encoding. Using a prepped request we can
@@ -684,6 +691,7 @@ def http_post(
684691 path : str ,
685692 query_data : Optional [Dict [str , Any ]] = None ,
686693 post_data : Optional [Dict [str , Any ]] = None ,
694+ raw : Optional [bool ] = False ,
687695 files : Optional [Dict [str , Any ]] = None ,
688696 ** kwargs : Any ,
689697 ) -> Union [Dict [str , Any ], requests .Response ]:
@@ -694,7 +702,8 @@ def http_post(
694702 'http://whatever/v4/api/projecs')
695703 query_data (dict): Data to send as query parameters
696704 post_data (dict): Data to send in the body (will be converted to
697- json)
705+ json by default)
706+ raw (bool): If True, do not convert post_data to json
698707 files (dict): The files to send to the server
699708 **kwargs: Extra options to send to the server (e.g. sudo)
700709
@@ -731,6 +740,7 @@ def http_put(
731740 path : str ,
732741 query_data : Optional [Dict [str , Any ]] = None ,
733742 post_data : Optional [Dict [str , Any ]] = None ,
743+ raw : Optional [bool ] = False ,
734744 files : Optional [Dict [str , Any ]] = None ,
735745 ** kwargs : Any ,
736746 ) -> Union [Dict [str , Any ], requests .Response ]:
@@ -741,7 +751,8 @@ def http_put(
741751 'http://whatever/v4/api/projecs')
742752 query_data (dict): Data to send as query parameters
743753 post_data (dict): Data to send in the body (will be converted to
744- json)
754+ json by default)
755+ raw (bool): If True, do not convert post_data to json
745756 files (dict): The files to send to the server
746757 **kwargs: Extra options to send to the server (e.g. sudo)
747758
@@ -761,6 +772,7 @@ def http_put(
761772 query_data = query_data ,
762773 post_data = post_data ,
763774 files = files ,
775+ raw = raw ,
764776 ** kwargs ,
765777 )
766778 try :
0 commit comments