kiba-core 0.5.3.dev45__tar.gz → 0.5.3.dev47__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/CHANGELOG.md +1 -0
  2. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/PKG-INFO +2 -2
  3. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/middleware/exception_handling_middleware.py +8 -2
  4. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/exceptions.py +61 -61
  5. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/file_util.py +2 -2
  6. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/web3/eth_client.py +15 -10
  7. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/kiba_core.egg-info/PKG-INFO +2 -2
  8. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/pyproject.toml +2 -3
  9. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/web3/test_rest_eth_client.py +113 -0
  10. kiba_core-0.5.3.dev47/uv.lock +3050 -0
  11. kiba_core-0.5.3.dev45/uv.lock +0 -2453
  12. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/.github/pull_request_template.md +0 -0
  13. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/.github/workflows/deploy.yml +0 -0
  14. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/.github/workflows/pull-request.yml +0 -0
  15. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/.github/workflows/release.yml +0 -0
  16. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/.gitignore +0 -0
  17. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/Dockerfile +0 -0
  18. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/README.md +0 -0
  19. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/__init__.py +0 -0
  20. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/__init__.py +0 -0
  21. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/api_request.py +0 -0
  22. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/api_response.py +0 -0
  23. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/authorizer.py +0 -0
  24. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/default_routes.py +0 -0
  25. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/health.py +0 -0
  26. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/json_route.py +0 -0
  27. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/middleware/__init__.py +0 -0
  28. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/middleware/database_connection_middleware.py +0 -0
  29. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/middleware/logging_middleware.py +0 -0
  30. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/middleware/server_headers_middleware.py +0 -0
  31. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/api/streaming_json_route.py +0 -0
  32. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/aws_requester.py +0 -0
  33. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/caching/__init__.py +0 -0
  34. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/caching/cache.py +0 -0
  35. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/caching/dict_cache.py +0 -0
  36. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/caching/file_cache.py +0 -0
  37. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/http/__init__.py +0 -0
  38. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/http/basic_authentication.py +0 -0
  39. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/http/jwt.py +0 -0
  40. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/http/rest_method.py +0 -0
  41. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/logging.py +0 -0
  42. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/notifications/__init__.py +0 -0
  43. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/notifications/discord_client.py +0 -0
  44. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/notifications/notification_client.py +0 -0
  45. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/notifications/slack_client.py +0 -0
  46. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/py.typed +0 -0
  47. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/queues/__init__.py +0 -0
  48. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/queues/aqs.py +0 -0
  49. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/queues/message_queue.py +0 -0
  50. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/queues/message_queue_processor.py +0 -0
  51. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/queues/model.py +0 -0
  52. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/queues/sqs.py +0 -0
  53. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/requester/__init__.py +0 -0
  54. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/requester/requester.py +0 -0
  55. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/s3_manager.py +0 -0
  56. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/service_client.py +0 -0
  57. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/store/__init__.py +0 -0
  58. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/store/database.py +0 -0
  59. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/store/retriever.py +0 -0
  60. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/store/saver.py +0 -0
  61. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/__init__.py +0 -0
  62. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/async_util.py +0 -0
  63. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/chain_util.py +0 -0
  64. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/date_util.py +0 -0
  65. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/dict_util.py +0 -0
  66. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/hashing_util.py +0 -0
  67. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/http_util.py +0 -0
  68. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/json_util.py +0 -0
  69. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/list_util.py +0 -0
  70. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/string_util.py +0 -0
  71. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/typing_util.py +0 -0
  72. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/url_util.py +0 -0
  73. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/util/value_holder.py +0 -0
  74. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/web3/__init__.py +0 -0
  75. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/core/web3/multicall3.py +0 -0
  76. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/kiba_core.egg-info/SOURCES.txt +0 -0
  77. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/kiba_core.egg-info/dependency_links.txt +0 -0
  78. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/kiba_core.egg-info/requires.txt +0 -0
  79. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/kiba_core.egg-info/top_level.txt +0 -0
  80. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/makefile +0 -0
  81. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/setup.cfg +0 -0
  82. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/__init__.py +0 -0
  83. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/api/test_json_route.py +0 -0
  84. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/api/test_streaming_json_route.py +0 -0
  85. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/caching/test_dict_cache.py +0 -0
  86. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/caching/test_file_cache.py +0 -0
  87. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/__init__.py +0 -0
  88. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_async_util.py +0 -0
  89. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_chain_util.py +0 -0
  90. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_date_util.py +0 -0
  91. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_dict_util.py +0 -0
  92. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_file_util.py +0 -0
  93. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_json_util.py +0 -0
  94. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_list_util.py +0 -0
  95. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_string_util.py +0 -0
  96. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/util/test_url_util.py +0 -0
  97. {kiba_core-0.5.3.dev45 → kiba_core-0.5.3.dev47}/tests/web3/__init__.py +0 -0
