appier 1.31.4__py2.py3-none-any.whl → 1.32.0__py2.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.
- appier/__init__.py +333 -52
- appier/amqp.py +29 -30
- appier/api.py +214 -212
- appier/asgi.py +54 -55
- appier/async_neo.py +46 -35
- appier/async_old.py +55 -42
- appier/asynchronous.py +7 -13
- appier/base.py +1762 -1429
- appier/bus.py +51 -52
- appier/cache.py +99 -84
- appier/common.py +9 -11
- appier/component.py +17 -19
- appier/compress.py +25 -28
- appier/config.py +96 -73
- appier/controller.py +9 -15
- appier/crypt.py +25 -21
- appier/data.py +73 -57
- appier/defines.py +191 -226
- appier/exceptions.py +103 -63
- appier/execution.py +94 -88
- appier/export.py +90 -88
- appier/extra.py +6 -13
- appier/extra_neo.py +8 -11
- appier/extra_old.py +18 -16
- appier/geo.py +57 -47
- appier/git.py +101 -90
- appier/graph.py +23 -24
- appier/http.py +520 -398
- appier/legacy.py +373 -180
- appier/log.py +90 -97
- appier/meta.py +42 -42
- appier/mock.py +32 -34
- appier/model.py +793 -681
- appier/model_a.py +208 -183
- appier/mongo.py +183 -107
- appier/observer.py +39 -31
- appier/part.py +23 -24
- appier/preferences.py +44 -47
- appier/queuing.py +78 -96
- appier/redisdb.py +40 -35
- appier/request.py +227 -175
- appier/scheduler.py +13 -18
- appier/serialize.py +37 -31
- appier/session.py +161 -147
- appier/settings.py +2 -11
- appier/smtp.py +53 -49
- appier/storage.py +39 -33
- appier/structures.py +50 -45
- appier/test/__init__.py +2 -11
- appier/test/base.py +111 -108
- appier/test/cache.py +28 -35
- appier/test/config.py +10 -19
- appier/test/crypt.py +3 -12
- appier/test/data.py +3 -12
- appier/test/exceptions.py +8 -17
- appier/test/export.py +16 -33
- appier/test/graph.py +27 -60
- appier/test/http.py +42 -54
- appier/test/legacy.py +20 -30
- appier/test/log.py +14 -35
- appier/test/mock.py +27 -123
- appier/test/model.py +79 -91
- appier/test/part.py +5 -14
- appier/test/preferences.py +5 -13
- appier/test/queuing.py +29 -37
- appier/test/request.py +61 -73
- appier/test/serialize.py +12 -23
- appier/test/session.py +10 -19
- appier/test/smtp.py +8 -14
- appier/test/structures.py +20 -24
- appier/test/typesf.py +14 -28
- appier/test/util.py +480 -438
- appier/typesf.py +251 -171
- appier/util.py +578 -407
- appier/validation.py +280 -143
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/METADATA +6 -1
- appier-1.32.0.dist-info/RECORD +86 -0
- appier-1.31.4.dist-info/RECORD +0 -86
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/LICENSE +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/WHEEL +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/top_level.txt +0 -0
appier/exceptions.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Hive Appier Framework
|
|
5
|
-
# Copyright (c) 2008-
|
|
5
|
+
# Copyright (c) 2008-2024 Hive Solutions Lda.
|
|
6
6
|
#
|
|
7
7
|
# This file is part of Hive Appier Framework.
|
|
8
8
|
#
|
|
@@ -22,16 +22,7 @@
|
|
|
22
22
|
__author__ = "João Magalhães <joamag@hive.pt>"
|
|
23
23
|
""" The author(s) of the module """
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
""" The version of the module """
|
|
27
|
-
|
|
28
|
-
__revision__ = "$LastChangedRevision$"
|
|
29
|
-
""" The revision number of the module """
|
|
30
|
-
|
|
31
|
-
__date__ = "$LastChangedDate$"
|
|
32
|
-
""" The last change date of the module """
|
|
33
|
-
|
|
34
|
-
__copyright__ = "Copyright (c) 2008-2022 Hive Solutions Lda."
|
|
25
|
+
__copyright__ = "Copyright (c) 2008-2024 Hive Solutions Lda."
|
|
35
26
|
""" The copyright for the module """
|
|
36
27
|
|
|
37
28
|
__license__ = "Apache License, Version 2.0"
|
|
@@ -43,6 +34,7 @@ import uuid
|
|
|
43
34
|
from . import common
|
|
44
35
|
from . import legacy
|
|
45
36
|
|
|
37
|
+
|
|
46
38
|
class AppierException(Exception):
|
|
47
39
|
"""
|
|
48
40
|
Top level exception to be used as the root of
|
|
@@ -80,32 +72,40 @@ class AppierException(Exception):
|
|
|
80
72
|
self._uid = None
|
|
81
73
|
|
|
82
74
|
def __str__(self):
|
|
83
|
-
if legacy.PYTHON_3:
|
|
75
|
+
if legacy.PYTHON_3:
|
|
76
|
+
return self.__unicode__()
|
|
84
77
|
is_unicode = legacy.is_unicode(self.message)
|
|
85
|
-
if is_unicode:
|
|
78
|
+
if is_unicode:
|
|
79
|
+
return self.message.encode("utf-8")
|
|
86
80
|
return self.message
|
|
87
81
|
|
|
88
82
|
def __unicode__(self):
|
|
89
83
|
is_unicode = legacy.is_unicode(self.message)
|
|
90
|
-
if not is_unicode:
|
|
84
|
+
if not is_unicode:
|
|
85
|
+
return self.message.decode("utf-8")
|
|
91
86
|
return self.message
|
|
92
87
|
|
|
93
|
-
def get_meta(self, name, default
|
|
94
|
-
if not self.meta:
|
|
88
|
+
def get_meta(self, name, default=None):
|
|
89
|
+
if not self.meta:
|
|
90
|
+
return default
|
|
95
91
|
return self.meta.get(name, default)
|
|
96
92
|
|
|
97
93
|
def set_meta(self, name, value):
|
|
98
|
-
if not self.meta:
|
|
94
|
+
if not self.meta:
|
|
95
|
+
self.meta = {}
|
|
99
96
|
self.meta[name] = value
|
|
100
97
|
|
|
101
98
|
def del_meta(self, name):
|
|
102
|
-
if not self.meta:
|
|
103
|
-
|
|
99
|
+
if not self.meta:
|
|
100
|
+
return
|
|
101
|
+
if not name in self.meta:
|
|
102
|
+
return
|
|
104
103
|
del self.meta[name]
|
|
105
104
|
|
|
106
105
|
@property
|
|
107
106
|
def uid(self):
|
|
108
|
-
if self._uid:
|
|
107
|
+
if self._uid:
|
|
108
|
+
return self._uid
|
|
109
109
|
self._uid = uuid.uuid4()
|
|
110
110
|
return self._uid
|
|
111
111
|
|
|
@@ -113,6 +113,7 @@ class AppierException(Exception):
|
|
|
113
113
|
cls = self.__class__
|
|
114
114
|
return common.util().camel_to_readable(cls.__name__)
|
|
115
115
|
|
|
116
|
+
|
|
116
117
|
class OperationalError(AppierException):
|
|
117
118
|
"""
|
|
118
119
|
Error raised for a runtime error and as a result
|
|
@@ -123,6 +124,7 @@ class OperationalError(AppierException):
|
|
|
123
124
|
|
|
124
125
|
pass
|
|
125
126
|
|
|
127
|
+
|
|
126
128
|
class SecurityError(AppierException):
|
|
127
129
|
"""
|
|
128
130
|
Error used to indicate security problems that may
|
|
@@ -133,6 +135,7 @@ class SecurityError(AppierException):
|
|
|
133
135
|
|
|
134
136
|
pass
|
|
135
137
|
|
|
138
|
+
|
|
136
139
|
class AssertionError(OperationalError):
|
|
137
140
|
"""
|
|
138
141
|
Error raised for failure to meet any pre-condition or
|
|
@@ -144,6 +147,7 @@ class AssertionError(OperationalError):
|
|
|
144
147
|
kwargs["code"] = kwargs.get("code", None)
|
|
145
148
|
OperationalError.__init__(self, *args, **kwargs)
|
|
146
149
|
|
|
150
|
+
|
|
147
151
|
class ValidationError(OperationalError):
|
|
148
152
|
"""
|
|
149
153
|
Error raised when a validation on the model fails
|
|
@@ -168,16 +172,19 @@ class ValidationError(OperationalError):
|
|
|
168
172
|
self.set_meta("errors", self.errors)
|
|
169
173
|
|
|
170
174
|
def __str__(self):
|
|
171
|
-
if legacy.PYTHON_3:
|
|
175
|
+
if legacy.PYTHON_3:
|
|
176
|
+
return self.__unicode__()
|
|
172
177
|
message = OperationalError.__str__(self)
|
|
173
178
|
extended = common.is_devel()
|
|
174
|
-
if not extended:
|
|
179
|
+
if not extended:
|
|
180
|
+
return message
|
|
175
181
|
errors_s = self.errors_s()
|
|
176
|
-
if not errors_s:
|
|
182
|
+
if not errors_s:
|
|
183
|
+
return message
|
|
177
184
|
if self.model:
|
|
178
185
|
message += " for model '%s' with id '%s'" % (
|
|
179
186
|
self.model.__class__._name(),
|
|
180
|
-
self.model._id if hasattr(self.model, "_id") else "unset"
|
|
187
|
+
self.model._id if hasattr(self.model, "_id") else "unset",
|
|
181
188
|
)
|
|
182
189
|
errors_s = errors_s.encode("utf-8")
|
|
183
190
|
message += " (" + errors_s + ")"
|
|
@@ -186,32 +193,39 @@ class ValidationError(OperationalError):
|
|
|
186
193
|
def __unicode__(self):
|
|
187
194
|
message = OperationalError.__unicode__(self)
|
|
188
195
|
extended = common.is_devel()
|
|
189
|
-
if not extended:
|
|
196
|
+
if not extended:
|
|
197
|
+
return message
|
|
190
198
|
errors_s = self.errors_s()
|
|
191
|
-
if not errors_s:
|
|
199
|
+
if not errors_s:
|
|
200
|
+
return message
|
|
192
201
|
if self.model:
|
|
193
202
|
message += " for model '%s' with id '%s'" % (
|
|
194
203
|
self.model.__class__._name(),
|
|
195
|
-
self.model._id if hasattr(self.model, "_id") else "unset"
|
|
204
|
+
self.model._id if hasattr(self.model, "_id") else "unset",
|
|
196
205
|
)
|
|
197
206
|
message += " (" + errors_s + ")"
|
|
198
207
|
return message
|
|
199
208
|
|
|
200
|
-
def errors_s(self, encoding
|
|
201
|
-
if not self.errors:
|
|
209
|
+
def errors_s(self, encoding="utf-8"):
|
|
210
|
+
if not self.errors:
|
|
211
|
+
return ""
|
|
202
212
|
buffer = []
|
|
203
213
|
is_first = True
|
|
204
214
|
for name, errors in legacy.iteritems(self.errors):
|
|
205
215
|
for error in errors:
|
|
206
216
|
is_bytes = legacy.is_bytes(error)
|
|
207
|
-
if is_bytes:
|
|
208
|
-
|
|
209
|
-
|
|
217
|
+
if is_bytes:
|
|
218
|
+
error = error.decode(encoding)
|
|
219
|
+
if is_first:
|
|
220
|
+
is_first = False
|
|
221
|
+
else:
|
|
222
|
+
buffer.append(", ")
|
|
210
223
|
buffer.append(name)
|
|
211
224
|
buffer.append(" => ")
|
|
212
225
|
buffer.append(error)
|
|
213
226
|
return legacy.u("").join(buffer)
|
|
214
227
|
|
|
228
|
+
|
|
215
229
|
class NotFoundError(OperationalError):
|
|
216
230
|
"""
|
|
217
231
|
Error originated from an operation that was not able
|
|
@@ -223,6 +237,7 @@ class NotFoundError(OperationalError):
|
|
|
223
237
|
kwargs["code"] = kwargs.get("code", 404)
|
|
224
238
|
OperationalError.__init__(self, *args, **kwargs)
|
|
225
239
|
|
|
240
|
+
|
|
226
241
|
class NotImplementedError(OperationalError):
|
|
227
242
|
"""
|
|
228
243
|
Error to be raised when a certain feature or route is not
|
|
@@ -234,6 +249,7 @@ class NotImplementedError(OperationalError):
|
|
|
234
249
|
kwargs["code"] = kwargs.get("code", 501)
|
|
235
250
|
OperationalError.__init__(self, *args, **kwargs)
|
|
236
251
|
|
|
252
|
+
|
|
237
253
|
class BaseInternalError(RuntimeError):
|
|
238
254
|
"""
|
|
239
255
|
The base (internal) error class from which all the
|
|
@@ -250,35 +266,43 @@ class BaseInternalError(RuntimeError):
|
|
|
250
266
|
that should be considered private in context, this
|
|
251
267
|
should be structured data ready to be serializable """
|
|
252
268
|
|
|
253
|
-
def __init__(self, message, meta
|
|
269
|
+
def __init__(self, message, meta=None):
|
|
254
270
|
RuntimeError.__init__(self, message)
|
|
255
271
|
self.message = message
|
|
256
272
|
self.meta = meta
|
|
257
273
|
|
|
258
274
|
def __str__(self):
|
|
259
|
-
if legacy.PYTHON_3:
|
|
275
|
+
if legacy.PYTHON_3:
|
|
276
|
+
return self.__unicode__()
|
|
260
277
|
is_unicode = legacy.is_unicode(self.message)
|
|
261
|
-
if is_unicode:
|
|
278
|
+
if is_unicode:
|
|
279
|
+
return self.message.encode("utf-8")
|
|
262
280
|
return self.message
|
|
263
281
|
|
|
264
282
|
def __unicode__(self):
|
|
265
283
|
is_unicode = legacy.is_unicode(self.message)
|
|
266
|
-
if not is_unicode:
|
|
284
|
+
if not is_unicode:
|
|
285
|
+
return self.message.decode("utf-8")
|
|
267
286
|
return self.message
|
|
268
287
|
|
|
269
|
-
def get_meta(self, name, default
|
|
270
|
-
if not self.meta:
|
|
288
|
+
def get_meta(self, name, default=None):
|
|
289
|
+
if not self.meta:
|
|
290
|
+
return default
|
|
271
291
|
return self.meta.get(name, default)
|
|
272
292
|
|
|
273
293
|
def set_meta(self, name, value):
|
|
274
|
-
if not self.meta:
|
|
294
|
+
if not self.meta:
|
|
295
|
+
self.meta = {}
|
|
275
296
|
self.meta[name] = value
|
|
276
297
|
|
|
277
298
|
def del_meta(self, name):
|
|
278
|
-
if not self.meta:
|
|
279
|
-
|
|
299
|
+
if not self.meta:
|
|
300
|
+
return
|
|
301
|
+
if not name in self.meta:
|
|
302
|
+
return
|
|
280
303
|
del self.meta[name]
|
|
281
304
|
|
|
305
|
+
|
|
282
306
|
class ValidationInternalError(BaseInternalError):
|
|
283
307
|
"""
|
|
284
308
|
Error raised when a validation on the model fails
|
|
@@ -290,10 +314,11 @@ class ValidationInternalError(BaseInternalError):
|
|
|
290
314
|
""" The name of the attribute that failed
|
|
291
315
|
the validation, for latter reference """
|
|
292
316
|
|
|
293
|
-
def __init__(self, name, message, meta
|
|
294
|
-
BaseInternalError.__init__(self, message, meta
|
|
317
|
+
def __init__(self, name, message, meta=None):
|
|
318
|
+
BaseInternalError.__init__(self, message, meta=meta)
|
|
295
319
|
self.name = name
|
|
296
320
|
|
|
321
|
+
|
|
297
322
|
class ValidationMultipleError(ValidationInternalError):
|
|
298
323
|
"""
|
|
299
324
|
Exception/error considered to be equivalent to the
|
|
@@ -305,19 +330,22 @@ class ValidationMultipleError(ValidationInternalError):
|
|
|
305
330
|
""" The sequence containing the multiple errors associated
|
|
306
331
|
with the validation multiple error """
|
|
307
332
|
|
|
308
|
-
def __init__(self, name
|
|
309
|
-
ValidationInternalError.__init__(self, name, message
|
|
333
|
+
def __init__(self, name=None, message=None, meta=None):
|
|
334
|
+
ValidationInternalError.__init__(self, name, message, meta=meta)
|
|
310
335
|
self.errors = []
|
|
311
336
|
self.set_meta("errors", self.errors)
|
|
312
337
|
|
|
313
338
|
def add_error(self, name, message):
|
|
314
|
-
if not self.name:
|
|
315
|
-
|
|
339
|
+
if not self.name:
|
|
340
|
+
self.name = name
|
|
341
|
+
if not self.message:
|
|
342
|
+
self.message = message
|
|
316
343
|
self.errors.append((name, message))
|
|
317
344
|
|
|
318
345
|
def add_exception(self, exception):
|
|
319
346
|
self.add_error(exception.name, exception.message)
|
|
320
347
|
|
|
348
|
+
|
|
321
349
|
class HTTPError(BaseInternalError):
|
|
322
350
|
"""
|
|
323
351
|
Top level HTTP error raised whenever a bad response
|
|
@@ -335,33 +363,43 @@ class HTTPError(BaseInternalError):
|
|
|
335
363
|
going to be used to cache the binary contents of the
|
|
336
364
|
error associated with this exception (data) stream """
|
|
337
365
|
|
|
338
|
-
def __init__(self, error, code
|
|
366
|
+
def __init__(self, error, code=None, message=None, extended=None, meta=None):
|
|
339
367
|
message = message or "Problem in the HTTP request"
|
|
340
|
-
if extended == None:
|
|
341
|
-
|
|
368
|
+
if extended == None:
|
|
369
|
+
extended = common.is_devel()
|
|
370
|
+
if code:
|
|
371
|
+
message = "[%d] %s" % (code, message)
|
|
342
372
|
if extended:
|
|
343
|
-
data = self.read(error
|
|
344
|
-
try:
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
373
|
+
data = self.read(error=error)
|
|
374
|
+
try:
|
|
375
|
+
data = data.decode("utf-8")
|
|
376
|
+
except Exception:
|
|
377
|
+
data = legacy.str(data)
|
|
378
|
+
if data:
|
|
379
|
+
message = message + "\n" + data if message else data
|
|
380
|
+
BaseInternalError.__init__(self, message, meta=meta)
|
|
348
381
|
self.code = code
|
|
349
382
|
self.error = error
|
|
350
383
|
|
|
351
|
-
def read(self, error
|
|
384
|
+
def read(self, error=None):
|
|
352
385
|
error = error or self.error
|
|
353
|
-
if not self._data == None:
|
|
386
|
+
if not self._data == None:
|
|
387
|
+
return self._data
|
|
354
388
|
self._data = error.read()
|
|
355
389
|
return self._data
|
|
356
390
|
|
|
357
|
-
def read_json(self, error
|
|
391
|
+
def read_json(self, error=None):
|
|
358
392
|
error = error or self.error
|
|
359
|
-
data = self.read(error
|
|
360
|
-
if legacy.is_bytes(data):
|
|
361
|
-
|
|
362
|
-
|
|
393
|
+
data = self.read(error=error)
|
|
394
|
+
if legacy.is_bytes(data):
|
|
395
|
+
data = data.decode("utf-8")
|
|
396
|
+
try:
|
|
397
|
+
data_j = json.loads(data)
|
|
398
|
+
except Exception:
|
|
399
|
+
data_j = None
|
|
363
400
|
return data_j
|
|
364
401
|
|
|
402
|
+
|
|
365
403
|
class APIError(BaseInternalError):
|
|
366
404
|
"""
|
|
367
405
|
Highest level error for API related problems that may be
|
|
@@ -372,7 +410,8 @@ class APIError(BaseInternalError):
|
|
|
372
410
|
def __init__(self, *args, **kwargs):
|
|
373
411
|
message = kwargs.get("message", None)
|
|
374
412
|
meta = kwargs.get("meta", None)
|
|
375
|
-
BaseInternalError.__init__(self, message, meta
|
|
413
|
+
BaseInternalError.__init__(self, message, meta=meta)
|
|
414
|
+
|
|
376
415
|
|
|
377
416
|
class APIAccessError(APIError):
|
|
378
417
|
"""
|
|
@@ -392,6 +431,7 @@ class APIAccessError(APIError):
|
|
|
392
431
|
kwargs["message"] = self.original.message
|
|
393
432
|
APIError.__init__(self, *args, **kwargs)
|
|
394
433
|
|
|
434
|
+
|
|
395
435
|
class OAuthAccessError(APIAccessError):
|
|
396
436
|
"""
|
|
397
437
|
OAuth related problems that typically involve either outdated
|