3030class OpenAPIError (Exception ):
3131 """Base Exception for errors related to using the openapi spec."""
3232
33- pass
34-
3533
3634class OpenAPIValidationError (OpenAPIError ):
3735 """Exception raised for failed client side validation of parameters or request bodies."""
3836
39- pass
40-
4137
4238class UnsafeCallError (OpenAPIError ):
4339 """Exception raised for POST, PUT, PATCH or DELETE calls with `safe_calls_only=True`."""
4440
45- pass
46-
4741
4842class AuthProviderBase :
4943 """
@@ -174,53 +168,71 @@ def __init__(
174168 user_agent : t .Optional [str ] = None ,
175169 cid : t .Optional [str ] = None ,
176170 ):
177- if verify is False :
178- urllib3 .disable_warnings (urllib3 .exceptions .InsecureRequestWarning )
179-
180- self .debug_callback : t .Callable [[int , str ], t .Any ] = debug_callback or (lambda i , x : None )
181- self .base_url : str = base_url
182- self .doc_path : str = doc_path
183- self .safe_calls_only : bool = safe_calls_only
184- self .auth_provider = auth_provider
185-
186- self ._session : requests .Session = requests .session ()
187- if self .auth_provider :
188- if cert or key :
189- raise OpenAPIError (_ ("Cannot use both 'auth' and 'cert'." ))
190- else :
191- if cert and key :
192- self ._session .cert = (cert , key )
193- elif cert :
194- self ._session .cert = cert
195- elif key :
196- raise OpenAPIError (_ ("Cert is required if key is set." ))
197- self ._session .headers .update (
171+ self ._debug_callback : t .Callable [[int , str ], t .Any ] = debug_callback or (lambda i , x : None )
172+ self ._base_url : str = base_url
173+ self ._doc_path : str = doc_path
174+ self ._safe_calls_only : bool = safe_calls_only
175+ self ._headers = headers or {}
176+ self ._verify = verify
177+ self ._auth_provider = auth_provider
178+ self ._cert = cert
179+ self ._key = key
180+
181+ self ._headers .update (
198182 {
199183 "User-Agent" : user_agent or f"Pulp-glue openapi parser ({ __version__ } )" ,
200184 "Accept" : "application/json" ,
201185 }
202186 )
203187 if cid :
204- self ._session .headers ["Correlation-Id" ] = cid
205- if headers :
206- self ._session .headers .update (headers )
207- self ._session .max_redirects = 0
188+ self ._headers ["Correlation-Id" ] = cid
189+
190+ self ._setup_session ()
208191
192+ self .load_api (refresh_cache = refresh_cache )
193+
194+ def _setup_session (self ) -> None :
195+ # This is specific requests library.
196+
197+ if self ._verify is False :
198+ urllib3 .disable_warnings (urllib3 .exceptions .InsecureRequestWarning )
199+
200+ self ._session : requests .Session = requests .session ()
201+ # Don't redirect, because carrying auth accross redirects is unsafe.
202+ self ._session .max_redirects = 0
203+ self ._session .headers .update (self ._headers )
204+ if self ._auth_provider :
205+ if self ._cert or self ._key :
206+ raise OpenAPIError (_ ("Cannot use both 'auth' and 'cert'." ))
207+ else :
208+ if self ._cert and self ._key :
209+ self ._session .cert = (self ._cert , self ._key )
210+ elif self ._cert :
211+ self ._session .cert = self ._cert
212+ elif self ._key :
213+ raise OpenAPIError (_ ("Cert is required if key is set." ))
209214 session_settings = self ._session .merge_environment_settings (
210- base_url , {}, None , verify , None
215+ self . _base_url , {}, None , self . _verify , None
211216 )
212217 self ._session .verify = session_settings ["verify" ]
213218 self ._session .proxies = session_settings ["proxies" ]
214219
215- self .load_api (refresh_cache = refresh_cache )
220+ @property
221+ def base_url (self ) -> str :
222+ return self ._base_url
223+
224+ @property
225+ def cid (self ) -> t .Optional [str ]:
226+ return self ._headers .get ("Correlation-Id" )
216227
217228 def load_api (self , refresh_cache : bool = False ) -> None :
218229 # TODO: Find a way to invalidate caches on upstream change
219230 xdg_cache_home : str = os .environ .get ("XDG_CACHE_HOME" ) or "~/.cache"
220231 apidoc_cache : str = os .path .join (
221232 os .path .expanduser (xdg_cache_home ),
222233 "squeezer" ,
223- (self .base_url + "_" + self .doc_path ).replace (":" , "_" ).replace ("/" , "_" ) + "api.json" ,
234+ (self ._base_url + "_" + self ._doc_path ).replace (":" , "_" ).replace ("/" , "_" )
235+ + "api.json" ,
224236 )
225237 try :
226238 if refresh_cache :
@@ -252,7 +264,7 @@ def _parse_api(self, data: bytes) -> None:
252264
253265 def _download_api (self ) -> bytes :
254266 try :
255- response : requests .Response = self ._session .get (urljoin (self .base_url , self .doc_path ))
267+ response : requests .Response = self ._session .get (urljoin (self ._base_url , self ._doc_path ))
256268 except requests .RequestException as e :
257269 raise OpenAPIError (str (e ))
258270 response .raise_for_status ()
@@ -261,14 +273,16 @@ def _download_api(self) -> bytes:
261273 return response .content
262274
263275 def _set_correlation_id (self , correlation_id : str ) -> None :
264- if "Correlation-ID" in self ._session . headers :
265- if self ._session . headers ["Correlation-ID" ] != correlation_id :
276+ if "Correlation-ID" in self ._headers :
277+ if self ._headers ["Correlation-ID" ] != correlation_id :
266278 raise OpenAPIError (
267279 _ ("Correlation ID returned from server did not match. {} != {}" ).format (
268- self ._session . headers ["Correlation-ID" ], correlation_id
280+ self ._headers ["Correlation-ID" ], correlation_id
269281 )
270282 )
271283 else :
284+ self ._headers ["Correlation-ID" ] = correlation_id
285+ # Do it for requests too...
272286 self ._session .headers ["Correlation-ID" ] = correlation_id
273287
274288 def param_spec (
@@ -420,7 +434,7 @@ def validate_schema(self, schema: t.Any, name: str, value: t.Any) -> t.Any:
420434 # TextField
421435 # DateTimeField etc.
422436 # ChoiceField
423- # FielField (binary data)
437+ # FileField (binary data)
424438 value = self .validate_string (schema , name , value )
425439 elif schema_type == "integer" :
426440 # IntegerField
@@ -654,12 +668,12 @@ def render_request(
654668 security : t .List [t .Dict [str , t .List [str ]]] = method_spec .get (
655669 "security" , self .api_spec .get ("security" , {})
656670 )
657- if security and self .auth_provider :
671+ if security and self ._auth_provider :
658672 if "Authorization" in self ._session .headers :
659673 # Bad idea, but you wanted it that way.
660674 auth = None
661675 else :
662- auth = self .auth_provider (security , self .api_spec ["components" ]["securitySchemes" ])
676+ auth = self ._auth_provider (security , self .api_spec ["components" ]["securitySchemes" ])
663677 else :
664678 # No auth required? Don't provide it.
665679 # No auth_provider available? Hope for the best (should do the trick for cert auth).
@@ -751,7 +765,7 @@ def call(
751765 names = ", " .join (parameters .keys ()), operation_id = operation_id
752766 )
753767 )
754- url = urljoin (self .base_url , path )
768+ url = urljoin (self ._base_url , path )
755769
756770 request : requests .PreparedRequest = self .render_request (
757771 path_spec ,
@@ -763,12 +777,12 @@ def call(
763777 validate_body = validate_body ,
764778 )
765779
766- self .debug_callback (1 , f"{ operation_id } : { method } { request .url } " )
780+ self ._debug_callback (1 , f"{ operation_id } : { method } { request .url } " )
767781 for key , value in request .headers .items ():
768- self .debug_callback (2 , f" { key } : { value } " )
782+ self ._debug_callback (2 , f" { key } : { value } " )
769783 if request .body is not None :
770- self .debug_callback (3 , f"{ request .body !r} " )
771- if self .safe_calls_only and method .upper () not in SAFE_METHODS :
784+ self ._debug_callback (3 , f"{ request .body !r} " )
785+ if self ._safe_calls_only and method .upper () not in SAFE_METHODS :
772786 raise UnsafeCallError (_ ("Call aborted due to safe mode" ))
773787 try :
774788 response : requests .Response = self ._session .send (request )
@@ -781,13 +795,13 @@ def call(
781795 )
782796 except requests .RequestException as e :
783797 raise OpenAPIError (str (e ))
784- self .debug_callback (
798+ self ._debug_callback (
785799 1 , _ ("Response: {status_code}" ).format (status_code = response .status_code )
786800 )
787801 for key , value in response .headers .items ():
788- self .debug_callback (2 , f" { key } : { value } " )
802+ self ._debug_callback (2 , f" { key } : { value } " )
789803 if response .text :
790- self .debug_callback (3 , f"{ response .text } " )
804+ self ._debug_callback (3 , f"{ response .text } " )
791805 if "Correlation-ID" in response .headers :
792806 self ._set_correlation_id (response .headers ["Correlation-ID" ])
793807 response .raise_for_status ()
0 commit comments