@@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
31
31
  - [MAJOR] Added `chainId` to `EthClientInterface`
32
32
  - [MINOR] Added `call` and `multicall` to `EthClientInterface`
33
33
  - [MINOR] Truncate discord notification messages to fit api
34
+ - [MINOR] Added `blockNumber` to `EthClient.multicall` function
34
35
 
35
36
  ### Changed
36
37
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kiba-core
3
- Version: 0.5.3.dev45
3
+ Version: 0.5.3.dev47
4
4
  Summary: Kiba Labs' python utilities
5
5
  Project-URL: repository, https://github.com/kibalabs/core-py
6
- Requires-Python: ~=3.12
6
+ Requires-Python: <4,>=3.12
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: aiofiles>=24.1.0
9
9
  Requires-Dist: pydantic>=2.11.7
@@ -12,9 +12,10 @@ from core.exceptions import RedirectException
12
12
 
13
13
 
14
14
  class ExceptionHandlingMiddleware(BaseHTTPMiddleware):
15
- def __init__(self, app: ASGIApp, shouldSquashClientExceptions: bool = True) -> None:
15
+ def __init__(self, app: ASGIApp, shouldSquashClientExceptions: bool = True, shouldHideInternalErrors: bool = True) -> None:
16
16
  super().__init__(app=app)
17
17
  self.shouldSquashClientExceptions = shouldSquashClientExceptions
18
+ self.shouldHideInternalErrors = shouldHideInternalErrors
18
19
 
19
20
  @staticmethod
20
21
  def _convert_exception(exception: KibaException) -> Response:
@@ -38,8 +39,13 @@ class ExceptionHandlingMiddleware(BaseHTTPMiddleware):
38
39
  response = self._convert_exception(exception=exception)
39
40
  except KibaException as exception:
40
41
  logging.exception(exception)
42
+ if self.shouldHideInternalErrors:
43
+ exception = KibaException(message='Internal Server Error', statusCode=exception.statusCode, exceptionType=exception.exceptionType)
41
44
  response = self._convert_exception(exception=exception)
42
45
  except Exception as exception: # noqa: BLE001
43
46
  logging.exception(exception)
44
- response = self._convert_exception(exception=KibaException.from_exception(exception=exception))
47
+ kibaException = KibaException.from_exception(exception=exception)
48
+ if self.shouldHideInternalErrors:
49
+ kibaException = KibaException(message='Internal Server Error', statusCode=kibaException.statusCode)
50
+ response = self._convert_exception(exception=kibaException)
45
51
  return response
@@ -10,7 +10,7 @@ class KibaException(Exception): # noqa: N818
10
10
  super().__init__(message)
11
11
  self.message = message
12
12
  self.statusCode = statusCode or 500
13
- self.exceptionType = exceptionType if exceptionType else self.__class__.__name__
13
+ self.exceptionType = exceptionType or self.__class__.__name__
14
14
 
15
15
  @staticmethod
16
16
  def from_exception(exception: Exception, statusCode: int = 500) -> KibaException:
@@ -45,205 +45,205 @@ class ClientException(KibaException):
45
45
 
46
46
  class BadRequestException(ClientException):
47
47
  def __init__(self, message: str | None = None) -> None:
48
- message = message if message else 'Bad Request'
48
+ message = message or 'Bad Request'
49
49
  super().__init__(message=message, statusCode=400)
