github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/clients/python-legacy/lakefs_client/configuration.py (about) 1 """ 2 lakeFS API 3 4 lakeFS HTTP API # noqa: E501 5 6 The version of the OpenAPI document: 1.0.0 7 Contact: services@treeverse.io 8 Generated by: https://openapi-generator.tech 9 """ 10 11 12 import copy 13 import logging 14 import multiprocessing 15 import sys 16 import urllib3 17 18 from http import client as http_client 19 from lakefs_client.exceptions import ApiValueError 20 21 22 JSON_SCHEMA_VALIDATION_KEYWORDS = { 23 'multipleOf', 'maximum', 'exclusiveMaximum', 24 'minimum', 'exclusiveMinimum', 'maxLength', 25 'minLength', 'pattern', 'maxItems', 'minItems' 26 } 27 28 class Configuration(object): 29 """NOTE: This class is auto generated by OpenAPI Generator 30 31 Ref: https://openapi-generator.tech 32 Do not edit the class manually. 33 34 :param host: Base url 35 :param api_key: Dict to store API key(s). 36 Each entry in the dict specifies an API key. 37 The dict key is the name of the security scheme in the OAS specification. 38 The dict value is the API key secret. 39 :param api_key_prefix: Dict to store API prefix (e.g. Bearer) 40 The dict key is the name of the security scheme in the OAS specification. 41 The dict value is an API key prefix when generating the auth data. 42 :param username: Username for HTTP basic authentication 43 :param password: Password for HTTP basic authentication 44 :param discard_unknown_keys: Boolean value indicating whether to discard 45 unknown properties. A server may send a response that includes additional 46 properties that are not known by the client in the following scenarios: 47 1. The OpenAPI document is incomplete, i.e. it does not match the server 48 implementation. 49 2. The client was generated using an older version of the OpenAPI document 50 and the server has been upgraded since then. 51 If a schema in the OpenAPI document defines the additionalProperties attribute, 52 then all undeclared properties received by the server are injected into the 53 additional properties map. In that case, there are undeclared properties, and 54 nothing to discard. 55 :param disabled_client_side_validations (string): Comma-separated list of 56 JSON schema validation keywords to disable JSON schema structural validation 57 rules. The following keywords may be specified: multipleOf, maximum, 58 exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern, 59 maxItems, minItems. 60 By default, the validation is performed for data generated locally by the client 61 and data received from the server, independent of any validation performed by 62 the server side. If the input data does not satisfy the JSON schema validation 63 rules specified in the OpenAPI document, an exception is raised. 64 If disabled_client_side_validations is set, structural validation is 65 disabled. This can be useful to troubleshoot data validation problem, such as 66 when the OpenAPI document validation rules do not match the actual API data 67 received by the server. 68 :param server_index: Index to servers configuration. 69 :param server_variables: Mapping with string values to replace variables in 70 templated server configuration. The validation of enums is performed for 71 variables with defined enum values before. 72 :param server_operation_index: Mapping from operation ID to an index to server 73 configuration. 74 :param server_operation_variables: Mapping from operation ID to a mapping with 75 string values to replace variables in templated server configuration. 76 The validation of enums is performed for variables with defined enum values before. 77 :param ssl_ca_cert: str - the path to a file of concatenated CA certificates 78 in PEM format 79 80 :Example: 81 82 API Key Authentication Example. 83 Given the following security scheme in the OpenAPI specification: 84 components: 85 securitySchemes: 86 cookieAuth: # name for the security scheme 87 type: apiKey 88 in: cookie 89 name: JSESSIONID # cookie name 90 91 You can programmatically set the cookie: 92 93 conf = lakefs_client.Configuration( 94 api_key={'cookieAuth': 'abc123'} 95 api_key_prefix={'cookieAuth': 'JSESSIONID'} 96 ) 97 98 The following cookie will be added to the HTTP request: 99 Cookie: JSESSIONID abc123 100 101 HTTP Basic Authentication Example. 102 Given the following security scheme in the OpenAPI specification: 103 components: 104 securitySchemes: 105 http_basic_auth: 106 type: http 107 scheme: basic 108 109 Configure API client with HTTP basic authentication: 110 111 conf = lakefs_client.Configuration( 112 username='the-user', 113 password='the-password', 114 ) 115 116 """ 117 118 _default = None 119 120 def __init__(self, host=None, 121 api_key=None, api_key_prefix=None, 122 access_token=None, 123 username=None, password=None, 124 discard_unknown_keys=False, 125 disabled_client_side_validations="", 126 server_index=None, server_variables=None, 127 server_operation_index=None, server_operation_variables=None, 128 ssl_ca_cert=None, 129 ): 130 """Constructor 131 """ 132 self._base_path = "http://localhost/api/v1" if host is None else host 133 """Default Base url 134 """ 135 self.server_index = 0 if server_index is None and host is None else server_index 136 self.server_operation_index = server_operation_index or {} 137 """Default server index 138 """ 139 self.server_variables = server_variables or {} 140 self.server_operation_variables = server_operation_variables or {} 141 """Default server variables 142 """ 143 self.temp_folder_path = None 144 """Temp file folder for downloading files 145 """ 146 # Authentication Settings 147 self.access_token = access_token 148 self.api_key = {} 149 if api_key: 150 self.api_key = api_key 151 """dict to store API key(s) 152 """ 153 self.api_key_prefix = {} 154 if api_key_prefix: 155 self.api_key_prefix = api_key_prefix 156 """dict to store API prefix (e.g. Bearer) 157 """ 158 self.refresh_api_key_hook = None 159 """function hook to refresh API key if expired 160 """ 161 self.username = username 162 """Username for HTTP basic authentication 163 """ 164 self.password = password 165 """Password for HTTP basic authentication 166 """ 167 self.discard_unknown_keys = discard_unknown_keys 168 self.disabled_client_side_validations = disabled_client_side_validations 169 self.logger = {} 170 """Logging Settings 171 """ 172 self.logger["package_logger"] = logging.getLogger("lakefs_client") 173 self.logger["urllib3_logger"] = logging.getLogger("urllib3") 174 self.logger_format = '%(asctime)s %(levelname)s %(message)s' 175 """Log format 176 """ 177 self.logger_stream_handler = None 178 """Log stream handler 179 """ 180 self.logger_file_handler = None 181 """Log file handler 182 """ 183 self.logger_file = None 184 """Debug file location 185 """ 186 self.debug = False 187 """Debug switch 188 """ 189 190 self.verify_ssl = True 191 """SSL/TLS verification 192 Set this to false to skip verifying SSL certificate when calling API 193 from https server. 194 """ 195 self.ssl_ca_cert = ssl_ca_cert 196 """Set this to customize the certificate file to verify the peer. 197 """ 198 self.cert_file = None 199 """client certificate file 200 """ 201 self.key_file = None 202 """client key file 203 """ 204 self.assert_hostname = None 205 """Set this to True/False to enable/disable SSL hostname verification. 206 """ 207 208 self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 209 """urllib3 connection pool's maximum number of connections saved 210 per pool. urllib3 uses 1 connection as default value, but this is 211 not the best value when you are making a lot of possibly parallel 212 requests to the same host, which is often the case here. 213 cpu_count * 5 is used as default value to increase performance. 214 """ 215 216 self.proxy = None 217 """Proxy URL 218 """ 219 self.proxy_headers = None 220 """Proxy headers 221 """ 222 self.safe_chars_for_path_param = '' 223 """Safe chars for path_param 224 """ 225 self.retries = None 226 """Adding retries to override urllib3 default value 3 227 """ 228 # Enable client side validation 229 self.client_side_validation = True 230 231 # Options to pass down to the underlying urllib3 socket 232 self.socket_options = None 233 234 def __deepcopy__(self, memo): 235 cls = self.__class__ 236 result = cls.__new__(cls) 237 memo[id(self)] = result 238 for k, v in self.__dict__.items(): 239 if k not in ('logger', 'logger_file_handler'): 240 setattr(result, k, copy.deepcopy(v, memo)) 241 # shallow copy of loggers 242 result.logger = copy.copy(self.logger) 243 # use setters to configure loggers 244 result.logger_file = self.logger_file 245 result.debug = self.debug 246 return result 247 248 def __setattr__(self, name, value): 249 object.__setattr__(self, name, value) 250 if name == 'disabled_client_side_validations': 251 s = set(filter(None, value.split(','))) 252 for v in s: 253 if v not in JSON_SCHEMA_VALIDATION_KEYWORDS: 254 raise ApiValueError( 255 "Invalid keyword: '{0}''".format(v)) 256 self._disabled_client_side_validations = s 257 258 @classmethod 259 def set_default(cls, default): 260 """Set default instance of configuration. 261 262 It stores default configuration, which can be 263 returned by get_default_copy method. 264 265 :param default: object of Configuration 266 """ 267 cls._default = copy.deepcopy(default) 268 269 @classmethod 270 def get_default_copy(cls): 271 """Return new instance of configuration. 272 273 This method returns newly created, based on default constructor, 274 object of Configuration class or returns a copy of default 275 configuration passed by the set_default method. 276 277 :return: The configuration object. 278 """ 279 if cls._default is not None: 280 return copy.deepcopy(cls._default) 281 return Configuration() 282 283 @property 284 def logger_file(self): 285 """The logger file. 286 287 If the logger_file is None, then add stream handler and remove file 288 handler. Otherwise, add file handler and remove stream handler. 289 290 :param value: The logger_file path. 291 :type: str 292 """ 293 return self.__logger_file 294 295 @logger_file.setter 296 def logger_file(self, value): 297 """The logger file. 298 299 If the logger_file is None, then add stream handler and remove file 300 handler. Otherwise, add file handler and remove stream handler. 301 302 :param value: The logger_file path. 303 :type: str 304 """ 305 self.__logger_file = value 306 if self.__logger_file: 307 # If set logging file, 308 # then add file handler and remove stream handler. 309 self.logger_file_handler = logging.FileHandler(self.__logger_file) 310 self.logger_file_handler.setFormatter(self.logger_formatter) 311 for _, logger in self.logger.items(): 312 logger.addHandler(self.logger_file_handler) 313 314 @property 315 def debug(self): 316 """Debug status 317 318 :param value: The debug status, True or False. 319 :type: bool 320 """ 321 return self.__debug 322 323 @debug.setter 324 def debug(self, value): 325 """Debug status 326 327 :param value: The debug status, True or False. 328 :type: bool 329 """ 330 self.__debug = value 331 if self.__debug: 332 # if debug status is True, turn on debug logging 333 for _, logger in self.logger.items(): 334 logger.setLevel(logging.DEBUG) 335 # turn on http_client debug 336 http_client.HTTPConnection.debuglevel = 1 337 else: 338 # if debug status is False, turn off debug logging, 339 # setting log level to default `logging.WARNING` 340 for _, logger in self.logger.items(): 341 logger.setLevel(logging.WARNING) 342 # turn off http_client debug 343 http_client.HTTPConnection.debuglevel = 0 344 345 @property 346 def logger_format(self): 347 """The logger format. 348 349 The logger_formatter will be updated when sets logger_format. 350 351 :param value: The format string. 352 :type: str 353 """ 354 return self.__logger_format 355 356 @logger_format.setter 357 def logger_format(self, value): 358 """The logger format. 359 360 The logger_formatter will be updated when sets logger_format. 361 362 :param value: The format string. 363 :type: str 364 """ 365 self.__logger_format = value 366 self.logger_formatter = logging.Formatter(self.__logger_format) 367 368 def get_api_key_with_prefix(self, identifier, alias=None): 369 """Gets API key (with prefix if set). 370 371 :param identifier: The identifier of apiKey. 372 :param alias: The alternative identifier of apiKey. 373 :return: The token for api key authentication. 374 """ 375 if self.refresh_api_key_hook is not None: 376 self.refresh_api_key_hook(self) 377 key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None) 378 if key: 379 prefix = self.api_key_prefix.get(identifier) 380 if prefix: 381 return "%s %s" % (prefix, key) 382 else: 383 return key 384 385 def get_basic_auth_token(self): 386 """Gets HTTP basic authentication header (string). 387 388 :return: The token for basic HTTP authentication. 389 """ 390 username = "" 391 if self.username is not None: 392 username = self.username 393 password = "" 394 if self.password is not None: 395 password = self.password 396 return urllib3.util.make_headers( 397 basic_auth=username + ':' + password 398 ).get('authorization') 399 400 def auth_settings(self): 401 """Gets Auth Settings dict for api client. 402 403 :return: The Auth Settings information dict. 404 """ 405 auth = {} 406 if self.username is not None and self.password is not None: 407 auth['basic_auth'] = { 408 'type': 'basic', 409 'in': 'header', 410 'key': 'Authorization', 411 'value': self.get_basic_auth_token() 412 } 413 if 'cookie_auth' in self.api_key: 414 auth['cookie_auth'] = { 415 'type': 'api_key', 416 'in': 'cookie', 417 'key': 'internal_auth_session', 418 'value': self.get_api_key_with_prefix( 419 'cookie_auth', 420 ), 421 } 422 if self.access_token is not None: 423 auth['jwt_token'] = { 424 'type': 'bearer', 425 'in': 'header', 426 'format': 'JWT', 427 'key': 'Authorization', 428 'value': 'Bearer ' + self.access_token 429 } 430 if 'oidc_auth' in self.api_key: 431 auth['oidc_auth'] = { 432 'type': 'api_key', 433 'in': 'cookie', 434 'key': 'oidc_auth_session', 435 'value': self.get_api_key_with_prefix( 436 'oidc_auth', 437 ), 438 } 439 if 'saml_auth' in self.api_key: 440 auth['saml_auth'] = { 441 'type': 'api_key', 442 'in': 'cookie', 443 'key': 'saml_auth_session', 444 'value': self.get_api_key_with_prefix( 445 'saml_auth', 446 ), 447 } 448 return auth 449 450 def to_debug_report(self): 451 """Gets the essential information for debugging. 452 453 :return: The report for debugging. 454 """ 455 return "Python SDK Debug Report:\n"\ 456 "OS: {env}\n"\ 457 "Python Version: {pyversion}\n"\ 458 "Version of the API: 1.0.0\n"\ 459 "SDK Package Version: 0.1.0-SNAPSHOT".\ 460 format(env=sys.platform, pyversion=sys.version) 461 462 def get_host_settings(self): 463 """Gets an array of host settings 464 465 :return: An array of host settings 466 """ 467 return [ 468 { 469 'url': "/api/v1", 470 'description': "lakeFS server endpoint", 471 } 472 ] 473 474 def get_host_from_settings(self, index, variables=None, servers=None): 475 """Gets host URL based on the index and variables 476 :param index: array index of the host settings 477 :param variables: hash of variable and the corresponding value 478 :param servers: an array of host settings or None 479 :return: URL based on host settings 480 """ 481 if index is None: 482 return self._base_path 483 484 variables = {} if variables is None else variables 485 servers = self.get_host_settings() if servers is None else servers 486 487 try: 488 server = servers[index] 489 except IndexError: 490 raise ValueError( 491 "Invalid index {0} when selecting the host settings. " 492 "Must be less than {1}".format(index, len(servers))) 493 494 url = server['url'] 495 496 # go through variables and replace placeholders 497 for variable_name, variable in server.get('variables', {}).items(): 498 used_value = variables.get( 499 variable_name, variable['default_value']) 500 501 if 'enum_values' in variable \ 502 and used_value not in variable['enum_values']: 503 raise ValueError( 504 "The variable `{0}` in the host URL has invalid value " 505 "{1}. Must be {2}.".format( 506 variable_name, variables[variable_name], 507 variable['enum_values'])) 508 509 url = url.replace("{" + variable_name + "}", used_value) 510 511 return url 512 513 @property 514 def host(self): 515 """Return generated host.""" 516 return self.get_host_from_settings(self.server_index, variables=self.server_variables) 517 518 @host.setter 519 def host(self, value): 520 """Fix base path.""" 521 self._base_path = value 522 self.server_index = None