osbot-utils 2.20.0__py3-none-any.whl → 2.22.0__py3-none-any.whl
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.
- osbot_utils/type_safe/shared/Type_Safe__Validation.py +43 -4
- osbot_utils/utils/Http.py +11 -1
- osbot_utils/version +1 -1
- {osbot_utils-2.20.0.dist-info → osbot_utils-2.22.0.dist-info}/METADATA +2 -2
- {osbot_utils-2.20.0.dist-info → osbot_utils-2.22.0.dist-info}/RECORD +7 -7
- {osbot_utils-2.20.0.dist-info → osbot_utils-2.22.0.dist-info}/LICENSE +0 -0
- {osbot_utils-2.20.0.dist-info → osbot_utils-2.22.0.dist-info}/WHEEL +0 -0
@@ -1,3 +1,5 @@
|
|
1
|
+
import collections
|
2
|
+
import inspect
|
1
3
|
import types
|
2
4
|
import typing
|
3
5
|
from enum import EnumMeta
|
@@ -151,14 +153,15 @@ class Type_Safe__Validation:
|
|
151
153
|
return all(isinstance(k, key_type) and isinstance(v, value_type)
|
152
154
|
for k, v in value.items()) # if it is not a Union or Annotated types just return None (to give an indication to the caller that the comparison was not made)
|
153
155
|
|
154
|
-
def check_if__type_matches__obj_annotation__for_attr(self, target,
|
155
|
-
attr_name,
|
156
|
-
value
|
157
|
-
) -> Optional[bool]:
|
156
|
+
def check_if__type_matches__obj_annotation__for_attr(self, target, attr_name, value) -> Optional[bool]:
|
158
157
|
annotations = type_safe_cache.get_obj_annotations(target)
|
159
158
|
attr_type = annotations.get(attr_name)
|
160
159
|
if attr_type:
|
161
160
|
origin_attr_type = get_origin(attr_type) # to handle when type definition contains a generic
|
161
|
+
|
162
|
+
if origin_attr_type is collections.abc.Callable: # Handle Callable types
|
163
|
+
return self.is_callable_compatible(value, attr_type) # ISSUE: THIS IS NEVER CALLED
|
164
|
+
|
162
165
|
if origin_attr_type is set:
|
163
166
|
if type(value) is list:
|
164
167
|
return True # if the attribute is a set and the value is a list, then they are compatible
|
@@ -190,6 +193,42 @@ class Type_Safe__Validation:
|
|
190
193
|
return value_type is attr_type
|
191
194
|
return None
|
192
195
|
|
196
|
+
def is_callable_compatible(self, value, expected_type) -> bool:
|
197
|
+
if not callable(value):
|
198
|
+
return False
|
199
|
+
|
200
|
+
expected_args = get_args(expected_type)
|
201
|
+
if not expected_args: # Callable without type hints
|
202
|
+
return True
|
203
|
+
|
204
|
+
if len(expected_args) != 2: # Should have args and return type
|
205
|
+
return False
|
206
|
+
|
207
|
+
expected_param_types = expected_args[0] # First element is tuple of parameter types
|
208
|
+
expected_return_type = expected_args[1] # Second element is return type
|
209
|
+
|
210
|
+
|
211
|
+
try: # Get the signature of the actual value
|
212
|
+
sig = inspect.signature(value)
|
213
|
+
except ValueError: # Some built-in functions don't support introspection
|
214
|
+
return True
|
215
|
+
|
216
|
+
actual_params = list(sig.parameters.values()) # Get actual parameters
|
217
|
+
|
218
|
+
if len(actual_params) != len(expected_param_types): # Check number of parameters matches
|
219
|
+
return False
|
220
|
+
|
221
|
+
for actual_param, expected_param_type in zip(actual_params, expected_param_types): # Check each parameter type
|
222
|
+
if actual_param.annotation != inspect.Parameter.empty:
|
223
|
+
if not self.are_types_compatible_for_assigment(actual_param.annotation, expected_param_type):
|
224
|
+
return False # todo: check if we shouldn't raise an exception here, since this is the only place where we actually know the types that don't match in the method signature
|
225
|
+
|
226
|
+
if sig.return_annotation != inspect.Parameter.empty: # Check return type
|
227
|
+
if not self.are_types_compatible_for_assigment(sig.return_annotation, expected_return_type):
|
228
|
+
return False # todo: check if we shouldn't raise an exception here, since this is the only place where we actually know the types that don't match in the method return type
|
229
|
+
|
230
|
+
return True
|
231
|
+
|
193
232
|
# todo: add cache support to this method
|
194
233
|
def should_skip_type_check(self, var_type): # Determine if type checking should be skipped
|
195
234
|
origin = type_safe_cache.get_origin(var_type) # Use cached get_origin
|
osbot_utils/utils/Http.py
CHANGED
@@ -56,7 +56,6 @@ def http_request(url, data=None, headers=None, method='GET', encoding ='utf-8',
|
|
56
56
|
ssl_request = url.startswith('https://')
|
57
57
|
headers = headers or {}
|
58
58
|
if data:
|
59
|
-
print()
|
60
59
|
if type(data) is not str: # if the data object is not a string
|
61
60
|
if headers.get('Content-Type') == "application/json": # and a json payload is expected
|
62
61
|
data = json.dumps(data) # convert it to json
|
@@ -164,6 +163,17 @@ def POST(url, data='', headers=None):
|
|
164
163
|
def POST_json(*args, **kwargs):
|
165
164
|
return json.loads(POST(*args, **kwargs))
|
166
165
|
|
166
|
+
def POST_json_get_bytes(url=None, data=None):
|
167
|
+
headers = {'Content-Type': "application/json"} # todo add support for providing custom headers
|
168
|
+
kwargs = dict(url = url ,
|
169
|
+
data = data,
|
170
|
+
headers = headers ,
|
171
|
+
method = 'POST' ,
|
172
|
+
encoding = None
|
173
|
+
)
|
174
|
+
response = http_request(**kwargs)
|
175
|
+
return response
|
176
|
+
|
167
177
|
def PUT(url, data='', headers=None):
|
168
178
|
return http_request(url, data, headers, 'PUT')
|
169
179
|
|
osbot_utils/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v2.
|
1
|
+
v2.22.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.22.0
|
4
4
|
Summary: OWASP Security Bot - Utils
|
5
5
|
License: MIT
|
6
6
|
Author: Dinis Cruz
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
23
23
|
|
24
24
|
Powerful Python util methods and classes that simplify common apis and tasks.
|
25
25
|
|
26
|
-

|
27
27
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
28
28
|
|
29
29
|
|
@@ -312,7 +312,7 @@ osbot_utils/type_safe/shared/Type_Safe__Convert.py,sha256=mS92_sKjKM_aNSB3ERMEgv
|
|
312
312
|
osbot_utils/type_safe/shared/Type_Safe__Not_Cached.py,sha256=25FAl6SOLxdStco_rm9tgOYLfuKyBWheGdl7vVa56UU,800
|
313
313
|
osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py,sha256=pbru8k8CTQMNUfmFBndiJhg2KkqEYzFvJAPcNZHeHfQ,829
|
314
314
|
osbot_utils/type_safe/shared/Type_Safe__Shared__Variables.py,sha256=SuZGl9LryQX6IpOE0I_lbzClT-h17UNylC__-M8ltTY,129
|
315
|
-
osbot_utils/type_safe/shared/Type_Safe__Validation.py,sha256=
|
315
|
+
osbot_utils/type_safe/shared/Type_Safe__Validation.py,sha256=5dVs2zDU_sDh3e025KjaDfUS7B8XENlQ77-7U34b2KY,19017
|
316
316
|
osbot_utils/type_safe/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
317
317
|
osbot_utils/type_safe/steps/Type_Safe__Step__Class_Kwargs.py,sha256=snoyJKvZ1crgF2fp0zexwNPnV_E63RfyRIsMAZdrKNY,6995
|
318
318
|
osbot_utils/type_safe/steps/Type_Safe__Step__Default_Kwargs.py,sha256=tzKXDUc0HVP5QvCWsmcPuuZodNvQZ9FeMDNI2x00Ngw,1943
|
@@ -335,7 +335,7 @@ osbot_utils/utils/Env.py,sha256=rBksAy6k-J5oAJp-S_JedVlcj1b2VK8V3zsQbacopMc,6076
|
|
335
335
|
osbot_utils/utils/Exceptions.py,sha256=KyOUHkXQ_6jDTq04Xm261dbEZuRidtsM4dgzNwSG8-8,389
|
336
336
|
osbot_utils/utils/Files.py,sha256=yxteAcyhDcUy1_r9Eihx80V16lV_UAE6cvoOe2Dc7DU,23001
|
337
337
|
osbot_utils/utils/Functions.py,sha256=0E6alPJ0fJpBiJgFOWooCOi265wSRyxxXAJ5CELBnso,3498
|
338
|
-
osbot_utils/utils/Http.py,sha256=
|
338
|
+
osbot_utils/utils/Http.py,sha256=ywjQlpKgklPnh7iLMGrbf4vbNMH50sUGX4crZHAfCQc,8201
|
339
339
|
osbot_utils/utils/Int.py,sha256=PmlUdU4lSwf4gJdmTVdqclulkEp7KPCVUDO6AcISMF4,116
|
340
340
|
osbot_utils/utils/Json.py,sha256=TvfDoXwOkWzWH-9KMnme5C7iFsMZOleAeue92qmkH6g,8831
|
341
341
|
osbot_utils/utils/Json_Cache.py,sha256=mLPkkDZN-3ZVJiDvV1KBJXILtKkTZ4OepzOsDoBPhWg,2006
|
@@ -353,8 +353,8 @@ osbot_utils/utils/Toml.py,sha256=Rxl8gx7mni5CvBAK-Ai02EKw-GwtJdd3yeHT2kMloik,166
|
|
353
353
|
osbot_utils/utils/Version.py,sha256=Ww6ChwTxqp1QAcxOnztkTicShlcx6fbNsWX5xausHrg,422
|
354
354
|
osbot_utils/utils/Zip.py,sha256=pR6sKliUY0KZXmqNzKY2frfW-YVQEVbLKiyqQX_lc-8,14052
|
355
355
|
osbot_utils/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
356
|
-
osbot_utils/version,sha256=
|
357
|
-
osbot_utils-2.
|
358
|
-
osbot_utils-2.
|
359
|
-
osbot_utils-2.
|
360
|
-
osbot_utils-2.
|
356
|
+
osbot_utils/version,sha256=pjqcOqrciyAyeCyzaoa2eweE7t6j5-cKqPjIXB68cZM,8
|
357
|
+
osbot_utils-2.22.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
358
|
+
osbot_utils-2.22.0.dist-info/METADATA,sha256=EOAI0IncGbtFRJgC2HW5R7OJWT5fQV30Fv6PmV_zL1M,1329
|
359
|
+
osbot_utils-2.22.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
360
|
+
osbot_utils-2.22.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|