50
50
 
51
51
 
52
52
  class UnauthorizedException(ClientException):
53
53
  def __init__(self, message: str | None = None) -> None:
54
- message = message if message else 'Unauthorized'
54
+ message = message or 'Unauthorized'
55
55
  super().__init__(message=message, statusCode=401)
56
56
 
57
57
 
58
58
  class PaymentRequiredException(ClientException):
59
59
  def __init__(self, message: str | None = None) -> None:
60
- message = message if message else 'Payment Required'
60
+ message = message or 'Payment Required'
61
61
  super().__init__(message=message, statusCode=402)
62
62
 
63
63
 
64
64
  class ForbiddenException(ClientException):
65
65
  def __init__(self, message: str | None = None) -> None:
66
- message = message if message else 'Forbidden'
66
+ message = message or 'Forbidden'
67
67
  super().__init__(message=message, statusCode=403)
68
68
 
69
69
 
70
70
  class NotFoundException(ClientException):
71
71
  def __init__(self, message: str | None = None) -> None:
72
- message = message if message else 'Not Found'
72
+ message = message or 'Not Found'
73
73
  super().__init__(message=message, statusCode=404)
74
74
 
75
75
 
76
76
  class MethodNotAllowedException(ClientException):
77
77
  def __init__(self, message: str | None = None) -> None:
78
- message = message if message else 'Method Not Allowed'
78
+ message = message or 'Method Not Allowed'
79
79
  super().__init__(message=message, statusCode=405)
80
80
 
81
81
 
82
82
  class NotAcceptableException(ClientException):
83
83
  def __init__(self, message: str | None = None) -> None:
84
- message = message if message else 'Not Acceptable'
84
+ message = message or 'Not Acceptable'
85
85
  super().__init__(message=message, statusCode=406)
86
86
 
87
87
 
88
88
  class ProxyAuthenticationRequiredException(ClientException):
89
89
  def __init__(self, message: str | None = None) -> None:
90
- message = message if message else 'Proxy Authentication Required'
90
+ message = message or 'Proxy Authentication Required'
91
91
  super().__init__(message=message, statusCode=407)
92
92
 
93
93
 
94
94
  class RequestTimeoutException(ClientException):
95
95
  def __init__(self, message: str | None = None) -> None:
96
- message = message if message else 'Request Timeout'
96
+ message = message or 'Request Timeout'
97
97
  super().__init__(message=message, statusCode=408)
98
98
 
99
99
 
100
100
  class ConflictException(ClientException):
101
101
  def __init__(self, message: str | None = None) -> None:
102
- message = message if message else 'Conflict'
102
+ message = message or 'Conflict'
103
103
  super().__init__(message=message, statusCode=409)
104
104
 
105
105
 
106
106
  class GoneException(ClientException):
107
107
  def __init__(self, message: str | None = None) -> None:
108
- message = message if message else 'Gone'
108
+ message = message or 'Gone'
109
109
  super().__init__(message=message, statusCode=410)
110
110
 
111
111
 
112
112
  class LengthRequiredException(ClientException):
113
113
  def __init__(self, message: str | None = None) -> None:
114
- message = message if message else 'Length Required'
114
+ message = message or 'Length Required'
115
115
  super().__init__(message=message, statusCode=411)
116
116
 
117
117
 
118
118
  class PreconditionFailedException(ClientException):
119
119
  def __init__(self, message: str | None = None) -> None:
120
- message = message if message else 'Precondition Failed'
120
+ message = message or 'Precondition Failed'
121
121
  super().__init__(message=message, statusCode=412)
122
122
 
123
123
 
124
124
  class PayloadTooLargeException(ClientException):
125
125
  def __init__(self, message: str | None = None) -> None:
126
- message = message if message else 'Payload Too Large'
126
+ message = message or 'Payload Too Large'
127
127
  super().__init__(message=message, statusCode=413)
128
128
 
129
129
 
130
130
  class UriTooLongException(ClientException):
131
131
  def __init__(self, message: str | None = None) -> None:
