clear-skies 2.0.3__py3-none-any.whl → 2.0.5__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.

Files changed (251) hide show
  1. clear_skies-2.0.5.dist-info/METADATA +74 -0
  2. clear_skies-2.0.5.dist-info/RECORD +4 -0
  3. {clear_skies-2.0.3.dist-info → clear_skies-2.0.5.dist-info}/WHEEL +1 -1
  4. clear_skies-2.0.3.dist-info/METADATA +0 -46
  5. clear_skies-2.0.3.dist-info/RECORD +0 -249
  6. clearskies/__init__.py +0 -59
  7. clearskies/action.py +0 -7
  8. clearskies/authentication/__init__.py +0 -15
  9. clearskies/authentication/authentication.py +0 -46
  10. clearskies/authentication/authorization.py +0 -16
  11. clearskies/authentication/authorization_pass_through.py +0 -20
  12. clearskies/authentication/jwks.py +0 -163
  13. clearskies/authentication/public.py +0 -5
  14. clearskies/authentication/secret_bearer.py +0 -553
  15. clearskies/autodoc/__init__.py +0 -8
  16. clearskies/autodoc/formats/__init__.py +0 -5
  17. clearskies/autodoc/formats/oai3_json/__init__.py +0 -7
  18. clearskies/autodoc/formats/oai3_json/oai3_json.py +0 -87
  19. clearskies/autodoc/formats/oai3_json/oai3_schema_resolver.py +0 -15
  20. clearskies/autodoc/formats/oai3_json/parameter.py +0 -35
  21. clearskies/autodoc/formats/oai3_json/request.py +0 -68
  22. clearskies/autodoc/formats/oai3_json/response.py +0 -28
  23. clearskies/autodoc/formats/oai3_json/schema/__init__.py +0 -11
  24. clearskies/autodoc/formats/oai3_json/schema/array.py +0 -9
  25. clearskies/autodoc/formats/oai3_json/schema/default.py +0 -13
  26. clearskies/autodoc/formats/oai3_json/schema/enum.py +0 -7
  27. clearskies/autodoc/formats/oai3_json/schema/object.py +0 -29
  28. clearskies/autodoc/formats/oai3_json/test.json +0 -1985
  29. clearskies/autodoc/py.typed +0 -0
  30. clearskies/autodoc/request/__init__.py +0 -15
  31. clearskies/autodoc/request/header.py +0 -6
  32. clearskies/autodoc/request/json_body.py +0 -6
  33. clearskies/autodoc/request/parameter.py +0 -8
  34. clearskies/autodoc/request/request.py +0 -38
  35. clearskies/autodoc/request/url_parameter.py +0 -6
  36. clearskies/autodoc/request/url_path.py +0 -6
  37. clearskies/autodoc/response/__init__.py +0 -5
  38. clearskies/autodoc/response/response.py +0 -9
  39. clearskies/autodoc/schema/__init__.py +0 -31
  40. clearskies/autodoc/schema/array.py +0 -10
  41. clearskies/autodoc/schema/base64.py +0 -8
  42. clearskies/autodoc/schema/boolean.py +0 -5
  43. clearskies/autodoc/schema/date.py +0 -5
  44. clearskies/autodoc/schema/datetime.py +0 -5
  45. clearskies/autodoc/schema/double.py +0 -5
  46. clearskies/autodoc/schema/enum.py +0 -17
  47. clearskies/autodoc/schema/integer.py +0 -6
  48. clearskies/autodoc/schema/long.py +0 -5
  49. clearskies/autodoc/schema/number.py +0 -6
  50. clearskies/autodoc/schema/object.py +0 -13
  51. clearskies/autodoc/schema/password.py +0 -5
  52. clearskies/autodoc/schema/schema.py +0 -11
  53. clearskies/autodoc/schema/string.py +0 -5
  54. clearskies/backends/__init__.py +0 -65
  55. clearskies/backends/api_backend.py +0 -1178
  56. clearskies/backends/backend.py +0 -136
  57. clearskies/backends/cursor_backend.py +0 -335
  58. clearskies/backends/memory_backend.py +0 -797
  59. clearskies/backends/secrets_backend.py +0 -106
  60. clearskies/column.py +0 -1233
  61. clearskies/columns/__init__.py +0 -71
  62. clearskies/columns/audit.py +0 -206
  63. clearskies/columns/belongs_to_id.py +0 -483
  64. clearskies/columns/belongs_to_model.py +0 -132
  65. clearskies/columns/belongs_to_self.py +0 -105
  66. clearskies/columns/boolean.py +0 -113
  67. clearskies/columns/category_tree.py +0 -275
  68. clearskies/columns/category_tree_ancestors.py +0 -51
  69. clearskies/columns/category_tree_children.py +0 -127
  70. clearskies/columns/category_tree_descendants.py +0 -48
  71. clearskies/columns/created.py +0 -95
  72. clearskies/columns/created_by_authorization_data.py +0 -116
  73. clearskies/columns/created_by_header.py +0 -99
  74. clearskies/columns/created_by_ip.py +0 -92
  75. clearskies/columns/created_by_routing_data.py +0 -97
  76. clearskies/columns/created_by_user_agent.py +0 -92
  77. clearskies/columns/date.py +0 -234
  78. clearskies/columns/datetime.py +0 -282
  79. clearskies/columns/email.py +0 -76
  80. clearskies/columns/float.py +0 -153
  81. clearskies/columns/has_many.py +0 -505
  82. clearskies/columns/has_many_self.py +0 -56
  83. clearskies/columns/has_one.py +0 -14
  84. clearskies/columns/integer.py +0 -160
  85. clearskies/columns/json.py +0 -126
  86. clearskies/columns/many_to_many_ids.py +0 -337
  87. clearskies/columns/many_to_many_ids_with_data.py +0 -274
  88. clearskies/columns/many_to_many_models.py +0 -158
  89. clearskies/columns/many_to_many_pivots.py +0 -134
  90. clearskies/columns/phone.py +0 -159
  91. clearskies/columns/select.py +0 -92
  92. clearskies/columns/string.py +0 -102
  93. clearskies/columns/timestamp.py +0 -164
  94. clearskies/columns/updated.py +0 -110
  95. clearskies/columns/uuid.py +0 -86
  96. clearskies/configs/README.md +0 -105
  97. clearskies/configs/__init__.py +0 -162
  98. clearskies/configs/actions.py +0 -43
  99. clearskies/configs/any.py +0 -13
  100. clearskies/configs/any_dict.py +0 -22
  101. clearskies/configs/any_dict_or_callable.py +0 -23
  102. clearskies/configs/authentication.py +0 -23
  103. clearskies/configs/authorization.py +0 -23
  104. clearskies/configs/boolean.py +0 -16
  105. clearskies/configs/boolean_or_callable.py +0 -18
  106. clearskies/configs/callable_config.py +0 -18
  107. clearskies/configs/columns.py +0 -34
  108. clearskies/configs/conditions.py +0 -30
  109. clearskies/configs/config.py +0 -24
  110. clearskies/configs/datetime.py +0 -18
  111. clearskies/configs/datetime_or_callable.py +0 -19
  112. clearskies/configs/endpoint.py +0 -23
  113. clearskies/configs/endpoint_list.py +0 -28
  114. clearskies/configs/float.py +0 -16
  115. clearskies/configs/float_or_callable.py +0 -18
  116. clearskies/configs/integer.py +0 -16
  117. clearskies/configs/integer_or_callable.py +0 -18
  118. clearskies/configs/joins.py +0 -30
  119. clearskies/configs/list_any_dict.py +0 -30
  120. clearskies/configs/list_any_dict_or_callable.py +0 -31
  121. clearskies/configs/model_class.py +0 -35
  122. clearskies/configs/model_column.py +0 -65
  123. clearskies/configs/model_columns.py +0 -56
  124. clearskies/configs/model_destination_name.py +0 -25
  125. clearskies/configs/model_to_id_column.py +0 -43
  126. clearskies/configs/readable_model_column.py +0 -9
  127. clearskies/configs/readable_model_columns.py +0 -9
  128. clearskies/configs/schema.py +0 -23
  129. clearskies/configs/searchable_model_columns.py +0 -9
  130. clearskies/configs/security_headers.py +0 -39
  131. clearskies/configs/select.py +0 -26
  132. clearskies/configs/select_list.py +0 -47
  133. clearskies/configs/string.py +0 -29
  134. clearskies/configs/string_dict.py +0 -32
  135. clearskies/configs/string_list.py +0 -32
  136. clearskies/configs/string_list_or_callable.py +0 -35
  137. clearskies/configs/string_or_callable.py +0 -18
  138. clearskies/configs/timedelta.py +0 -18
  139. clearskies/configs/timezone.py +0 -18
  140. clearskies/configs/url.py +0 -23
  141. clearskies/configs/validators.py +0 -45
  142. clearskies/configs/writeable_model_column.py +0 -9
  143. clearskies/configs/writeable_model_columns.py +0 -9
  144. clearskies/configurable.py +0 -76
  145. clearskies/contexts/__init__.py +0 -11
  146. clearskies/contexts/cli.py +0 -117
  147. clearskies/contexts/context.py +0 -98
  148. clearskies/contexts/wsgi.py +0 -76
  149. clearskies/contexts/wsgi_ref.py +0 -82
  150. clearskies/decorators.py +0 -33
  151. clearskies/di/__init__.py +0 -14
  152. clearskies/di/additional_config.py +0 -130
  153. clearskies/di/additional_config_auto_import.py +0 -17
  154. clearskies/di/di.py +0 -968
  155. clearskies/di/inject/__init__.py +0 -23
  156. clearskies/di/inject/by_class.py +0 -21
  157. clearskies/di/inject/by_name.py +0 -18
  158. clearskies/di/inject/di.py +0 -13
  159. clearskies/di/inject/environment.py +0 -14
  160. clearskies/di/inject/input_output.py +0 -20
  161. clearskies/di/inject/now.py +0 -13
  162. clearskies/di/inject/requests.py +0 -13
  163. clearskies/di/inject/secrets.py +0 -14
  164. clearskies/di/inject/utcnow.py +0 -13
  165. clearskies/di/inject/uuid.py +0 -15
  166. clearskies/di/injectable.py +0 -29
  167. clearskies/di/injectable_properties.py +0 -131
  168. clearskies/di/test_module/__init__.py +0 -6
  169. clearskies/di/test_module/another_module/__init__.py +0 -2
  170. clearskies/di/test_module/module_class.py +0 -5
  171. clearskies/end.py +0 -183
  172. clearskies/endpoint.py +0 -1310
  173. clearskies/endpoint_group.py +0 -310
  174. clearskies/endpoints/__init__.py +0 -23
  175. clearskies/endpoints/advanced_search.py +0 -526
  176. clearskies/endpoints/callable.py +0 -388
  177. clearskies/endpoints/create.py +0 -202
  178. clearskies/endpoints/delete.py +0 -139
  179. clearskies/endpoints/get.py +0 -275
  180. clearskies/endpoints/health_check.py +0 -181
  181. clearskies/endpoints/list.py +0 -573
  182. clearskies/endpoints/restful_api.py +0 -427
  183. clearskies/endpoints/simple_search.py +0 -286
  184. clearskies/endpoints/update.py +0 -190
  185. clearskies/environment.py +0 -104
  186. clearskies/exceptions/__init__.py +0 -17
  187. clearskies/exceptions/authentication.py +0 -2
  188. clearskies/exceptions/authorization.py +0 -2
  189. clearskies/exceptions/client_error.py +0 -2
  190. clearskies/exceptions/input_errors.py +0 -4
  191. clearskies/exceptions/moved_permanently.py +0 -3
  192. clearskies/exceptions/moved_temporarily.py +0 -3
  193. clearskies/exceptions/not_found.py +0 -2
  194. clearskies/functional/__init__.py +0 -7
  195. clearskies/functional/routing.py +0 -92
  196. clearskies/functional/string.py +0 -112
  197. clearskies/functional/validations.py +0 -76
  198. clearskies/input_outputs/__init__.py +0 -13
  199. clearskies/input_outputs/cli.py +0 -171
  200. clearskies/input_outputs/exceptions/__init__.py +0 -2
  201. clearskies/input_outputs/exceptions/cli_input_error.py +0 -2
  202. clearskies/input_outputs/exceptions/cli_not_found.py +0 -2
  203. clearskies/input_outputs/headers.py +0 -45
  204. clearskies/input_outputs/input_output.py +0 -138
  205. clearskies/input_outputs/programmatic.py +0 -69
  206. clearskies/input_outputs/py.typed +0 -0
  207. clearskies/input_outputs/wsgi.py +0 -77
  208. clearskies/model.py +0 -1922
  209. clearskies/py.typed +0 -0
  210. clearskies/query/__init__.py +0 -12
  211. clearskies/query/condition.py +0 -223
  212. clearskies/query/join.py +0 -136
  213. clearskies/query/query.py +0 -196
  214. clearskies/query/sort.py +0 -27
  215. clearskies/schema.py +0 -82
  216. clearskies/secrets/__init__.py +0 -6
  217. clearskies/secrets/additional_configs/__init__.py +0 -32
  218. clearskies/secrets/additional_configs/mysql_connection_dynamic_producer.py +0 -61
  219. clearskies/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssh_cert_bastion.py +0 -160
  220. clearskies/secrets/akeyless.py +0 -182
  221. clearskies/secrets/exceptions/__init__.py +0 -1
  222. clearskies/secrets/exceptions/not_found.py +0 -2
  223. clearskies/secrets/secrets.py +0 -38
  224. clearskies/security_header.py +0 -15
  225. clearskies/security_headers/__init__.py +0 -11
  226. clearskies/security_headers/cache_control.py +0 -67
  227. clearskies/security_headers/cors.py +0 -50
  228. clearskies/security_headers/csp.py +0 -94
  229. clearskies/security_headers/hsts.py +0 -22
  230. clearskies/security_headers/x_content_type_options.py +0 -0
  231. clearskies/security_headers/x_frame_options.py +0 -0
  232. clearskies/test_base.py +0 -8
  233. clearskies/typing.py +0 -11
  234. clearskies/validator.py +0 -37
  235. clearskies/validators/__init__.py +0 -33
  236. clearskies/validators/after_column.py +0 -62
  237. clearskies/validators/before_column.py +0 -13
  238. clearskies/validators/in_the_future.py +0 -32
  239. clearskies/validators/in_the_future_at_least.py +0 -11
  240. clearskies/validators/in_the_future_at_most.py +0 -10
  241. clearskies/validators/in_the_past.py +0 -32
  242. clearskies/validators/in_the_past_at_least.py +0 -10
  243. clearskies/validators/in_the_past_at_most.py +0 -10
  244. clearskies/validators/maximum_length.py +0 -26
  245. clearskies/validators/maximum_value.py +0 -29
  246. clearskies/validators/minimum_length.py +0 -26
  247. clearskies/validators/minimum_value.py +0 -29
  248. clearskies/validators/required.py +0 -34
  249. clearskies/validators/timedelta.py +0 -59
  250. clearskies/validators/unique.py +0 -30
  251. {clear_skies-2.0.3.dist-info → clear_skies-2.0.5.dist-info/licenses}/LICENSE +0 -0
