@@ -395,15 +395,9 @@ def enable_debug(self) -> None:
395395 requests_log .setLevel (logging .DEBUG )
396396 requests_log .propagate = True
397397
398- def _create_headers (self , content_type : Optional [str ] = None ) -> Dict [str , Any ]:
399- request_headers = self .headers .copy ()
400- if content_type is not None :
401- request_headers ["Content-type" ] = content_type
402- return request_headers
403-
404- def _get_session_opts (self , content_type : str ) -> Dict [str , Any ]:
398+ def _get_session_opts (self ) -> Dict [str , Any ]:
405399 return {
406- "headers" : self ._create_headers ( content_type ),
400+ "headers" : self .headers . copy ( ),
407401 "auth" : self ._http_auth ,
408402 "timeout" : self .timeout ,
409403 "verify" : self .ssl_verify ,
@@ -443,12 +437,39 @@ def _check_redirects(self, result: requests.Response) -> None:
443437 if location and location .startswith ("https://" ):
444438 raise gitlab .exceptions .RedirectError (REDIRECT_MSG )
445439
440+ def _prepare_send_data (
441+ self ,
442+ files : Dict [str , Any ] = None ,
443+ post_data : Dict [str , Any ] = None ,
444+ raw : Optional [bool ] = False ,
445+ ) -> Tuple :
446+ if files :
447+ if post_data is None :
448+ post_data = {}
449+ else :
450+ # booleans does not exists for data (neither for MultipartEncoder):
451+ # cast to string int to avoid: 'bool' object has no attribute 'encode'
452+ for k , v in post_data .items ():
453+ if isinstance (v , bool ):
454+ post_data [k ] = str (int (v ))
455+ post_data ["file" ] = files .get ("file" )
456+ post_data ["avatar" ] = files .get ("avatar" )
457+
458+ data = MultipartEncoder (post_data )
459+ return (None , data , data .content_type )
460+
461+ if raw and post_data :
462+ return (None , post_data , "application/octet-stream" )
463+
464+ return (post_data , None , "application/json" )
465+
446466 def http_request (
447467 self ,
448468 verb : str ,
449469 path : str ,
450470 query_data : Optional [Dict [str , Any ]] = None ,
451471 post_data : Optional [Dict [str , Any ]] = None ,
472+ raw : Optional [bool ] = False ,
452473 streamed : bool = False ,
453474 files : Optional [Dict [str , Any ]] = None ,
454475 timeout : Optional [float ] = None ,
@@ -466,7 +487,8 @@ def http_request(
466487 'http://whatever/v4/api/projecs')
467488 query_data (dict): Data to send as query parameters
468489 post_data (dict): Data to send in the body (will be converted to
469- json)
490+ json by default)
491+ raw (bool): If True, do not convert post_data to json
470492 streamed (bool): Whether the data should be streamed
471493 files (dict): The files to send to the server
472494 timeout (float): The timeout, in seconds, for the request
@@ -505,7 +527,7 @@ def http_request(
505527 else :
506528 utils .copy_dict (params , kwargs )
507529
508- opts = self ._get_session_opts (content_type = "application/json" )
530+ opts = self ._get_session_opts ()
509531
510532 verify = opts .pop ("verify" )
511533 opts_timeout = opts .pop ("timeout" )
@@ -514,23 +536,8 @@ def http_request(
514536 timeout = opts_timeout
515537
516538 # We need to deal with json vs. data when uploading files
517- if files :
518- json = None
519- if post_data is None :
520- post_data = {}
521- else :
522- # booleans does not exists for data (neither for MultipartEncoder):
523- # cast to string int to avoid: 'bool' object has no attribute 'encode'
524- for k , v in post_data .items ():
525- if isinstance (v , bool ):
526- post_data [k ] = str (int (v ))
527- post_data ["file" ] = files .get ("file" )
528- post_data ["avatar" ] = files .get ("avatar" )
529- data = MultipartEncoder (post_data )
530- opts ["headers" ]["Content-type" ] = data .content_type
531- else :
532- json = post_data
533- data = None
539+ json , data , content_type = self ._prepare_send_data (files , post_data , raw )
540+ opts ["headers" ]["Content-type" ] = content_type
534541
535542 # Requests assumes that `.` should not be encoded as %2E and will make
536543 # changes to urls using this encoding. Using a prepped request we can
@@ -685,6 +692,7 @@ def http_post(
685692 path : str ,
686693 query_data : Optional [Dict [str , Any ]] = None ,
687694 post_data : Optional [Dict [str , Any ]] = None ,
695+ raw : Optional [bool ] = False ,
688696 files : Optional [Dict [str , Any ]] = None ,
689697 ** kwargs : Any ,
690698 ) -> Union [Dict [str , Any ], requests .Response ]:
@@ -695,7 +703,8 @@ def http_post(
695703 'http://whatever/v4/api/projecs')
696704 query_data (dict): Data to send as query parameters
697705 post_data (dict): Data to send in the body (will be converted to
698- json)
706+ json by default)
707+ raw (bool): If True, do not convert post_data to json
699708 files (dict): The files to send to the server
700709 **kwargs: Extra options to send to the server (e.g. sudo)
701710
@@ -732,6 +741,7 @@ def http_put(
732741 path : str ,
733742 query_data : Optional [Dict [str , Any ]] = None ,
734743 post_data : Optional [Dict [str , Any ]] = None ,
744+ raw : Optional [bool ] = False ,
735745 files : Optional [Dict [str , Any ]] = None ,
736746 ** kwargs : Any ,
737747 ) -> Union [Dict [str , Any ], requests .Response ]:
@@ -742,7 +752,8 @@ def http_put(
742752 'http://whatever/v4/api/projecs')
743753 query_data (dict): Data to send as query parameters
744754 post_data (dict): Data to send in the body (will be converted to
745- json)
755+ json by default)
756+ raw (bool): If True, do not convert post_data to json
746757 files (dict): The files to send to the server
747758 **kwargs: Extra options to send to the server (e.g. sudo)
748759
@@ -762,6 +773,7 @@ def http_put(
762773 query_data = query_data ,
763774 post_data = post_data ,
764775 files = files ,
776+ raw = raw ,
765777 ** kwargs ,
766778 )
767779 try :
0 commit comments