132
- message = message if message else 'URI Too Long'
132
+ message = message or 'URI Too Long'
133
133
  super().__init__(message=message, statusCode=414)
134
134
 
135
135
 
136
136
  class UnsupportedMediaTypeException(ClientException):
137
137
  def __init__(self, message: str | None = None) -> None:
138
- message = message if message else 'Unsupported Media Type'
138
+ message = message or 'Unsupported Media Type'
139
139
  super().__init__(message=message, statusCode=415)
140
140
 
141
141
 
142
142
  class RangeNotSatisfiableException(ClientException):
143
143
  def __init__(self, message: str | None = None) -> None:
144
- message = message if message else 'Range Not Satisfiable'
144
+ message = message or 'Range Not Satisfiable'
145
145
  super().__init__(message=message, statusCode=416)
146
146
 
147
147
 
148
148
  class ExpectationFailedException(ClientException):
149
149
  def __init__(self, message: str | None = None) -> None:
150
- message = message if message else 'Expectation Failed'
150
+ message = message or 'Expectation Failed'
151
151
  super().__init__(message=message, statusCode=417)
152
152
 
153
153
 
154
154
  class ImATeapotException(ClientException):
155
155
  def __init__(self, message: str | None = None) -> None:
156
- message = message if message else "I'm a teapot"
156
+ message = message or "I'm a teapot"
157
157
  super().__init__(message=message, statusCode=418)
158
158
 
159
159
 
160
160
  class MisdirectedRequestException(ClientException):
161
161
  def __init__(self, message: str | None = None) -> None:
162
- message = message if message else 'Misdirected Request'
162
+ message = message or 'Misdirected Request'
163
163
  super().__init__(message=message, statusCode=421)
164
164
 
165
165
 
166
166
  class UnprocessableEntityException(ClientException):
167
167
  def __init__(self, message: str | None = None) -> None:
168
- message = message if message else 'Unprocessable Entity'
168
+ message = message or 'Unprocessable Entity'
169
169
  super().__init__(message=message, statusCode=422)
170
170
 
171
171
 
172
172
  class LockedException(ClientException):
173
173
  def __init__(self, message: str | None = None) -> None:
174
- message = message if message else 'Locked'
174
+ message = message or 'Locked'
175
175
  super().__init__(message=message, statusCode=423)
176
176
 
177
177
 
178
178
  class FailedDependencyException(ClientException):
179
179
  def __init__(self, message: str | None = None) -> None:
180
- message = message if message else 'Failed Dependency'
180
+ message = message or 'Failed Dependency'
181
181
  super().__init__(message=message, statusCode=424)
182
182
 
183
183
 
184
184
  class UpgradeRequiredException(ClientException):
185
185
  def __init__(self, message: str | None = None) -> None:
186
- message = message if message else 'Upgrade Required'
186
+ message = message or 'Upgrade Required'
187
187
  super().__init__(message=message, statusCode=426)
188
188
 
189
189
 
190
190
  class PreconditionRequiredException(ClientException):
191
191
  def __init__(self, message: str | None = None) -> None:
192
- message = message if message else 'Precondition Required'
192
+ message = message or 'Precondition Required'
193
193
  super().__init__(message=message, statusCode=428)
194
194
 
195
195
 
196
196
  class TooManyRequestsException(ClientException):
197
197
  def __init__(self, message: str | None = None) -> None:
198
- message = message if message else 'Too Many Requests'
198
+ message = message or 'Too Many Requests'
199
199
  super().__init__(message=message, statusCode=429)
200
200
 
201
201
 
202
202
  class RequestHeaderFieldsTooLargeException(ClientException):
203
203
  def __init__(self, message: str | None = None) -> None:
204
- message = message if message else 'Request Header Fields Too Large'
204
+ message = message or 'Request Header Fields Too Large'
205
205
  super().__init__(message=message, statusCode=431)
206
206
 
207
207
 
208
208
  class UnavailableForLegalReasonsException(ClientException):
209
209
  def __init__(self, message: str | None = None) -> None:
210
- message = message if message else 'Unavailable For Legal Reasons'
210
+ message = message or 'Unavailable For Legal Reasons'
211
211
  super().__init__(message=message, statusCode=451)
