appier 1.34.4__tar.gz → 1.34.6__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.
- {appier-1.34.4/src/appier.egg-info → appier-1.34.6}/PKG-INFO +1 -1
- appier-1.34.6/pyproject.toml +2 -0
- {appier-1.34.4 → appier-1.34.6}/setup.py +1 -1
- {appier-1.34.4 → appier-1.34.6}/src/appier/base.py +22 -11
- {appier-1.34.4 → appier-1.34.6}/src/appier/config.py +1 -4
- {appier-1.34.4 → appier-1.34.6}/src/appier/model.py +5 -4
- {appier-1.34.4 → appier-1.34.6}/src/appier/model.pyi +20 -1
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/base.py +2 -5
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/util.py +3 -16
- {appier-1.34.4 → appier-1.34.6}/src/appier/util.py +1 -6
- {appier-1.34.4 → appier-1.34.6/src/appier.egg-info}/PKG-INFO +1 -1
- {appier-1.34.4 → appier-1.34.6}/src/appier.egg-info/SOURCES.txt +1 -0
- {appier-1.34.4 → appier-1.34.6}/MANIFEST.in +0 -0
- {appier-1.34.4 → appier-1.34.6}/README.rst +0 -0
- {appier-1.34.4 → appier-1.34.6}/setup.cfg +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/__init__.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/amqp.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/api.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/asgi.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/async_neo.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/async_old.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/asynchronous.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/asynchronous.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/base.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/bus.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/bus.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/cache.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/cache.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/common.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/component.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/component.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/compress.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/controller.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/crypt.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/data.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/data.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/defines.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/exceptions.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/execution.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/export.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/extra.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/extra_neo.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/extra_old.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/geo.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/git.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/graph.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/http.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/legacy.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/log.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/meta.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/mock.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/model_a.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/mongo.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/observer.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/part.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/part.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/preferences.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/preferences.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/queuing.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/redisdb.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/request.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/res/static/css/base.css +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/res/static/images/favicon.ico +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/res/static/js/base.js +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/res/templates/error.html.tpl +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/res/templates/holder.html.tpl +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/res/templates/layout.html.tpl +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/scheduler.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/scheduler.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/serialize.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/session.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/session.pyi +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/settings.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/smtp.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/storage.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/structures.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/__init__.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/cache.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/config.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/crypt.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/data.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/exceptions.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/export.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/graph.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/http.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/legacy.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/log.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/mock.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/model.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/part.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/preferences.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/queuing.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/request.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/scheduler.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/serialize.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/session.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/smtp.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/structures.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/typesf.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/test/validation.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/typesf.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier/validation.py +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier.egg-info/dependency_links.txt +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier.egg-info/not-zip-safe +0 -0
- {appier-1.34.4 → appier-1.34.6}/src/appier.egg-info/top_level.txt +0 -0
|
@@ -94,7 +94,7 @@ NAME = "appier"
|
|
|
94
94
|
""" The name to be used to describe the framework while working
|
|
95
95
|
on its own environment, this is just a descriptive value """
|
|
96
96
|
|
|
97
|
-
VERSION = "1.34.
|
|
97
|
+
VERSION = "1.34.6"
|
|
98
98
|
""" The version of the framework that is currently installed
|
|
99
99
|
this value may be used for debugging/diagnostic purposes """
|
|
100
100
|
|
|
@@ -1781,7 +1781,7 @@ class App(
|
|
|
1781
1781
|
# so that class level operations may be performed
|
|
1782
1782
|
cls = self.__class__
|
|
1783
1783
|
|
|
1784
|
-
# tries to ensure that the
|
|
1784
|
+
# tries to ensure that the UUID value of the exception is set,
|
|
1785
1785
|
# notice that under some extreme occasions it may not be possible
|
|
1786
1786
|
# to ensure such behavior (eg: native code based exception)
|
|
1787
1787
|
if not hasattr(exception, "uid"):
|
|
@@ -1821,6 +1821,10 @@ class App(
|
|
|
1821
1821
|
# "raised" by the current exception object in handling
|
|
1822
1822
|
self.request.set_headers(headers)
|
|
1823
1823
|
|
|
1824
|
+
# sets the additional error trace identifier header in the request, to allow
|
|
1825
|
+
# extra debug support for the error
|
|
1826
|
+
self.request.set_header("X-Error-Id", exception.uid)
|
|
1827
|
+
|
|
1824
1828
|
# runs the on error processor in the base application object and in case
|
|
1825
1829
|
# a value is returned by a possible handler it is used as the response
|
|
1826
1830
|
# for the current request (instead of the normal handler)
|
|
@@ -2232,7 +2236,7 @@ class App(
|
|
|
2232
2236
|
def warning(self, message):
|
|
2233
2237
|
self.request.warning(message)
|
|
2234
2238
|
|
|
2235
|
-
def redirect(self, url, code=303, params=None, **kwargs):
|
|
2239
|
+
def redirect(self, url, code=303, relative=False, params=None, **kwargs):
|
|
2236
2240
|
# in case there are no explicit parameters provided then the
|
|
2237
2241
|
# named arguments should be used instead
|
|
2238
2242
|
if params == None:
|
|
@@ -2244,6 +2248,15 @@ class App(
|
|
|
2244
2248
|
if query:
|
|
2245
2249
|
url += ("&" if "?" in url else "?") + query
|
|
2246
2250
|
|
|
2251
|
+
# in case a relative URL is expected, makes sure we enforce one
|
|
2252
|
+
# preventing possible absolute URL redirections
|
|
2253
|
+
if relative:
|
|
2254
|
+
is_absolute = url.startswith(("http://", "https://", "//"))
|
|
2255
|
+
if is_absolute:
|
|
2256
|
+
raise exceptions.SecurityError(
|
|
2257
|
+
message="Attempt to redirect to absolute URL", code=401
|
|
2258
|
+
)
|
|
2259
|
+
|
|
2247
2260
|
# sets both the (redirection) code and the new location URL
|
|
2248
2261
|
# values in the current request (response) object
|
|
2249
2262
|
self.request.code = code
|
|
@@ -2454,11 +2467,7 @@ class App(
|
|
|
2454
2467
|
|
|
2455
2468
|
parameters = dict(kwargs)
|
|
2456
2469
|
parameters.update(
|
|
2457
|
-
sender=sender,
|
|
2458
|
-
receivers=receivers,
|
|
2459
|
-
cc=cc,
|
|
2460
|
-
bcc=bcc,
|
|
2461
|
-
subject=subject,
|
|
2470
|
+
sender=sender, receivers=receivers, cc=cc, bcc=bcc, subject=subject
|
|
2462
2471
|
)
|
|
2463
2472
|
|
|
2464
2473
|
if html == None:
|
|
@@ -4065,9 +4074,7 @@ class App(
|
|
|
4065
4074
|
# is possible raises a not found error
|
|
4066
4075
|
part_s = self.get_part(part)
|
|
4067
4076
|
if not part_s:
|
|
4068
|
-
raise exceptions.NotFoundError(
|
|
4069
|
-
message="Part not found '%s'" % part,
|
|
4070
|
-
)
|
|
4077
|
+
raise exceptions.NotFoundError(message="Part not found '%s'" % part)
|
|
4071
4078
|
|
|
4072
4079
|
# sends the static information taking into account the
|
|
4073
4080
|
# provided data and the base static path of the part
|
|
@@ -6576,6 +6583,10 @@ class WebApp(App):
|
|
|
6576
6583
|
# "raised" by the current exception object in handling
|
|
6577
6584
|
self.request.set_headers(headers)
|
|
6578
6585
|
|
|
6586
|
+
# sets the additional error trace identifier header in the request, to allow
|
|
6587
|
+
# extra debug support for the error
|
|
6588
|
+
self.request.set_header("X-Error-Id", exception.uid)
|
|
6589
|
+
|
|
6579
6590
|
# run the on error processor in the base application object and in case
|
|
6580
6591
|
# a value is returned by a possible handler it is used as the response
|
|
6581
6592
|
# for the current request (instead of the normal handler)
|
|
@@ -163,10 +163,7 @@ def load(names=(FILE_NAME,), path=None, encoding="utf-8", ctx=None):
|
|
|
163
163
|
paths = []
|
|
164
164
|
homes = get_homes()
|
|
165
165
|
for home in homes:
|
|
166
|
-
paths += [
|
|
167
|
-
os.path.join(home),
|
|
168
|
-
os.path.join(home, ".config"),
|
|
169
|
-
]
|
|
166
|
+
paths += [os.path.join(home), os.path.join(home, ".config")]
|
|
170
167
|
paths += [sys.prefix]
|
|
171
168
|
paths.append(path)
|
|
172
169
|
for path in paths:
|
|
@@ -148,10 +148,7 @@ so that they are lazy loaded from the data source, these kind
|
|
|
148
148
|
of types should be compliant to a common interface so that they
|
|
149
149
|
may be used "blindly" from an external entity """
|
|
150
150
|
|
|
151
|
-
REVERSE = dict(
|
|
152
|
-
descending="ascending",
|
|
153
|
-
ascending="descending",
|
|
154
|
-
)
|
|
151
|
+
REVERSE = dict(descending="ascending", ascending="descending")
|
|
155
152
|
""" The reverse order dictionary that maps a certain
|
|
156
153
|
order direction (as a string) with the opposite one
|
|
157
154
|
this may be used to "calculate" the reverse value """
|
|
@@ -2260,6 +2257,10 @@ class Model(legacy.with_meta(meta.Ordered, observer.Observable, *EXTRA_CLS)):
|
|
|
2260
2257
|
return result
|
|
2261
2258
|
return base
|
|
2262
2259
|
|
|
2260
|
+
@property
|
|
2261
|
+
def identity(self):
|
|
2262
|
+
return self._id
|
|
2263
|
+
|
|
2263
2264
|
@property
|
|
2264
2265
|
def request(self):
|
|
2265
2266
|
return common.base().get_request()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Callable, Self, Sequence
|
|
1
|
+
from typing import Any, Callable, Self, Sequence
|
|
2
2
|
from .base import App
|
|
3
3
|
|
|
4
4
|
class Model:
|
|
@@ -40,9 +40,28 @@ class Model:
|
|
|
40
40
|
before_callbacks: Sequence[Callable[[Self], None]] = ...,
|
|
41
41
|
after_callbacks: Sequence[Callable[[Self], None]] = ...,
|
|
42
42
|
) -> Self: ...
|
|
43
|
+
@property
|
|
44
|
+
def identity(self) -> Any: ...
|
|
43
45
|
...
|
|
44
46
|
|
|
45
47
|
class Field:
|
|
46
48
|
def __init__(self, *args, **kwargs): ...
|
|
47
49
|
|
|
50
|
+
def link(
|
|
51
|
+
name: str | None = ...,
|
|
52
|
+
description: str | None = ...,
|
|
53
|
+
parameters: tuple = ...,
|
|
54
|
+
context: bool = ...,
|
|
55
|
+
devel: bool = ...,
|
|
56
|
+
) -> Callable[[Callable], Callable]: ...
|
|
57
|
+
def operation(
|
|
58
|
+
name: str | None = ...,
|
|
59
|
+
description: str | None = ...,
|
|
60
|
+
parameters: tuple = ...,
|
|
61
|
+
kwargs: dict[str, Any] | None = ...,
|
|
62
|
+
factory: bool = ...,
|
|
63
|
+
level: int = ...,
|
|
64
|
+
devel: bool = ...,
|
|
65
|
+
) -> Callable[[Callable], Callable]: ...
|
|
66
|
+
|
|
48
67
|
field = Field
|
|
@@ -173,7 +173,7 @@ class BaseTest(unittest.TestCase):
|
|
|
173
173
|
invalid_email=["john"],
|
|
174
174
|
valid_length=["1234"],
|
|
175
175
|
invalid_length=["12345"],
|
|
176
|
-
)
|
|
176
|
+
)
|
|
177
177
|
)
|
|
178
178
|
self.app._request = request
|
|
179
179
|
|
|
@@ -369,10 +369,7 @@ class BaseTest(unittest.TestCase):
|
|
|
369
369
|
self.skipTest("No Jinja2 template engine present")
|
|
370
370
|
|
|
371
371
|
self.app._register_bundle(
|
|
372
|
-
{
|
|
373
|
-
"hello": appier.legacy.u("olá"),
|
|
374
|
-
"world": appier.legacy.u("mundo"),
|
|
375
|
-
},
|
|
372
|
+
{"hello": appier.legacy.u("olá"), "world": appier.legacy.u("mundo")},
|
|
376
373
|
"pt_pt",
|
|
377
374
|
)
|
|
378
375
|
|
|
@@ -555,11 +555,7 @@ class UtilTest(unittest.TestCase):
|
|
|
555
555
|
self.assertEqual(type(result), list)
|
|
556
556
|
self.assertEqual(result, [])
|
|
557
557
|
|
|
558
|
-
result = appier.email_base(
|
|
559
|
-
[
|
|
560
|
-
appier.legacy.u(""),
|
|
561
|
-
]
|
|
562
|
-
)
|
|
558
|
+
result = appier.email_base([appier.legacy.u("")])
|
|
563
559
|
self.assertEqual(type(result), list)
|
|
564
560
|
self.assertEqual(result, [])
|
|
565
561
|
|
|
@@ -582,8 +578,7 @@ class UtilTest(unittest.TestCase):
|
|
|
582
578
|
raise appier.OperationalError(message="hello")
|
|
583
579
|
|
|
584
580
|
struct = appier.lazy_dict(
|
|
585
|
-
first=appier.lazy(lambda: raiser()),
|
|
586
|
-
second=appier.lazy(lambda: 2),
|
|
581
|
+
first=appier.lazy(lambda: raiser()), second=appier.lazy(lambda: 2)
|
|
587
582
|
)
|
|
588
583
|
|
|
589
584
|
errors = appier.gather_errors(struct)
|
|
@@ -1077,15 +1072,7 @@ class UtilTest(unittest.TestCase):
|
|
|
1077
1072
|
),
|
|
1078
1073
|
)
|
|
1079
1074
|
|
|
1080
|
-
first = {
|
|
1081
|
-
"info": {
|
|
1082
|
-
"personal": {
|
|
1083
|
-
"general": {
|
|
1084
|
-
"kind": "human",
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1075
|
+
first = {"info": {"personal": {"general": {"kind": "human"}}}}
|
|
1089
1076
|
second = {
|
|
1090
1077
|
"info": {
|
|
1091
1078
|
"personal": {"general": {"kind": "cat", "tail": "long", "meaw": 12}},
|
|
@@ -68,12 +68,7 @@ ALL_CAP_REGEX = re.compile(r"([a-z0-9])([A-Z])")
|
|
|
68
68
|
upper case letter regex that will provide a way of
|
|
69
69
|
putting the underscore in the middle of the transition """
|
|
70
70
|
|
|
71
|
-
SORT_MAP = {
|
|
72
|
-
"1": 1,
|
|
73
|
-
"-1": -1,
|
|
74
|
-
"ascending": 1,
|
|
75
|
-
"descending": -1,
|
|
76
|
-
}
|
|
71
|
+
SORT_MAP = {"1": 1, "-1": -1, "ascending": 1, "descending": -1}
|
|
77
72
|
""" The map associating the normalized (text) way of
|
|
78
73
|
representing sorting with the current infra-structure
|
|
79
74
|
number way of representing the same information """
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|