clear-skies 2.0.7__py3-none-any.whl → 2.0.9__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.
Potentially problematic release.
This version of clear-skies might be problematic. Click here for more details.
- {clear_skies-2.0.7.dist-info → clear_skies-2.0.9.dist-info}/METADATA +1 -1
- clear_skies-2.0.9.dist-info/RECORD +256 -0
- clearskies/__init__.py +2 -2
- clearskies/authentication/authentication.py +1 -3
- clearskies/authentication/authorization.py +12 -5
- clearskies/authentication/authorization_pass_through.py +5 -3
- clearskies/authentication/jwks.py +25 -23
- clearskies/authentication/secret_bearer.py +15 -17
- clearskies/autodoc/schema/schema.py +1 -1
- clearskies/backends/api_backend.py +50 -56
- clearskies/backends/backend.py +14 -14
- clearskies/backends/cursor_backend.py +17 -23
- clearskies/backends/memory_backend.py +27 -30
- clearskies/backends/secrets_backend.py +13 -18
- clearskies/column.py +44 -56
- clearskies/columns/audit.py +14 -13
- clearskies/columns/belongs_to_id.py +10 -15
- clearskies/columns/belongs_to_model.py +6 -9
- clearskies/columns/belongs_to_self.py +13 -9
- clearskies/columns/boolean.py +13 -16
- clearskies/columns/category_tree.py +9 -11
- clearskies/columns/category_tree_children.py +2 -3
- clearskies/columns/category_tree_descendants.py +1 -1
- clearskies/columns/created.py +8 -11
- clearskies/columns/created_by_authorization_data.py +7 -9
- clearskies/columns/created_by_header.py +12 -8
- clearskies/columns/created_by_ip.py +6 -8
- clearskies/columns/created_by_routing_data.py +12 -7
- clearskies/columns/created_by_user_agent.py +6 -9
- clearskies/columns/date.py +12 -14
- clearskies/columns/datetime.py +19 -17
- clearskies/columns/email.py +3 -1
- clearskies/columns/float.py +10 -14
- clearskies/columns/has_many.py +8 -10
- clearskies/columns/has_many_self.py +13 -7
- clearskies/columns/has_one.py +2 -0
- clearskies/columns/integer.py +9 -11
- clearskies/columns/json.py +10 -12
- clearskies/columns/many_to_many_ids.py +14 -16
- clearskies/columns/many_to_many_ids_with_data.py +16 -16
- clearskies/columns/many_to_many_models.py +5 -7
- clearskies/columns/many_to_many_pivots.py +3 -5
- clearskies/columns/phone.py +12 -9
- clearskies/columns/select.py +12 -9
- clearskies/columns/string.py +1 -1
- clearskies/columns/timestamp.py +15 -15
- clearskies/columns/updated.py +8 -10
- clearskies/columns/uuid.py +7 -10
- clearskies/configs/__init__.py +8 -0
- clearskies/configs/any.py +2 -0
- clearskies/configs/any_dict.py +2 -0
- clearskies/configs/any_dict_or_callable.py +2 -0
- clearskies/configs/boolean.py +2 -0
- clearskies/configs/boolean_or_callable.py +2 -0
- clearskies/configs/callable_config.py +2 -0
- clearskies/configs/config.py +2 -0
- clearskies/configs/datetime.py +2 -0
- clearskies/configs/datetime_or_callable.py +2 -0
- clearskies/configs/email.py +10 -0
- clearskies/configs/email_list.py +17 -0
- clearskies/configs/email_list_or_callable.py +19 -0
- clearskies/configs/email_or_email_list_or_callable.py +59 -0
- clearskies/configs/float.py +2 -0
- clearskies/configs/float_or_callable.py +2 -0
- clearskies/configs/integer.py +2 -0
- clearskies/configs/integer_or_callable.py +2 -0
- clearskies/configs/list_any_dict.py +2 -0
- clearskies/configs/list_any_dict_or_callable.py +2 -0
- clearskies/configs/model_column.py +2 -0
- clearskies/configs/model_columns.py +2 -0
- clearskies/configs/model_destination_name.py +2 -1
- clearskies/configs/model_to_id_column.py +2 -0
- clearskies/configs/readable_model_column.py +2 -0
- clearskies/configs/readable_model_columns.py +2 -0
- clearskies/configs/searchable_model_columns.py +2 -0
- clearskies/configs/select.py +2 -0
- clearskies/configs/select_list.py +2 -0
- clearskies/configs/string.py +4 -2
- clearskies/configs/string_dict.py +2 -0
- clearskies/configs/string_list.py +17 -2
- clearskies/configs/string_list_or_callable.py +13 -0
- clearskies/configs/timedelta.py +2 -0
- clearskies/configs/timezone.py +2 -0
- clearskies/configs/url.py +2 -0
- clearskies/configs/writeable_model_column.py +2 -0
- clearskies/configs/writeable_model_columns.py +2 -0
- clearskies/configurable.py +2 -0
- clearskies/contexts/cli.py +9 -1
- clearskies/contexts/context.py +13 -14
- clearskies/contexts/wsgi.py +12 -10
- clearskies/contexts/wsgi_ref.py +12 -6
- clearskies/decorators.py +1 -1
- clearskies/decorators.pyi +10 -0
- clearskies/di/di.py +7 -6
- clearskies/di/inject/by_class.py +2 -0
- clearskies/di/inject/by_name.py +2 -0
- clearskies/di/inject/di.py +2 -0
- clearskies/di/inject/environment.py +1 -1
- clearskies/di/inject/now.py +2 -0
- clearskies/di/inject/requests.py +2 -0
- clearskies/di/inject/secrets.py +2 -2
- clearskies/di/inject/utcnow.py +2 -0
- clearskies/di/inject/uuid.py +2 -2
- clearskies/end.py +45 -7
- clearskies/endpoint.py +43 -59
- clearskies/endpoint_group.py +15 -18
- clearskies/endpoints/advanced_search.py +19 -26
- clearskies/endpoints/callable.py +10 -16
- clearskies/endpoints/create.py +6 -10
- clearskies/endpoints/delete.py +5 -11
- clearskies/endpoints/get.py +11 -15
- clearskies/endpoints/health_check.py +9 -11
- clearskies/endpoints/list.py +29 -36
- clearskies/endpoints/restful_api.py +43 -53
- clearskies/endpoints/schema.py +14 -18
- clearskies/endpoints/simple_search.py +5 -12
- clearskies/endpoints/update.py +6 -11
- clearskies/environment.py +2 -0
- clearskies/input_outputs/cli.py +2 -0
- clearskies/input_outputs/headers.py +2 -0
- clearskies/input_outputs/input_output.py +15 -15
- clearskies/input_outputs/programmatic.py +2 -2
- clearskies/input_outputs/wsgi.py +2 -2
- clearskies/model.py +120 -25
- clearskies/query/query.py +1 -4
- clearskies/secrets/__init__.py +2 -1
- clearskies/secrets/akeyless.py +16 -11
- clearskies/secrets/secrets.py +7 -2
- clearskies/security_header.py +4 -2
- clearskies/security_headers/cache_control.py +15 -14
- clearskies/security_headers/cors.py +10 -9
- clearskies/security_headers/csp.py +25 -24
- clearskies/security_headers/hsts.py +6 -5
- clearskies/typing.py +1 -1
- clearskies/validator.py +5 -6
- clearskies/validators/after_column.py +6 -7
- clearskies/validators/before_column.py +2 -0
- clearskies/validators/in_the_future.py +5 -8
- clearskies/validators/in_the_future_at_least.py +2 -0
- clearskies/validators/in_the_future_at_most.py +2 -0
- clearskies/validators/in_the_past.py +5 -8
- clearskies/validators/in_the_past_at_least.py +2 -0
- clearskies/validators/in_the_past_at_most.py +2 -0
- clearskies/validators/maximum_length.py +4 -5
- clearskies/validators/maximum_value.py +4 -4
- clearskies/validators/minimum_length.py +4 -4
- clearskies/validators/minimum_value.py +4 -4
- clearskies/validators/required.py +2 -4
- clearskies/validators/timedelta.py +8 -9
- clearskies/validators/unique.py +2 -3
- clear_skies-2.0.7.dist-info/RECORD +0 -251
- {clear_skies-2.0.7.dist-info → clear_skies-2.0.9.dist-info}/WHEEL +0 -0
- {clear_skies-2.0.7.dist-info → clear_skies-2.0.9.dist-info}/licenses/LICENSE +0 -0
clearskies/columns/float.py
CHANGED
|
@@ -2,16 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Callable, Self, overload
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import clearskies.typing
|
|
7
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
8
6
|
from clearskies.autodoc.schema import Number as AutoDocNumber
|
|
9
|
-
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
10
7
|
from clearskies.column import Column
|
|
11
|
-
from clearskies.query import Condition
|
|
12
8
|
|
|
13
9
|
if TYPE_CHECKING:
|
|
14
|
-
from clearskies import Model
|
|
10
|
+
from clearskies import Model, typing
|
|
11
|
+
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
12
|
+
from clearskies.query import Condition
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
class Float(Column):
|
|
@@ -75,7 +73,7 @@ class Float(Column):
|
|
|
75
73
|
auto_doc_class: type[AutoDocSchema] = AutoDocNumber
|
|
76
74
|
_descriptor_config_map = None
|
|
77
75
|
|
|
78
|
-
@
|
|
76
|
+
@decorators.parameters_to_properties
|
|
79
77
|
def __init__(
|
|
80
78
|
self,
|
|
81
79
|
default: float | None = None,
|
|
@@ -84,10 +82,10 @@ class Float(Column):
|
|
|
84
82
|
is_writeable: bool = True,
|
|
85
83
|
is_searchable: bool = True,
|
|
86
84
|
is_temporary: bool = False,
|
|
87
|
-
validators:
|
|
88
|
-
on_change_pre_save:
|
|
89
|
-
on_change_post_save:
|
|
90
|
-
on_change_save_finished:
|
|
85
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
86
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
87
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
88
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
91
89
|
created_by_source_type: str = "",
|
|
92
90
|
created_by_source_key: str = "",
|
|
93
91
|
created_by_source_strict: bool = True,
|
|
@@ -147,7 +145,5 @@ class Float(Column):
|
|
|
147
145
|
|
|
148
146
|
def input_error_for_value(self, value, operator=None):
|
|
149
147
|
return (
|
|
150
|
-
"value should be an integer or float"
|
|
151
|
-
if (type(value) != int and type(value) != float and value is not None)
|
|
152
|
-
else ""
|
|
148
|
+
"value should be an integer or float" if not isinstance(value, (int, float)) and value is not None else ""
|
|
153
149
|
)
|
clearskies/columns/has_many.py
CHANGED
|
@@ -2,18 +2,16 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any, Self, overload
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import clearskies.typing
|
|
7
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators, typing
|
|
8
6
|
from clearskies.autodoc.schema import Array as AutoDocArray
|
|
9
7
|
from clearskies.autodoc.schema import Object as AutoDocObject
|
|
10
|
-
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
11
8
|
from clearskies.column import Column
|
|
12
9
|
from clearskies.di.inject import InputOutput
|
|
13
10
|
from clearskies.functional import string, validations
|
|
14
11
|
|
|
15
12
|
if TYPE_CHECKING:
|
|
16
|
-
from clearskies import Column, Model
|
|
13
|
+
from clearskies import Column, Model, typing
|
|
14
|
+
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
class HasMany(Column):
|
|
@@ -382,17 +380,17 @@ class HasMany(Column):
|
|
|
382
380
|
|
|
383
381
|
input_output = InputOutput()
|
|
384
382
|
|
|
385
|
-
@
|
|
383
|
+
@decorators.parameters_to_properties
|
|
386
384
|
def __init__(
|
|
387
385
|
self,
|
|
388
386
|
child_model_class,
|
|
389
387
|
foreign_column_name: str | None = None,
|
|
390
388
|
readable_child_column_names: list[str] = [],
|
|
391
|
-
where:
|
|
389
|
+
where: typing.condition | list[typing.condition] = [],
|
|
392
390
|
is_readable: bool = True,
|
|
393
|
-
on_change_pre_save:
|
|
394
|
-
on_change_post_save:
|
|
395
|
-
on_change_save_finished:
|
|
391
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
392
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
393
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
396
394
|
):
|
|
397
395
|
pass
|
|
398
396
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from clearskies import decorators
|
|
3
6
|
from clearskies.columns.has_many import HasMany
|
|
4
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from clearskies import typing
|
|
10
|
+
|
|
5
11
|
|
|
6
12
|
class HasManySelf(HasMany):
|
|
7
13
|
"""
|
|
@@ -20,16 +26,16 @@ class HasManySelf(HasMany):
|
|
|
20
26
|
|
|
21
27
|
_descriptor_config_map = None
|
|
22
28
|
|
|
23
|
-
@
|
|
29
|
+
@decorators.parameters_to_properties
|
|
24
30
|
def __init__(
|
|
25
31
|
self,
|
|
26
32
|
foreign_column_name: str | None = None,
|
|
27
33
|
readable_child_columns: list[str] = [],
|
|
28
|
-
where:
|
|
34
|
+
where: typing.condition | list[typing.condition] = [],
|
|
29
35
|
is_readable: bool = True,
|
|
30
|
-
on_change_pre_save:
|
|
31
|
-
on_change_post_save:
|
|
32
|
-
on_change_save_finished:
|
|
36
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
37
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
38
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
33
39
|
):
|
|
34
40
|
pass
|
|
35
41
|
|
clearskies/columns/has_one.py
CHANGED
clearskies/columns/integer.py
CHANGED
|
@@ -2,16 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Callable, Self, overload
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import clearskies.typing
|
|
7
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
8
6
|
from clearskies.autodoc.schema import Integer as AutoDocInteger
|
|
9
|
-
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
10
7
|
from clearskies.column import Column
|
|
11
|
-
from clearskies.query import Condition
|
|
12
8
|
|
|
13
9
|
if TYPE_CHECKING:
|
|
14
|
-
from clearskies import Model
|
|
10
|
+
from clearskies import Model, typing
|
|
11
|
+
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
12
|
+
from clearskies.query import Condition
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
class Integer(Column):
|
|
@@ -77,7 +75,7 @@ class Integer(Column):
|
|
|
77
75
|
|
|
78
76
|
_descriptor_config_map = None
|
|
79
77
|
|
|
80
|
-
@
|
|
78
|
+
@decorators.parameters_to_properties
|
|
81
79
|
def __init__(
|
|
82
80
|
self,
|
|
83
81
|
default: int | None = None,
|
|
@@ -86,10 +84,10 @@ class Integer(Column):
|
|
|
86
84
|
is_writeable: bool = True,
|
|
87
85
|
is_searchable: bool = True,
|
|
88
86
|
is_temporary: bool = False,
|
|
89
|
-
validators:
|
|
90
|
-
on_change_pre_save:
|
|
91
|
-
on_change_post_save:
|
|
92
|
-
on_change_save_finished:
|
|
87
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
88
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
89
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
90
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
93
91
|
created_by_source_type: str = "",
|
|
94
92
|
created_by_source_key: str = "",
|
|
95
93
|
created_by_source_strict: bool = True,
|
clearskies/columns/json.py
CHANGED
|
@@ -3,13 +3,11 @@ from __future__ import annotations
|
|
|
3
3
|
import json
|
|
4
4
|
from typing import TYPE_CHECKING, Any, Callable, Self, overload
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.typing
|
|
8
|
-
from clearskies import configs
|
|
6
|
+
from clearskies import configs, decorators
|
|
9
7
|
from clearskies.column import Column
|
|
10
8
|
|
|
11
9
|
if TYPE_CHECKING:
|
|
12
|
-
from clearskies import Model
|
|
10
|
+
from clearskies import Model, typing
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
class Json(Column):
|
|
@@ -69,12 +67,12 @@ class Json(Column):
|
|
|
69
67
|
|
|
70
68
|
"""
|
|
71
69
|
|
|
72
|
-
setable =
|
|
73
|
-
default =
|
|
70
|
+
setable = configs.Any(default=None) # type: ignore
|
|
71
|
+
default = configs.Any(default=None) # type: ignore
|
|
74
72
|
is_searchable = configs.Boolean(default=False)
|
|
75
73
|
_descriptor_config_map = None
|
|
76
74
|
|
|
77
|
-
@
|
|
75
|
+
@decorators.parameters_to_properties
|
|
78
76
|
def __init__(
|
|
79
77
|
self,
|
|
80
78
|
default: dict[str, Any] | list[Any] | None = None,
|
|
@@ -82,10 +80,10 @@ class Json(Column):
|
|
|
82
80
|
is_readable: bool = True,
|
|
83
81
|
is_writeable: bool = True,
|
|
84
82
|
is_temporary: bool = False,
|
|
85
|
-
validators:
|
|
86
|
-
on_change_pre_save:
|
|
87
|
-
on_change_post_save:
|
|
88
|
-
on_change_save_finished:
|
|
83
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
84
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
85
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
86
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
89
87
|
created_by_source_type: str = "",
|
|
90
88
|
created_by_source_key: str = "",
|
|
91
89
|
created_by_source_strict: bool = True,
|
|
@@ -111,7 +109,7 @@ class Json(Column):
|
|
|
111
109
|
instance._next_data[self.name] = value
|
|
112
110
|
|
|
113
111
|
def from_backend(self, value) -> dict[str, Any] | list[Any] | None:
|
|
114
|
-
if
|
|
112
|
+
if isinstance(value, (list, dict)):
|
|
115
113
|
return value
|
|
116
114
|
if not value:
|
|
117
115
|
return None
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from collections import OrderedDict
|
|
4
3
|
from typing import TYPE_CHECKING, Any, Callable, Self, overload
|
|
5
4
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.typing
|
|
8
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
9
6
|
from clearskies.autodoc.schema import Array as AutoDocArray
|
|
10
7
|
from clearskies.autodoc.schema import String as AutoDocString
|
|
11
8
|
from clearskies.column import Column
|
|
12
|
-
from clearskies.functional import string
|
|
13
9
|
|
|
14
10
|
if TYPE_CHECKING:
|
|
15
|
-
from clearskies import Column, Model
|
|
11
|
+
from clearskies import Column, Model, typing
|
|
16
12
|
|
|
17
13
|
|
|
18
14
|
class ManyToManyIds(Column):
|
|
@@ -78,10 +74,12 @@ class ManyToManyIds(Column):
|
|
|
78
74
|
thing_1 = thingies.create({"name": "Thing 1"})
|
|
79
75
|
thing_2 = thingies.create({"name": "Thing 2"})
|
|
80
76
|
thing_3 = thingies.create({"name": "Thing 3"})
|
|
81
|
-
widget = widgets.create(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
widget = widgets.create(
|
|
78
|
+
{
|
|
79
|
+
"name": "Widget 1",
|
|
80
|
+
"thingy_ids": [thing_1.id, thing_2.id],
|
|
81
|
+
}
|
|
82
|
+
)
|
|
85
83
|
|
|
86
84
|
# remove an item by saving without it's id in place
|
|
87
85
|
widget.save({"thingy_ids": [thing.id for thing in widget.thingies if thing.id != thing_1.id]})
|
|
@@ -173,7 +171,7 @@ class ManyToManyIds(Column):
|
|
|
173
171
|
is_searchable = configs.Boolean(default=False)
|
|
174
172
|
_descriptor_config_map = None
|
|
175
173
|
|
|
176
|
-
@
|
|
174
|
+
@decorators.parameters_to_properties
|
|
177
175
|
def __init__(
|
|
178
176
|
self,
|
|
179
177
|
related_model_class,
|
|
@@ -186,10 +184,10 @@ class ManyToManyIds(Column):
|
|
|
186
184
|
is_readable: bool = True,
|
|
187
185
|
is_writeable: bool = True,
|
|
188
186
|
is_temporary: bool = False,
|
|
189
|
-
validators:
|
|
190
|
-
on_change_pre_save:
|
|
191
|
-
on_change_post_save:
|
|
192
|
-
on_change_save_finished:
|
|
187
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
188
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
189
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
190
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
193
191
|
created_by_source_type: str = "",
|
|
194
192
|
created_by_source_key: str = "",
|
|
195
193
|
created_by_source_strict: bool = True,
|
|
@@ -280,7 +278,7 @@ class ManyToManyIds(Column):
|
|
|
280
278
|
f"{self.own_column_name_in_pivot}=" + getattr(model, self.model_class.id_column_name)
|
|
281
279
|
)
|
|
282
280
|
|
|
283
|
-
def post_save(self, data: dict[str, Any], model:
|
|
281
|
+
def post_save(self, data: dict[str, Any], model: Model, id: int | str) -> None:
|
|
284
282
|
# if our incoming data is not in the data array or is None, then nothing has been set and we do not want
|
|
285
283
|
# to make any changes
|
|
286
284
|
if self.name not in data or data[self.name] is None:
|
|
@@ -2,13 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any, Callable, Self, overload
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import clearskies.typing
|
|
7
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
8
6
|
from clearskies.columns.many_to_many_ids import ManyToManyIds
|
|
9
7
|
|
|
10
8
|
if TYPE_CHECKING:
|
|
11
|
-
from clearskies import Model
|
|
9
|
+
from clearskies import Model, typing
|
|
12
10
|
|
|
13
11
|
|
|
14
12
|
class ManyToManyIdsWithData(ManyToManyIds):
|
|
@@ -64,13 +62,15 @@ class ManyToManyIdsWithData(ManyToManyIds):
|
|
|
64
62
|
thing_1 = thingies.create({"name": "Thing 1"})
|
|
65
63
|
thing_2 = thingies.create({"name": "Thing 2"})
|
|
66
64
|
thing_3 = thingies.create({"name": "Thing 3"})
|
|
67
|
-
widget = widgets.create(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
widget = widgets.create(
|
|
66
|
+
{
|
|
67
|
+
"name": "Widget 1",
|
|
68
|
+
"thingy_ids": [
|
|
69
|
+
{"thingy_id": thing_1.id, "name": "Widget Thing 1", "kind": "Special"},
|
|
70
|
+
{"thingy_id": thing_2.id, "name": "Widget Thing 2", "kind": "Also Special"},
|
|
71
|
+
],
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
74
|
|
|
75
75
|
return widget
|
|
76
76
|
|
|
@@ -149,7 +149,7 @@ class ManyToManyIdsWithData(ManyToManyIds):
|
|
|
149
149
|
setable = configs.ListAnyDictOrCallable(default=None) # type: ignore
|
|
150
150
|
_descriptor_config_map = None
|
|
151
151
|
|
|
152
|
-
@
|
|
152
|
+
@decorators.parameters_to_properties
|
|
153
153
|
def __init__(
|
|
154
154
|
self,
|
|
155
155
|
related_model_class,
|
|
@@ -165,10 +165,10 @@ class ManyToManyIdsWithData(ManyToManyIds):
|
|
|
165
165
|
is_readable: bool = True,
|
|
166
166
|
is_writeable: bool = True,
|
|
167
167
|
is_temporary: bool = False,
|
|
168
|
-
validators:
|
|
169
|
-
on_change_pre_save:
|
|
170
|
-
on_change_post_save:
|
|
171
|
-
on_change_save_finished:
|
|
168
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
169
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
170
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
171
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
172
172
|
created_by_source_type: str = "",
|
|
173
173
|
created_by_source_key: str = "",
|
|
174
174
|
created_by_source_strict: bool = True,
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from collections import OrderedDict
|
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Self, overload
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.typing
|
|
8
|
-
from clearskies import configs
|
|
6
|
+
from clearskies import configs, decorators
|
|
9
7
|
from clearskies.autodoc.schema import Array as AutoDocArray
|
|
10
8
|
from clearskies.autodoc.schema import Object as AutoDocObject
|
|
11
9
|
from clearskies.column import Column
|
|
@@ -30,7 +28,7 @@ class ManyToManyModels(Column):
|
|
|
30
28
|
is_searchable = configs.Boolean(default=False)
|
|
31
29
|
_descriptor_config_map = None
|
|
32
30
|
|
|
33
|
-
@
|
|
31
|
+
@decorators.parameters_to_properties
|
|
34
32
|
def __init__(
|
|
35
33
|
self,
|
|
36
34
|
many_to_many_column_name,
|
|
@@ -93,7 +91,7 @@ class ManyToManyModels(Column):
|
|
|
93
91
|
|
|
94
92
|
# we allow a list of models or a model, but if it's a model it may represent a single record or a query.
|
|
95
93
|
# if it's a single record then we want to wrap it in a list so we can iterate over it.
|
|
96
|
-
if hasattr(value, "_data") and value._data:
|
|
94
|
+
if hasattr(value, "_data") and isinstance(value, Model) and value._data:
|
|
97
95
|
value = []
|
|
98
96
|
many_to_many_column: ManyToManyIds = self.many_to_many_column # type: ignore
|
|
99
97
|
related_model_class = many_to_many_column.related_model_class
|
|
@@ -147,7 +145,7 @@ class ManyToManyModels(Column):
|
|
|
147
145
|
|
|
148
146
|
for column_name in many_to_many_column.readable_related_column_names:
|
|
149
147
|
related_docs = columns[column_name].documentation()
|
|
150
|
-
if
|
|
148
|
+
if not isinstance(related_docs, list):
|
|
151
149
|
related_docs = [related_docs]
|
|
152
150
|
related_properties.extend(related_docs)
|
|
153
151
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from collections import OrderedDict
|
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Self, overload
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.typing
|
|
8
|
-
from clearskies import configs
|
|
6
|
+
from clearskies import configs, decorators
|
|
9
7
|
from clearskies.autodoc.schema import Array as AutoDocArray
|
|
10
8
|
from clearskies.autodoc.schema import Object as AutoDocObject
|
|
11
9
|
from clearskies.column import Column
|
|
@@ -31,7 +29,7 @@ class ManyToManyPivots(Column):
|
|
|
31
29
|
is_searchable = configs.Boolean(default=False)
|
|
32
30
|
_descriptor_config_map = None
|
|
33
31
|
|
|
34
|
-
@
|
|
32
|
+
@decorators.parameters_to_properties
|
|
35
33
|
def __init__(
|
|
36
34
|
self,
|
|
37
35
|
many_to_many_column_name,
|
clearskies/columns/phone.py
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import re
|
|
2
|
-
from typing import Any, Callable
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Callable
|
|
3
5
|
|
|
4
|
-
import
|
|
5
|
-
import clearskies.typing
|
|
6
|
-
from clearskies import configs
|
|
6
|
+
from clearskies import configs, decorators
|
|
7
7
|
from clearskies.columns.string import String
|
|
8
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from clearskies import typing
|
|
11
|
+
|
|
9
12
|
|
|
10
13
|
class Phone(String):
|
|
11
14
|
"""
|
|
@@ -99,7 +102,7 @@ class Phone(String):
|
|
|
99
102
|
usa_only = configs.Boolean(default=True)
|
|
100
103
|
_descriptor_config_map = None
|
|
101
104
|
|
|
102
|
-
@
|
|
105
|
+
@decorators.parameters_to_properties
|
|
103
106
|
def __init__(
|
|
104
107
|
self,
|
|
105
108
|
usa_only: bool = True,
|
|
@@ -109,10 +112,10 @@ class Phone(String):
|
|
|
109
112
|
is_writeable: bool = True,
|
|
110
113
|
is_searchable: bool = True,
|
|
111
114
|
is_temporary: bool = False,
|
|
112
|
-
validators:
|
|
113
|
-
on_change_pre_save:
|
|
114
|
-
on_change_post_save:
|
|
115
|
-
on_change_save_finished:
|
|
115
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
116
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
117
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
118
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
116
119
|
created_by_source_type: str = "",
|
|
117
120
|
created_by_source_key: str = "",
|
|
118
121
|
created_by_source_strict: bool = True,
|
clearskies/columns/select.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
from clearskies import configs
|
|
3
|
+
from typing import TYPE_CHECKING, Callable
|
|
4
|
+
|
|
5
|
+
from clearskies import configs, decorators
|
|
6
6
|
from clearskies.columns.string import String
|
|
7
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from clearskies import typing
|
|
10
|
+
|
|
8
11
|
|
|
9
12
|
class Select(String):
|
|
10
13
|
"""
|
|
@@ -68,7 +71,7 @@ class Select(String):
|
|
|
68
71
|
allowed_values = configs.StringList(required=True)
|
|
69
72
|
_descriptor_config_map = None
|
|
70
73
|
|
|
71
|
-
@
|
|
74
|
+
@decorators.parameters_to_properties
|
|
72
75
|
def __init__(
|
|
73
76
|
self,
|
|
74
77
|
allowed_values: list[str],
|
|
@@ -78,10 +81,10 @@ class Select(String):
|
|
|
78
81
|
is_writeable: bool = True,
|
|
79
82
|
is_searchable: bool = True,
|
|
80
83
|
is_temporary: bool = False,
|
|
81
|
-
validators:
|
|
82
|
-
on_change_pre_save:
|
|
83
|
-
on_change_post_save:
|
|
84
|
-
on_change_save_finished:
|
|
84
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
85
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
86
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
87
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
85
88
|
created_by_source_type: str = "",
|
|
86
89
|
created_by_source_key: str = "",
|
|
87
90
|
created_by_source_strict: bool = True,
|
clearskies/columns/string.py
CHANGED
|
@@ -99,4 +99,4 @@ class String(Column):
|
|
|
99
99
|
instance._next_data[self.name] = value
|
|
100
100
|
|
|
101
101
|
def input_error_for_value(self, value: str, operator: str | None = None) -> str:
|
|
102
|
-
return "value should be a string" if
|
|
102
|
+
return "value should be a string" if not isinstance(value, str) else ""
|
clearskies/columns/timestamp.py
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import datetime
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Callable, Self,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Callable, Self, overload
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.typing
|
|
8
|
-
from clearskies import configs
|
|
6
|
+
from clearskies import configs, decorators
|
|
9
7
|
from clearskies.columns.datetime import Datetime
|
|
10
8
|
|
|
11
9
|
if TYPE_CHECKING:
|
|
12
|
-
from clearskies import Model
|
|
10
|
+
from clearskies import Model, typing
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
class Timestamp(Datetime):
|
|
@@ -36,10 +34,12 @@ class Timestamp(Datetime):
|
|
|
36
34
|
|
|
37
35
|
|
|
38
36
|
def demo_timestamp(utcnow: datetime.datetime, pets: Pet) -> dict[str, str | int]:
|
|
39
|
-
pet = pets.create(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
pet = pets.create(
|
|
38
|
+
{
|
|
39
|
+
"name": "Spot",
|
|
40
|
+
"last_fed": utcnow,
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
43
|
return {
|
|
44
44
|
"last_fed": pet.last_fed.isoformat(),
|
|
45
45
|
"raw_data": pet.get_raw_data()["last_fed"],
|
|
@@ -76,7 +76,7 @@ class Timestamp(Datetime):
|
|
|
76
76
|
include_microseconds = configs.Boolean(default=False)
|
|
77
77
|
_descriptor_config_map = None
|
|
78
78
|
|
|
79
|
-
@
|
|
79
|
+
@decorators.parameters_to_properties
|
|
80
80
|
def __init__(
|
|
81
81
|
self,
|
|
82
82
|
include_microseconds: bool = False,
|
|
@@ -86,10 +86,10 @@ class Timestamp(Datetime):
|
|
|
86
86
|
is_writeable: bool = True,
|
|
87
87
|
is_searchable: bool = True,
|
|
88
88
|
is_temporary: bool = False,
|
|
89
|
-
validators:
|
|
90
|
-
on_change_pre_save:
|
|
91
|
-
on_change_post_save:
|
|
92
|
-
on_change_save_finished:
|
|
89
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
90
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
91
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
92
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
93
93
|
created_by_source_type: str = "",
|
|
94
94
|
created_by_source_key: str = "",
|
|
95
95
|
created_by_source_strict: bool = True,
|
|
@@ -106,7 +106,7 @@ class Timestamp(Datetime):
|
|
|
106
106
|
f"Invalid data was found in the backend for model {self.model_class.__name__} and column {self.name}: a string value was found that is not a timestamp. It was '{value}'"
|
|
107
107
|
)
|
|
108
108
|
date = datetime.datetime.fromtimestamp(int(value) / mult, datetime.timezone.utc)
|
|
109
|
-
elif isinstance(value, int
|
|
109
|
+
elif isinstance(value, (int, float)):
|
|
110
110
|
date = datetime.datetime.fromtimestamp(value / mult, datetime.timezone.utc)
|
|
111
111
|
else:
|
|
112
112
|
if not isinstance(value, datetime.datetime):
|
clearskies/columns/updated.py
CHANGED
|
@@ -3,14 +3,12 @@ from __future__ import annotations
|
|
|
3
3
|
import datetime
|
|
4
4
|
from typing import TYPE_CHECKING, Any
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.di
|
|
8
|
-
import clearskies.typing
|
|
9
|
-
from clearskies import configs
|
|
6
|
+
from clearskies import configs, decorators
|
|
10
7
|
from clearskies.columns.datetime import Datetime
|
|
8
|
+
from clearskies.di import inject
|
|
11
9
|
|
|
12
10
|
if TYPE_CHECKING:
|
|
13
|
-
from clearskies import Model
|
|
11
|
+
from clearskies import Model, typing
|
|
14
12
|
|
|
15
13
|
|
|
16
14
|
class Updated(Datetime):
|
|
@@ -83,9 +81,9 @@ class Updated(Datetime):
|
|
|
83
81
|
is_writeable = configs.Boolean(default=False)
|
|
84
82
|
_descriptor_config_map = None
|
|
85
83
|
|
|
86
|
-
now =
|
|
84
|
+
now = inject.Now()
|
|
87
85
|
|
|
88
|
-
@
|
|
86
|
+
@decorators.parameters_to_properties
|
|
89
87
|
def __init__(
|
|
90
88
|
self,
|
|
91
89
|
in_utc: bool = True,
|
|
@@ -94,9 +92,9 @@ class Updated(Datetime):
|
|
|
94
92
|
is_readable: bool = True,
|
|
95
93
|
is_searchable: bool = True,
|
|
96
94
|
is_temporary: bool = False,
|
|
97
|
-
on_change_pre_save:
|
|
98
|
-
on_change_post_save:
|
|
99
|
-
on_change_save_finished:
|
|
95
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
96
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
97
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
100
98
|
):
|
|
101
99
|
pass
|
|
102
100
|
|