212
212
 
213
213
 
214
214
  class NoResponseException(ClientException):
215
215
  def __init__(self, message: str | None = None) -> None:
216
- message = message if message else 'No Response'
216
+ message = message or 'No Response'
217
217
  super().__init__(message=message, statusCode=444)
218
218
 
219
219
 
220
220
  class RequestHeaderTooLargeException(ClientException):
221
221
  def __init__(self, message: str | None = None) -> None:
222
- message = message if message else 'Request Header Too Large'
222
+ message = message or 'Request Header Too Large'
223
223
  super().__init__(message=message, statusCode=494)
224
224
 
225
225
 
226
226
  class SSLCertificateErrorException(ClientException):
227
227
  def __init__(self, message: str | None = None) -> None:
228
- message = message if message else 'SSL Certificate Error'
228
+ message = message or 'SSL Certificate Error'
229
229
  super().__init__(message=message, statusCode=495)
230
230
 
231
231
 
232
232
  class SSLCertificateRequiredException(ClientException):
233
233
  def __init__(self, message: str | None = None) -> None:
234
- message = message if message else 'SSL Certificate Required'
234
+ message = message or 'SSL Certificate Required'
235
235
  super().__init__(message=message, statusCode=496)
236
236
 
237
237
 
238
238
  class HttpRequestSentToHttpsException(ClientException):
239
239
  def __init__(self, message: str | None = None) -> None:
240
- message = message if message else 'HTTP Request Sent to HTTPS Port'
240
+ message = message or 'HTTP Request Sent to HTTPS Port'
241
241
  super().__init__(message=message, statusCode=497)
242
242
 
243
243
 
244
244
  class ClientClosedRequestException(ClientException):
245
245
  def __init__(self, message: str | None = None) -> None:
246
- message = message if message else 'Client Closed Request'
246
+ message = message or 'Client Closed Request'
247
247
  super().__init__(message=message, statusCode=499)
248
248
 
249
249
 
@@ -253,133 +253,133 @@ class ServerException(KibaException):
253
253
 
254
254
  class InternalServerErrorException(ServerException):
255
255
  def __init__(self, message: str | None = None) -> None:
256
- message = message if message else 'Internal Server Error'
256
+ message = message or 'Internal Server Error'
257
257
  super().__init__(message=message, statusCode=500)
258
258
 
259
259
 
260
260
  class NotImplementedException(ServerException):
261
261
  def __init__(self, message: str | None = None) -> None:
262
- message = message if message else 'Not Implemented'
262
+ message = message or 'Not Implemented'
263
263
  super().__init__(message=message, statusCode=501)
264
264
 
265
265
 
266
266
  class BadGatewayException(ServerException):
267
267
  def __init__(self, message: str | None = None) -> None:
268
- message = message if message else 'Bad Gateway'
268
+ message = message or 'Bad Gateway'
269
269
  super().__init__(message=message, statusCode=502)
270
270
 
271
271
 
272
272
  class ServiceUnavailableException(ServerException):
273
273
  def __init__(self, message: str | None = None) -> None:
274
- message = message if message else 'Service Unavailable'
274
+ message = message or 'Service Unavailable'
275
275
  super().__init__(message=message, statusCode=503)
276
276
 
277
277
 
278
278
  class GatewayTimeoutException(ServerException):
279
279
  def __init__(self, message: str | None = None) -> None:
280
- message = message if message else 'Gateway Timeout'
280
+ message = message or 'Gateway Timeout'
281
281
  super().__init__(message=message, statusCode=504)
282
282
 
283
283
 
284
284
  class HttpVersionNotSupportedException(ServerException):
285
285
  def __init__(self, message: str | None = None) -> None:
286
- message = message if message else 'HTTP Version Not Supported'
286
+ message = message or 'HTTP Version Not Supported'
287
287
  super().__init__(message=message, statusCode=505)
288
288
 
289
289
 
290
290
  class VariantAlsoNegotiatesException(ServerException):
291
291
  def __init__(self, message: str | None = None) -> None:
