lighter-sdk 0.1.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. lighter/__init__.py +140 -0
  2. lighter/api/__init__.py +11 -0
  3. lighter/api/account_api.py +2371 -0
  4. lighter/api/block_api.py +863 -0
  5. lighter/api/candlestick_api.py +718 -0
  6. lighter/api/info_api.py +282 -0
  7. lighter/api/order_api.py +2734 -0
  8. lighter/api/root_api.py +529 -0
  9. lighter/api/transaction_api.py +3525 -0
  10. lighter/api_client.py +784 -0
  11. lighter/api_response.py +21 -0
  12. lighter/configuration.py +475 -0
  13. lighter/exceptions.py +199 -0
  14. lighter/models/__init__.py +112 -0
  15. lighter/models/account.py +110 -0
  16. lighter/models/account_api_keys.py +104 -0
  17. lighter/models/account_market_stats.py +98 -0
  18. lighter/models/account_metadata.py +94 -0
  19. lighter/models/account_pn_l.py +106 -0
  20. lighter/models/account_position.py +112 -0
  21. lighter/models/account_stats.py +102 -0
  22. lighter/models/accounts.py +106 -0
  23. lighter/models/api_key.py +98 -0
  24. lighter/models/block.py +124 -0
  25. lighter/models/blocks.py +106 -0
  26. lighter/models/bridge_supported_network.py +96 -0
  27. lighter/models/candlestick.py +106 -0
  28. lighter/models/candlesticks.py +106 -0
  29. lighter/models/contract_address.py +94 -0
  30. lighter/models/current_height.py +96 -0
  31. lighter/models/cursor.py +92 -0
  32. lighter/models/deposit_history.py +106 -0
  33. lighter/models/deposit_history_item.py +105 -0
  34. lighter/models/detailed_account.py +152 -0
  35. lighter/models/detailed_accounts.py +106 -0
  36. lighter/models/detailed_candlestick.py +108 -0
  37. lighter/models/enriched_tx.py +129 -0
  38. lighter/models/exchange_stats.py +110 -0
  39. lighter/models/fee_bucket.py +96 -0
  40. lighter/models/funding.py +98 -0
  41. lighter/models/fundings.py +106 -0
  42. lighter/models/is_whitelisted.py +98 -0
  43. lighter/models/l1_provider_info.py +98 -0
  44. lighter/models/layer2_basic_info.py +100 -0
  45. lighter/models/liquidation.py +100 -0
  46. lighter/models/market_info.py +116 -0
  47. lighter/models/next_nonce.py +96 -0
  48. lighter/models/order.py +159 -0
  49. lighter/models/order_book.py +119 -0
  50. lighter/models/order_book_depth.py +115 -0
  51. lighter/models/order_book_detail.py +151 -0
  52. lighter/models/order_book_details.py +104 -0
  53. lighter/models/order_book_orders.py +117 -0
  54. lighter/models/order_book_stats.py +102 -0
  55. lighter/models/order_books.py +104 -0
  56. lighter/models/orders.py +106 -0
  57. lighter/models/pn_l_entry.py +94 -0
  58. lighter/models/position_funding.py +111 -0
  59. lighter/models/price_level.py +94 -0
  60. lighter/models/public_pool.py +128 -0
  61. lighter/models/public_pool_info.py +100 -0
  62. lighter/models/public_pool_share.py +96 -0
  63. lighter/models/public_pools.py +106 -0
  64. lighter/models/req_get_account.py +101 -0
  65. lighter/models/req_get_account_active_orders.py +96 -0
  66. lighter/models/req_get_account_api_keys.py +94 -0
  67. lighter/models/req_get_account_by_l1_address.py +92 -0
  68. lighter/models/req_get_account_inactive_orders.py +103 -0
  69. lighter/models/req_get_account_orders.py +99 -0
  70. lighter/models/req_get_account_pending_txs.py +106 -0
  71. lighter/models/req_get_account_pn_l.py +118 -0
  72. lighter/models/req_get_account_txs.py +111 -0
  73. lighter/models/req_get_block.py +101 -0
  74. lighter/models/req_get_block_txs.py +101 -0
  75. lighter/models/req_get_by_account.py +101 -0
  76. lighter/models/req_get_candlesticks.py +109 -0
  77. lighter/models/req_get_deposit_history.py +106 -0
  78. lighter/models/req_get_fee_bucket.py +92 -0
  79. lighter/models/req_get_fundings.py +107 -0
  80. lighter/models/req_get_l1_tx.py +92 -0
  81. lighter/models/req_get_latest_deposit.py +92 -0
  82. lighter/models/req_get_next_nonce.py +94 -0
  83. lighter/models/req_get_order_book_details.py +92 -0
  84. lighter/models/req_get_order_book_orders.py +95 -0
  85. lighter/models/req_get_order_books.py +92 -0
  86. lighter/models/req_get_public_pools.py +109 -0
  87. lighter/models/req_get_range_with_cursor.py +95 -0
  88. lighter/models/req_get_range_with_index.py +95 -0
  89. lighter/models/req_get_range_with_index_sortable.py +107 -0
  90. lighter/models/req_get_recent_trades.py +95 -0
  91. lighter/models/req_get_trades.py +126 -0
  92. lighter/models/req_get_tx.py +101 -0
  93. lighter/models/req_get_withdraw_history.py +106 -0
  94. lighter/models/req_is_whitelisted.py +92 -0
  95. lighter/models/result_code.py +94 -0
  96. lighter/models/simple_order.py +102 -0
  97. lighter/models/status.py +94 -0
  98. lighter/models/sub_accounts.py +106 -0
  99. lighter/models/ticker.py +103 -0
  100. lighter/models/trade.py +125 -0
  101. lighter/models/trades.py +106 -0
  102. lighter/models/tx.py +121 -0
  103. lighter/models/tx_hash.py +96 -0
  104. lighter/models/tx_hashes.py +96 -0
  105. lighter/models/txs.py +104 -0
  106. lighter/models/validator_info.py +94 -0
  107. lighter/models/withdraw_history.py +110 -0
  108. lighter/models/withdraw_history_cursor.py +94 -0
  109. lighter/models/withdraw_history_item.py +114 -0
  110. lighter/models/zk_lighter_info.py +92 -0
  111. lighter/py.typed +0 -0
  112. lighter/rest.py +215 -0
  113. lighter/signer_client.py +440 -0
  114. lighter/signers/signer-amd64.so +0 -0
  115. lighter/signers/signer-arm64.dylib +0 -0
  116. lighter/transactions/__init__.py +3 -0
  117. lighter/transactions/cancel_order.py +27 -0
  118. lighter/transactions/create_order.py +33 -0
  119. lighter/transactions/withdraw.py +25 -0
  120. lighter/ws_client.py +160 -0
  121. lighter_sdk-0.1.0.dist-info/LICENSE +201 -0
  122. lighter_sdk-0.1.0.dist-info/METADATA +26 -0
  123. lighter_sdk-0.1.0.dist-info/RECORD +125 -0
  124. lighter_sdk-0.1.0.dist-info/WHEEL +5 -0
  125. lighter_sdk-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ """API response object."""
