@@ -393,15 +393,9 @@ def enable_debug(self) -> None:
393393 requests_log .setLevel (logging .DEBUG )
394394 requests_log .propagate = True
395395
396- def _create_headers (self , content_type : Optional [str ] = None ) -> Dict [str , Any ]:
397- request_headers = self .headers .copy ()
398- if content_type is not None :
399- request_headers ["Content-type" ] = content_type
400- return request_headers
401-
402- def _get_session_opts (self , content_type : str ) -> Dict [str , Any ]:
396+ def _get_session_opts (self ) -> Dict [str , Any ]:
403397 return {
404- "headers" : self ._create_headers ( content_type ),
398+ "headers" : self .headers . copy ( ),
405399 "auth" : self ._http_auth ,
406400 "timeout" : self .timeout ,
407401 "verify" : self .ssl_verify ,
@@ -441,12 +435,39 @@ def _check_redirects(self, result: requests.Response) -> None:
441435 if location and location .startswith ("https://" ):
442436 raise gitlab .exceptions .RedirectError (REDIRECT_MSG )
443437
438+ def _prepare_send_data (
439+ self ,
440+ files : Dict [str , Any ] = None ,
441+ post_data : Dict [str , Any ] = None ,
442+ raw : Optional [bool ] = False ,
443+ ) -> Tuple :
444+ if files :
445+ if post_data is None :
446+ post_data = {}
447+ else :
448+ # booleans does not exists for data (neither for MultipartEncoder):
449+ # cast to string int to avoid: 'bool' object has no attribute 'encode'
450+ for k , v in post_data .items ():
451+ if isinstance (v , bool ):
452+ post_data [k ] = str (int (v ))
453+ post_data ["file" ] = files .get ("file" )
454+ post_data ["avatar" ] = files .get ("avatar" )
455+
456+ data = MultipartEncoder (post_data )
457+ return (None , data , data .content_type )
458+
459+ if raw and post_data :
460+ return (None , post_data , "application/octet-stream" )
461+
462+ return (post_data , None , "application/json" )
463+
444464 def http_request (
445465 self ,
446466 verb : str ,
447467 path : str ,
448468 query_data : Optional [Dict [str , Any ]] = None ,
449469 post_data : Optional [Dict [str , Any ]] = None ,
470+ raw : Optional [bool ] = False ,
450471 streamed : bool = False ,
451472 files : Optional [Dict [str , Any ]] = None ,
452473 timeout : Optional [float ] = None ,
@@ -464,7 +485,8 @@ def http_request(
464485 'http://whatever/v4/api/projecs')
465486 query_data (dict): Data to send as query parameters
466487 post_data (dict): Data to send in the body (will be converted to
467- json)
488+ json by default)
489+ raw (bool): If True, do not convert post_data to json
468490 streamed (bool): Whether the data should be streamed
469491 files (dict): The files to send to the server
470492 timeout (float): The timeout, in seconds, for the request
@@ -503,7 +525,7 @@ def http_request(
503525 else :
504526 utils .copy_dict (params , kwargs )
505527
506- opts = self ._get_session_opts (content_type = "application/json" )
528+ opts = self ._get_session_opts ()
507529
508530 verify = opts .pop ("verify" )
509531 opts_timeout = opts .pop ("timeout" )
@@ -512,23 +534,8 @@ def http_request(
512534 timeout = opts_timeout
513535
514536 # We need to deal with json vs. data when uploading files
515- if files :
516- json = None
517- if post_data is None :
518- post_data = {}
519- else :
520- # booleans does not exists for data (neither for MultipartEncoder):
521- # cast to string int to avoid: 'bool' object has no attribute 'encode'
522- for k , v in post_data .items ():
523- if isinstance (v , bool ):
524- post_data [k ] = str (int (v ))
525- post_data ["file" ] = files .get ("file" )
526- post_data ["avatar" ] = files .get ("avatar" )
527- data = MultipartEncoder (post_data )
528- opts ["headers" ]["Content-type" ] = data .content_type
529- else :
530- json = post_data
531- data = None
537+ json , data , content_type = self ._prepare_send_data (files , post_data , raw )
538+ opts ["headers" ]["Content-type" ] = content_type
532539
533540 # Requests assumes that `.` should not be encoded as %2E and will make
534541 # changes to urls using this encoding. Using a prepped request we can
@@ -683,6 +690,7 @@ def http_post(
683690 path : str ,
684691 query_data : Optional [Dict [str , Any ]] = None ,
685692 post_data : Optional [Dict [str , Any ]] = None ,
693+ raw : Optional [bool ] = False ,
686694 files : Optional [Dict [str , Any ]] = None ,
687695 ** kwargs : Any ,
688696 ) -> Union [Dict [str , Any ], requests .Response ]:
@@ -693,7 +701,8 @@ def http_post(
693701 'http://whatever/v4/api/projecs')
694702 query_data (dict): Data to send as query parameters
695703 post_data (dict): Data to send in the body (will be converted to
696- json)
704+ json by default)
705+ raw (bool): If True, do not convert post_data to json
697706 files (dict): The files to send to the server
698707 **kwargs: Extra options to send to the server (e.g. sudo)
699708
@@ -730,6 +739,7 @@ def http_put(
730739 path : str ,
731740 query_data : Optional [Dict [str , Any ]] = None ,
732741 post_data : Optional [Dict [str , Any ]] = None ,
742+ raw : Optional [bool ] = False ,
733743 files : Optional [Dict [str , Any ]] = None ,
734744 ** kwargs : Any ,
735745 ) -> Union [Dict [str , Any ], requests .Response ]:
@@ -740,7 +750,8 @@ def http_put(
740750 'http://whatever/v4/api/projecs')
741751 query_data (dict): Data to send as query parameters
742752 post_data (dict): Data to send in the body (will be converted to
743- json)
753+ json by default)
754+ raw (bool): If True, do not convert post_data to json
744755 files (dict): The files to send to the server
745756 **kwargs: Extra options to send to the server (e.g. sudo)
746757
@@ -760,6 +771,7 @@ def http_put(
760771 query_data = query_data ,
761772 post_data = post_data ,
762773 files = files ,
774+ raw = raw ,
763775 ** kwargs ,
764776 )
765777 try :
0 commit comments