292
- message = message if message else 'Variant Also Negotiates'
292
+ message = message or 'Variant Also Negotiates'
293
293
  super().__init__(message=message, statusCode=506)
294
294
 
295
295
 
296
296
  class InsufficientStorageException(ServerException):
297
297
  def __init__(self, message: str | None = None) -> None:
298
- message = message if message else 'Insufficient Storage'
298
+ message = message or 'Insufficient Storage'
299
299
  super().__init__(message=message, statusCode=507)
300
300
 
301
301
 
302
302
  class LoopDetectedException(ServerException):
303
303
  def __init__(self, message: str | None = None) -> None:
304
- message = message if message else 'Loop Detected'
304
+ message = message or 'Loop Detected'
305
305
  super().__init__(message=message, statusCode=508)
306
306
 
307
307
 
308
308
  class BandwidthLimitExceededException(ServerException):
309
309
  def __init__(self, message: str | None = None) -> None:
310
- message = message if message else 'Bandwidth Limit Exceeded'
310
+ message = message or 'Bandwidth Limit Exceeded'
311
311
  super().__init__(message=message, statusCode=509)
312
312
 
313
313
 
314
314
  class NotExtendedException(ServerException):
315
315
  def __init__(self, message: str | None = None) -> None:
316
- message = message if message else 'Not Extended'
316
+ message = message or 'Not Extended'
317
317
  super().__init__(message=message, statusCode=510)
318
318
 
319
319
 
320
320
  class NetworkAuthenticationRequiredException(ServerException):
321
321
  def __init__(self, message: str | None = None) -> None:
322
- message = message if message else 'Network Authentication Required'
322
+ message = message or 'Network Authentication Required'
323
323
  super().__init__(message=message, statusCode=511)
324
324
 
325
325
 
326
326
  class UnknownErrorException(ServerException):
327
327
  def __init__(self, message: str | None = None) -> None:
328
- message = message if message else 'Unknown Error'
328
+ message = message or 'Unknown Error'
329
329
  super().__init__(message=message, statusCode=520)
330
330
 
331
331
 
332
332
  class WebServerIsDownException(ServerException):
333
333
  def __init__(self, message: str | None = None) -> None:
334
- message = message if message else 'Web Server Is Down'
334
+ message = message or 'Web Server Is Down'
335
335
  super().__init__(message=message, statusCode=521)
336
336
 
337
337
 
338
338
  class ConnectionTimeoutException(ServerException):
339
339
  def __init__(self, message: str | None = None) -> None:
340
- message = message if message else 'Connection Timeout'
340
+ message = message or 'Connection Timeout'
341
341
  super().__init__(message=message, statusCode=522)
342
342
 
343
343
 
344
344
  class UnreachableOriginException(ServerException):
345
345
  def __init__(self, message: str | None = None) -> None:
346
- message = message if message else 'Origin Is Unreachable'
346
+ message = message or 'Origin Is Unreachable'
347
347
  super().__init__(message=message, statusCode=523)
348
348
 
349
349
 
350
350
  class TimeoutOccurredException(ServerException):
351
351
  def __init__(self, message: str | None = None) -> None:
352
- message = message if message else 'A Timeout Occurred'
352
+ message = message or 'A Timeout Occurred'
353
353
  super().__init__(message=message, statusCode=524)
354
354
 
355
355
 
356
356
  class SSLHandshakeFailedException(ServerException):
357
357
  def __init__(self, message: str | None = None) -> None:
358
- message = message if message else 'SSL Handshake Failed'
358
+ message = message or 'SSL Handshake Failed'
359
359
  super().__init__(message=message, statusCode=525)
360
360
 
361
361
 
362
362
  class InvalidSSLCertificateException(ServerException):
363
363
  def __init__(self, message: str | None = None) -> None:
364
- message = message if message else 'Invalid SSL Certificate'
364
+ message = message or 'Invalid SSL Certificate'
365
365
  super().__init__(message=message, statusCode=526)
366
366
 
367
367
 
368
368
  class RailgunErrorException(ServerException):
369
369
  def __init__(self, message: str | None = None) -> None:
