clear-skies 2.0.7__py3-none-any.whl → 2.0.8__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.8.dist-info}/METADATA +1 -1
- clear_skies-2.0.8.dist-info/RECORD +252 -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/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/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 +2 -0
- clearskies/configs/string_dict.py +2 -0
- clearskies/configs/string_list.py +2 -0
- clearskies/configs/string_list_or_callable.py +2 -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 +12 -10
- 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.8.dist-info}/WHEEL +0 -0
- {clear_skies-2.0.7.dist-info → clear_skies-2.0.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,8 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from collections import OrderedDict
|
|
4
4
|
from typing import TYPE_CHECKING, Any, Self, overload
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
from clearskies import configs
|
|
6
|
+
from clearskies import configs, decorators
|
|
8
7
|
from clearskies.column import Column
|
|
9
8
|
from clearskies.columns.belongs_to_id import BelongsToId
|
|
10
9
|
from clearskies.functional import validations
|
|
@@ -19,10 +18,10 @@ class BelongsToModel(Column):
|
|
|
19
18
|
""" The name of the belongs to column we are connected to. """
|
|
20
19
|
belongs_to_column_name = configs.ModelColumn(required=True)
|
|
21
20
|
|
|
22
|
-
is_temporary =
|
|
21
|
+
is_temporary = configs.boolean.Boolean(default=True)
|
|
23
22
|
_descriptor_config_map = None
|
|
24
23
|
|
|
25
|
-
@
|
|
24
|
+
@decorators.parameters_to_properties
|
|
26
25
|
def __init__(
|
|
27
26
|
self,
|
|
28
27
|
belongs_to_column_name: str,
|
|
@@ -45,11 +44,11 @@ class BelongsToModel(Column):
|
|
|
45
44
|
belongs_to_column.model_column_name = name
|
|
46
45
|
|
|
47
46
|
@overload
|
|
48
|
-
def __get__(self,
|
|
47
|
+
def __get__(self, model: None, cls: type[Model]) -> Self:
|
|
49
48
|
pass
|
|
50
49
|
|
|
51
50
|
@overload
|
|
52
|
-
def __get__(self,
|
|
51
|
+
def __get__(self, model: Model, cls: type[Model]) -> Model:
|
|
53
52
|
pass
|
|
54
53
|
|
|
55
54
|
def __get__(self, model, cls):
|
|
@@ -106,9 +105,7 @@ class BelongsToModel(Column):
|
|
|
106
105
|
def join_table_alias(self) -> str:
|
|
107
106
|
return getattr(self.model_class, self.belongs_to_column_name).join_table_alias()
|
|
108
107
|
|
|
109
|
-
def add_search(
|
|
110
|
-
self, model: clearskies.model.Model, value: str, operator: str = "", relationship_reference: str = ""
|
|
111
|
-
) -> clearskies.model.Model:
|
|
108
|
+
def add_search(self, model: Model, value: str, operator: str = "", relationship_reference: str = "") -> Model:
|
|
112
109
|
return getattr(self.model_class, self.belongs_to_column_name).add_search(
|
|
113
110
|
model, value, operator, relationship_reference=relationship_reference
|
|
114
111
|
)
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
from typing import TYPE_CHECKING, Callable
|
|
4
|
+
|
|
5
|
+
from clearskies import decorators
|
|
5
6
|
from clearskies.columns.belongs_to_id import BelongsToId
|
|
6
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from clearskies import typing
|
|
10
|
+
|
|
7
11
|
|
|
8
12
|
class BelongsToSelf(BelongsToId):
|
|
9
13
|
"""
|
|
@@ -69,22 +73,22 @@ class BelongsToSelf(BelongsToId):
|
|
|
69
73
|
|
|
70
74
|
_descriptor_config_map = None
|
|
71
75
|
|
|
72
|
-
@
|
|
76
|
+
@decorators.parameters_to_properties
|
|
73
77
|
def __init__(
|
|
74
78
|
self,
|
|
75
79
|
readable_parent_columns: list[str] = [],
|
|
76
80
|
join_type: str | None = None,
|
|
77
|
-
where:
|
|
81
|
+
where: typing.condition | list[typing.condition] = [],
|
|
78
82
|
default: str | None = None,
|
|
79
83
|
setable: str | Callable | None = None,
|
|
80
84
|
is_readable: bool = True,
|
|
81
85
|
is_writeable: bool = True,
|
|
82
86
|
is_searchable: bool = True,
|
|
83
87
|
is_temporary: bool = False,
|
|
84
|
-
validators:
|
|
85
|
-
on_change_pre_save:
|
|
86
|
-
on_change_post_save:
|
|
87
|
-
on_change_save_finished:
|
|
88
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
89
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
90
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
91
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
88
92
|
created_by_source_type: str = "",
|
|
89
93
|
created_by_source_key: str = "",
|
|
90
94
|
created_by_source_strict: bool = True,
|
clearskies/columns/boolean.py
CHANGED
|
@@ -2,17 +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.decorators
|
|
7
|
-
import clearskies.typing
|
|
8
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
9
6
|
from clearskies.autodoc.schema import Boolean as AutoDocBoolean
|
|
10
|
-
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
11
7
|
from clearskies.column import Column
|
|
12
|
-
from clearskies.query import Condition
|
|
13
8
|
|
|
14
9
|
if TYPE_CHECKING:
|
|
15
|
-
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
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
class Boolean(Column):
|
|
@@ -21,12 +18,12 @@ class Boolean(Column):
|
|
|
21
18
|
"""
|
|
22
19
|
Actions to trigger when the column changes to True
|
|
23
20
|
"""
|
|
24
|
-
on_true =
|
|
21
|
+
on_true = configs.actions.Actions(default=[])
|
|
25
22
|
|
|
26
23
|
"""
|
|
27
24
|
Actions to trigger when the column changes to False
|
|
28
25
|
"""
|
|
29
|
-
on_false =
|
|
26
|
+
on_false = configs.actions.Actions(default=[])
|
|
30
27
|
|
|
31
28
|
"""
|
|
32
29
|
The class to use when documenting this column
|
|
@@ -38,7 +35,7 @@ class Boolean(Column):
|
|
|
38
35
|
setable = configs.BooleanOrCallable() # type: ignore
|
|
39
36
|
_descriptor_config_map = None
|
|
40
37
|
|
|
41
|
-
@
|
|
38
|
+
@decorators.parameters_to_properties
|
|
42
39
|
def __init__(
|
|
43
40
|
self,
|
|
44
41
|
default: bool | None = None,
|
|
@@ -47,12 +44,12 @@ class Boolean(Column):
|
|
|
47
44
|
is_writeable: bool = True,
|
|
48
45
|
is_searchable: bool = True,
|
|
49
46
|
is_temporary: bool = False,
|
|
50
|
-
validators:
|
|
51
|
-
on_change_pre_save:
|
|
52
|
-
on_change_post_save:
|
|
53
|
-
on_change_save_finished:
|
|
54
|
-
on_true:
|
|
55
|
-
on_false:
|
|
47
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
48
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
49
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
50
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
51
|
+
on_true: typing.action | list[typing.action] = [],
|
|
52
|
+
on_false: typing.action | list[typing.action] = [],
|
|
56
53
|
created_by_source_type: str = "",
|
|
57
54
|
created_by_source_key: str = "",
|
|
58
55
|
created_by_source_strict: bool = True,
|
|
@@ -2,13 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any, Callable
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import clearskies.typing
|
|
7
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
8
6
|
from clearskies.columns.belongs_to_id import BelongsToId
|
|
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 CategoryTree(BelongsToId):
|
|
@@ -163,7 +161,7 @@ class CategoryTree(BelongsToId):
|
|
|
163
161
|
|
|
164
162
|
_descriptor_config_map = None
|
|
165
163
|
|
|
166
|
-
@
|
|
164
|
+
@decorators.parameters_to_properties
|
|
167
165
|
def __init__(
|
|
168
166
|
self,
|
|
169
167
|
tree_model_class,
|
|
@@ -175,17 +173,17 @@ class CategoryTree(BelongsToId):
|
|
|
175
173
|
load_relatives_strategy: str = "join",
|
|
176
174
|
readable_parent_columns: list[str] = [],
|
|
177
175
|
join_type: str | None = None,
|
|
178
|
-
where:
|
|
176
|
+
where: typing.condition | list[typing.condition] = [],
|
|
179
177
|
default: str | None = None,
|
|
180
178
|
setable: str | Callable | None = None,
|
|
181
179
|
is_readable: bool = True,
|
|
182
180
|
is_writeable: bool = True,
|
|
183
181
|
is_searchable: bool = True,
|
|
184
182
|
is_temporary: bool = False,
|
|
185
|
-
validators:
|
|
186
|
-
on_change_pre_save:
|
|
187
|
-
on_change_post_save:
|
|
188
|
-
on_change_save_finished:
|
|
183
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
184
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
185
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
186
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
189
187
|
created_by_source_type: str = "",
|
|
190
188
|
created_by_source_key: str = "",
|
|
191
189
|
created_by_source_strict: bool = True,
|
|
@@ -216,7 +214,7 @@ class CategoryTree(BelongsToId):
|
|
|
216
214
|
self.update_tree_table(model, id, model.latest(self.name, data))
|
|
217
215
|
return
|
|
218
216
|
|
|
219
|
-
def force_tree_update(self, model: Model):
|
|
217
|
+
def force_tree_update(self, model: Model) -> None:
|
|
220
218
|
self.update_tree_table(model, getattr(model, model.id_column_name), getattr(model, self.name))
|
|
221
219
|
|
|
222
220
|
def update_tree_table(self, model: Model, child_id: int | str, direct_parent_id: int | str) -> None:
|
|
@@ -2,8 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Self, overload
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
7
6
|
from clearskies.column import Column
|
|
8
7
|
from clearskies.columns import CategoryTree
|
|
9
8
|
|
|
@@ -36,7 +35,7 @@ class CategoryTreeChildren(Column):
|
|
|
36
35
|
is_searchable = configs.Boolean(default=False)
|
|
37
36
|
_descriptor_config_map = None
|
|
38
37
|
|
|
39
|
-
@
|
|
38
|
+
@decorators.parameters_to_properties
|
|
40
39
|
def __init__(
|
|
41
40
|
self,
|
|
42
41
|
category_tree_column_name: str,
|
clearskies/columns/created.py
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import datetime
|
|
4
3
|
from typing import TYPE_CHECKING, Any
|
|
5
4
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.di
|
|
8
|
-
import clearskies.typing
|
|
9
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
10
6
|
from clearskies.columns.datetime import Datetime
|
|
7
|
+
from clearskies.di import inject
|
|
11
8
|
|
|
12
9
|
if TYPE_CHECKING:
|
|
13
|
-
from clearskies import Model
|
|
10
|
+
from clearskies import Model, typing
|
|
14
11
|
|
|
15
12
|
|
|
16
13
|
class Created(Datetime):
|
|
@@ -66,9 +63,9 @@ class Created(Datetime):
|
|
|
66
63
|
is_writeable = configs.Boolean(default=False)
|
|
67
64
|
_descriptor_config_map = None
|
|
68
65
|
|
|
69
|
-
now =
|
|
66
|
+
now = inject.Now()
|
|
70
67
|
|
|
71
|
-
@
|
|
68
|
+
@decorators.parameters_to_properties
|
|
72
69
|
def __init__(
|
|
73
70
|
self,
|
|
74
71
|
date_format: str = "%Y-%m-%d %H:%M:%S",
|
|
@@ -77,9 +74,9 @@ class Created(Datetime):
|
|
|
77
74
|
is_readable: bool = True,
|
|
78
75
|
is_searchable: bool = True,
|
|
79
76
|
is_temporary: bool = False,
|
|
80
|
-
on_change_pre_save:
|
|
81
|
-
on_change_post_save:
|
|
82
|
-
on_change_save_finished:
|
|
77
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
78
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
79
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
83
80
|
):
|
|
84
81
|
pass
|
|
85
82
|
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import clearskies.typing
|
|
7
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
8
6
|
from clearskies.columns.string import String
|
|
9
7
|
|
|
10
8
|
if TYPE_CHECKING:
|
|
11
|
-
from clearskies import
|
|
9
|
+
from clearskies import typing
|
|
12
10
|
|
|
13
11
|
|
|
14
12
|
class CreatedByAuthorizationData(String):
|
|
@@ -100,7 +98,7 @@ class CreatedByAuthorizationData(String):
|
|
|
100
98
|
|
|
101
99
|
_allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
|
|
102
100
|
|
|
103
|
-
@
|
|
101
|
+
@decorators.parameters_to_properties
|
|
104
102
|
def __init__(
|
|
105
103
|
self,
|
|
106
104
|
authorization_data_key_name: str,
|
|
@@ -108,9 +106,9 @@ class CreatedByAuthorizationData(String):
|
|
|
108
106
|
is_readable: bool = True,
|
|
109
107
|
is_searchable: bool = True,
|
|
110
108
|
is_temporary: bool = False,
|
|
111
|
-
on_change_pre_save:
|
|
112
|
-
on_change_post_save:
|
|
113
|
-
on_change_save_finished:
|
|
109
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
110
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
111
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
114
112
|
):
|
|
115
113
|
self.created_by_source_key = authorization_data_key_name
|
|
116
114
|
self.created_by_source_type = "authorization_data"
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from clearskies import configs, decorators
|
|
4
6
|
from clearskies.columns.string import String
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from clearskies import typing
|
|
6
10
|
|
|
7
11
|
|
|
8
12
|
class CreatedByHeader(String):
|
|
@@ -83,7 +87,7 @@ class CreatedByHeader(String):
|
|
|
83
87
|
|
|
84
88
|
_allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
|
|
85
89
|
|
|
86
|
-
@
|
|
90
|
+
@decorators.parameters_to_properties
|
|
87
91
|
def __init__(
|
|
88
92
|
self,
|
|
89
93
|
header_name: str,
|
|
@@ -91,9 +95,9 @@ class CreatedByHeader(String):
|
|
|
91
95
|
is_readable: bool = True,
|
|
92
96
|
is_searchable: bool = True,
|
|
93
97
|
is_temporary: bool = False,
|
|
94
|
-
on_change_pre_save:
|
|
95
|
-
on_change_post_save:
|
|
96
|
-
on_change_save_finished:
|
|
98
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
99
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
100
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
97
101
|
):
|
|
98
102
|
self.created_by_source_key = header_name
|
|
99
103
|
self.created_by_source_type = "http_header"
|
|
@@ -2,13 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import clearskies.typing
|
|
7
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
8
6
|
from clearskies.columns.string import String
|
|
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 CreatedByIp(String):
|
|
@@ -70,15 +68,15 @@ class CreatedByIp(String):
|
|
|
70
68
|
|
|
71
69
|
_allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
|
|
72
70
|
|
|
73
|
-
@
|
|
71
|
+
@decorators.parameters_to_properties
|
|
74
72
|
def __init__(
|
|
75
73
|
self,
|
|
76
74
|
is_readable: bool = True,
|
|
77
75
|
is_searchable: bool = True,
|
|
78
76
|
is_temporary: bool = False,
|
|
79
|
-
on_change_pre_save:
|
|
80
|
-
on_change_post_save:
|
|
81
|
-
on_change_save_finished:
|
|
77
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
78
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
79
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
82
80
|
):
|
|
83
81
|
pass
|
|
84
82
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from clearskies import configs, decorators
|
|
4
6
|
from clearskies.columns.string import String
|
|
5
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from clearskies import typing
|
|
10
|
+
|
|
6
11
|
|
|
7
12
|
class CreatedByRoutingData(String):
|
|
8
13
|
"""
|
|
@@ -81,7 +86,7 @@ class CreatedByRoutingData(String):
|
|
|
81
86
|
|
|
82
87
|
_allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
|
|
83
88
|
|
|
84
|
-
@
|
|
89
|
+
@decorators.parameters_to_properties
|
|
85
90
|
def __init__(
|
|
86
91
|
self,
|
|
87
92
|
routing_path_name: str,
|
|
@@ -89,9 +94,9 @@ class CreatedByRoutingData(String):
|
|
|
89
94
|
is_readable: bool = True,
|
|
90
95
|
is_searchable: bool = True,
|
|
91
96
|
is_temporary: bool = False,
|
|
92
|
-
on_change_pre_save:
|
|
93
|
-
on_change_post_save:
|
|
94
|
-
on_change_save_finished:
|
|
97
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
98
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
99
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
95
100
|
):
|
|
96
101
|
self.created_by_source_key = routing_path_name
|
|
97
102
|
self.created_by_source_type = "routing_data"
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import datetime
|
|
4
3
|
from typing import TYPE_CHECKING, Any
|
|
5
4
|
|
|
6
|
-
import
|
|
7
|
-
import clearskies.typing
|
|
8
|
-
from clearskies import configs
|
|
5
|
+
from clearskies import configs, decorators
|
|
9
6
|
from clearskies.columns.string import String
|
|
10
7
|
|
|
11
8
|
if TYPE_CHECKING:
|
|
12
|
-
from clearskies import Model
|
|
9
|
+
from clearskies import Model, typing
|
|
13
10
|
|
|
14
11
|
|
|
15
12
|
class CreatedByUserAgent(String):
|
|
@@ -70,15 +67,15 @@ class CreatedByUserAgent(String):
|
|
|
70
67
|
|
|
71
68
|
_allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
|
|
72
69
|
|
|
73
|
-
@
|
|
70
|
+
@decorators.parameters_to_properties
|
|
74
71
|
def __init__(
|
|
75
72
|
self,
|
|
76
73
|
is_readable: bool = True,
|
|
77
74
|
is_searchable: bool = True,
|
|
78
75
|
is_temporary: bool = False,
|
|
79
|
-
on_change_pre_save:
|
|
80
|
-
on_change_post_save:
|
|
81
|
-
on_change_save_finished:
|
|
76
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
77
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
78
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
82
79
|
):
|
|
83
80
|
pass
|
|
84
81
|
|
clearskies/columns/date.py
CHANGED
|
@@ -3,18 +3,16 @@ from __future__ import annotations
|
|
|
3
3
|
import datetime
|
|
4
4
|
from typing import TYPE_CHECKING, Any, Callable, Self, overload
|
|
5
5
|
|
|
6
|
-
import dateparser
|
|
6
|
+
import dateparser
|
|
7
7
|
|
|
8
|
-
import
|
|
9
|
-
import clearskies.typing
|
|
10
|
-
from clearskies import configs
|
|
8
|
+
from clearskies import configs, decorators
|
|
11
9
|
from clearskies.autodoc.schema import Datetime as AutoDocDatetime
|
|
12
|
-
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
13
10
|
from clearskies.columns.datetime import Datetime
|
|
14
|
-
from clearskies.query import Condition
|
|
15
11
|
|
|
16
12
|
if TYPE_CHECKING:
|
|
17
|
-
from clearskies import Model
|
|
13
|
+
from clearskies import Model, typing
|
|
14
|
+
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
15
|
+
from clearskies.query import Condition
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
class Date(Datetime):
|
|
@@ -102,7 +100,7 @@ class Date(Datetime):
|
|
|
102
100
|
auto_doc_class: type[AutoDocSchema] = AutoDocDatetime
|
|
103
101
|
_descriptor_config_map = None
|
|
104
102
|
|
|
105
|
-
@
|
|
103
|
+
@decorators.parameters_to_properties
|
|
106
104
|
def __init__(
|
|
107
105
|
self,
|
|
108
106
|
date_format: str = "%Y-%m-%d",
|
|
@@ -113,10 +111,10 @@ class Date(Datetime):
|
|
|
113
111
|
is_writeable: bool = True,
|
|
114
112
|
is_searchable: bool = True,
|
|
115
113
|
is_temporary: bool = False,
|
|
116
|
-
validators:
|
|
117
|
-
on_change_pre_save:
|
|
118
|
-
on_change_post_save:
|
|
119
|
-
on_change_save_finished:
|
|
114
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
115
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
116
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
117
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
120
118
|
created_by_source_type: str = "",
|
|
121
119
|
created_by_source_key: str = "",
|
|
122
120
|
created_by_source_strict: bool = True,
|
|
@@ -218,10 +216,10 @@ class Date(Datetime):
|
|
|
218
216
|
|
|
219
217
|
if type(value_1) == str:
|
|
220
218
|
value_1 = dateparser.parse(value_1)
|
|
221
|
-
value_1 = datetime.date(value_1.year, value_1.month, value_1.day)
|
|
219
|
+
value_1 = datetime.date(value_1.year, value_1.month, value_1.day) if value_1 else None
|
|
222
220
|
if type(value_2) == str:
|
|
223
221
|
value_2 = dateparser.parse(value_2)
|
|
224
|
-
value_2 = datetime.date(value_2.year, value_2.month, value_2.day)
|
|
222
|
+
value_2 = datetime.date(value_2.year, value_2.month, value_2.day) if value_2 else None
|
|
225
223
|
|
|
226
224
|
# two times can be the same but if one is datetime-aware and one is not, python will treat them as not equal.
|
|
227
225
|
# we want to treat such times as being the same. Therefore, check for equality but ignore the timezone.
|
clearskies/columns/datetime.py
CHANGED
|
@@ -5,16 +5,14 @@ from typing import TYPE_CHECKING, Any, Callable, Self, overload
|
|
|
5
5
|
|
|
6
6
|
import dateparser # type: ignore
|
|
7
7
|
|
|
8
|
-
import
|
|
9
|
-
import clearskies.typing
|
|
10
|
-
from clearskies import configs
|
|
8
|
+
from clearskies import configs, decorators
|
|
11
9
|
from clearskies.autodoc.schema import Datetime as AutoDocDatetime
|
|
12
|
-
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
13
10
|
from clearskies.column import Column
|
|
14
|
-
from clearskies.query import Condition
|
|
15
11
|
|
|
16
12
|
if TYPE_CHECKING:
|
|
17
|
-
from clearskies import Model
|
|
13
|
+
from clearskies import Model, typing
|
|
14
|
+
from clearskies.autodoc.schema import Schema as AutoDocSchema
|
|
15
|
+
from clearskies.query import Condition
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
class Datetime(Column):
|
|
@@ -127,7 +125,7 @@ class Datetime(Column):
|
|
|
127
125
|
auto_doc_class: type[AutoDocSchema] = AutoDocDatetime
|
|
128
126
|
_descriptor_config_map = None
|
|
129
127
|
|
|
130
|
-
@
|
|
128
|
+
@decorators.parameters_to_properties
|
|
131
129
|
def __init__(
|
|
132
130
|
self,
|
|
133
131
|
date_format: str = "%Y-%m-%d %H:%M:%S",
|
|
@@ -140,10 +138,10 @@ class Datetime(Column):
|
|
|
140
138
|
is_writeable: bool = True,
|
|
141
139
|
is_searchable: bool = True,
|
|
142
140
|
is_temporary: bool = False,
|
|
143
|
-
validators:
|
|
144
|
-
on_change_pre_save:
|
|
145
|
-
on_change_post_save:
|
|
146
|
-
on_change_save_finished:
|
|
141
|
+
validators: typing.validator | list[typing.validator] = [],
|
|
142
|
+
on_change_pre_save: typing.action | list[typing.action] = [],
|
|
143
|
+
on_change_post_save: typing.action | list[typing.action] = [],
|
|
144
|
+
on_change_save_finished: typing.action | list[typing.action] = [],
|
|
147
145
|
created_by_source_type: str = "",
|
|
148
146
|
created_by_source_key: str = "",
|
|
149
147
|
created_by_source_strict: bool = True,
|
|
@@ -184,7 +182,7 @@ class Datetime(Column):
|
|
|
184
182
|
self.name: value.strftime(self.date_format),
|
|
185
183
|
}
|
|
186
184
|
|
|
187
|
-
def to_json(self, model:
|
|
185
|
+
def to_json(self, model: Model) -> dict[str, Any]:
|
|
188
186
|
"""Grabs the column out of the model and converts it into a representation that can be turned into JSON."""
|
|
189
187
|
value = self.__get__(model, model.__class__)
|
|
190
188
|
if value and (isinstance(value, datetime.datetime) or isinstance(value, datetime.date)):
|
|
@@ -242,13 +240,13 @@ class Datetime(Column):
|
|
|
242
240
|
return "date is missing timezone information"
|
|
243
241
|
return ""
|
|
244
242
|
|
|
245
|
-
def values_match(self, value_1, value_2):
|
|
243
|
+
def values_match(self, value_1: None | str | datetime.datetime, value_2: None | str | datetime.datetime) -> bool:
|
|
246
244
|
"""Compare two values to see if they are the same."""
|
|
247
245
|
# in this function we deal with data directly out of the backend, so our date is likely
|
|
248
246
|
# to be string-ified and we want to look for default (e.g. null) values in string form.
|
|
249
|
-
if
|
|
247
|
+
if isinstance(value_1, str) and ("0000-00-00" in value_1 or value_1 == self.backend_default):
|
|
250
248
|
value_1 = None
|
|
251
|
-
if
|
|
249
|
+
if isinstance(value_2, str) and ("0000-00-00" in value_2 or value_2 == self.backend_default):
|
|
252
250
|
value_2 = None
|
|
253
251
|
number_values = 0
|
|
254
252
|
if value_1:
|
|
@@ -260,11 +258,15 @@ class Datetime(Column):
|
|
|
260
258
|
if number_values == 1:
|
|
261
259
|
return False
|
|
262
260
|
|
|
263
|
-
if
|
|
261
|
+
if isinstance(value_1, str):
|
|
264
262
|
value_1 = dateparser.parse(value_1)
|
|
265
|
-
if
|
|
263
|
+
if isinstance(value_2, str):
|
|
266
264
|
value_2 = dateparser.parse(value_2)
|
|
267
265
|
|
|
266
|
+
# If neither value is a datetime, we can't compare them so they don't match.
|
|
267
|
+
if not isinstance(value_1, datetime.datetime) or not isinstance(value_2, datetime.datetime):
|
|
268
|
+
return False
|
|
269
|
+
|
|
268
270
|
# we need to make sure we're comparing in the same timezones. For our purposes, a difference in timezone
|
|
269
271
|
# is fine as long as they represent the same time (e.g. 16:00EST == 20:00UTC). For python, same time in different
|
|
270
272
|
# timezones is treated as different datetime objects.
|
clearskies/columns/email.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import re
|
|
2
4
|
|
|
3
5
|
from clearskies.columns.string import String
|
|
@@ -65,7 +67,7 @@ class Email(String):
|
|
|
65
67
|
"""
|
|
66
68
|
|
|
67
69
|
def input_error_for_value(self, value: str, operator: str | None = None) -> str:
|
|
68
|
-
if
|
|
70
|
+
if not isinstance(value, str):
|
|
69
71
|
return f"Value must be a string for {self.name}"
|
|
70
72
|
if operator and operator.lower() == "like":
|
|
71
73
|
# don't check for an email if doing a fuzzy search, since we may be searching
|