github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/python/configuration.mustache (about) 1 # coding: utf-8 2 3 {{>partial_header}} 4 5 from __future__ import absolute_import 6 7 import copy 8 import logging 9 {{^asyncio}} 10 import multiprocessing 11 {{/asyncio}} 12 import sys 13 import urllib3 14 15 import six 16 from six.moves import http_client as httplib 17 18 19 class Configuration(object): 20 """NOTE: This class is auto generated by OpenAPI Generator 21 22 Ref: https://openapi-generator.tech 23 Do not edit the class manually. 24 25 :param host: Base url 26 :param api_key: Dict to store API key(s). 27 Each entry in the dict specifies an API key. 28 The dict key is the name of the security scheme in the OAS specification. 29 The dict value is the API key secret. 30 :param api_key_prefix: Dict to store API prefix (e.g. token) 31 The dict key is the name of the security scheme in the OAS specification. 32 The dict value is an API key prefix when generating the auth data. 33 :param username: Username for HTTP basic authentication 34 :param password: Password for HTTP basic authentication 35 :param discard_unknown_keys: Boolean value indicating whether to discard 36 unknown properties. A server may send a response that includes additional 37 properties that are not known by the client in the following scenarios: 38 1. The OpenAPI document is incomplete, i.e. it does not match the server 39 implementation. 40 2. The client was generated using an older version of the OpenAPI document 41 and the server has been upgraded since then. 42 If a schema in the OpenAPI document defines the additionalProperties attribute, 43 then all undeclared properties received by the server are injected into the 44 additional properties map. In that case, there are undeclared properties, and 45 nothing to discard. 46 {{#hasHttpSignatureMethods}} 47 :param signing_info: Configuration parameters for the HTTP signature security scheme. 48 Must be an instance of {{{packageName}}}.signing.HttpSigningConfiguration 49 {{/hasHttpSignatureMethods}} 50 51 {{#hasAuthMethods}} 52 :Example: 53 {{#hasApiKeyMethods}} 54 55 API Key Authentication Example. 56 Given the following security scheme in the OpenAPI specification: 57 components: 58 securitySchemes: 59 cookieAuth: # name for the security scheme 60 type: apiKey 61 in: cookie 62 name: JSESSIONID # cookie name 63 64 You can programmatically set the cookie: 65 conf = {{{packageName}}}.Configuration( 66 api_key={'cookieAuth': 'abc123'} 67 api_key_prefix={'cookieAuth': 'JSESSIONID'} 68 ) 69 The following cookie will be added to the HTTP request: 70 Cookie: JSESSIONID abc123 71 {{/hasApiKeyMethods}} 72 {{#hasHttpBasicMethods}} 73 74 HTTP Basic Authentication Example. 75 Given the following security scheme in the OpenAPI specification: 76 components: 77 securitySchemes: 78 http_basic_auth: 79 type: http 80 scheme: basic 81 82 Configure API client with HTTP basic authentication: 83 conf = {{{packageName}}}.Configuration( 84 username='the-user', 85 password='the-password', 86 ) 87 {{/hasHttpBasicMethods}} 88 {{#hasHttpSignatureMethods}} 89 90 HTTP Signature Authentication Example. 91 Given the following security scheme in the OpenAPI specification: 92 components: 93 securitySchemes: 94 http_basic_auth: 95 type: http 96 scheme: signature 97 98 Configure API client with HTTP signature authentication. Use the 'hs2019' signature scheme, 99 sign the HTTP requests with the RSA-SSA-PSS signature algorithm, and set the expiration time 100 of the signature to 5 minutes after the signature has been created. 101 Note you can use the constants defined in the {{{packageName}}}.signing module, and you can 102 also specify arbitrary HTTP headers to be included in the HTTP signature, except for the 103 'Authorization' header, which is used to carry the signature. 104 105 One may be tempted to sign all headers by default, but in practice it rarely works. 106 This is beccause explicit proxies, transparent proxies, TLS termination endpoints or 107 load balancers may add/modify/remove headers. Include the HTTP headers that you know 108 are not going to be modified in transit. 109 110 conf = {{{packageName}}}.Configuration( 111 signing_info = {{{packageName}}}.signing.HttpSigningConfiguration( 112 key_id = 'my-key-id', 113 private_key_path = 'rsa.pem', 114 signing_scheme = signing.SCHEME_HS2019, 115 signing_algorithm = signing.ALGORITHM_RSASSA_PSS, 116 signed_headers = [signing.HEADER_REQUEST_TARGET, 117 signing.HEADER_CREATED, 118 signing.HEADER_EXPIRES, 119 signing.HEADER_HOST, 120 signing.HEADER_DATE, 121 signing.HEADER_DIGEST, 122 'Content-Type', 123 'User-Agent' 124 ], 125 signature_max_validity = datetime.timedelta(minutes=5) 126 ) 127 ) 128 {{/hasHttpSignatureMethods}} 129 {{/hasAuthMethods}} 130 """ 131 132 _default = None 133 134 def __init__(self, host="{{{basePath}}}", 135 api_key=None, api_key_prefix=None, 136 username=None, password=None, 137 discard_unknown_keys=False, 138 {{#hasHttpSignatureMethods}} 139 signing_info=None, 140 {{/hasHttpSignatureMethods}} 141 ): 142 """Constructor 143 """ 144 self.host = host 145 """Default Base url 146 """ 147 self.temp_folder_path = None 148 """Temp file folder for downloading files 149 """ 150 # Authentication Settings 151 self.api_key = {} 152 if api_key: 153 self.api_key = api_key 154 """dict to store API key(s) 155 """ 156 self.api_key_prefix = {} 157 if api_key_prefix: 158 self.api_key_prefix = api_key_prefix 159 """dict to store API prefix (e.g. token) 160 """ 161 self.refresh_api_key_hook = None 162 """function hook to refresh API key if expired 163 """ 164 self.username = username 165 """Username for HTTP basic authentication 166 """ 167 self.password = password 168 """Password for HTTP basic authentication 169 """ 170 self.discard_unknown_keys = discard_unknown_keys 171 {{#hasHttpSignatureMethods}} 172 if signing_info is not None: 173 signing_info.host = host 174 self.signing_info = signing_info 175 """The HTTP signing configuration 176 """ 177 {{/hasHttpSignatureMethods}} 178 {{#hasOAuthMethods}} 179 self.access_token = None 180 """access token for OAuth/Bearer 181 """ 182 {{/hasOAuthMethods}} 183 {{^hasOAuthMethods}} 184 {{#hasBearerMethods}} 185 self.access_token = None 186 """access token for OAuth/Bearer 187 """ 188 {{/hasBearerMethods}} 189 {{/hasOAuthMethods}} 190 self.logger = {} 191 """Logging Settings 192 """ 193 self.logger["package_logger"] = logging.getLogger("{{packageName}}") 194 self.logger["urllib3_logger"] = logging.getLogger("urllib3") 195 self.logger_format = '%(asctime)s %(levelname)s %(message)s' 196 """Log format 197 """ 198 self.logger_stream_handler = None 199 """Log stream handler 200 """ 201 self.logger_file_handler = None 202 """Log file handler 203 """ 204 self.logger_file = None 205 """Debug file location 206 """ 207 self.debug = False 208 """Debug switch 209 """ 210 211 self.verify_ssl = True 212 """SSL/TLS verification 213 Set this to false to skip verifying SSL certificate when calling API 214 from https server. 215 """ 216 self.ssl_ca_cert = None 217 """Set this to customize the certificate file to verify the peer. 218 """ 219 self.cert_file = None 220 """client certificate file 221 """ 222 self.key_file = None 223 """client key file 224 """ 225 self.assert_hostname = None 226 """Set this to True/False to enable/disable SSL hostname verification. 227 """ 228 229 {{#asyncio}} 230 self.connection_pool_maxsize = 100 231 """This value is passed to the aiohttp to limit simultaneous connections. 232 Default values is 100, None means no-limit. 233 """ 234 {{/asyncio}} 235 {{^asyncio}} 236 self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 237 """urllib3 connection pool's maximum number of connections saved 238 per pool. urllib3 uses 1 connection as default value, but this is 239 not the best value when you are making a lot of possibly parallel 240 requests to the same host, which is often the case here. 241 cpu_count * 5 is used as default value to increase performance. 242 """ 243 {{/asyncio}} 244 245 self.proxy = None 246 """Proxy URL 247 """ 248 self.proxy_headers = None 249 """Proxy headers 250 """ 251 self.safe_chars_for_path_param = '' 252 """Safe chars for path_param 253 """ 254 self.retries = None 255 """Adding retries to override urllib3 default value 3 256 """ 257 # Disable client side validation 258 self.client_side_validation = True 259 260 def __deepcopy__(self, memo): 261 cls = self.__class__ 262 result = cls.__new__(cls) 263 memo[id(self)] = result 264 for k, v in self.__dict__.items(): 265 if k not in ('logger', 'logger_file_handler'): 266 setattr(result, k, copy.deepcopy(v, memo)) 267 # shallow copy of loggers 268 result.logger = copy.copy(self.logger) 269 # use setters to configure loggers 270 result.logger_file = self.logger_file 271 result.debug = self.debug 272 return result 273 274 def __setattr__(self, name, value): 275 object.__setattr__(self, name, value) 276 {{#hasHttpSignatureMethods}} 277 if name == "signing_info" and value is not None: 278 # Ensure the host paramater from signing info is the same as 279 # Configuration.host. 280 value.host = self.host 281 {{/hasHttpSignatureMethods}} 282 283 @classmethod 284 def set_default(cls, default): 285 """Set default instance of configuration. 286 287 It stores default configuration, which can be 288 returned by get_default_copy method. 289 290 :param default: object of Configuration 291 """ 292 cls._default = copy.deepcopy(default) 293 294 @classmethod 295 def get_default_copy(cls): 296 """Return new instance of configuration. 297 298 This method returns newly created, based on default constructor, 299 object of Configuration class or returns a copy of default 300 configuration passed by the set_default method. 301 302 :return: The configuration object. 303 """ 304 if cls._default is not None: 305 return copy.deepcopy(cls._default) 306 return Configuration() 307 308 @property 309 def logger_file(self): 310 """The logger file. 311 312 If the logger_file is None, then add stream handler and remove file 313 handler. Otherwise, add file handler and remove stream handler. 314 315 :param value: The logger_file path. 316 :type: str 317 """ 318 return self.__logger_file 319 320 @logger_file.setter 321 def logger_file(self, value): 322 """The logger file. 323 324 If the logger_file is None, then add stream handler and remove file 325 handler. Otherwise, add file handler and remove stream handler. 326 327 :param value: The logger_file path. 328 :type: str 329 """ 330 self.__logger_file = value 331 if self.__logger_file: 332 # If set logging file, 333 # then add file handler and remove stream handler. 334 self.logger_file_handler = logging.FileHandler(self.__logger_file) 335 self.logger_file_handler.setFormatter(self.logger_formatter) 336 for _, logger in six.iteritems(self.logger): 337 logger.addHandler(self.logger_file_handler) 338 339 @property 340 def debug(self): 341 """Debug status 342 343 :param value: The debug status, True or False. 344 :type: bool 345 """ 346 return self.__debug 347 348 @debug.setter 349 def debug(self, value): 350 """Debug status 351 352 :param value: The debug status, True or False. 353 :type: bool 354 """ 355 self.__debug = value 356 if self.__debug: 357 # if debug status is True, turn on debug logging 358 for _, logger in six.iteritems(self.logger): 359 logger.setLevel(logging.DEBUG) 360 # turn on httplib debug 361 httplib.HTTPConnection.debuglevel = 1 362 else: 363 # if debug status is False, turn off debug logging, 364 # setting log level to default `logging.WARNING` 365 for _, logger in six.iteritems(self.logger): 366 logger.setLevel(logging.WARNING) 367 # turn off httplib debug 368 httplib.HTTPConnection.debuglevel = 0 369 370 @property 371 def logger_format(self): 372 """The logger format. 373 374 The logger_formatter will be updated when sets logger_format. 375 376 :param value: The format string. 377 :type: str 378 """ 379 return self.__logger_format 380 381 @logger_format.setter 382 def logger_format(self, value): 383 """The logger format. 384 385 The logger_formatter will be updated when sets logger_format. 386 387 :param value: The format string. 388 :type: str 389 """ 390 self.__logger_format = value 391 self.logger_formatter = logging.Formatter(self.__logger_format) 392 393 def get_api_key_with_prefix(self, identifier): 394 """Gets API key (with prefix if set). 395 396 :param identifier: The identifier of apiKey. 397 :return: The token for api key authentication. 398 """ 399 if self.refresh_api_key_hook is not None: 400 self.refresh_api_key_hook(self) 401 key = self.api_key.get(identifier) 402 if key: 403 prefix = self.api_key_prefix.get(identifier) 404 if prefix: 405 return "%s %s" % (prefix, key) 406 else: 407 return key 408 409 def get_basic_auth_token(self): 410 """Gets HTTP basic authentication header (string). 411 412 :return: The token for basic HTTP authentication. 413 """ 414 username = "" 415 if self.username is not None: 416 username = self.username 417 password = "" 418 if self.password is not None: 419 password = self.password 420 return urllib3.util.make_headers( 421 basic_auth=username + ':' + password 422 ).get('authorization') 423 424 def auth_settings(self): 425 """Gets Auth Settings dict for api client. 426 427 :return: The Auth Settings information dict. 428 """ 429 auth = {} 430 {{#authMethods}} 431 {{#isApiKey}} 432 if '{{keyParamName}}' in self.api_key: 433 auth['{{name}}'] = { 434 'type': 'api_key', 435 'in': {{#isKeyInCookie}}'cookie'{{/isKeyInCookie}}{{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}}, 436 'key': '{{keyParamName}}', 437 'value': self.get_api_key_with_prefix('{{keyParamName}}') 438 } 439 {{/isApiKey}} 440 {{#isBasic}} 441 {{#isBasicBasic}} 442 if self.username is not None and self.password is not None: 443 auth['{{name}}'] = { 444 'type': 'basic', 445 'in': 'header', 446 'key': 'Authorization', 447 'value': self.get_basic_auth_token() 448 } 449 {{/isBasicBasic}} 450 {{#isBasicBearer}} 451 if self.access_token is not None: 452 auth['{{name}}'] = { 453 'type': 'bearer', 454 'in': 'header', 455 {{#bearerFormat}} 456 'format': '{{{.}}}', 457 {{/bearerFormat}} 458 'key': 'Authorization', 459 'value': 'Bearer ' + self.access_token 460 } 461 {{/isBasicBearer}} 462 {{#isHttpSignature}} 463 if self.signing_info is not None: 464 auth['{{name}}'] = { 465 'type': 'http-signature', 466 'in': 'header', 467 'key': 'Authorization', 468 'value': None # Signature headers are calculated for every HTTP request 469 } 470 {{/isHttpSignature}} 471 {{/isBasic}} 472 {{#isOAuth}} 473 if self.access_token is not None: 474 auth['{{name}}'] = { 475 'type': 'oauth2', 476 'in': 'header', 477 'key': 'Authorization', 478 'value': 'Bearer ' + self.access_token 479 } 480 {{/isOAuth}} 481 {{/authMethods}} 482 return auth 483 484 def to_debug_report(self): 485 """Gets the essential information for debugging. 486 487 :return: The report for debugging. 488 """ 489 return "Python SDK Debug Report:\n"\ 490 "OS: {env}\n"\ 491 "Python Version: {pyversion}\n"\ 492 "Version of the API: {{version}}\n"\ 493 "SDK Package Version: {{packageVersion}}".\ 494 format(env=sys.platform, pyversion=sys.version) 495 496 def get_host_settings(self): 497 """Gets an array of host settings 498 499 :return: An array of host settings 500 """ 501 return [ 502 {{#servers}} 503 { 504 'url': "{{{url}}}", 505 'description': "{{{description}}}{{^description}}No description provided{{/description}}", 506 {{#variables}} 507 {{#-first}} 508 'variables': { 509 {{/-first}} 510 '{{{name}}}': { 511 'description': "{{{description}}}{{^description}}No description provided{{/description}}", 512 'default_value': "{{{defaultValue}}}", 513 {{#enumValues}} 514 {{#-first}} 515 'enum_values': [ 516 {{/-first}} 517 "{{{.}}}"{{^-last}},{{/-last}} 518 {{#-last}} 519 ] 520 {{/-last}} 521 {{/enumValues}} 522 }{{^-last}},{{/-last}} 523 {{#-last}} 524 } 525 {{/-last}} 526 {{/variables}} 527 }{{^-last}},{{/-last}} 528 {{/servers}} 529 ] 530 531 def get_host_from_settings(self, index, variables=None): 532 """Gets host URL based on the index and variables 533 :param index: array index of the host settings 534 :param variables: hash of variable and the corresponding value 535 :return: URL based on host settings 536 """ 537 variables = {} if variables is None else variables 538 servers = self.get_host_settings() 539 540 try: 541 server = servers[index] 542 except IndexError: 543 raise ValueError( 544 "Invalid index {0} when selecting the host settings. " 545 "Must be less than {1}".format(index, len(servers))) 546 547 url = server['url'] 548 549 # go through variables and replace placeholders 550 for variable_name, variable in server['variables'].items(): 551 used_value = variables.get( 552 variable_name, variable['default_value']) 553 554 if 'enum_values' in variable \ 555 and used_value not in variable['enum_values']: 556 raise ValueError( 557 "The variable `{0}` in the host URL has invalid value " 558 "{1}. Must be {2}.".format( 559 variable_name, variables[variable_name], 560 variable['enum_values'])) 561 562 url = url.replace("{" + variable_name + "}", used_value) 563 564 return url