2
+
3
+ from __future__ import annotations
4
+ from typing import Optional, Generic, Mapping, TypeVar
5
+ from pydantic import Field, StrictInt, StrictBytes, BaseModel
6
+
7
+ T = TypeVar("T")
8
+
9
+ class ApiResponse(BaseModel, Generic[T]):
10
+ """
11
+ API response object
12
+ """
13
+
14
+ status_code: StrictInt = Field(description="HTTP status code")
15
+ headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers")
16
+ data: T = Field(description="Deserialized data given the data type")
17
+ raw_data: StrictBytes = Field(description="Raw data (HTTP response body)")
18
+
19
+ model_config = {
20
+ "arbitrary_types_allowed": True
21
+ }
@@ -0,0 +1,475 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document:
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ import copy
16
+ import logging
17
+ from logging import FileHandler
18
+ import sys
19
+ from typing import Optional
20
+ import urllib3
21
+
22
+ import http.client as httplib
23
+
24
+ JSON_SCHEMA_VALIDATION_KEYWORDS = {
25
+ 'multipleOf', 'maximum', 'exclusiveMaximum',
26
+ 'minimum', 'exclusiveMinimum', 'maxLength',
27
+ 'minLength', 'pattern', 'maxItems', 'minItems'
28
+ }
29
+
30
+ class Configuration:
31
+ """This class contains various settings of the API client.
32
+
33
+ :param host: Base url.
34
+ :param ignore_operation_servers
35
+ Boolean to ignore operation servers for the API client.
36
+ Config will use `host` as the base url regardless of the operation servers.
37
+ :param api_key: Dict to store API key(s).
38
+ Each entry in the dict specifies an API key.
39
+ The dict key is the name of the security scheme in the OAS specification.
40
+ The dict value is the API key secret.
41
+ :param api_key_prefix: Dict to store API prefix (e.g. Bearer).
42
+ The dict key is the name of the security scheme in the OAS specification.
43
+ The dict value is an API key prefix when generating the auth data.
44
+ :param username: Username for HTTP basic authentication.
45
+ :param password: Password for HTTP basic authentication.
46
+ :param access_token: Access token.
47
+ :param server_index: Index to servers configuration.
48
+ :param server_variables: Mapping with string values to replace variables in
49
+ templated server configuration. The validation of enums is performed for
50
+ variables with defined enum values before.
51
+ :param server_operation_index: Mapping from operation ID to an index to server
52
+ configuration.
53
+ :param server_operation_variables: Mapping from operation ID to a mapping with
54
+ string values to replace variables in templated server configuration.
55
+ The validation of enums is performed for variables with defined enum
56
+ values before.
57
+ :param ssl_ca_cert: str - the path to a file of concatenated CA certificates
58
+ in PEM format.
59
+ :param retries: Number of retries for API requests.
60
+
61
+ :Example:
62
+
63
+ API Key Authentication Example.
64
+ Given the following security scheme in the OpenAPI specification:
65
+ components:
66
+ securitySchemes:
67
+ cookieAuth: # name for the security scheme
68
+ type: apiKey
69
+ in: cookie
70
+ name: JSESSIONID # cookie name
71
+
72
+ You can programmatically set the cookie:
73
+
74
+ conf = lighter.Configuration(
75
+ api_key={'cookieAuth': 'abc123'}
76
+ api_key_prefix={'cookieAuth': 'JSESSIONID'}
77
+ )
78
+
79
+ The following cookie will be added to the HTTP request:
80
+ Cookie: JSESSIONID abc123
81
+ """
82
+
83
+ _default = None
84
+
85
+ def __init__(self, host=None,
86
+ api_key=None, api_key_prefix=None,
87
+ username=None, password=None,
88
+ access_token=None,
89
+ server_index=None, server_variables=None,
90
+ server_operation_index=None, server_operation_variables=None,
91
+ ignore_operation_servers=False,
92
+ ssl_ca_cert=None,
93
+ retries=None,
94
+ *,
95
+ debug: Optional[bool] = None
96
+ ) -> None:
97
+ """Constructor
98
+ """
99
+ self._base_path = "https://mainnet.zklighter.elliot.ai" if host is None else host
100
+ """Default Base url
101
+ """
102
+ self.server_index = 0 if server_index is None and host is None else server_index
103
+ self.server_operation_index = server_operation_index or {}
104
+ """Default server index
105
+ """
106
+ self.server_variables = server_variables or {}
107
+ self.server_operation_variables = server_operation_variables or {}
108
+ """Default server variables
109
+ """
110
+ self.ignore_operation_servers = ignore_operation_servers
111
+ """Ignore operation servers
112
+ """
113
+ self.temp_folder_path = None
114
+ """Temp file folder for downloading files
115
+ """
116
+ # Authentication Settings
117
+ self.api_key = {}
118
+ if api_key:
119
+ self.api_key = api_key
120
+ """dict to store API key(s)
121
+ """
122
+ self.api_key_prefix = {}
123
+ if api_key_prefix:
124
+ self.api_key_prefix = api_key_prefix
125
+ """dict to store API prefix (e.g. Bearer)
126
+ """
127
+ self.refresh_api_key_hook = None
128
+ """function hook to refresh API key if expired
129
+ """
130
+ self.username = username
131
+ """Username for HTTP basic authentication
132
+ """
133
+ self.password = password
134
+ """Password for HTTP basic authentication
135
+ """
136
+ self.access_token = access_token
137
+ """Access token
138
+ """
139
+ self.logger = {}
140
+ """Logging Settings
141
+ """
142
+ self.logger["package_logger"] = logging.getLogger("lighter")
143
+ self.logger["urllib3_logger"] = logging.getLogger("urllib3")
144
+ self.logger_format = '%(asctime)s %(levelname)s %(message)s'
145
+ """Log format
146
+ """
147
+ self.logger_stream_handler = None
148
+ """Log stream handler
149
+ """
150
+ self.logger_file_handler: Optional[FileHandler] = None
151
+ """Log file handler
152
+ """
153
+ self.logger_file = None
154
+ """Debug file location
155
+ """
156
+ if debug is not None:
157
+ self.debug = debug
158
+ else:
159
+ self.__debug = False
160
+ """Debug switch
161
+ """
162
+
163
+ self.verify_ssl = True
164
+ """SSL/TLS verification
165
+ Set this to false to skip verifying SSL certificate when calling API
166
+ from https server.
167
+ """
168
+ self.ssl_ca_cert = ssl_ca_cert
169
+ """Set this to customize the certificate file to verify the peer.
170
+ """
171
+ self.cert_file = None
172
+ """client certificate file
173
+ """
174
+ self.key_file = None
175
+ """client key file
176
+ """
177
+ self.assert_hostname = None
178
+ """Set this to True/False to enable/disable SSL hostname verification.
179
+ """
180
+ self.tls_server_name = None
181
+ """SSL/TLS Server Name Indication (SNI)
182
+ Set this to the SNI value expected by the server.
183
+ """
184
+
185
+ self.connection_pool_maxsize = 100
186
+ """This value is passed to the aiohttp to limit simultaneous connections.
187
+ Default values is 100, None means no-limit.
188
+ """
189
+
190
+ self.proxy: Optional[str] = None
191
+ """Proxy URL
192
+ """
193
+ self.proxy_headers = None
194
+ """Proxy headers
195
+ """
196
+ self.safe_chars_for_path_param = ''
197
+ """Safe chars for path_param
198
+ """
199
+ self.retries = retries
200
+ """Adding retries to override urllib3 default value 3
201
+ """
202
+ # Enable client side validation
203
+ self.client_side_validation = True
204
+
205
+ self.socket_options = None
206
+ """Options to pass down to the underlying urllib3 socket
207
+ """
208
+
209
+ self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z"
210
+ """datetime format
211
+ """
212
+
213
+ self.date_format = "%Y-%m-%d"
214
+ """date format
215
+ """
216
+
217
+ def __deepcopy__(self, memo):
218
+ cls = self.__class__
219
+ result = cls.__new__(cls)
220
+ memo[id(self)] = result
221
+ for k, v in self.__dict__.items():
222
+ if k not in ('logger', 'logger_file_handler'):
223
+ setattr(result, k, copy.deepcopy(v, memo))
224
+ # shallow copy of loggers
225
+ result.logger = copy.copy(self.logger)
226
+ # use setters to configure loggers
227
+ result.logger_file = self.logger_file
228
+ result.debug = self.debug
229
+ return result
230
+
231
+ def __setattr__(self, name, value):
232
+ object.__setattr__(self, name, value)
233
+
234
+ @classmethod
235
+ def set_default(cls, default):
236
+ """Set default instance of configuration.
237
+
238
+ It stores default configuration, which can be
239
+ returned by get_default_copy method.
240
+
241
+ :param default: object of Configuration
242
+ """
243
+ cls._default = default
244
+
245
+ @classmethod
246
+ def get_default_copy(cls):
247
+ """Deprecated. Please use `get_default` instead.
248
+
249
+ Deprecated. Please use `get_default` instead.
250
+
251
+ :return: The configuration object.
252
+ """
253
+ return cls.get_default()
254
+
255
+ @classmethod
256
+ def get_default(cls):
257
+ """Return the default configuration.
258
+
259
+ This method returns newly created, based on default constructor,
260
+ object of Configuration class or returns a copy of default
261
+ configuration.
262
+
263
+ :return: The configuration object.
264
+ """
265
+ if cls._default is None:
266
+ cls._default = Configuration()
267
+ return cls._default
268
+
269
+ @property
270
+ def logger_file(self):
271
+ """The logger file.
272
+
273
+ If the logger_file is None, then add stream handler and remove file
274
+ handler. Otherwise, add file handler and remove stream handler.
275
+
276
+ :param value: The logger_file path.
277
+ :type: str
278
+ """
279
+ return self.__logger_file
280
+
281
+ @logger_file.setter
282
+ def logger_file(self, value):
283
+ """The logger file.
284
+
285
+ If the logger_file is None, then add stream handler and remove file
286
+ handler. Otherwise, add file handler and remove stream handler.
287
+
288
+ :param value: The logger_file path.
289
+ :type: str
290
+ """
291
+ self.__logger_file = value
292
+ if self.__logger_file:
293
+ # If set logging file,
294
+ # then add file handler and remove stream handler.
295
+ self.logger_file_handler = logging.FileHandler(self.__logger_file)
296
+ self.logger_file_handler.setFormatter(self.logger_formatter)
297
+ for _, logger in self.logger.items():
298
+ logger.addHandler(self.logger_file_handler)
299
+
300
+ @property
301
+ def debug(self):
302
+ """Debug status
303
+
304
+ :param value: The debug status, True or False.
305
+ :type: bool
306
+ """
307
+ return self.__debug
308
+
309
+ @debug.setter
310
+ def debug(self, value):
311
+ """Debug status
312
+
313
+ :param value: The debug status, True or False.
314
+ :type: bool
315
+ """
316
+ self.__debug = value
317
+ if self.__debug:
318
+ # if debug status is True, turn on debug logging
319
+ for _, logger in self.logger.items():
320
+ logger.setLevel(logging.DEBUG)
321
+ # turn on httplib debug
322
+ httplib.HTTPConnection.debuglevel = 1
323
+ else:
324
+ # if debug status is False, turn off debug logging,
325
+ # setting log level to default `logging.WARNING`
326
+ for _, logger in self.logger.items():
327
+ logger.setLevel(logging.WARNING)
328
+ # turn off httplib debug
329
+ httplib.HTTPConnection.debuglevel = 0
330
+
331
+ @property
332
+ def logger_format(self):
333
+ """The logger format.
334
+
335
+ The logger_formatter will be updated when sets logger_format.
336
+
337
+ :param value: The format string.
338
+ :type: str
339
+ """
340
+ return self.__logger_format
341
+
342
+ @logger_format.setter
343
+ def logger_format(self, value):
344
+ """The logger format.
345
+
346
+ The logger_formatter will be updated when sets logger_format.
347
+
348
+ :param value: The format string.
349
+ :type: str
350
+ """
351
+ self.__logger_format = value
352
+ self.logger_formatter = logging.Formatter(self.__logger_format)
353
+
354
+ def get_api_key_with_prefix(self, identifier, alias=None):
355
+ """Gets API key (with prefix if set).
356
+
357
+ :param identifier: The identifier of apiKey.
358
+ :param alias: The alternative identifier of apiKey.
359
+ :return: The token for api key authentication.
360
+ """
361
+ if self.refresh_api_key_hook is not None:
362
+ self.refresh_api_key_hook(self)
363
+ key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None)
364
+ if key:
365
+ prefix = self.api_key_prefix.get(identifier)
366
+ if prefix:
367
+ return "%s %s" % (prefix, key)
368
+ else:
369
+ return key
370
+
371
+ def get_basic_auth_token(self):
372
+ """Gets HTTP basic authentication header (string).
373
+
374
+ :return: The token for basic HTTP authentication.
375
+ """
376
+ username = ""
377
+ if self.username is not None:
378
+ username = self.username
379
+ password = ""
380
+ if self.password is not None:
381
+ password = self.password
382
+ return urllib3.util.make_headers(
383
+ basic_auth=username + ':' + password
384
+ ).get('authorization')
385
+
386
+ def auth_settings(self):
387
+ """Gets Auth Settings dict for api client.
388
+
389
+ :return: The Auth Settings information dict.
390
+ """
391
+ auth = {}
392
+ if 'apiKey' in self.api_key:
393
+ auth['apiKey'] = {
394
+ 'type': 'api_key',
395
+ 'in': 'header',
396
+ 'key': 'Authorization',
397
+ 'value': self.get_api_key_with_prefix(
398
+ 'apiKey',
399
+ ),
400
+ }
401
+ return auth
402
+
403
+ def to_debug_report(self):
404
+ """Gets the essential information for debugging.
405
+
406
+ :return: The report for debugging.
407
+ """
408
+ return "Python SDK Debug Report:\n"\
409
+ "OS: {env}\n"\
410
+ "Python Version: {pyversion}\n"\
411
+ "Version of the API: \n"\
412
+ "SDK Package Version: 1.0.0".\
413
+ format(env=sys.platform, pyversion=sys.version)
414
+
415
+ def get_host_settings(self):
416
+ """Gets an array of host settings
417
+
418
+ :return: An array of host settings
419
+ """
420
+ return [
421
+ {
422
+ 'url': "https://mainnet.zklighter.elliot.ai",
423
+ 'description': "No description provided",
424
+ }
425
+ ]
426
+
427
+ def get_host_from_settings(self, index, variables=None, servers=None):
428
+ """Gets host URL based on the index and variables
429
+ :param index: array index of the host settings
430
+ :param variables: hash of variable and the corresponding value
431
+ :param servers: an array of host settings or None
432
+ :return: URL based on host settings
433
+ """
434
+ if index is None:
435
+ return self._base_path
436
+
437
+ variables = {} if variables is None else variables
438
+ servers = self.get_host_settings() if servers is None else servers
439
+
440
+ try:
441
+ server = servers[index]
442
+ except IndexError:
443
+ raise ValueError(
444
+ "Invalid index {0} when selecting the host settings. "
445
+ "Must be less than {1}".format(index, len(servers)))
446
+
447
+ url = server['url']
448
+
449
+ # go through variables and replace placeholders
450
+ for variable_name, variable in server.get('variables', {}).items():
451
+ used_value = variables.get(
452
+ variable_name, variable['default_value'])
453
+
454
+ if 'enum_values' in variable \
455
+ and used_value not in variable['enum_values']:
456
+ raise ValueError(
457
+ "The variable `{0}` in the host URL has invalid value "
458
+ "{1}. Must be {2}.".format(
459
+ variable_name, variables[variable_name],
460
+ variable['enum_values']))
461
+
462
+ url = url.replace("{" + variable_name + "}", used_value)
463
+
464
+ return url
465
+
466
+ @property
467
+ def host(self):
468
+ """Return generated host."""
469
+ return self.get_host_from_settings(self.server_index, variables=self.server_variables)
470
+
471
+ @host.setter
472
+ def host(self, value):
473
+ """Fix base path."""
474
+ self._base_path = value
475
+ self.server_index = None
lighter/exceptions.py ADDED
@@ -0,0 +1,199 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+
5
+
6
+ No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
+
8
+ The version of the OpenAPI document:
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+ from typing import Any, Optional
15
+ from typing_extensions import Self
16
+
17
+ class OpenApiException(Exception):
18
+ """The base exception class for all OpenAPIExceptions"""
19
+
20
+
21
+ class ApiTypeError(OpenApiException, TypeError):
22
+ def __init__(self, msg, path_to_item=None, valid_classes=None,
23
+ key_type=None) -> None:
24
+ """ Raises an exception for TypeErrors
25
+
26
+ Args:
27
+ msg (str): the exception message
28
+
29
+ Keyword Args:
30
+ path_to_item (list): a list of keys an indices to get to the
31
+ current_item
32
+ None if unset
33
+ valid_classes (tuple): the primitive classes that current item
34
+ should be an instance of
35
+ None if unset
36
+ key_type (bool): False if our value is a value in a dict
37
+ True if it is a key in a dict
38
+ False if our item is an item in a list
39
+ None if unset
40
+ """
41
+ self.path_to_item = path_to_item
42
+ self.valid_classes = valid_classes
43
+ self.key_type = key_type
44
+ full_msg = msg
45
+ if path_to_item:
46
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
47
+ super(ApiTypeError, self).__init__(full_msg)
48
+
49
+
50
+ class ApiValueError(OpenApiException, ValueError):
51
+ def __init__(self, msg, path_to_item=None) -> None:
52
+ """
53
+ Args:
54
+ msg (str): the exception message
55
+
56
+ Keyword Args:
57
+ path_to_item (list) the path to the exception in the
58
+ received_data dict. None if unset
59
+ """
60
+
61
+ self.path_to_item = path_to_item
62
+ full_msg = msg
63
+ if path_to_item:
64
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
65
+ super(ApiValueError, self).__init__(full_msg)
66
+
67
+
68
+ class ApiAttributeError(OpenApiException, AttributeError):
69
+ def __init__(self, msg, path_to_item=None) -> None:
70
+ """
71
+ Raised when an attribute reference or assignment fails.
72
+
73
+ Args:
74
+ msg (str): the exception message
75
+
76
+ Keyword Args:
77
+ path_to_item (None/list) the path to the exception in the
78
+ received_data dict
79
+ """
80
+ self.path_to_item = path_to_item
81
+ full_msg = msg
82
+ if path_to_item:
83
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
84
+ super(ApiAttributeError, self).__init__(full_msg)
85
+
86
+
87
+ class ApiKeyError(OpenApiException, KeyError):
88
+ def __init__(self, msg, path_to_item=None) -> None:
89
+ """
90
+ Args:
91
+ msg (str): the exception message
92
+
93
+ Keyword Args:
94
+ path_to_item (None/list) the path to the exception in the
95
+ received_data dict
96
+ """
97
+ self.path_to_item = path_to_item
98
+ full_msg = msg
99
+ if path_to_item:
100
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
101
+ super(ApiKeyError, self).__init__(full_msg)
102
+
103
+
104
+ class ApiException(OpenApiException):
105
+
106
+ def __init__(
107
+ self,
108
+ status=None,
109
+ reason=None,
110
+ http_resp=None,
111
+ *,
112
+ body: Optional[str] = None,
113
+ data: Optional[Any] = None,
114
+ ) -> None:
115
+ self.status = status
116
+ self.reason = reason
117
+ self.body = body
118
+ self.data = data
119
+ self.headers = None
120
+
121
+ if http_resp:
122
+ if self.status is None:
123
+ self.status = http_resp.status
124
+ if self.reason is None:
125
+ self.reason = http_resp.reason
126
+ if self.body is None:
127
+ try:
128
+ self.body = http_resp.data.decode('utf-8')
129
+ except Exception:
130
+ pass
131
+ self.headers = http_resp.getheaders()
132
+
133
+ @classmethod
134
+ def from_response(
135
+ cls,
136
+ *,
137
+ http_resp,
138
+ body: Optional[str],
139
+ data: Optional[Any],
140
+ ) -> Self:
141
+ if http_resp.status == 400:
142
+ raise BadRequestException(http_resp=http_resp, body=body, data=data)
143
+
144
+ if http_resp.status == 401:
145
+ raise UnauthorizedException(http_resp=http_resp, body=body, data=data)
146
+
147
+ if http_resp.status == 403:
148
+ raise ForbiddenException(http_resp=http_resp, body=body, data=data)
149
+
150
+ if http_resp.status == 404:
151
+ raise NotFoundException(http_resp=http_resp, body=body, data=data)
152
+
153
+ if 500 <= http_resp.status <= 599:
154
+ raise ServiceException(http_resp=http_resp, body=body, data=data)
155
+ raise ApiException(http_resp=http_resp, body=body, data=data)
156
+
157
+ def __str__(self):
158
+ """Custom error messages for exception"""
159
+ error_message = "({0})\n"\
160
+ "Reason: {1}\n".format(self.status, self.reason)
161
+ if self.headers:
162
+ error_message += "HTTP response headers: {0}\n".format(
163
+ self.headers)
164
+
165
+ if self.data or self.body:
166
+ error_message += "HTTP response body: {0}\n".format(self.data or self.body)
167
+
168
+ return error_message
169
+
170
+
171
+ class BadRequestException(ApiException):
172
+ pass
173
+
174
+
175
+ class NotFoundException(ApiException):
176
+ pass
177
+
178
+
179
+ class UnauthorizedException(ApiException):
180
+ pass
181
+
182
+
183
+ class ForbiddenException(ApiException):
184
+ pass
185
+
186
+
187
+ class ServiceException(ApiException):
188
+ pass
189
+
190
+
191
+ def render_path(path_to_item):
192
+ """Returns a string representation of a path"""
193
+ result = ""
194
+ for pth in path_to_item:
195
+ if isinstance(pth, int):
196
+ result += "[{0}]".format(pth)
197
+ else:
198
+ result += "['{0}']".format(pth)
199
+ return result