370
- message = message if message else 'Railgun Error'
370
+ message = message or 'Railgun Error'
371
371
  super().__init__(message=message, statusCode=527)
372
372
 
373
373
 
374
374
  class OriginDNSErrorException(ServerException):
375
375
  def __init__(self, message: str | None = None) -> None:
376
- message = message if message else 'Origin DNS Error'
376
+ message = message or 'Origin DNS Error'
377
377
  super().__init__(message=message, statusCode=530)
378
378
 
379
379
 
380
380
  class NetworkReadTimeoutException(ServerException):
381
381
  def __init__(self, message: str | None = None) -> None:
382
- message = message if message else 'Network Read Timeout'
382
+ message = message or 'Network Read Timeout'
383
383
  super().__init__(message=message, statusCode=598)
384
384
 
385
385
 
@@ -389,7 +389,7 @@ class DuplicateValueException(BadRequestException):
389
389
 
390
390
  class RedirectException(KibaException):
391
391
  def __init__(self, location: str, statusCode: int, message: str | None = None, shouldAddCacheHeader: bool | None = True) -> None:
392
- message = message if message else 'RedirectException'
392
+ message = message or 'RedirectException'
393
393
  super().__init__(message=message, statusCode=statusCode)
394
394
  self.location = location
395
395
  self.shouldAddCacheHeader = shouldAddCacheHeader
@@ -397,19 +397,19 @@ class RedirectException(KibaException):
397
397
 
398
398
  class MovedPermanentlyRedirectException(RedirectException):
399
399
  def __init__(self, location: str, message: str | None = None, shouldAddCacheHeader: bool | None = True) -> None:
400
- message = message if message else 'Moved Permanently'
400
+ message = message or 'Moved Permanently'
401
401
  super().__init__(location=location, message=message, statusCode=301, shouldAddCacheHeader=shouldAddCacheHeader)
402
402
 
403
403
 
404
404
  class FoundRedirectException(RedirectException):
405
405
  def __init__(self, location: str, message: str | None = None) -> None:
406
- message = message if message else 'Found Redirect'
406
+ message = message or 'Found Redirect'
407
407
  super().__init__(location=location, message=message, statusCode=302, shouldAddCacheHeader=False)
408
408
 
409
409
 
410
410
  class PermanentRedirectException(RedirectException):
411
411
  def __init__(self, location: str, message: str | None = None, shouldAddCacheHeader: bool | None = True) -> None:
412
- message = message if message else 'Permanent Redirect'
412
+ message = message or 'Permanent Redirect'
413
413
  super().__init__(location=location, message=message, statusCode=308, shouldAddCacheHeader=shouldAddCacheHeader)
414
414
 
415
415
 
@@ -56,7 +56,7 @@ def file_exists_sync(filePath: str) -> bool:
56
56
 
57
57
  async def get_file_age_millis(filePath: str) -> int:
58
58
  # NOTE(krishan711): is there an async verison of this?
59
- return int((time.time() - os.path.getmtime(filePath)) * 1000)
59
+ return int((time.time() - os.path.getmtime(filePath)) * 1000) # noqa: ASYNC240
60
60
 
61
61
 
62
62
  def get_file_age_millis_sync(filePath: str) -> int:
@@ -112,7 +112,7 @@ def write_file_bytes_sync(filePath: str, content: bytes, shouldCreateParentDirec
112
112
 
113
113
 
114
114
  async def create_directory(directory: str, shouldAllowExisting: bool = True) -> None:
115
- pathlib.Path(directory).mkdir(parents=True, exist_ok=shouldAllowExisting)
115
+ pathlib.Path(directory).mkdir(parents=True, exist_ok=shouldAllowExisting) # noqa: ASYNC240
116
116
 
117
117
 
118
118
  def create_directory_sync(directory: str, shouldAllowExisting: bool = True) -> None:
@@ -4,11 +4,13 @@ from typing import Any
4
4
 
5
5
  from eth_typing import ABI
6
6
  from eth_typing import ABIFunction
7
+ from eth_typing import ChecksumAddress
7
8
  from pydantic import BaseModel
8
9
  from web3 import Web3
9
10
  from web3._utils import method_formatters
10
11
  from web3._utils.rpc_abi import RPC
11
12
  from web3.types import BlockData
13
+ from web3.types import FilterParams
12
14
  from web3.types import HexBytes
13
15
  from web3.types import HexStr
14
16
  from web3.types import LogReceipt
@@ -220,10 +222,10 @@ class EthClientInterface:
220
222
  raise TransactionFailedException(transactionReceipt=transactionReceipt)
221
223
  return transactionReceipt
222
224
 
223
- async def multicall(self, contractCalls: list[ContractCall], shouldUseMulticall3: bool = True) -> list[ListAny]:
225
+ async def multicall(self, contractCalls: list[ContractCall], shouldUseMulticall3: bool = True, blockNumber: int | None = None) -> list[ListAny]:
224
226
  multicall3Address = CHAIN_ID_MULTICALL3_ADDRESS_MAP.get(self.chainId) if shouldUseMulticall3 else None
225
227
  if not multicall3Address or not shouldUseMulticall3:
226
- results = await asyncio.gather(*[self.call(contractCall=contractCall) for contractCall in contractCalls])
228
+ results = await asyncio.gather(*[self.call(contractCall=contractCall, blockNumber=blockNumber) for contractCall in contractCalls])
227
229
  return results
228
230
  multicallResponse = await self.call_function_by_name(
229
231
  toAddress=multicall3Address,
@@ -235,6 +237,7 @@ class EthClientInterface:
235
237
  for contractCall in contractCalls
236
238
  ]
237
239
  },
240
+ blockNumber=blockNumber,
238
241
  )
239
242
  multicallResults = multicallResponse[0]
240
243
  decodedResults: list[ListAny] = []
@@ -277,14 +280,16 @@ class Web3EthClient(EthClientInterface):
277
280
  endBlockNumber: int | None = None,
278
281
  address: str | None = None,
279
282
  ) -> list[LogReceipt]:
280
- contractFilter = self.w3.eth.filter(
281
- {
282
- 'fromBlock': startBlockNumber, # type: ignore[typeddict-item]
283
- 'toBlock': endBlockNumber, # type: ignore[typeddict-item]
284
- 'topics': topics, # type: ignore[typeddict-item]
285
- 'address': address, # type: ignore[typeddict-item]
286
- }
287
- )
283
+ params: FilterParams = {}
284
+ if startBlockNumber is not None:
285
+ params['fromBlock'] = startBlockNumber
286
+ if endBlockNumber is not None:
287
+ params['toBlock'] = endBlockNumber
288
+ if topics is not None:
289
+ params['topics'] = topics
290
+ if address is not None:
291
+ params['address'] = typing.cast(ChecksumAddress, address)
292
+ contractFilter = self.w3.eth.filter(params)
288
293
  return contractFilter.get_all_entries()
289
294
 
290
295
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kiba-core
3
- Version: 0.5.3.dev45
3
+ Version: 0.5.3.dev47
4
4
  Summary: Kiba Labs' python utilities
5
5
  Project-URL: repository, https://github.com/kibalabs/core-py
6
- Requires-Python: ~=3.12
6
+ Requires-Python: <4,>=3.12
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: aiofiles>=24.1.0
9
9
  Requires-Dist: pydantic>=2.11.7
@@ -1,9 +1,9 @@
1
1
  [project]
2
2
  name = "kiba-core"
3
- version = "0.5.3.dev45"
3
+ version = "0.5.3.dev47"
4
4
  description = "Kiba Labs' python utilities"
5
5
  readme = "README.md"
6
- requires-python = "~=3.12"
6
+ requires-python = ">=3.12, <4"
7
7
  dependencies = [
8
8
  "aiofiles>=24.1.0",
9
9
  "pydantic>=2.11.7",
@@ -54,7 +54,6 @@ types = [
54
54
  [dependency-groups]
55
55
  dev = [
56
56
  "kiba-build==0.1.11.dev10",
57
- "pytest-only>=2.1.2",
58
57
  ]
59
58
 
60
59
  [project.urls]