@@ -1,48 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING, Self, Type, overload
4
-
5
- from clearskies.columns import CategoryTreeChildren
6
-
7
- if TYPE_CHECKING:
8
- from clearskies import Model
9
-
10
-
11
- class CategoryTreeDescendants(CategoryTreeChildren):
12
- """
13
- Return all descendants from a category tree column.
14
-
15
- See the CategoryTree column for usage examples.
16
-
17
- The descendants are the recursive children of a given category. So, given the following tree:
18
-
19
- ```
20
- Root/
21
- ├─ Sub/
22
- │ ├─ Sub Sub/
23
- │ │ ├─ Sub Sub Sub/
24
- ├─ Another Child/
25
-
26
- The descendants of `Root` are `["Sub", "Sub Sub", "Sub Sub Sub", "Another Child"]`.
27
- """
28
-
29
- _descriptor_config_map = None
30
-
31
- @overload
32
- def __get__(self, instance: None, cls: type[Model]) -> Self:
33
- pass
34
-
35
- @overload
36
- def __get__(self, instance: Model, cls: type[Model]) -> Model:
37
- pass
38
-
39
- def __get__(self, model, cls):
40
- if model is None:
41
- self.model_class = cls
42
- return self # type: ignore
43
-
44
- # this makes sure we're initialized
45
- if "name" not in self._config: # type: ignore
46
- model.get_columns()
47
-
48
- return self.relatives(model, include_all=True)
@@ -1,95 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import datetime
4
- from typing import TYPE_CHECKING, Any
5
-
6
- import clearskies.decorators
7
- import clearskies.di
8
- import clearskies.typing
9
- from clearskies import configs
10
- from clearskies.columns.datetime import Datetime
11
-
12
- if TYPE_CHECKING:
13
- from clearskies import Model
14
-
15
-
16
- class Created(Datetime):
17
- """
18
- The created column records the time that a record is created.
19
-
20
- This will always populate the column when the model is first created. If you attempt to set a value
21
- to this column on create then it will be overwritten.
22
-
23
- ```python
24
- import clearskies
25
-
26
-
27
- class MyModel(clearskies.Model):
28
- backend = clearskies.backends.MemoryBackend()
29
- id_column_name = "id"
30
- id = clearskies.columns.Uuid()
31
- name = clearskies.columns.String()
32
- created = clearskies.columns.Created()
33
-
34
-
35
- cli = clearskies.contexts.Cli(
36
- clearskies.endpoints.Callable(
37
- lambda my_models: my_models.create({"name": "An Example"}),
38
- model_class=MyModel,
39
- readable_column_names=["id", "name", "created"],
40
- ),
41
- classes=[MyModel],
42
- )
43
- cli()
44
- ```
45
-
46
- And if you execute this you'll see that the `created` column was automatically populated:
47
-
48
- ```json
49
- {
50
- "status": "success",
51
- "error": "",
52
- "data": {
53
- "id": "c54d74ac-5282-439e-af4f-23efb9ba96d4",
54
- "name": "An Example",
55
- "created": "2025-05-09T19:58:43+00:00",
56
- },
57
- "pagination": {},
58
- "input_errors": {},
59
- }
60
- ```
61
- """
62
-
63
- """
64
- Created fields are never writeable because they always set the created time automatically.
65
- """
66
- is_writeable = configs.Boolean(default=False)
67
- _descriptor_config_map = None
68
-
69
- now = clearskies.di.inject.Now()
70
-
71
- @clearskies.decorators.parameters_to_properties
72
- def __init__(
73
- self,
74
- date_format: str = "%Y-%m-%d %H:%M:%S",
75
- in_utc: bool = True,
76
- backend_default: str = "0000-00-00 00:00:00",
77
- is_readable: bool = True,
78
- is_searchable: bool = True,
79
- is_temporary: bool = False,
80
- on_change_pre_save: clearskies.typing.action | list[clearskies.typing.action] = [],
81
- on_change_post_save: clearskies.typing.action | list[clearskies.typing.action] = [],
82
- on_change_save_finished: clearskies.typing.action | list[clearskies.typing.action] = [],
83
- ):
84
- pass
85
-
86
- def pre_save(self, data: dict[str, Any], model: Model) -> dict[str, Any]:
87
- if model:
88
- return data
89
- now = self.now
90
- if self.timezone_aware:
91
- now = now.astimezone(self.timezone)
92
- data = {**data, self.name: now}
93
- if self.on_change_pre_save:
94
- data = self.execute_actions_with_data(self.on_change_pre_save, model, data)
95
- return data
@@ -1,116 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING, Any
4
-
5
- import clearskies.decorators
6
- import clearskies.typing
7
- from clearskies import configs
8
- from clearskies.columns.string import String
9
-
10
- if TYPE_CHECKING:
11
- from clearskies import Model
12
-
13
-
14
- class CreatedByAuthorizationData(String):
15
- """
16
- This column will automatically take data from the authorization data attached to a request and store it in the model upon creation.
17
-
18
- If authorization data isn't available from the context being executed, then you may end up with an error
19
- (depending on the context). This is a good thing if you are trying to consistely provide audit information,
20
- but may be a problem if your model creation needs to happen more flexibly. Obviously, a pre-requisite for using this
21
- class is to have an authentication class attached to your endpoint which populates the authorization data.
22
-
23
- NOTE: columns generally also have the `created_by_source_type` and `created_by_source_key` properties that perform
24
- this exact same function. Why do we have those properties and this column? This column works well if we have
25
- some simple string values that we want to always pull from the authorization data (email, for instance). The
26
- properties work better if you need to pull authorization data but it's not just a string type. An example might
27
- be if you wanted to pull the user id out of the authorziation data to populate a `BelongsToId` column. You wouldn't
28
- use this column because it can't provide all the functionality related to `BelongsToId`, so instead you would
29
- use the `BelongsToId` column and set `created_by_source_type` to `authorization_data` and `created_by_source_key` to `user_id`.
30
- Example usage:
31
-
32
- ```python
33
- class MyModel(clearskies.Model):
34
- backend = clearskies.backends.MemoryBackend()
35
- id_column_name = "id"
36
-
37
- id = clearskies.columns.Uuid()
38
- name = clearskies.columns.String()
39
- organization_id = clearskies.columns.CreatedByAuthorizationData("organization_id")
40
-
41
-
42
- class MyAuthentication(clearskies.authentication.Authentication):
43
- def authenticate(self, input_output) -> bool:
44
- # Authenticate the user!
45
- #
46
- # This is where you would normally authenticate the user and provide any data about them to the
47
- # authorization system. This might mean validating a JWT and then providing the claims as authorization data,
48
- # or looking up a session id and providing the session data to the authorization system. In this case,
49
- # we're just going to return a fixed id for our organization.
50
- input_output.authorization_data = {
51
- "organization_id": "my-super-awesome-organization",
52
- }
53
- return True
54
-
55
-
56
- cli = clearskies.contexts.Cli(
57
- clearskies.endpoints.Create(
58
- MyModel,
59
- writeable_column_names=["name"],
60
- readable_column_names=["id", "name", "organization_id"],
61
- authentication=MyAuthentication(),
62
- ),
63
- classes=[MyModel],
64
- )
65
- cli()
66
- ```
67
-
68
- And running this will give you something like:
69
-
70
- ```json
71
- {
72
- "status": "success",
73
- "error": "",
74
- "data": {
75
- "id": "49816ea4-0956-461e-abd4-03dbde845ba9",
76
- "name": "Bob",
77
- "organization_id": "my-super-awesome-organization",
78
- },
79
- "pagination": {},
80
- "input_errors": {},
81
- }
82
- ```
83
- """
84
-
85
- """
86
- The key inside the authorization data that should be pulled into the column value when the record is created
87
- """
88
- authorization_data_key_name = configs.String(required=True)
89
-
90
- """
91
- Whether or not to throw an error if the key is not present in the authorization data.
92
- """
93
- strict = configs.Boolean(default=True)
94
-
95
- """
96
- Since this column is always populated automatically, it is never directly writeable.
97
- """
98
- is_writeable = configs.Boolean(default=False)
99
- _descriptor_config_map = None
100
-
101
- _allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
102
-
103
- @clearskies.decorators.parameters_to_properties
104
- def __init__(
105
- self,
106
- authorization_data_key_name: str,
107
- strict: bool = True,
108
- is_readable: bool = True,
109
- is_searchable: bool = True,
110
- is_temporary: bool = False,
111
- on_change_pre_save: clearskies.typing.action | list[clearskies.typing.action] = [],
112
- on_change_post_save: clearskies.typing.action | list[clearskies.typing.action] = [],
113
- on_change_save_finished: clearskies.typing.action | list[clearskies.typing.action] = [],
114
- ):
115
- self.created_by_source_key = authorization_data_key_name
116
- self.created_by_source_type = "authorization_data"
@@ -1,99 +0,0 @@
1
- import clearskies.decorators
2
- import clearskies.typing
3
- from clearskies import configs
4
- from clearskies.columns.string import String
5
- from clearskies.query import Condition
6
-
7
-
8
- class CreatedByHeader(String):
9
- """
10
- This column will automatically take data from the header attached to a request and store it in the model upon creation.
11
-
12
- If header data isn't available from the context being executed, then you may end up with an error
13
- (depending on the context). This is a good thing if you are trying to consistely provide audit information,
14
- but may be a problem if your model creation needs to happen more flexibly.
15
-
16
- NOTE: columns generally also have the `created_by_source_type` and `created_by_source_key` properties that perform
17
- this exact same function. Why do we have those properties and this column? This column works well if we have
18
- some simple string values that we want to always pull from the header data. The properties work better if you need to
19
- pull header data but it's not just a string type. An example might be if you wanted to pull the user id out of the
20
- header data to populate a `BelongsToId` column. You wouldn't use this column because it can't provide all the functionality
21
- related to `BelongsToId`, so instead you would use the `BelongsToId` column and set `created_by_source_type` to `http_header` and
22
- `created_by_source_key` to `user_id`. Example usage:
23
-
24
- ```python
25
- import clearskies
26
-
27
-
28
- class MyModel(clearskies.Model):
29
- backend = clearskies.backends.MemoryBackend()
30
- id_column_name = "id"
31
-
32
- id = clearskies.columns.Uuid()
33
- name = clearskies.columns.String()
34
- custom_header = clearskies.columns.CreatedByHeader("my_custom_header")
35
-
36
-
37
- wsgi = clearskies.contexts.WsgiRef(
38
- clearskies.endpoints.Create(
39
- MyModel,
40
- writeable_column_names=["name"],
41
- readable_column_names=["id", "name", "custom_header"],
42
- ),
43
- classes=[MyModel],
44
- )
45
- wsgi()
46
- ```
47
-
48
- If you invoked this:
49
-
50
- ```bash
51
- $ curl 'http://localhost:8080' -d '{"name":"Bob"}' -H 'my_custom_header: some header value' | jq
52
-
53
- {
54
- "status": "success",
55
- "error": "",
56
- "data": {
57
- "id": "10459ee4-a75e-4fd1-9993-2feeea629144",
58
- "name": "Bob",
59
- "custom_header": "some header value"
60
- },
61
- "pagination": {},
62
- "input_errors": {}
63
- }
64
-
65
- ```
66
- """
67
-
68
- """
69
- The name of the header that this column should be populated from.
70
- """
71
- header_name = configs.String(required=True)
72
-
73
- """
74
- Whether or not to throw an error if the key is not present in the header data.
75
- """
76
- strict = configs.Boolean(default=True)
77
-
78
- """
79
- Since this column is always populated automatically, it is never directly writeable.
80
- """
81
- is_writeable = configs.Boolean(default=False)
82
- _descriptor_config_map = None
83
-
84
- _allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
85
-
86
- @clearskies.decorators.parameters_to_properties
87
- def __init__(
88
- self,
89
- header_name: str,
90
- strict: bool = True,
91
- is_readable: bool = True,
92
- is_searchable: bool = True,
93
- is_temporary: bool = False,
94
- on_change_pre_save: clearskies.typing.action | list[clearskies.typing.action] = [],
95
- on_change_post_save: clearskies.typing.action | list[clearskies.typing.action] = [],
96
- on_change_save_finished: clearskies.typing.action | list[clearskies.typing.action] = [],
97
- ):
98
- self.created_by_source_key = header_name
99
- self.created_by_source_type = "http_header"
@@ -1,92 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING, Any
4
-
5
- import clearskies.decorators
6
- import clearskies.typing
7
- from clearskies import configs
8
- from clearskies.columns.string import String
9
-
10
- if TYPE_CHECKING:
11
- from clearskies import Model
12
-
13
-
14
- class CreatedByIp(String):
15
- """
16
- Return the ip address of the client when the record is created.
17
-
18
- If the ip address isn't available from the context being executed, then you may end up with an error
19
- (depending on the context). This is a good thing if you are trying to consistely provide audit information,
20
- but may be a problem if your model creation needs to happen more flexibly. Example:
21
-
22
- ```python
23
- import clearskies
24
-
25
-
26
- class MyModel(clearskies.Model):
27
- backend = clearskies.backends.MemoryBackend()
28
- id_column_name = "id"
29
-
30
- id = clearskies.columns.Uuid()
31
- name = clearskies.columns.String()
32
- ip_address = clearskies.columns.CreatedByIp()
33
-
34
-
35
- wsgi = clearskies.contexts.WsgiRef(
36
- clearskies.endpoints.Create(
37
- MyModel,
38
- writeable_column_names=["name"],
39
- readable_column_names=["id", "name", "ip_address"],
40
- ),
41
- classes=[MyModel],
42
- )
43
- wsgi()
44
- ```
45
-
46
- And if you invoked this:
47
-
48
- ```bash
49
- $ curl 'http://localhost:8080' -d '{"name":"Bob"}' | jq
50
- {
51
- "status": "success",
52
- "error": "",
53
- "data": {
54
- "id": "62e457fe-1680-4fa1-b4e3-0329f304fedb",
55
- "name": "Bob",
56
- "ip_address": "127.0.0.1"
57
- },
58
- "pagination": {},
59
- "input_errors": {}
60
- }
61
-
62
- ```
63
- """
64
-
65
- """
66
- Since this column is always populated automatically, it is never directly writeable.
67
- """
68
- is_writeable = configs.Boolean(default=False)
69
- _descriptor_config_map = None
70
-
71
- _allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
72
-
73
- @clearskies.decorators.parameters_to_properties
74
- def __init__(
75
- self,
76
- is_readable: bool = True,
77
- is_searchable: bool = True,
78
- is_temporary: bool = False,
79
- on_change_pre_save: clearskies.typing.action | list[clearskies.typing.action] = [],
80
- on_change_post_save: clearskies.typing.action | list[clearskies.typing.action] = [],
81
- on_change_save_finished: clearskies.typing.action | list[clearskies.typing.action] = [],
82
- ):
83
- pass
84
-
85
- def pre_save(self, data: dict[str, Any], model: Model) -> dict[str, Any]:
86
- if model:
87
- return data
88
- input_output = self.di.build("input_output", cache=True)
89
- data = {**data, self.name: input_output.get_client_ip()}
90
- if self.on_change_pre_save:
91
- data = self.execute_actions_with_data(self.on_change_pre_save, model, data)
92
- return data
@@ -1,97 +0,0 @@
1
- import clearskies.decorators
2
- import clearskies.typing
3
- from clearskies import configs
4
- from clearskies.columns.string import String
5
-
6
-
7
- class CreatedByRoutingData(String):
8
- """
9
- This column will automatically take data from the route path in the request and store it in the model upon creation.
10
-
11
- If routing data isn't available from the context being executed, then you may end up with an error
12
- (depending on the context). This is a good thing if you are trying to consistely provide audit information,
13
- but may be a problem if your model creation needs to happen more flexibly.
14
-
15
- NOTE: columns generally also have the `created_by_source_type` and `created_by_source_key` properties that perform
16
- this exact same function. Why do we have those properties and this column? This column works well if we have
17
- some simple string values that we want to always pull from the route path. The properties work better if you need to
18
- pull route data but it's not just a string type. An example might be if you wanted to pull the user id out of the
19
- route data to populate a `BelongsToId` column. You wouldn't use this column because it can't provide all the functionality
20
- related to `BelongsToId`, so instead you would use the `BelongsToId` column and set `created_by_source_type` to `routing_data` and
21
- `created_by_source_key` to `user_id`. Example usage:
22
-
23
- ```python
24
- import clearskies
25
-
26
-
27
- class MyModel(clearskies.Model):
28
- backend = clearskies.backends.MemoryBackend()
29
- id_column_name = "id"
30
-
31
- id = clearskies.columns.Uuid()
32
- name = clearskies.columns.String()
33
- organization_id = clearskies.columns.CreatedByRoutingData("organization_id")
34
-
35
-
36
- wsgi = clearskies.contexts.WsgiRef(
37
- clearskies.endpoints.Create(
38
- MyModel,
39
- url="/{organization_id}",
40
- writeable_column_names=["name"],
41
- readable_column_names=["id", "name", "organization_id"],
42
- ),
43
- classes=[MyModel],
44
- )
45
- wsgi()
46
- ```
47
-
48
- And if you invoked this:
49
-
50
- ```bash
51
- $ curl 'http://localhost:8080/my-org-id' -d '{"name":"Bob"}' | jq
52
- {
53
- "status": "success",
54
- "error": "",
55
- "data": {
56
- "id": "3643db8c-c9d4-47ee-a747-8922c59d9e7e",
57
- "name": "Bob",
58
- "organization_id": "my-org-id"
59
- },
60
- "pagination": {},
61
- "input_errors": {}
62
- }
63
- ```
64
- """
65
-
66
- """
67
- The name of the route path to populate the column with.
68
- """
69
- routing_path_name = configs.String(required=True)
70
-
71
- """
72
- Whether or not to throw an error if the key is not present in the header data.
73
- """
74
- strict = configs.Boolean(default=True)
75
-
76
- """
77
- Since this column is always populated automatically, it is never directly writeable.
78
- """
79
- is_writeable = configs.Boolean(default=False)
80
- _descriptor_config_map = None
81
-
82
- _allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
83
-
84
- @clearskies.decorators.parameters_to_properties
85
- def __init__(
86
- self,
87
- routing_path_name: str,
88
- strict: bool = True,
89
- is_readable: bool = True,
90
- is_searchable: bool = True,
91
- is_temporary: bool = False,
92
- on_change_pre_save: clearskies.typing.action | list[clearskies.typing.action] = [],
93
- on_change_post_save: clearskies.typing.action | list[clearskies.typing.action] = [],
94
- on_change_save_finished: clearskies.typing.action | list[clearskies.typing.action] = [],
95
- ):
96
- self.created_by_source_key = routing_path_name
97
- self.created_by_source_type = "routing_data"
@@ -1,92 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import datetime
4
- from typing import TYPE_CHECKING, Any
5
-
6
- import clearskies.decorators
7
- import clearskies.typing
8
- from clearskies import configs
9
- from clearskies.columns.string import String
10
-
11
- if TYPE_CHECKING:
12
- from clearskies import Model
13
-
14
-
15
- class CreatedByUserAgent(String):
16
- """
17
- This column will automatically take the user agent from the client and store it in the model upon creation.
18
-
19
- If the user agent isn't available from the context being executed, then you may end up with an error
20
- (depending on the context). This is a good thing if you are trying to consistely provide audit information,
21
- but may be a problem if your model creation needs to happen more flexibly. Example:
22
-
23
- ```python
24
- import clearskies
25
-
26
-
27
- class MyModel(clearskies.Model):
28
- backend = clearskies.backends.MemoryBackend()
29
- id_column_name = "id"
30
-
31
- id = clearskies.columns.Uuid()
32
- name = clearskies.columns.String()
33
- user_agent = clearskies.columns.CreatedByUserAgent()
34
-
35
-
36
- wsgi = clearskies.contexts.WsgiRef(
37
- clearskies.endpoints.Create(
38
- MyModel,
39
- writeable_column_names=["name"],
40
- readable_column_names=["id", "name", "user_agent"],
41
- ),
42
- classes=[MyModel],
43
- )
44
- wsgi()
45
- ```
46
-
47
- And if you invoked this:
48
-
49
- ```bash
50
- $ curl 'http://localhost:8080' -d '{"name":"Bob"}' | jq
51
- {
52
- "status": "success",
53
- "error": "",
54
- "data": {
55
- "id": "a66e5fa9-6377-4d3b-9d50-fc7feaed6d1a",
56
- "name": "Bob",
57
- "user_agent": "curl/8.5.0"
58
- },
59
- "pagination": {},
60
- "input_errors": {}
61
- }
62
- ```
63
- """
64
-
65
- """
66
- Since this column is always populated automatically, it is never directly writeable.
67
- """
68
- is_writeable = configs.Boolean(default=False)
69
- _descriptor_config_map = None
70
-
71
- _allowed_search_operators = ["=", "in", "is not null", "is null", "like"]
72
-
73
- @clearskies.decorators.parameters_to_properties
74
- def __init__(
75
- self,
76
- is_readable: bool = True,
77
- is_searchable: bool = True,
78
- is_temporary: bool = False,
79
- on_change_pre_save: clearskies.typing.action | list[clearskies.typing.action] = [],
80
- on_change_post_save: clearskies.typing.action | list[clearskies.typing.action] = [],
81
- on_change_save_finished: clearskies.typing.action | list[clearskies.typing.action] = [],
82
- ):
83
- pass
84
-
85
- def pre_save(self, data: dict[str, Any], model: Model) -> dict[str, Any]:
86
- if model:
87
- return data
88
- input_output = self.di.build("input_output", cache=True)
89
- data = {**data, self.name: input_output.request_headers.user_agent}
90
- if self.on_change_pre_save:
91
- data = self.execute_actions_with_data(self.on_change_pre_save, model, data)
92
- return data