nova.api
1# Provide autogenerated NOVA API client 2from wandelbots_api_client import * # noqa 3from wandelbots_api_client import api, api_client, configuration, exceptions, models 4 5__all__ = [ 6 "models", 7 "api", 8 "api_client", 9 "configuration", 10 "exceptions", 11 "ApiResponse", # noqa: F405 12 "ApiClient", # noqa: F405 13 "Configuration", # noqa: F405 14 "OpenApiException", # noqa: F405 15 "ApiTypeError", # noqa: F405 16 "ApiValueError", # noqa: F405 17 "ApiKeyError", # noqa: F405 18 "ApiAttributeError", # noqa: F405 19 "ApiException", # noqa: F405 20]
10class ApiResponse(BaseModel, Generic[T]): 11 """ 12 API response object 13 """ 14 15 status_code: StrictInt = Field(description="HTTP status code") 16 headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers") 17 data: T = Field(description="Deserialized data given the data type") 18 raw_data: StrictBytes = Field(description="Raw data (HTTP response body)") 19 20 model_config = { 21 "arbitrary_types_allowed": True 22 }
API response object
45class ApiClient: 46 """Generic API client for OpenAPI client library builds. 47 48 OpenAPI generic API client. This client handles the client- 49 server communication, and is invariant across implementations. Specifics of 50 the methods and models for each application are generated from the OpenAPI 51 templates. 52 53 :param configuration: .Configuration object for this client 54 :param header_name: a header to pass when making calls to the API. 55 :param header_value: a header value to pass when making calls to 56 the API. 57 :param cookie: a cookie to include in the header when making calls 58 to the API 59 """ 60 61 PRIMITIVE_TYPES = (float, bool, bytes, str, int) 62 NATIVE_TYPES_MAPPING = { 63 'int': int, 64 'long': int, # TODO remove as only py3 is supported? 65 'float': float, 66 'str': str, 67 'bool': bool, 68 'date': datetime.date, 69 'datetime': datetime.datetime, 70 'object': object, 71 } 72 _pool = None 73 74 def __init__( 75 self, 76 configuration=None, 77 header_name=None, 78 header_value=None, 79 cookie=None 80 ) -> None: 81 # use default configuration if none is provided 82 if configuration is None: 83 configuration = Configuration.get_default() 84 self.configuration = configuration 85 86 self.rest_client = rest.RESTClientObject(configuration) 87 self.default_headers = {} 88 if header_name is not None: 89 self.default_headers[header_name] = header_value 90 self.cookie = cookie 91 # Set default User-Agent. 92 self.user_agent = 'OpenAPI-Generator/25.1.0/python' 93 self.client_side_validation = configuration.client_side_validation 94 95 async def __aenter__(self): 96 return self 97 98 async def __aexit__(self, exc_type, exc_value, traceback): 99 await self.close() 100 101 async def close(self): 102 await self.rest_client.close() 103 104 @property 105 def user_agent(self): 106 """User agent for this API client""" 107 return self.default_headers['User-Agent'] 108 109 @user_agent.setter 110 def user_agent(self, value): 111 self.default_headers['User-Agent'] = value 112 113 def set_default_header(self, header_name, header_value): 114 self.default_headers[header_name] = header_value 115 116 117 _default = None 118 119 @classmethod 120 def get_default(cls): 121 """Return new instance of ApiClient. 122 123 This method returns newly created, based on default constructor, 124 object of ApiClient class or returns a copy of default 125 ApiClient. 126 127 :return: The ApiClient object. 128 """ 129 if cls._default is None: 130 cls._default = ApiClient() 131 return cls._default 132 133 @classmethod 134 def set_default(cls, default): 135 """Set default instance of ApiClient. 136 137 It stores default ApiClient. 138 139 :param default: object of ApiClient. 140 """ 141 cls._default = default 142 143 def param_serialize( 144 self, 145 method, 146 resource_path, 147 path_params=None, 148 query_params=None, 149 header_params=None, 150 body=None, 151 post_params=None, 152 files=None, auth_settings=None, 153 collection_formats=None, 154 _host=None, 155 _request_auth=None 156 ) -> RequestSerialized: 157 158 """Builds the HTTP request params needed by the request. 159 :param method: Method to call. 160 :param resource_path: Path to method endpoint. 161 :param path_params: Path parameters in the url. 162 :param query_params: Query parameters in the url. 163 :param header_params: Header parameters to be 164 placed in the request header. 165 :param body: Request body. 166 :param post_params dict: Request post form parameters, 167 for `application/x-www-form-urlencoded`, `multipart/form-data`. 168 :param auth_settings list: Auth Settings names for the request. 169 :param files dict: key -> filename, value -> filepath, 170 for `multipart/form-data`. 171 :param collection_formats: dict of collection formats for path, query, 172 header, and post parameters. 173 :param _request_auth: set to override the auth_settings for an a single 174 request; this effectively ignores the authentication 175 in the spec for a single request. 176 :return: tuple of form (path, http_method, query_params, header_params, 177 body, post_params, files) 178 """ 179 180 config = self.configuration 181 182 # header parameters 183 header_params = header_params or {} 184 header_params.update(self.default_headers) 185 if self.cookie: 186 header_params['Cookie'] = self.cookie 187 if header_params: 188 header_params = self.sanitize_for_serialization(header_params) 189 header_params = dict( 190 self.parameters_to_tuples(header_params,collection_formats) 191 ) 192 193 # path parameters 194 if path_params: 195 path_params = self.sanitize_for_serialization(path_params) 196 path_params = self.parameters_to_tuples( 197 path_params, 198 collection_formats 199 ) 200 for k, v in path_params: 201 # specified safe chars, encode everything 202 resource_path = resource_path.replace( 203 '{%s}' % k, 204 quote(str(v), safe=config.safe_chars_for_path_param) 205 ) 206 207 # post parameters 208 if post_params or files: 209 post_params = post_params if post_params else [] 210 post_params = self.sanitize_for_serialization(post_params) 211 post_params = self.parameters_to_tuples( 212 post_params, 213 collection_formats 214 ) 215 if files: 216 post_params.extend(self.files_parameters(files)) 217 218 # auth setting 219 self.update_params_for_auth( 220 header_params, 221 query_params, 222 auth_settings, 223 resource_path, 224 method, 225 body, 226 request_auth=_request_auth 227 ) 228 229 # body 230 if body: 231 body = self.sanitize_for_serialization(body) 232 233 # request url 234 if _host is None: 235 url = self.configuration.host + resource_path 236 else: 237 # use server/host defined in path or operation instead 238 url = _host + resource_path 239 240 # query parameters 241 if query_params: 242 query_params = self.sanitize_for_serialization(query_params) 243 url_query = self.parameters_to_url_query( 244 query_params, 245 collection_formats 246 ) 247 url += "?" + url_query 248 249 return method, url, header_params, body, post_params 250 251 252 async def call_api( 253 self, 254 method, 255 url, 256 header_params=None, 257 body=None, 258 post_params=None, 259 _request_timeout=None 260 ) -> rest.RESTResponse: 261 """Makes the HTTP request (synchronous) 262 :param method: Method to call. 263 :param url: Path to method endpoint. 264 :param header_params: Header parameters to be 265 placed in the request header. 266 :param body: Request body. 267 :param post_params dict: Request post form parameters, 268 for `application/x-www-form-urlencoded`, `multipart/form-data`. 269 :param _request_timeout: timeout setting for this request. 270 :return: RESTResponse 271 """ 272 273 try: 274 # perform request and return response 275 response_data = await self.rest_client.request( 276 method, url, 277 headers=header_params, 278 body=body, post_params=post_params, 279 _request_timeout=_request_timeout 280 ) 281 282 except ApiException as e: 283 raise e 284 285 return response_data 286 287 def response_deserialize( 288 self, 289 response_data: rest.RESTResponse, 290 response_types_map: Optional[Dict[str, ApiResponseT]]=None 291 ) -> ApiResponse[ApiResponseT]: 292 """Deserializes response into an object. 293 :param response_data: RESTResponse object to be deserialized. 294 :param response_types_map: dict of response types. 295 :return: ApiResponse 296 """ 297 298 msg = "RESTResponse.read() must be called before passing it to response_deserialize()" 299 assert response_data.data is not None, msg 300 301 response_type = response_types_map.get(str(response_data.status), None) 302 if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599: 303 # if not found, look for '1XX', '2XX', etc. 304 response_type = response_types_map.get(str(response_data.status)[0] + "XX", None) 305 306 # deserialize response data 307 response_text = None 308 return_data = None 309 try: 310 if response_type == "bytearray": 311 return_data = response_data.data 312 elif response_type == "file": 313 return_data = self.__deserialize_file(response_data) 314 elif response_type is not None: 315 match = None 316 content_type = response_data.getheader('content-type') 317 if content_type is not None: 318 match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) 319 encoding = match.group(1) if match else "utf-8" 320 response_text = response_data.data.decode(encoding) 321 if response_type in ["bytearray", "str"]: 322 return_data = self.__deserialize_primitive(response_text, response_type) 323 else: 324 return_data = self.deserialize(response_text, response_type) 325 finally: 326 if not 200 <= response_data.status <= 299: 327 raise ApiException.from_response( 328 http_resp=response_data, 329 body=response_text, 330 data=return_data, 331 ) 332 333 return ApiResponse( 334 status_code = response_data.status, 335 data = return_data, 336 headers = response_data.getheaders(), 337 raw_data = response_data.data 338 ) 339 340 def sanitize_for_serialization(self, obj): 341 """Builds a JSON POST object. 342 343 If obj is None, return None. 344 If obj is SecretStr, return obj.get_secret_value() 345 If obj is str, int, long, float, bool, return directly. 346 If obj is datetime.datetime, datetime.date 347 convert to string in iso8601 format. 348 If obj is list, sanitize each element in the list. 349 If obj is dict, return the dict. 350 If obj is OpenAPI model, return the properties dict. 351 352 :param obj: The data to serialize. 353 :return: The serialized form of data. 354 """ 355 if obj is None: 356 return None 357 elif isinstance(obj, Enum): 358 return obj.value 359 elif isinstance(obj, SecretStr): 360 return obj.get_secret_value() 361 elif isinstance(obj, self.PRIMITIVE_TYPES): 362 return obj 363 elif isinstance(obj, list): 364 return [ 365 self.sanitize_for_serialization(sub_obj) for sub_obj in obj 366 ] 367 elif isinstance(obj, tuple): 368 return tuple( 369 self.sanitize_for_serialization(sub_obj) for sub_obj in obj 370 ) 371 elif isinstance(obj, (datetime.datetime, datetime.date)): 372 return obj.isoformat() 373 374 elif isinstance(obj, dict): 375 obj_dict = obj 376 else: 377 # Convert model obj to dict except 378 # attributes `openapi_types`, `attribute_map` 379 # and attributes which value is not None. 380 # Convert attribute name to json key in 381 # model definition for request. 382 if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): 383 obj_dict = obj.to_dict() 384 else: 385 obj_dict = obj.__dict__ 386 387 return { 388 key: self.sanitize_for_serialization(val) 389 for key, val in obj_dict.items() 390 } 391 392 def deserialize(self, response_text, response_type): 393 """Deserializes response into an object. 394 395 :param response: RESTResponse object to be deserialized. 396 :param response_type: class literal for 397 deserialized object, or string of class name. 398 399 :return: deserialized object. 400 """ 401 402 # fetch data from response object 403 try: 404 data = json.loads(response_text) 405 except ValueError: 406 data = response_text 407 408 return self.__deserialize(data, response_type) 409 410 def __deserialize(self, data, klass): 411 """Deserializes dict, list, str into an object. 412 413 :param data: dict, list or str. 414 :param klass: class literal, or string of class name. 415 416 :return: object. 417 """ 418 if data is None: 419 return None 420 421 if isinstance(klass, str): 422 if klass.startswith('List['): 423 m = re.match(r'List\[(.*)]', klass) 424 assert m is not None, "Malformed List type definition" 425 sub_kls = m.group(1) 426 return [self.__deserialize(sub_data, sub_kls) 427 for sub_data in data] 428 429 if klass.startswith('Dict['): 430 m = re.match(r'Dict\[([^,]*), (.*)]', klass) 431 assert m is not None, "Malformed Dict type definition" 432 sub_kls = m.group(2) 433 return {k: self.__deserialize(v, sub_kls) 434 for k, v in data.items()} 435 436 # convert str to class 437 if klass in self.NATIVE_TYPES_MAPPING: 438 klass = self.NATIVE_TYPES_MAPPING[klass] 439 else: 440 klass = getattr(wandelbots_api_client.models, klass) 441 442 if klass in self.PRIMITIVE_TYPES: 443 return self.__deserialize_primitive(data, klass) 444 elif klass == object: 445 return self.__deserialize_object(data) 446 elif klass == datetime.date: 447 return self.__deserialize_date(data) 448 elif klass == datetime.datetime: 449 return self.__deserialize_datetime(data) 450 elif issubclass(klass, Enum): 451 return self.__deserialize_enum(data, klass) 452 else: 453 return self.__deserialize_model(data, klass) 454 455 def parameters_to_tuples(self, params, collection_formats): 456 """Get parameters as list of tuples, formatting collections. 457 458 :param params: Parameters as dict or list of two-tuples 459 :param dict collection_formats: Parameter collection formats 460 :return: Parameters as list of tuples, collections formatted 461 """ 462 new_params: List[Tuple[str, str]] = [] 463 if collection_formats is None: 464 collection_formats = {} 465 for k, v in params.items() if isinstance(params, dict) else params: 466 if k in collection_formats: 467 collection_format = collection_formats[k] 468 if collection_format == 'multi': 469 new_params.extend((k, value) for value in v) 470 else: 471 if collection_format == 'ssv': 472 delimiter = ' ' 473 elif collection_format == 'tsv': 474 delimiter = '\t' 475 elif collection_format == 'pipes': 476 delimiter = '|' 477 else: # csv is the default 478 delimiter = ',' 479 new_params.append( 480 (k, delimiter.join(str(value) for value in v))) 481 else: 482 new_params.append((k, v)) 483 return new_params 484 485 def parameters_to_url_query(self, params, collection_formats): 486 """Get parameters as list of tuples, formatting collections. 487 488 :param params: Parameters as dict or list of two-tuples 489 :param dict collection_formats: Parameter collection formats 490 :return: URL query string (e.g. a=Hello%20World&b=123) 491 """ 492 new_params: List[Tuple[str, str]] = [] 493 if collection_formats is None: 494 collection_formats = {} 495 for k, v in params.items() if isinstance(params, dict) else params: 496 if isinstance(v, bool): 497 v = str(v).lower() 498 if isinstance(v, (int, float)): 499 v = str(v) 500 if isinstance(v, dict): 501 v = json.dumps(v) 502 503 if k in collection_formats: 504 collection_format = collection_formats[k] 505 if collection_format == 'multi': 506 new_params.extend((k, str(value)) for value in v) 507 else: 508 if collection_format == 'ssv': 509 delimiter = ' ' 510 elif collection_format == 'tsv': 511 delimiter = '\t' 512 elif collection_format == 'pipes': 513 delimiter = '|' 514 else: # csv is the default 515 delimiter = ',' 516 new_params.append( 517 (k, delimiter.join(quote(str(value)) for value in v)) 518 ) 519 else: 520 new_params.append((k, quote(str(v)))) 521 522 return "&".join(["=".join(map(str, item)) for item in new_params]) 523 524 def files_parameters(self, files: Dict[str, Union[str, bytes]]): 525 """Builds form parameters. 526 527 :param files: File parameters. 528 :return: Form parameters with files. 529 """ 530 params = [] 531 for k, v in files.items(): 532 if isinstance(v, str): 533 with open(v, 'rb') as f: 534 filename = os.path.basename(f.name) 535 filedata = f.read() 536 elif isinstance(v, bytes): 537 filename = k 538 filedata = v 539 else: 540 raise ValueError("Unsupported file value") 541 mimetype = ( 542 mimetypes.guess_type(filename)[0] 543 or 'application/octet-stream' 544 ) 545 params.append( 546 tuple([k, tuple([filename, filedata, mimetype])]) 547 ) 548 return params 549 550 def select_header_accept(self, accepts: List[str]) -> Optional[str]: 551 """Returns `Accept` based on an array of accepts provided. 552 553 :param accepts: List of headers. 554 :return: Accept (e.g. application/json). 555 """ 556 if not accepts: 557 return None 558 559 for accept in accepts: 560 if re.search('json', accept, re.IGNORECASE): 561 return accept 562 563 return accepts[0] 564 565 def select_header_content_type(self, content_types): 566 """Returns `Content-Type` based on an array of content_types provided. 567 568 :param content_types: List of content-types. 569 :return: Content-Type (e.g. application/json). 570 """ 571 if not content_types: 572 return None 573 574 for content_type in content_types: 575 if re.search('json', content_type, re.IGNORECASE): 576 return content_type 577 578 return content_types[0] 579 580 def update_params_for_auth( 581 self, 582 headers, 583 queries, 584 auth_settings, 585 resource_path, 586 method, 587 body, 588 request_auth=None 589 ) -> None: 590 """Updates header and query params based on authentication setting. 591 592 :param headers: Header parameters dict to be updated. 593 :param queries: Query parameters tuple list to be updated. 594 :param auth_settings: Authentication setting identifiers list. 595 :resource_path: A string representation of the HTTP request resource path. 596 :method: A string representation of the HTTP request method. 597 :body: A object representing the body of the HTTP request. 598 The object type is the return value of sanitize_for_serialization(). 599 :param request_auth: if set, the provided settings will 600 override the token in the configuration. 601 """ 602 if not auth_settings: 603 return 604 605 if request_auth: 606 self._apply_auth_params( 607 headers, 608 queries, 609 resource_path, 610 method, 611 body, 612 request_auth 613 ) 614 else: 615 for auth in auth_settings: 616 auth_setting = self.configuration.auth_settings().get(auth) 617 if auth_setting: 618 self._apply_auth_params( 619 headers, 620 queries, 621 resource_path, 622 method, 623 body, 624 auth_setting 625 ) 626 627 def _apply_auth_params( 628 self, 629 headers, 630 queries, 631 resource_path, 632 method, 633 body, 634 auth_setting 635 ) -> None: 636 """Updates the request parameters based on a single auth_setting 637 638 :param headers: Header parameters dict to be updated. 639 :param queries: Query parameters tuple list to be updated. 640 :resource_path: A string representation of the HTTP request resource path. 641 :method: A string representation of the HTTP request method. 642 :body: A object representing the body of the HTTP request. 643 The object type is the return value of sanitize_for_serialization(). 644 :param auth_setting: auth settings for the endpoint 645 """ 646 if auth_setting['in'] == 'cookie': 647 headers['Cookie'] = auth_setting['value'] 648 elif auth_setting['in'] == 'header': 649 if auth_setting['type'] != 'http-signature': 650 headers[auth_setting['key']] = auth_setting['value'] 651 elif auth_setting['in'] == 'query': 652 queries.append((auth_setting['key'], auth_setting['value'])) 653 else: 654 raise ApiValueError( 655 'Authentication token must be in `query` or `header`' 656 ) 657 658 def __deserialize_file(self, response): 659 """Deserializes body to file 660 661 Saves response body into a file in a temporary folder, 662 using the filename from the `Content-Disposition` header if provided. 663 664 handle file downloading 665 save response body into a tmp file and return the instance 666 667 :param response: RESTResponse. 668 :return: file path. 669 """ 670 fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) 671 os.close(fd) 672 os.remove(path) 673 674 content_disposition = response.getheader("Content-Disposition") 675 if content_disposition: 676 m = re.search( 677 r'filename=[\'"]?([^\'"\s]+)[\'"]?', 678 content_disposition 679 ) 680 assert m is not None, "Unexpected 'content-disposition' header value" 681 filename = m.group(1) 682 path = os.path.join(os.path.dirname(path), filename) 683 684 with open(path, "wb") as f: 685 f.write(response.data) 686 687 return path 688 689 def __deserialize_primitive(self, data, klass): 690 """Deserializes string to primitive type. 691 692 :param data: str. 693 :param klass: class literal. 694 695 :return: int, long, float, str, bool. 696 """ 697 try: 698 return klass(data) 699 except UnicodeEncodeError: 700 return str(data) 701 except TypeError: 702 return data 703 704 def __deserialize_object(self, value): 705 """Return an original value. 706 707 :return: object. 708 """ 709 return value 710 711 def __deserialize_date(self, string): 712 """Deserializes string to date. 713 714 :param string: str. 715 :return: date. 716 """ 717 try: 718 return parse(string).date() 719 except ImportError: 720 return string 721 except ValueError: 722 raise rest.ApiException( 723 status=0, 724 reason="Failed to parse `{0}` as date object".format(string) 725 ) 726 727 def __deserialize_datetime(self, string): 728 """Deserializes string to datetime. 729 730 The string should be in iso8601 datetime format. 731 732 :param string: str. 733 :return: datetime. 734 """ 735 try: 736 return parse(string) 737 except ImportError: 738 return string 739 except ValueError: 740 raise rest.ApiException( 741 status=0, 742 reason=( 743 "Failed to parse `{0}` as datetime object" 744 .format(string) 745 ) 746 ) 747 748 def __deserialize_enum(self, data, klass): 749 """Deserializes primitive type to enum. 750 751 :param data: primitive type. 752 :param klass: class literal. 753 :return: enum value. 754 """ 755 try: 756 return klass(data) 757 except ValueError: 758 raise rest.ApiException( 759 status=0, 760 reason=( 761 "Failed to parse `{0}` as `{1}`" 762 .format(data, klass) 763 ) 764 ) 765 766 def __deserialize_model(self, data, klass): 767 """Deserializes list or dict to model. 768 769 :param data: dict, list. 770 :param klass: class literal. 771 :return: model object. 772 """ 773 774 return klass.from_dict(data)
Generic API client for OpenAPI client library builds.
OpenAPI generic API client. This client handles the client- server communication, and is invariant across implementations. Specifics of the methods and models for each application are generated from the OpenAPI templates.
Parameters
- configuration: .Configuration object for this client
- header_name: a header to pass when making calls to the API.
- header_value: a header value to pass when making calls to the API.
- cookie: a cookie to include in the header when making calls to the API
74 def __init__( 75 self, 76 configuration=None, 77 header_name=None, 78 header_value=None, 79 cookie=None 80 ) -> None: 81 # use default configuration if none is provided 82 if configuration is None: 83 configuration = Configuration.get_default() 84 self.configuration = configuration 85 86 self.rest_client = rest.RESTClientObject(configuration) 87 self.default_headers = {} 88 if header_name is not None: 89 self.default_headers[header_name] = header_value 90 self.cookie = cookie 91 # Set default User-Agent. 92 self.user_agent = 'OpenAPI-Generator/25.1.0/python' 93 self.client_side_validation = configuration.client_side_validation
104 @property 105 def user_agent(self): 106 """User agent for this API client""" 107 return self.default_headers['User-Agent']
User agent for this API client
119 @classmethod 120 def get_default(cls): 121 """Return new instance of ApiClient. 122 123 This method returns newly created, based on default constructor, 124 object of ApiClient class or returns a copy of default 125 ApiClient. 126 127 :return: The ApiClient object. 128 """ 129 if cls._default is None: 130 cls._default = ApiClient() 131 return cls._default
Return new instance of ApiClient.
This method returns newly created, based on default constructor, object of ApiClient class or returns a copy of default ApiClient.
Returns
The ApiClient object.
133 @classmethod 134 def set_default(cls, default): 135 """Set default instance of ApiClient. 136 137 It stores default ApiClient. 138 139 :param default: object of ApiClient. 140 """ 141 cls._default = default
Set default instance of ApiClient.
It stores default ApiClient.
Parameters
- default: object of ApiClient.
143 def param_serialize( 144 self, 145 method, 146 resource_path, 147 path_params=None, 148 query_params=None, 149 header_params=None, 150 body=None, 151 post_params=None, 152 files=None, auth_settings=None, 153 collection_formats=None, 154 _host=None, 155 _request_auth=None 156 ) -> RequestSerialized: 157 158 """Builds the HTTP request params needed by the request. 159 :param method: Method to call. 160 :param resource_path: Path to method endpoint. 161 :param path_params: Path parameters in the url. 162 :param query_params: Query parameters in the url. 163 :param header_params: Header parameters to be 164 placed in the request header. 165 :param body: Request body. 166 :param post_params dict: Request post form parameters, 167 for `application/x-www-form-urlencoded`, `multipart/form-data`. 168 :param auth_settings list: Auth Settings names for the request. 169 :param files dict: key -> filename, value -> filepath, 170 for `multipart/form-data`. 171 :param collection_formats: dict of collection formats for path, query, 172 header, and post parameters. 173 :param _request_auth: set to override the auth_settings for an a single 174 request; this effectively ignores the authentication 175 in the spec for a single request. 176 :return: tuple of form (path, http_method, query_params, header_params, 177 body, post_params, files) 178 """ 179 180 config = self.configuration 181 182 # header parameters 183 header_params = header_params or {} 184 header_params.update(self.default_headers) 185 if self.cookie: 186 header_params['Cookie'] = self.cookie 187 if header_params: 188 header_params = self.sanitize_for_serialization(header_params) 189 header_params = dict( 190 self.parameters_to_tuples(header_params,collection_formats) 191 ) 192 193 # path parameters 194 if path_params: 195 path_params = self.sanitize_for_serialization(path_params) 196 path_params = self.parameters_to_tuples( 197 path_params, 198 collection_formats 199 ) 200 for k, v in path_params: 201 # specified safe chars, encode everything 202 resource_path = resource_path.replace( 203 '{%s}' % k, 204 quote(str(v), safe=config.safe_chars_for_path_param) 205 ) 206 207 # post parameters 208 if post_params or files: 209 post_params = post_params if post_params else [] 210 post_params = self.sanitize_for_serialization(post_params) 211 post_params = self.parameters_to_tuples( 212 post_params, 213 collection_formats 214 ) 215 if files: 216 post_params.extend(self.files_parameters(files)) 217 218 # auth setting 219 self.update_params_for_auth( 220 header_params, 221 query_params, 222 auth_settings, 223 resource_path, 224 method, 225 body, 226 request_auth=_request_auth 227 ) 228 229 # body 230 if body: 231 body = self.sanitize_for_serialization(body) 232 233 # request url 234 if _host is None: 235 url = self.configuration.host + resource_path 236 else: 237 # use server/host defined in path or operation instead 238 url = _host + resource_path 239 240 # query parameters 241 if query_params: 242 query_params = self.sanitize_for_serialization(query_params) 243 url_query = self.parameters_to_url_query( 244 query_params, 245 collection_formats 246 ) 247 url += "?" + url_query 248 249 return method, url, header_params, body, post_params
Builds the HTTP request params needed by the request.
Parameters
- method: Method to call.
- resource_path: Path to method endpoint.
- path_params: Path parameters in the url.
- query_params: Query parameters in the url.
- header_params: Header parameters to be placed in the request header.
- body: Request body.
- post_params dict: Request post form parameters,
for
application/x-www-form-urlencoded
,multipart/form-data
. - auth_settings list: Auth Settings names for the request.
- files dict: key -> filename, value -> filepath,
for
multipart/form-data
. - collection_formats: dict of collection formats for path, query, header, and post parameters.
- _request_auth: set to override the auth_settings for an a single request; this effectively ignores the authentication in the spec for a single request.
Returns
tuple of form (path, http_method, query_params, header_params, body, post_params, files)
252 async def call_api( 253 self, 254 method, 255 url, 256 header_params=None, 257 body=None, 258 post_params=None, 259 _request_timeout=None 260 ) -> rest.RESTResponse: 261 """Makes the HTTP request (synchronous) 262 :param method: Method to call. 263 :param url: Path to method endpoint. 264 :param header_params: Header parameters to be 265 placed in the request header. 266 :param body: Request body. 267 :param post_params dict: Request post form parameters, 268 for `application/x-www-form-urlencoded`, `multipart/form-data`. 269 :param _request_timeout: timeout setting for this request. 270 :return: RESTResponse 271 """ 272 273 try: 274 # perform request and return response 275 response_data = await self.rest_client.request( 276 method, url, 277 headers=header_params, 278 body=body, post_params=post_params, 279 _request_timeout=_request_timeout 280 ) 281 282 except ApiException as e: 283 raise e 284 285 return response_data
Makes the HTTP request (synchronous)
Parameters
- method: Method to call.
- url: Path to method endpoint.
- header_params: Header parameters to be placed in the request header.
- body: Request body.
- post_params dict: Request post form parameters,
for
application/x-www-form-urlencoded
,multipart/form-data
. - _request_timeout: timeout setting for this request.
Returns
RESTResponse
287 def response_deserialize( 288 self, 289 response_data: rest.RESTResponse, 290 response_types_map: Optional[Dict[str, ApiResponseT]]=None 291 ) -> ApiResponse[ApiResponseT]: 292 """Deserializes response into an object. 293 :param response_data: RESTResponse object to be deserialized. 294 :param response_types_map: dict of response types. 295 :return: ApiResponse 296 """ 297 298 msg = "RESTResponse.read() must be called before passing it to response_deserialize()" 299 assert response_data.data is not None, msg 300 301 response_type = response_types_map.get(str(response_data.status), None) 302 if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599: 303 # if not found, look for '1XX', '2XX', etc. 304 response_type = response_types_map.get(str(response_data.status)[0] + "XX", None) 305 306 # deserialize response data 307 response_text = None 308 return_data = None 309 try: 310 if response_type == "bytearray": 311 return_data = response_data.data 312 elif response_type == "file": 313 return_data = self.__deserialize_file(response_data) 314 elif response_type is not None: 315 match = None 316 content_type = response_data.getheader('content-type') 317 if content_type is not None: 318 match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) 319 encoding = match.group(1) if match else "utf-8" 320 response_text = response_data.data.decode(encoding) 321 if response_type in ["bytearray", "str"]: 322 return_data = self.__deserialize_primitive(response_text, response_type) 323 else: 324 return_data = self.deserialize(response_text, response_type) 325 finally: 326 if not 200 <= response_data.status <= 299: 327 raise ApiException.from_response( 328 http_resp=response_data, 329 body=response_text, 330 data=return_data, 331 ) 332 333 return ApiResponse( 334 status_code = response_data.status, 335 data = return_data, 336 headers = response_data.getheaders(), 337 raw_data = response_data.data 338 )
Deserializes response into an object.
Parameters
- response_data: RESTResponse object to be deserialized.
- response_types_map: dict of response types.
Returns
ApiResponse
340 def sanitize_for_serialization(self, obj): 341 """Builds a JSON POST object. 342 343 If obj is None, return None. 344 If obj is SecretStr, return obj.get_secret_value() 345 If obj is str, int, long, float, bool, return directly. 346 If obj is datetime.datetime, datetime.date 347 convert to string in iso8601 format. 348 If obj is list, sanitize each element in the list. 349 If obj is dict, return the dict. 350 If obj is OpenAPI model, return the properties dict. 351 352 :param obj: The data to serialize. 353 :return: The serialized form of data. 354 """ 355 if obj is None: 356 return None 357 elif isinstance(obj, Enum): 358 return obj.value 359 elif isinstance(obj, SecretStr): 360 return obj.get_secret_value() 361 elif isinstance(obj, self.PRIMITIVE_TYPES): 362 return obj 363 elif isinstance(obj, list): 364 return [ 365 self.sanitize_for_serialization(sub_obj) for sub_obj in obj 366 ] 367 elif isinstance(obj, tuple): 368 return tuple( 369 self.sanitize_for_serialization(sub_obj) for sub_obj in obj 370 ) 371 elif isinstance(obj, (datetime.datetime, datetime.date)): 372 return obj.isoformat() 373 374 elif isinstance(obj, dict): 375 obj_dict = obj 376 else: 377 # Convert model obj to dict except 378 # attributes `openapi_types`, `attribute_map` 379 # and attributes which value is not None. 380 # Convert attribute name to json key in 381 # model definition for request. 382 if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): 383 obj_dict = obj.to_dict() 384 else: 385 obj_dict = obj.__dict__ 386 387 return { 388 key: self.sanitize_for_serialization(val) 389 for key, val in obj_dict.items() 390 }
Builds a JSON POST object.
If obj is None, return None. If obj is SecretStr, return obj.get_secret_value() If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. If obj is list, sanitize each element in the list. If obj is dict, return the dict. If obj is OpenAPI model, return the properties dict.
Parameters
- obj: The data to serialize.
Returns
The serialized form of data.
392 def deserialize(self, response_text, response_type): 393 """Deserializes response into an object. 394 395 :param response: RESTResponse object to be deserialized. 396 :param response_type: class literal for 397 deserialized object, or string of class name. 398 399 :return: deserialized object. 400 """ 401 402 # fetch data from response object 403 try: 404 data = json.loads(response_text) 405 except ValueError: 406 data = response_text 407 408 return self.__deserialize(data, response_type)
Deserializes response into an object.
Parameters
- response: RESTResponse object to be deserialized.
- response_type: class literal for deserialized object, or string of class name.
Returns
deserialized object.
455 def parameters_to_tuples(self, params, collection_formats): 456 """Get parameters as list of tuples, formatting collections. 457 458 :param params: Parameters as dict or list of two-tuples 459 :param dict collection_formats: Parameter collection formats 460 :return: Parameters as list of tuples, collections formatted 461 """ 462 new_params: List[Tuple[str, str]] = [] 463 if collection_formats is None: 464 collection_formats = {} 465 for k, v in params.items() if isinstance(params, dict) else params: 466 if k in collection_formats: 467 collection_format = collection_formats[k] 468 if collection_format == 'multi': 469 new_params.extend((k, value) for value in v) 470 else: 471 if collection_format == 'ssv': 472 delimiter = ' ' 473 elif collection_format == 'tsv': 474 delimiter = '\t' 475 elif collection_format == 'pipes': 476 delimiter = '|' 477 else: # csv is the default 478 delimiter = ',' 479 new_params.append( 480 (k, delimiter.join(str(value) for value in v))) 481 else: 482 new_params.append((k, v)) 483 return new_params
Get parameters as list of tuples, formatting collections.
Parameters
- params: Parameters as dict or list of two-tuples
- dict collection_formats: Parameter collection formats
Returns
Parameters as list of tuples, collections formatted
485 def parameters_to_url_query(self, params, collection_formats): 486 """Get parameters as list of tuples, formatting collections. 487 488 :param params: Parameters as dict or list of two-tuples 489 :param dict collection_formats: Parameter collection formats 490 :return: URL query string (e.g. a=Hello%20World&b=123) 491 """ 492 new_params: List[Tuple[str, str]] = [] 493 if collection_formats is None: 494 collection_formats = {} 495 for k, v in params.items() if isinstance(params, dict) else params: 496 if isinstance(v, bool): 497 v = str(v).lower() 498 if isinstance(v, (int, float)): 499 v = str(v) 500 if isinstance(v, dict): 501 v = json.dumps(v) 502 503 if k in collection_formats: 504 collection_format = collection_formats[k] 505 if collection_format == 'multi': 506 new_params.extend((k, str(value)) for value in v) 507 else: 508 if collection_format == 'ssv': 509 delimiter = ' ' 510 elif collection_format == 'tsv': 511 delimiter = '\t' 512 elif collection_format == 'pipes': 513 delimiter = '|' 514 else: # csv is the default 515 delimiter = ',' 516 new_params.append( 517 (k, delimiter.join(quote(str(value)) for value in v)) 518 ) 519 else: 520 new_params.append((k, quote(str(v)))) 521 522 return "&".join(["=".join(map(str, item)) for item in new_params])
Get parameters as list of tuples, formatting collections.
Parameters
- params: Parameters as dict or list of two-tuples
- dict collection_formats: Parameter collection formats
Returns
URL query string (e.g. a=Hello%20World&b=123)
524 def files_parameters(self, files: Dict[str, Union[str, bytes]]): 525 """Builds form parameters. 526 527 :param files: File parameters. 528 :return: Form parameters with files. 529 """ 530 params = [] 531 for k, v in files.items(): 532 if isinstance(v, str): 533 with open(v, 'rb') as f: 534 filename = os.path.basename(f.name) 535 filedata = f.read() 536 elif isinstance(v, bytes): 537 filename = k 538 filedata = v 539 else: 540 raise ValueError("Unsupported file value") 541 mimetype = ( 542 mimetypes.guess_type(filename)[0] 543 or 'application/octet-stream' 544 ) 545 params.append( 546 tuple([k, tuple([filename, filedata, mimetype])]) 547 ) 548 return params
Builds form parameters.
Parameters
- files: File parameters.
Returns
Form parameters with files.
550 def select_header_accept(self, accepts: List[str]) -> Optional[str]: 551 """Returns `Accept` based on an array of accepts provided. 552 553 :param accepts: List of headers. 554 :return: Accept (e.g. application/json). 555 """ 556 if not accepts: 557 return None 558 559 for accept in accepts: 560 if re.search('json', accept, re.IGNORECASE): 561 return accept 562 563 return accepts[0]
Returns Accept
based on an array of accepts provided.
Parameters
- accepts: List of headers.
Returns
Accept (e.g. application/json).
565 def select_header_content_type(self, content_types): 566 """Returns `Content-Type` based on an array of content_types provided. 567 568 :param content_types: List of content-types. 569 :return: Content-Type (e.g. application/json). 570 """ 571 if not content_types: 572 return None 573 574 for content_type in content_types: 575 if re.search('json', content_type, re.IGNORECASE): 576 return content_type 577 578 return content_types[0]
Returns Content-Type
based on an array of content_types provided.
Parameters
- content_types: List of content-types.
Returns
Content-Type (e.g. application/json).
580 def update_params_for_auth( 581 self, 582 headers, 583 queries, 584 auth_settings, 585 resource_path, 586 method, 587 body, 588 request_auth=None 589 ) -> None: 590 """Updates header and query params based on authentication setting. 591 592 :param headers: Header parameters dict to be updated. 593 :param queries: Query parameters tuple list to be updated. 594 :param auth_settings: Authentication setting identifiers list. 595 :resource_path: A string representation of the HTTP request resource path. 596 :method: A string representation of the HTTP request method. 597 :body: A object representing the body of the HTTP request. 598 The object type is the return value of sanitize_for_serialization(). 599 :param request_auth: if set, the provided settings will 600 override the token in the configuration. 601 """ 602 if not auth_settings: 603 return 604 605 if request_auth: 606 self._apply_auth_params( 607 headers, 608 queries, 609 resource_path, 610 method, 611 body, 612 request_auth 613 ) 614 else: 615 for auth in auth_settings: 616 auth_setting = self.configuration.auth_settings().get(auth) 617 if auth_setting: 618 self._apply_auth_params( 619 headers, 620 queries, 621 resource_path, 622 method, 623 body, 624 auth_setting 625 )
Updates header and query params based on authentication setting.
Parameters
- headers: Header parameters dict to be updated.
- queries: Query parameters tuple list to be updated.
- auth_settings: Authentication setting identifiers list. :resource_path: A string representation of the HTTP request resource path. :method: A string representation of the HTTP request method. :body: A object representing the body of the HTTP request. The object type is the return value of sanitize_for_serialization().
- request_auth: if set, the provided settings will override the token in the configuration.
31class Configuration: 32 """This class contains various settings of the API client. 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 access_token: Access token. 45 :param server_index: Index to servers configuration. 46 :param server_variables: Mapping with string values to replace variables in 47 templated server configuration. The validation of enums is performed for 48 variables with defined enum values before. 49 :param server_operation_index: Mapping from operation ID to an index to server 50 configuration. 51 :param server_operation_variables: Mapping from operation ID to a mapping with 52 string values to replace variables in templated server configuration. 53 The validation of enums is performed for variables with defined enum 54 values before. 55 :param ssl_ca_cert: str - the path to a file of concatenated CA certificates 56 in PEM format. 57 58 :Example: 59 60 HTTP Basic Authentication Example. 61 Given the following security scheme in the OpenAPI specification: 62 components: 63 securitySchemes: 64 http_basic_auth: 65 type: http 66 scheme: basic 67 68 Configure API client with HTTP basic authentication: 69 70conf = wandelbots_api_client.Configuration( 71 username='the-user', 72 password='the-password', 73) 74 75 """ 76 77 _default = None 78 79 def __init__(self, host=None, 80 api_key=None, api_key_prefix=None, 81 username=None, password=None, 82 access_token=None, 83 server_index=None, server_variables=None, 84 server_operation_index=None, server_operation_variables=None, 85 ssl_ca_cert=None, 86 ) -> None: 87 """Constructor 88 """ 89 self._base_path = "/api/v1" if host is None else host 90 """Default Base url 91 """ 92 self.server_index = 0 if server_index is None and host is None else server_index 93 self.server_operation_index = server_operation_index or {} 94 """Default server index 95 """ 96 self.server_variables = server_variables or {} 97 self.server_operation_variables = server_operation_variables or {} 98 """Default server variables 99 """ 100 self.temp_folder_path = None 101 """Temp file folder for downloading files 102 """ 103 # Authentication Settings 104 self.api_key = {} 105 if api_key: 106 self.api_key = api_key 107 """dict to store API key(s) 108 """ 109 self.api_key_prefix = {} 110 if api_key_prefix: 111 self.api_key_prefix = api_key_prefix 112 """dict to store API prefix (e.g. Bearer) 113 """ 114 self.refresh_api_key_hook = None 115 """function hook to refresh API key if expired 116 """ 117 self.username = username 118 """Username for HTTP basic authentication 119 """ 120 self.password = password 121 """Password for HTTP basic authentication 122 """ 123 self.access_token = access_token 124 """Access token 125 """ 126 self.logger = {} 127 """Logging Settings 128 """ 129 self.logger["package_logger"] = logging.getLogger("wandelbots_api_client") 130 self.logger["urllib3_logger"] = logging.getLogger("urllib3") 131 self.logger_format = '%(asctime)s %(levelname)s %(message)s' 132 """Log format 133 """ 134 self.logger_stream_handler = None 135 """Log stream handler 136 """ 137 self.logger_file_handler: Optional[FileHandler] = None 138 """Log file handler 139 """ 140 self.logger_file = None 141 """Debug file location 142 """ 143 self.debug = False 144 """Debug switch 145 """ 146 147 self.verify_ssl = True 148 """SSL/TLS verification 149 Set this to false to skip verifying SSL certificate when calling API 150 from https server. 151 """ 152 self.ssl_ca_cert = ssl_ca_cert 153 """Set this to customize the certificate file to verify the peer. 154 """ 155 self.cert_file = None 156 """client certificate file 157 """ 158 self.key_file = None 159 """client key file 160 """ 161 self.assert_hostname = None 162 """Set this to True/False to enable/disable SSL hostname verification. 163 """ 164 self.tls_server_name = None 165 """SSL/TLS Server Name Indication (SNI) 166 Set this to the SNI value expected by the server. 167 """ 168 169 self.connection_pool_maxsize = 100 170 """This value is passed to the aiohttp to limit simultaneous connections. 171 Default values is 100, None means no-limit. 172 """ 173 174 self.proxy: Optional[str] = None 175 """Proxy URL 176 """ 177 self.proxy_headers = None 178 """Proxy headers 179 """ 180 self.safe_chars_for_path_param = '' 181 """Safe chars for path_param 182 """ 183 self.retries = None 184 """Adding retries to override urllib3 default value 3 185 """ 186 # Enable client side validation 187 self.client_side_validation = True 188 189 self.socket_options = None 190 """Options to pass down to the underlying urllib3 socket 191 """ 192 193 self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z" 194 """datetime format 195 """ 196 197 self.date_format = "%Y-%m-%d" 198 """date format 199 """ 200 201 def __deepcopy__(self, memo): 202 cls = self.__class__ 203 result = cls.__new__(cls) 204 memo[id(self)] = result 205 for k, v in self.__dict__.items(): 206 if k not in ('logger', 'logger_file_handler'): 207 setattr(result, k, copy.deepcopy(v, memo)) 208 # shallow copy of loggers 209 result.logger = copy.copy(self.logger) 210 # use setters to configure loggers 211 result.logger_file = self.logger_file 212 result.debug = self.debug 213 return result 214 215 def __setattr__(self, name, value): 216 object.__setattr__(self, name, value) 217 218 @classmethod 219 def set_default(cls, default): 220 """Set default instance of configuration. 221 222 It stores default configuration, which can be 223 returned by get_default_copy method. 224 225 :param default: object of Configuration 226 """ 227 cls._default = default 228 229 @classmethod 230 def get_default_copy(cls): 231 """Deprecated. Please use `get_default` instead. 232 233 Deprecated. Please use `get_default` instead. 234 235 :return: The configuration object. 236 """ 237 return cls.get_default() 238 239 @classmethod 240 def get_default(cls): 241 """Return the default configuration. 242 243 This method returns newly created, based on default constructor, 244 object of Configuration class or returns a copy of default 245 configuration. 246 247 :return: The configuration object. 248 """ 249 if cls._default is None: 250 cls._default = Configuration() 251 return cls._default 252 253 @property 254 def logger_file(self): 255 """The logger file. 256 257 If the logger_file is None, then add stream handler and remove file 258 handler. Otherwise, add file handler and remove stream handler. 259 260 :param value: The logger_file path. 261 :type: str 262 """ 263 return self.__logger_file 264 265 @logger_file.setter 266 def logger_file(self, value): 267 """The logger file. 268 269 If the logger_file is None, then add stream handler and remove file 270 handler. Otherwise, add file handler and remove stream handler. 271 272 :param value: The logger_file path. 273 :type: str 274 """ 275 self.__logger_file = value 276 if self.__logger_file: 277 # If set logging file, 278 # then add file handler and remove stream handler. 279 self.logger_file_handler = logging.FileHandler(self.__logger_file) 280 self.logger_file_handler.setFormatter(self.logger_formatter) 281 for _, logger in self.logger.items(): 282 logger.addHandler(self.logger_file_handler) 283 284 @property 285 def debug(self): 286 """Debug status 287 288 :param value: The debug status, True or False. 289 :type: bool 290 """ 291 return self.__debug 292 293 @debug.setter 294 def debug(self, value): 295 """Debug status 296 297 :param value: The debug status, True or False. 298 :type: bool 299 """ 300 self.__debug = value 301 if self.__debug: 302 # if debug status is True, turn on debug logging 303 for _, logger in self.logger.items(): 304 logger.setLevel(logging.DEBUG) 305 # turn on httplib debug 306 httplib.HTTPConnection.debuglevel = 1 307 else: 308 # if debug status is False, turn off debug logging, 309 # setting log level to default `logging.WARNING` 310 for _, logger in self.logger.items(): 311 logger.setLevel(logging.WARNING) 312 # turn off httplib debug 313 httplib.HTTPConnection.debuglevel = 0 314 315 @property 316 def logger_format(self): 317 """The logger format. 318 319 The logger_formatter will be updated when sets logger_format. 320 321 :param value: The format string. 322 :type: str 323 """ 324 return self.__logger_format 325 326 @logger_format.setter 327 def logger_format(self, value): 328 """The logger format. 329 330 The logger_formatter will be updated when sets logger_format. 331 332 :param value: The format string. 333 :type: str 334 """ 335 self.__logger_format = value 336 self.logger_formatter = logging.Formatter(self.__logger_format) 337 338 def get_api_key_with_prefix(self, identifier, alias=None): 339 """Gets API key (with prefix if set). 340 341 :param identifier: The identifier of apiKey. 342 :param alias: The alternative identifier of apiKey. 343 :return: The token for api key authentication. 344 """ 345 if self.refresh_api_key_hook is not None: 346 self.refresh_api_key_hook(self) 347 key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None) 348 if key: 349 prefix = self.api_key_prefix.get(identifier) 350 if prefix: 351 return "%s %s" % (prefix, key) 352 else: 353 return key 354 355 def get_basic_auth_token(self): 356 """Gets HTTP basic authentication header (string). 357 358 :return: The token for basic HTTP authentication. 359 """ 360 username = "" 361 if self.username is not None: 362 username = self.username 363 password = "" 364 if self.password is not None: 365 password = self.password 366 return urllib3.util.make_headers( 367 basic_auth=username + ':' + password 368 ).get('authorization') 369 370 def auth_settings(self): 371 """Gets Auth Settings dict for api client. 372 373 :return: The Auth Settings information dict. 374 """ 375 auth = {} 376 if self.username is not None and self.password is not None: 377 auth['BasicAuth'] = { 378 'type': 'basic', 379 'in': 'header', 380 'key': 'Authorization', 381 'value': self.get_basic_auth_token() 382 } 383 if self.access_token is not None: 384 auth['BearerAuth'] = { 385 'type': 'bearer', 386 'in': 'header', 387 'format': 'JWT', 388 'key': 'Authorization', 389 'value': 'Bearer ' + self.access_token 390 } 391 return auth 392 393 def to_debug_report(self): 394 """Gets the essential information for debugging. 395 396 :return: The report for debugging. 397 """ 398 return "Python SDK Debug Report:\n"\ 399 "OS: {env}\n"\ 400 "Python Version: {pyversion}\n"\ 401 "Version of the API: 1.0.0 beta\n"\ 402 "SDK Package Version: 25.1.0".\ 403 format(env=sys.platform, pyversion=sys.version) 404 405 def get_host_settings(self): 406 """Gets an array of host settings 407 408 :return: An array of host settings 409 """ 410 return [ 411 { 412 'url': "/api/v1", 413 'description': "No description provided", 414 } 415 ] 416 417 def get_host_from_settings(self, index, variables=None, servers=None): 418 """Gets host URL based on the index and variables 419 :param index: array index of the host settings 420 :param variables: hash of variable and the corresponding value 421 :param servers: an array of host settings or None 422 :return: URL based on host settings 423 """ 424 if index is None: 425 return self._base_path 426 427 variables = {} if variables is None else variables 428 servers = self.get_host_settings() if servers is None else servers 429 430 try: 431 server = servers[index] 432 except IndexError: 433 raise ValueError( 434 "Invalid index {0} when selecting the host settings. " 435 "Must be less than {1}".format(index, len(servers))) 436 437 url = server['url'] 438 439 # go through variables and replace placeholders 440 for variable_name, variable in server.get('variables', {}).items(): 441 used_value = variables.get( 442 variable_name, variable['default_value']) 443 444 if 'enum_values' in variable \ 445 and used_value not in variable['enum_values']: 446 raise ValueError( 447 "The variable `{0}` in the host URL has invalid value " 448 "{1}. Must be {2}.".format( 449 variable_name, variables[variable_name], 450 variable['enum_values'])) 451 452 url = url.replace("{" + variable_name + "}", used_value) 453 454 return url 455 456 @property 457 def host(self): 458 """Return generated host.""" 459 return self.get_host_from_settings(self.server_index, variables=self.server_variables) 460 461 @host.setter 462 def host(self, value): 463 """Fix base path.""" 464 self._base_path = value 465 self.server_index = None
This class contains various settings of the API client.
:param host: Base url.
:param api_key: Dict to store API key(s).
Each entry in the dict specifies an API key.
The dict key is the name of the security scheme in the OAS specification.
The dict value is the API key secret.
:param api_key_prefix: Dict to store API prefix (e.g. Bearer).
The dict key is the name of the security scheme in the OAS specification.
The dict value is an API key prefix when generating the auth data.
:param username: Username for HTTP basic authentication.
:param password: Password for HTTP basic authentication.
:param access_token: Access token.
:param server_index: Index to servers configuration.
:param server_variables: Mapping with string values to replace variables in
templated server configuration. The validation of enums is performed for
variables with defined enum values before.
:param server_operation_index: Mapping from operation ID to an index to server
configuration.
:param server_operation_variables: Mapping from operation ID to a mapping with
string values to replace variables in templated server configuration.
The validation of enums is performed for variables with defined enum
values before.
:param ssl_ca_cert: str - the path to a file of concatenated CA certificates
in PEM format.
:Example:
HTTP Basic Authentication Example.
Given the following security scheme in the OpenAPI specification:
components:
securitySchemes:
http_basic_auth:
type: http
scheme: basic
Configure API client with HTTP basic authentication:
conf = wandelbots_api_client.Configuration( username='the-user', password='the-password', )
79 def __init__(self, host=None, 80 api_key=None, api_key_prefix=None, 81 username=None, password=None, 82 access_token=None, 83 server_index=None, server_variables=None, 84 server_operation_index=None, server_operation_variables=None, 85 ssl_ca_cert=None, 86 ) -> None: 87 """Constructor 88 """ 89 self._base_path = "/api/v1" if host is None else host 90 """Default Base url 91 """ 92 self.server_index = 0 if server_index is None and host is None else server_index 93 self.server_operation_index = server_operation_index or {} 94 """Default server index 95 """ 96 self.server_variables = server_variables or {} 97 self.server_operation_variables = server_operation_variables or {} 98 """Default server variables 99 """ 100 self.temp_folder_path = None 101 """Temp file folder for downloading files 102 """ 103 # Authentication Settings 104 self.api_key = {} 105 if api_key: 106 self.api_key = api_key 107 """dict to store API key(s) 108 """ 109 self.api_key_prefix = {} 110 if api_key_prefix: 111 self.api_key_prefix = api_key_prefix 112 """dict to store API prefix (e.g. Bearer) 113 """ 114 self.refresh_api_key_hook = None 115 """function hook to refresh API key if expired 116 """ 117 self.username = username 118 """Username for HTTP basic authentication 119 """ 120 self.password = password 121 """Password for HTTP basic authentication 122 """ 123 self.access_token = access_token 124 """Access token 125 """ 126 self.logger = {} 127 """Logging Settings 128 """ 129 self.logger["package_logger"] = logging.getLogger("wandelbots_api_client") 130 self.logger["urllib3_logger"] = logging.getLogger("urllib3") 131 self.logger_format = '%(asctime)s %(levelname)s %(message)s' 132 """Log format 133 """ 134 self.logger_stream_handler = None 135 """Log stream handler 136 """ 137 self.logger_file_handler: Optional[FileHandler] = None 138 """Log file handler 139 """ 140 self.logger_file = None 141 """Debug file location 142 """ 143 self.debug = False 144 """Debug switch 145 """ 146 147 self.verify_ssl = True 148 """SSL/TLS verification 149 Set this to false to skip verifying SSL certificate when calling API 150 from https server. 151 """ 152 self.ssl_ca_cert = ssl_ca_cert 153 """Set this to customize the certificate file to verify the peer. 154 """ 155 self.cert_file = None 156 """client certificate file 157 """ 158 self.key_file = None 159 """client key file 160 """ 161 self.assert_hostname = None 162 """Set this to True/False to enable/disable SSL hostname verification. 163 """ 164 self.tls_server_name = None 165 """SSL/TLS Server Name Indication (SNI) 166 Set this to the SNI value expected by the server. 167 """ 168 169 self.connection_pool_maxsize = 100 170 """This value is passed to the aiohttp to limit simultaneous connections. 171 Default values is 100, None means no-limit. 172 """ 173 174 self.proxy: Optional[str] = None 175 """Proxy URL 176 """ 177 self.proxy_headers = None 178 """Proxy headers 179 """ 180 self.safe_chars_for_path_param = '' 181 """Safe chars for path_param 182 """ 183 self.retries = None 184 """Adding retries to override urllib3 default value 3 185 """ 186 # Enable client side validation 187 self.client_side_validation = True 188 189 self.socket_options = None 190 """Options to pass down to the underlying urllib3 socket 191 """ 192 193 self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z" 194 """datetime format 195 """ 196 197 self.date_format = "%Y-%m-%d" 198 """date format 199 """
Constructor
315 @property 316 def logger_format(self): 317 """The logger format. 318 319 The logger_formatter will be updated when sets logger_format. 320 321 :param value: The format string. 322 :type: str 323 """ 324 return self.__logger_format
Log format
253 @property 254 def logger_file(self): 255 """The logger file. 256 257 If the logger_file is None, then add stream handler and remove file 258 handler. Otherwise, add file handler and remove stream handler. 259 260 :param value: The logger_file path. 261 :type: str 262 """ 263 return self.__logger_file
Debug file location
284 @property 285 def debug(self): 286 """Debug status 287 288 :param value: The debug status, True or False. 289 :type: bool 290 """ 291 return self.__debug
Debug switch
SSL/TLS verification Set this to false to skip verifying SSL certificate when calling API from https server.
SSL/TLS Server Name Indication (SNI) Set this to the SNI value expected by the server.
This value is passed to the aiohttp to limit simultaneous connections. Default values is 100, None means no-limit.
218 @classmethod 219 def set_default(cls, default): 220 """Set default instance of configuration. 221 222 It stores default configuration, which can be 223 returned by get_default_copy method. 224 225 :param default: object of Configuration 226 """ 227 cls._default = default
Set default instance of configuration.
It stores default configuration, which can be returned by get_default_copy method.
Parameters
- default: object of Configuration
229 @classmethod 230 def get_default_copy(cls): 231 """Deprecated. Please use `get_default` instead. 232 233 Deprecated. Please use `get_default` instead. 234 235 :return: The configuration object. 236 """ 237 return cls.get_default()
Deprecated. Please use get_default
instead.
Deprecated. Please use get_default
instead.
Returns
The configuration object.
239 @classmethod 240 def get_default(cls): 241 """Return the default configuration. 242 243 This method returns newly created, based on default constructor, 244 object of Configuration class or returns a copy of default 245 configuration. 246 247 :return: The configuration object. 248 """ 249 if cls._default is None: 250 cls._default = Configuration() 251 return cls._default
Return the default configuration.
This method returns newly created, based on default constructor, object of Configuration class or returns a copy of default configuration.
Returns
The configuration object.
338 def get_api_key_with_prefix(self, identifier, alias=None): 339 """Gets API key (with prefix if set). 340 341 :param identifier: The identifier of apiKey. 342 :param alias: The alternative identifier of apiKey. 343 :return: The token for api key authentication. 344 """ 345 if self.refresh_api_key_hook is not None: 346 self.refresh_api_key_hook(self) 347 key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None) 348 if key: 349 prefix = self.api_key_prefix.get(identifier) 350 if prefix: 351 return "%s %s" % (prefix, key) 352 else: 353 return key
Gets API key (with prefix if set).
Parameters
- identifier: The identifier of apiKey.
- alias: The alternative identifier of apiKey.
Returns
The token for api key authentication.
355 def get_basic_auth_token(self): 356 """Gets HTTP basic authentication header (string). 357 358 :return: The token for basic HTTP authentication. 359 """ 360 username = "" 361 if self.username is not None: 362 username = self.username 363 password = "" 364 if self.password is not None: 365 password = self.password 366 return urllib3.util.make_headers( 367 basic_auth=username + ':' + password 368 ).get('authorization')
Gets HTTP basic authentication header (string).
Returns
The token for basic HTTP authentication.
370 def auth_settings(self): 371 """Gets Auth Settings dict for api client. 372 373 :return: The Auth Settings information dict. 374 """ 375 auth = {} 376 if self.username is not None and self.password is not None: 377 auth['BasicAuth'] = { 378 'type': 'basic', 379 'in': 'header', 380 'key': 'Authorization', 381 'value': self.get_basic_auth_token() 382 } 383 if self.access_token is not None: 384 auth['BearerAuth'] = { 385 'type': 'bearer', 386 'in': 'header', 387 'format': 'JWT', 388 'key': 'Authorization', 389 'value': 'Bearer ' + self.access_token 390 } 391 return auth
Gets Auth Settings dict for api client.
Returns
The Auth Settings information dict.
393 def to_debug_report(self): 394 """Gets the essential information for debugging. 395 396 :return: The report for debugging. 397 """ 398 return "Python SDK Debug Report:\n"\ 399 "OS: {env}\n"\ 400 "Python Version: {pyversion}\n"\ 401 "Version of the API: 1.0.0 beta\n"\ 402 "SDK Package Version: 25.1.0".\ 403 format(env=sys.platform, pyversion=sys.version)
Gets the essential information for debugging.
Returns
The report for debugging.
405 def get_host_settings(self): 406 """Gets an array of host settings 407 408 :return: An array of host settings 409 """ 410 return [ 411 { 412 'url': "/api/v1", 413 'description': "No description provided", 414 } 415 ]
Gets an array of host settings
Returns
An array of host settings
417 def get_host_from_settings(self, index, variables=None, servers=None): 418 """Gets host URL based on the index and variables 419 :param index: array index of the host settings 420 :param variables: hash of variable and the corresponding value 421 :param servers: an array of host settings or None 422 :return: URL based on host settings 423 """ 424 if index is None: 425 return self._base_path 426 427 variables = {} if variables is None else variables 428 servers = self.get_host_settings() if servers is None else servers 429 430 try: 431 server = servers[index] 432 except IndexError: 433 raise ValueError( 434 "Invalid index {0} when selecting the host settings. " 435 "Must be less than {1}".format(index, len(servers))) 436 437 url = server['url'] 438 439 # go through variables and replace placeholders 440 for variable_name, variable in server.get('variables', {}).items(): 441 used_value = variables.get( 442 variable_name, variable['default_value']) 443 444 if 'enum_values' in variable \ 445 and used_value not in variable['enum_values']: 446 raise ValueError( 447 "The variable `{0}` in the host URL has invalid value " 448 "{1}. Must be {2}.".format( 449 variable_name, variables[variable_name], 450 variable['enum_values'])) 451 452 url = url.replace("{" + variable_name + "}", used_value) 453 454 return url
Gets host URL based on the index and variables
Parameters
- index: array index of the host settings
- variables: hash of variable and the corresponding value
- servers: an array of host settings or None
Returns
URL based on host settings
The base exception class for all OpenAPIExceptions
22class ApiTypeError(OpenApiException, TypeError): 23 def __init__(self, msg, path_to_item=None, valid_classes=None, 24 key_type=None) -> None: 25 """ Raises an exception for TypeErrors 26 27 Args: 28 msg (str): the exception message 29 30 Keyword Args: 31 path_to_item (list): a list of keys an indices to get to the 32 current_item 33 None if unset 34 valid_classes (tuple): the primitive classes that current item 35 should be an instance of 36 None if unset 37 key_type (bool): False if our value is a value in a dict 38 True if it is a key in a dict 39 False if our item is an item in a list 40 None if unset 41 """ 42 self.path_to_item = path_to_item 43 self.valid_classes = valid_classes 44 self.key_type = key_type 45 full_msg = msg 46 if path_to_item: 47 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 48 super(ApiTypeError, self).__init__(full_msg)
The base exception class for all OpenAPIExceptions
23 def __init__(self, msg, path_to_item=None, valid_classes=None, 24 key_type=None) -> None: 25 """ Raises an exception for TypeErrors 26 27 Args: 28 msg (str): the exception message 29 30 Keyword Args: 31 path_to_item (list): a list of keys an indices to get to the 32 current_item 33 None if unset 34 valid_classes (tuple): the primitive classes that current item 35 should be an instance of 36 None if unset 37 key_type (bool): False if our value is a value in a dict 38 True if it is a key in a dict 39 False if our item is an item in a list 40 None if unset 41 """ 42 self.path_to_item = path_to_item 43 self.valid_classes = valid_classes 44 self.key_type = key_type 45 full_msg = msg 46 if path_to_item: 47 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 48 super(ApiTypeError, self).__init__(full_msg)
Raises an exception for TypeErrors
Args: msg (str): the exception message
Keyword Args: path_to_item (list): a list of keys an indices to get to the current_item None if unset valid_classes (tuple): the primitive classes that current item should be an instance of None if unset key_type (bool): False if our value is a value in a dict True if it is a key in a dict False if our item is an item in a list None if unset
51class ApiValueError(OpenApiException, ValueError): 52 def __init__(self, msg, path_to_item=None) -> None: 53 """ 54 Args: 55 msg (str): the exception message 56 57 Keyword Args: 58 path_to_item (list) the path to the exception in the 59 received_data dict. None if unset 60 """ 61 62 self.path_to_item = path_to_item 63 full_msg = msg 64 if path_to_item: 65 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 66 super(ApiValueError, self).__init__(full_msg)
The base exception class for all OpenAPIExceptions
52 def __init__(self, msg, path_to_item=None) -> None: 53 """ 54 Args: 55 msg (str): the exception message 56 57 Keyword Args: 58 path_to_item (list) the path to the exception in the 59 received_data dict. None if unset 60 """ 61 62 self.path_to_item = path_to_item 63 full_msg = msg 64 if path_to_item: 65 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 66 super(ApiValueError, self).__init__(full_msg)
Args: msg (str): the exception message
Keyword Args: path_to_item (list) the path to the exception in the received_data dict. None if unset
88class ApiKeyError(OpenApiException, KeyError): 89 def __init__(self, msg, path_to_item=None) -> None: 90 """ 91 Args: 92 msg (str): the exception message 93 94 Keyword Args: 95 path_to_item (None/list) the path to the exception in the 96 received_data dict 97 """ 98 self.path_to_item = path_to_item 99 full_msg = msg 100 if path_to_item: 101 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 102 super(ApiKeyError, self).__init__(full_msg)
The base exception class for all OpenAPIExceptions
89 def __init__(self, msg, path_to_item=None) -> None: 90 """ 91 Args: 92 msg (str): the exception message 93 94 Keyword Args: 95 path_to_item (None/list) the path to the exception in the 96 received_data dict 97 """ 98 self.path_to_item = path_to_item 99 full_msg = msg 100 if path_to_item: 101 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 102 super(ApiKeyError, self).__init__(full_msg)
Args: msg (str): the exception message
Keyword Args: path_to_item (None/list) the path to the exception in the received_data dict
69class ApiAttributeError(OpenApiException, AttributeError): 70 def __init__(self, msg, path_to_item=None) -> None: 71 """ 72 Raised when an attribute reference or assignment fails. 73 74 Args: 75 msg (str): the exception message 76 77 Keyword Args: 78 path_to_item (None/list) the path to the exception in the 79 received_data dict 80 """ 81 self.path_to_item = path_to_item 82 full_msg = msg 83 if path_to_item: 84 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 85 super(ApiAttributeError, self).__init__(full_msg)
The base exception class for all OpenAPIExceptions
70 def __init__(self, msg, path_to_item=None) -> None: 71 """ 72 Raised when an attribute reference or assignment fails. 73 74 Args: 75 msg (str): the exception message 76 77 Keyword Args: 78 path_to_item (None/list) the path to the exception in the 79 received_data dict 80 """ 81 self.path_to_item = path_to_item 82 full_msg = msg 83 if path_to_item: 84 full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) 85 super(ApiAttributeError, self).__init__(full_msg)
Raised when an attribute reference or assignment fails.
Args: msg (str): the exception message
Keyword Args: path_to_item (None/list) the path to the exception in the received_data dict
105class ApiException(OpenApiException): 106 107 def __init__( 108 self, 109 status=None, 110 reason=None, 111 http_resp=None, 112 *, 113 body: Optional[str] = None, 114 data: Optional[Any] = None, 115 ) -> None: 116 self.status = status 117 self.reason = reason 118 self.body = body 119 self.data = data 120 self.headers = None 121 122 if http_resp: 123 if self.status is None: 124 self.status = http_resp.status 125 if self.reason is None: 126 self.reason = http_resp.reason 127 if self.body is None: 128 try: 129 self.body = http_resp.data.decode('utf-8') 130 except Exception: 131 pass 132 self.headers = http_resp.getheaders() 133 134 @classmethod 135 def from_response( 136 cls, 137 *, 138 http_resp, 139 body: Optional[str], 140 data: Optional[Any], 141 ) -> Self: 142 if http_resp.status == 400: 143 raise BadRequestException(http_resp=http_resp, body=body, data=data) 144 145 if http_resp.status == 401: 146 raise UnauthorizedException(http_resp=http_resp, body=body, data=data) 147 148 if http_resp.status == 403: 149 raise ForbiddenException(http_resp=http_resp, body=body, data=data) 150 151 if http_resp.status == 404: 152 raise NotFoundException(http_resp=http_resp, body=body, data=data) 153 154 if 500 <= http_resp.status <= 599: 155 raise ServiceException(http_resp=http_resp, body=body, data=data) 156 raise ApiException(http_resp=http_resp, body=body, data=data) 157 158 def __str__(self): 159 """Custom error messages for exception""" 160 error_message = "({0})\n"\ 161 "Reason: {1}\n".format(self.status, self.reason) 162 if self.headers: 163 error_message += "HTTP response headers: {0}\n".format( 164 self.headers) 165 166 if self.data or self.body: 167 error_message += "HTTP response body: {0}\n".format(self.data or self.body) 168 169 return error_message
The base exception class for all OpenAPIExceptions
107 def __init__( 108 self, 109 status=None, 110 reason=None, 111 http_resp=None, 112 *, 113 body: Optional[str] = None, 114 data: Optional[Any] = None, 115 ) -> None: 116 self.status = status 117 self.reason = reason 118 self.body = body 119 self.data = data 120 self.headers = None 121 122 if http_resp: 123 if self.status is None: 124 self.status = http_resp.status 125 if self.reason is None: 126 self.reason = http_resp.reason 127 if self.body is None: 128 try: 129 self.body = http_resp.data.decode('utf-8') 130 except Exception: 131 pass 132 self.headers = http_resp.getheaders()
134 @classmethod 135 def from_response( 136 cls, 137 *, 138 http_resp, 139 body: Optional[str], 140 data: Optional[Any], 141 ) -> Self: 142 if http_resp.status == 400: 143 raise BadRequestException(http_resp=http_resp, body=body, data=data) 144 145 if http_resp.status == 401: 146 raise UnauthorizedException(http_resp=http_resp, body=body, data=data) 147 148 if http_resp.status == 403: 149 raise ForbiddenException(http_resp=http_resp, body=body, data=data) 150 151 if http_resp.status == 404: 152 raise NotFoundException(http_resp=http_resp, body=body, data=data) 153 154 if 500 <= http_resp.status <= 599: 155 raise ServiceException(http_resp=http_resp, body=body, data=data) 156 raise ApiException(http_resp=http_resp, body=body, data=data)