@@ -12,20 +12,25 @@ class UnsupportedAuthenticationError(Exception):
1212 """
1313 Raised when an unsupported authentication method is used.
1414 """
15+
1516 def __init__ (self , auth_type ):
1617 super ().__init__ (f"unsupported authentication type: { auth_type } " )
1718
19+
1820class AuthenticationError (Exception ):
1921 """
2022 Raised when an unknown authentication error is encountered.
2123 """
24+
2225 def __init__ (self , user ):
2326 super ().__init__ (f"failed to authenticate as user: { user } " )
2427
28+
2529class CatalogError (Exception ):
2630 """
2731 Raised when an unknown catalog service type is requested.
2832 """
33+
2934 def __init__ (self , name ):
3035 super ().__init__ (f"service type { name } not found in OpenStack service catalog" )
3136
@@ -34,7 +39,10 @@ class Auth(httpx.Auth):
3439 """
3540 Authenticator class for OpenStack connections.
3641 """
37- def __init__ (self , auth_url , application_credential_id , application_credential_secret ):
42+
43+ def __init__ (
44+ self , auth_url , application_credential_id , application_credential_secret
45+ ):
3846 self .url = auth_url
3947 self ._application_credential_id = application_credential_id
4048 self ._application_credential_secret = application_credential_secret
@@ -58,7 +66,7 @@ def _build_token_request(self):
5866 return httpx .Request (
5967 "POST" ,
6068 f"{ self .url } /v3/auth/tokens" ,
61- json = {
69+ json = {
6270 "auth" : {
6371 "identity" : {
6472 "methods" : ["application_credential" ],
@@ -68,7 +76,7 @@ def _build_token_request(self):
6876 },
6977 },
7078 },
71- }
79+ },
7280 )
7381
7482 def _handle_token_response (self , response ):
@@ -82,15 +90,16 @@ async def async_auth_flow(self, request):
8290 response = yield self ._build_token_request ()
8391 await response .aread ()
8492 self ._handle_token_response (response )
85- request .headers [' X-Auth-Token' ] = self ._token
93+ request .headers [" X-Auth-Token" ] = self ._token
8694 response = yield request
8795
8896
8997class Resource (rest .Resource ):
9098 """
9199 Base resource for OpenStack APIs.
92100 """
93- def __init__ (self , client , name , prefix = None , plural_name = None , singular_name = None ):
101+
102+ def __init__ (self , client , name , prefix = None , plural_name = None , singular_name = None ):
94103 super ().__init__ (client , name , prefix )
95104 # Some resources support a /detail endpoint
96105 # In this case, we just want to use the name up to the slash as the plural name
@@ -114,7 +123,7 @@ def _extract_next_page(self, response):
114123 for link in response .json ().get (f"{ self ._plural_name } _links" , [])
115124 if link ["rel" ] == "next"
116125 ),
117- None
126+ None ,
118127 )
119128 # Sometimes, the returned URLs have http where they should have https
120129 # To mitigate this, we split the URL and return the path and params separately
@@ -134,24 +143,27 @@ class Client(rest.AsyncClient):
134143 """
135144 Client for OpenStack APIs.
136145 """
137- def __init__ (self , / , base_url , prefix = None , ** kwargs ):
146+
147+ def __init__ (self , / , base_url , prefix = None , ** kwargs ):
138148 # Extract the path part of the base_url
139149 url = urllib .parse .urlsplit (base_url )
140150 # Initialise the client with the scheme/host
141- super ().__init__ (base_url = f"{ url .scheme } ://{ url .netloc } " , ** kwargs )
151+ super ().__init__ (base_url = f"{ url .scheme } ://{ url .netloc } " , ** kwargs )
142152 # If another prefix is not given, use the path from the base URL as the prefix,
143153 # otherwise combine the prefixes and remove duplicated path sections.
144154 # This ensures things like pagination work nicely without duplicating the prefix
145155 if prefix :
146- self ._prefix = "/" .join ([url .path .rstrip ("/" ), prefix .lstrip ("/" ).lstrip (url .path )])
156+ self ._prefix = "/" .join (
157+ [url .path .rstrip ("/" ), prefix .lstrip ("/" ).lstrip (url .path )]
158+ )
147159 else :
148160 self ._prefix = url .path
149161
150162 def __aenter__ (self ):
151163 # Prevent individual clients from being used in a context manager
152164 raise RuntimeError ("clients must be used via a cloud object" )
153165
154- def resource (self , name , prefix = None , plural_name = None , singular_name = None ):
166+ def resource (self , name , prefix = None , plural_name = None , singular_name = None ):
155167 # If an additional prefix is given, combine it with the existing prefix
156168 if prefix :
157169 prefix = "/" .join ([self ._prefix .rstrip ("/" ), prefix .lstrip ("/" )])
@@ -164,7 +176,8 @@ class Cloud:
164176 """
165177 Object for interacting with OpenStack clouds.
166178 """
167- def __init__ (self , auth , transport , interface , region = None ):
179+
180+ def __init__ (self , auth , transport , interface , region = None ):
168181 self ._auth = auth
169182 self ._transport = transport
170183 self ._interface = interface
@@ -176,7 +189,9 @@ def __init__(self, auth, transport, interface, region = None):
176189 async def __aenter__ (self ):
177190 await self ._transport .__aenter__ ()
178191 # Once the transport has been initialised, we can initialise the endpoints
179- client = Client (base_url = self ._auth .url , auth = self ._auth , transport = self ._transport )
192+ client = Client (
193+ base_url = self ._auth .url , auth = self ._auth , transport = self ._transport
194+ )
180195 try :
181196 response = await client .get ("/v3/auth/catalog" )
182197 except httpx .HTTPStatusError as exc :
@@ -190,8 +205,8 @@ async def __aenter__(self):
190205 ep ["url" ]
191206 for ep in entry ["endpoints" ]
192207 if (
193- ep ["interface" ] == self ._interface and
194- (not self ._region or ep ["region" ] == self ._region )
208+ ep ["interface" ] == self ._interface
209+ and (not self ._region or ep ["region" ] == self ._region )
195210 )
196211 )
197212 for entry in response .json ()["catalog" ]
@@ -223,16 +238,16 @@ def apis(self):
223238 """
224239 return list (self ._endpoints .keys ())
225240
226- def api_client (self , name , prefix = None ):
241+ def api_client (self , name , prefix = None ):
227242 """
228243 Returns a client for the named API.
229244 """
230245 if name not in self ._clients :
231246 self ._clients [name ] = Client (
232- base_url = self ._endpoints [name ],
233- prefix = prefix ,
234- auth = self ._auth ,
235- transport = self ._transport
247+ base_url = self ._endpoints [name ],
248+ prefix = prefix ,
249+ auth = self ._auth ,
250+ transport = self ._transport ,
236251 )
237252 return self ._clients [name ]
238253
@@ -245,13 +260,13 @@ def from_clouds(cls, clouds, cloud, cacert):
245260 auth = Auth (
246261 auth_url ,
247262 config ["auth" ]["application_credential_id" ],
248- config ["auth" ]["application_credential_secret" ]
263+ config ["auth" ]["application_credential_secret" ],
249264 )
250265 region = config .get ("region_name" )
251266 # Create a default context using the verification from the config
252- context = httpx .create_ssl_context (verify = config .get ("verify" , True ))
267+ context = httpx .create_ssl_context (verify = config .get ("verify" , True ))
253268 # If a cacert was given, load it into the context
254269 if cacert is not None :
255- context .load_verify_locations (cadata = cacert )
256- transport = httpx .AsyncHTTPTransport (verify = context )
270+ context .load_verify_locations (cadata = cacert )
271+ transport = httpx .AsyncHTTPTransport (verify = context )
257272 return cls (auth , transport , config .get ("interface" , "public" ), region )
0 commit comments