clear-skies 1.19.22__py3-none-any.whl → 2.0.23__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.
Files changed (362) hide show
  1. clear_skies-2.0.23.dist-info/METADATA +76 -0
  2. clear_skies-2.0.23.dist-info/RECORD +265 -0
  3. {clear_skies-1.19.22.dist-info → clear_skies-2.0.23.dist-info}/WHEEL +1 -1
  4. clearskies/__init__.py +37 -21
  5. clearskies/action.py +7 -0
  6. clearskies/authentication/__init__.py +9 -38
  7. clearskies/authentication/authentication.py +44 -0
  8. clearskies/authentication/authorization.py +14 -8
  9. clearskies/authentication/authorization_pass_through.py +22 -0
  10. clearskies/authentication/jwks.py +135 -58
  11. clearskies/authentication/public.py +3 -26
  12. clearskies/authentication/secret_bearer.py +515 -44
  13. clearskies/autodoc/formats/oai3_json/__init__.py +2 -2
  14. clearskies/autodoc/formats/oai3_json/oai3_json.py +11 -9
  15. clearskies/autodoc/formats/oai3_json/parameter.py +6 -3
  16. clearskies/autodoc/formats/oai3_json/request.py +7 -5
  17. clearskies/autodoc/formats/oai3_json/response.py +7 -4
  18. clearskies/autodoc/formats/oai3_json/schema/object.py +10 -1
  19. clearskies/autodoc/request/__init__.py +2 -0
  20. clearskies/autodoc/request/header.py +4 -6
  21. clearskies/autodoc/request/json_body.py +4 -6
  22. clearskies/autodoc/request/parameter.py +8 -0
  23. clearskies/autodoc/request/request.py +16 -4
  24. clearskies/autodoc/request/url_parameter.py +4 -6
  25. clearskies/autodoc/request/url_path.py +4 -6
  26. clearskies/autodoc/schema/__init__.py +4 -2
  27. clearskies/autodoc/schema/array.py +5 -6
  28. clearskies/autodoc/schema/boolean.py +4 -10
  29. clearskies/autodoc/schema/date.py +0 -3
  30. clearskies/autodoc/schema/datetime.py +1 -4
  31. clearskies/autodoc/schema/double.py +0 -3
  32. clearskies/autodoc/schema/enum.py +4 -2
  33. clearskies/autodoc/schema/integer.py +4 -9
  34. clearskies/autodoc/schema/long.py +0 -3
  35. clearskies/autodoc/schema/number.py +4 -9
  36. clearskies/autodoc/schema/object.py +5 -7
  37. clearskies/autodoc/schema/password.py +0 -3
  38. clearskies/autodoc/schema/schema.py +11 -0
  39. clearskies/autodoc/schema/string.py +4 -10
  40. clearskies/backends/__init__.py +56 -17
  41. clearskies/backends/api_backend.py +1128 -166
  42. clearskies/backends/backend.py +54 -85
  43. clearskies/backends/cursor_backend.py +246 -191
  44. clearskies/backends/memory_backend.py +514 -208
  45. clearskies/backends/secrets_backend.py +68 -31
  46. clearskies/column.py +1221 -0
  47. clearskies/columns/__init__.py +71 -0
  48. clearskies/columns/audit.py +306 -0
  49. clearskies/columns/belongs_to_id.py +478 -0
  50. clearskies/columns/belongs_to_model.py +129 -0
  51. clearskies/columns/belongs_to_self.py +109 -0
  52. clearskies/columns/boolean.py +110 -0
  53. clearskies/columns/category_tree.py +273 -0
  54. clearskies/columns/category_tree_ancestors.py +51 -0
  55. clearskies/columns/category_tree_children.py +126 -0
  56. clearskies/columns/category_tree_descendants.py +48 -0
  57. clearskies/columns/created.py +92 -0
  58. clearskies/columns/created_by_authorization_data.py +114 -0
  59. clearskies/columns/created_by_header.py +103 -0
  60. clearskies/columns/created_by_ip.py +90 -0
  61. clearskies/columns/created_by_routing_data.py +102 -0
  62. clearskies/columns/created_by_user_agent.py +89 -0
  63. clearskies/columns/date.py +232 -0
  64. clearskies/columns/datetime.py +284 -0
  65. clearskies/columns/email.py +78 -0
  66. clearskies/columns/float.py +149 -0
  67. clearskies/columns/has_many.py +529 -0
  68. clearskies/columns/has_many_self.py +62 -0
  69. clearskies/columns/has_one.py +21 -0
  70. clearskies/columns/integer.py +158 -0
  71. clearskies/columns/json.py +126 -0
  72. clearskies/columns/many_to_many_ids.py +335 -0
  73. clearskies/columns/many_to_many_ids_with_data.py +274 -0
  74. clearskies/columns/many_to_many_models.py +156 -0
  75. clearskies/columns/many_to_many_pivots.py +132 -0
  76. clearskies/columns/phone.py +162 -0
  77. clearskies/columns/select.py +95 -0
  78. clearskies/columns/string.py +102 -0
  79. clearskies/columns/timestamp.py +164 -0
  80. clearskies/columns/updated.py +107 -0
  81. clearskies/columns/uuid.py +83 -0
  82. clearskies/configs/README.md +105 -0
  83. clearskies/configs/__init__.py +170 -0
  84. clearskies/configs/actions.py +43 -0
  85. clearskies/configs/any.py +15 -0
  86. clearskies/configs/any_dict.py +24 -0
  87. clearskies/configs/any_dict_or_callable.py +25 -0
  88. clearskies/configs/authentication.py +23 -0
  89. clearskies/configs/authorization.py +23 -0
  90. clearskies/configs/boolean.py +18 -0
  91. clearskies/configs/boolean_or_callable.py +20 -0
  92. clearskies/configs/callable_config.py +20 -0
  93. clearskies/configs/columns.py +34 -0
  94. clearskies/configs/conditions.py +30 -0
  95. clearskies/configs/config.py +26 -0
  96. clearskies/configs/datetime.py +20 -0
  97. clearskies/configs/datetime_or_callable.py +21 -0
  98. clearskies/configs/email.py +10 -0
  99. clearskies/configs/email_list.py +17 -0
  100. clearskies/configs/email_list_or_callable.py +17 -0
  101. clearskies/configs/email_or_email_list_or_callable.py +59 -0
  102. clearskies/configs/endpoint.py +23 -0
  103. clearskies/configs/endpoint_list.py +29 -0
  104. clearskies/configs/float.py +18 -0
  105. clearskies/configs/float_or_callable.py +20 -0
  106. clearskies/configs/headers.py +28 -0
  107. clearskies/configs/integer.py +18 -0
  108. clearskies/configs/integer_or_callable.py +20 -0
  109. clearskies/configs/joins.py +30 -0
  110. clearskies/configs/list_any_dict.py +32 -0
  111. clearskies/configs/list_any_dict_or_callable.py +33 -0
  112. clearskies/configs/model_class.py +35 -0
  113. clearskies/configs/model_column.py +67 -0
  114. clearskies/configs/model_columns.py +58 -0
  115. clearskies/configs/model_destination_name.py +26 -0
  116. clearskies/configs/model_to_id_column.py +45 -0
  117. clearskies/configs/readable_model_column.py +11 -0
  118. clearskies/configs/readable_model_columns.py +11 -0
  119. clearskies/configs/schema.py +23 -0
  120. clearskies/configs/searchable_model_columns.py +11 -0
  121. clearskies/configs/security_headers.py +39 -0
  122. clearskies/configs/select.py +28 -0
  123. clearskies/configs/select_list.py +49 -0
  124. clearskies/configs/string.py +31 -0
  125. clearskies/configs/string_dict.py +34 -0
  126. clearskies/configs/string_list.py +47 -0
  127. clearskies/configs/string_list_or_callable.py +48 -0
  128. clearskies/configs/string_or_callable.py +18 -0
  129. clearskies/configs/timedelta.py +20 -0
  130. clearskies/configs/timezone.py +20 -0
  131. clearskies/configs/url.py +25 -0
  132. clearskies/configs/validators.py +45 -0
  133. clearskies/configs/writeable_model_column.py +11 -0
  134. clearskies/configs/writeable_model_columns.py +11 -0
  135. clearskies/configurable.py +78 -0
  136. clearskies/contexts/__init__.py +8 -8
  137. clearskies/contexts/cli.py +129 -43
  138. clearskies/contexts/context.py +93 -56
  139. clearskies/contexts/wsgi.py +79 -33
  140. clearskies/contexts/wsgi_ref.py +87 -0
  141. clearskies/cursors/__init__.py +7 -0
  142. clearskies/cursors/cursor.py +166 -0
  143. clearskies/cursors/from_environment/__init__.py +5 -0
  144. clearskies/cursors/from_environment/mysql.py +51 -0
  145. clearskies/cursors/from_environment/postgresql.py +49 -0
  146. clearskies/cursors/from_environment/sqlite.py +35 -0
  147. clearskies/cursors/mysql.py +61 -0
  148. clearskies/cursors/postgresql.py +61 -0
  149. clearskies/cursors/sqlite.py +62 -0
  150. clearskies/decorators.py +33 -0
  151. clearskies/decorators.pyi +10 -0
  152. clearskies/di/__init__.py +11 -7
  153. clearskies/di/additional_config.py +117 -3
  154. clearskies/di/additional_config_auto_import.py +12 -0
  155. clearskies/di/di.py +717 -126
  156. clearskies/di/inject/__init__.py +23 -0
  157. clearskies/di/inject/akeyless_sdk.py +16 -0
  158. clearskies/di/inject/by_class.py +24 -0
  159. clearskies/di/inject/by_name.py +22 -0
  160. clearskies/di/inject/di.py +16 -0
  161. clearskies/di/inject/environment.py +15 -0
  162. clearskies/di/inject/input_output.py +19 -0
  163. clearskies/di/inject/now.py +16 -0
  164. clearskies/di/inject/requests.py +16 -0
  165. clearskies/di/inject/secrets.py +15 -0
  166. clearskies/di/inject/utcnow.py +16 -0
  167. clearskies/di/inject/uuid.py +16 -0
  168. clearskies/di/injectable.py +32 -0
  169. clearskies/di/injectable_properties.py +131 -0
  170. clearskies/end.py +219 -0
  171. clearskies/endpoint.py +1303 -0
  172. clearskies/endpoint_group.py +333 -0
  173. clearskies/endpoints/__init__.py +25 -0
  174. clearskies/endpoints/advanced_search.py +519 -0
  175. clearskies/endpoints/callable.py +382 -0
  176. clearskies/endpoints/create.py +201 -0
  177. clearskies/endpoints/delete.py +133 -0
  178. clearskies/endpoints/get.py +267 -0
  179. clearskies/endpoints/health_check.py +181 -0
  180. clearskies/endpoints/list.py +567 -0
  181. clearskies/endpoints/restful_api.py +417 -0
  182. clearskies/endpoints/schema.py +185 -0
  183. clearskies/endpoints/simple_search.py +279 -0
  184. clearskies/endpoints/update.py +188 -0
  185. clearskies/environment.py +7 -3
  186. clearskies/exceptions/__init__.py +19 -0
  187. clearskies/{handlers/exceptions/input_error.py → exceptions/input_errors.py} +1 -1
  188. clearskies/exceptions/missing_dependency.py +2 -0
  189. clearskies/exceptions/moved_permanently.py +3 -0
  190. clearskies/exceptions/moved_temporarily.py +3 -0
  191. clearskies/functional/__init__.py +2 -2
  192. clearskies/functional/json.py +47 -0
  193. clearskies/functional/routing.py +92 -0
  194. clearskies/functional/string.py +19 -11
  195. clearskies/functional/validations.py +61 -9
  196. clearskies/input_outputs/__init__.py +9 -7
  197. clearskies/input_outputs/cli.py +135 -152
  198. clearskies/input_outputs/exceptions/__init__.py +6 -1
  199. clearskies/input_outputs/headers.py +54 -0
  200. clearskies/input_outputs/input_output.py +77 -123
  201. clearskies/input_outputs/programmatic.py +62 -0
  202. clearskies/input_outputs/wsgi.py +36 -48
  203. clearskies/model.py +1894 -199
  204. clearskies/query/__init__.py +12 -0
  205. clearskies/query/condition.py +228 -0
  206. clearskies/query/join.py +136 -0
  207. clearskies/query/query.py +193 -0
  208. clearskies/query/sort.py +27 -0
  209. clearskies/schema.py +82 -0
  210. clearskies/secrets/__init__.py +4 -31
  211. clearskies/secrets/additional_configs/mysql_connection_dynamic_producer.py +15 -4
  212. clearskies/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssh_cert_bastion.py +11 -5
  213. clearskies/secrets/akeyless.py +421 -155
  214. clearskies/secrets/exceptions/__init__.py +7 -1
  215. clearskies/secrets/exceptions/not_found_error.py +2 -0
  216. clearskies/secrets/exceptions/permissions_error.py +2 -0
  217. clearskies/secrets/secrets.py +12 -11
  218. clearskies/security_header.py +17 -0
  219. clearskies/security_headers/__init__.py +8 -8
  220. clearskies/security_headers/cache_control.py +47 -109
  221. clearskies/security_headers/cors.py +38 -92
  222. clearskies/security_headers/csp.py +76 -150
  223. clearskies/security_headers/hsts.py +14 -15
  224. clearskies/typing.py +11 -0
  225. clearskies/validator.py +36 -0
  226. clearskies/validators/__init__.py +33 -0
  227. clearskies/validators/after_column.py +61 -0
  228. clearskies/validators/before_column.py +15 -0
  229. clearskies/validators/in_the_future.py +29 -0
  230. clearskies/validators/in_the_future_at_least.py +13 -0
  231. clearskies/validators/in_the_future_at_most.py +12 -0
  232. clearskies/validators/in_the_past.py +29 -0
  233. clearskies/validators/in_the_past_at_least.py +12 -0
  234. clearskies/validators/in_the_past_at_most.py +12 -0
  235. clearskies/validators/maximum_length.py +25 -0
  236. clearskies/validators/maximum_value.py +28 -0
  237. clearskies/validators/minimum_length.py +25 -0
  238. clearskies/validators/minimum_value.py +28 -0
  239. clearskies/{input_requirements → validators}/required.py +18 -9
  240. clearskies/validators/timedelta.py +58 -0
  241. clearskies/validators/unique.py +28 -0
  242. clear_skies-1.19.22.dist-info/METADATA +0 -46
  243. clear_skies-1.19.22.dist-info/RECORD +0 -206
  244. clearskies/application.py +0 -29
  245. clearskies/authentication/auth0_jwks.py +0 -118
  246. clearskies/authentication/auth_exception.py +0 -2
  247. clearskies/authentication/jwks_jwcrypto.py +0 -39
  248. clearskies/backends/example_backend.py +0 -43
  249. clearskies/backends/file_backend.py +0 -48
  250. clearskies/backends/json_backend.py +0 -7
  251. clearskies/backends/restful_api_advanced_search_backend.py +0 -138
  252. clearskies/binding_config.py +0 -16
  253. clearskies/column_types/__init__.py +0 -184
  254. clearskies/column_types/audit.py +0 -235
  255. clearskies/column_types/belongs_to.py +0 -250
  256. clearskies/column_types/boolean.py +0 -60
  257. clearskies/column_types/category_tree.py +0 -226
  258. clearskies/column_types/column.py +0 -373
  259. clearskies/column_types/created.py +0 -26
  260. clearskies/column_types/created_by_authorization_data.py +0 -26
  261. clearskies/column_types/created_by_header.py +0 -24
  262. clearskies/column_types/created_by_ip.py +0 -17
  263. clearskies/column_types/created_by_routing_data.py +0 -25
  264. clearskies/column_types/created_by_user_agent.py +0 -17
  265. clearskies/column_types/created_micro.py +0 -26
  266. clearskies/column_types/datetime.py +0 -108
  267. clearskies/column_types/datetime_micro.py +0 -12
  268. clearskies/column_types/email.py +0 -18
  269. clearskies/column_types/float.py +0 -43
  270. clearskies/column_types/has_many.py +0 -139
  271. clearskies/column_types/integer.py +0 -41
  272. clearskies/column_types/json.py +0 -25
  273. clearskies/column_types/many_to_many.py +0 -278
  274. clearskies/column_types/many_to_many_with_data.py +0 -162
  275. clearskies/column_types/select.py +0 -11
  276. clearskies/column_types/string.py +0 -24
  277. clearskies/column_types/updated.py +0 -24
  278. clearskies/column_types/updated_micro.py +0 -24
  279. clearskies/column_types/uuid.py +0 -25
  280. clearskies/columns.py +0 -123
  281. clearskies/condition_parser.py +0 -172
  282. clearskies/contexts/build_context.py +0 -54
  283. clearskies/contexts/convert_to_application.py +0 -190
  284. clearskies/contexts/extract_handler.py +0 -37
  285. clearskies/contexts/test.py +0 -94
  286. clearskies/decorators/__init__.py +0 -39
  287. clearskies/decorators/auth0_jwks.py +0 -22
  288. clearskies/decorators/authorization.py +0 -10
  289. clearskies/decorators/binding_classes.py +0 -9
  290. clearskies/decorators/binding_modules.py +0 -9
  291. clearskies/decorators/bindings.py +0 -9
  292. clearskies/decorators/create.py +0 -10
  293. clearskies/decorators/delete.py +0 -10
  294. clearskies/decorators/docs.py +0 -14
  295. clearskies/decorators/get.py +0 -10
  296. clearskies/decorators/jwks.py +0 -26
  297. clearskies/decorators/merge.py +0 -124
  298. clearskies/decorators/patch.py +0 -10
  299. clearskies/decorators/post.py +0 -10
  300. clearskies/decorators/public.py +0 -11
  301. clearskies/decorators/response_headers.py +0 -10
  302. clearskies/decorators/return_raw_response.py +0 -9
  303. clearskies/decorators/schema.py +0 -10
  304. clearskies/decorators/secret_bearer.py +0 -24
  305. clearskies/decorators/security_headers.py +0 -10
  306. clearskies/di/standard_dependencies.py +0 -140
  307. clearskies/di/test_module/__init__.py +0 -6
  308. clearskies/di/test_module/another_module/__init__.py +0 -2
  309. clearskies/di/test_module/module_class.py +0 -5
  310. clearskies/handlers/__init__.py +0 -41
  311. clearskies/handlers/advanced_search.py +0 -271
  312. clearskies/handlers/base.py +0 -473
  313. clearskies/handlers/callable.py +0 -189
  314. clearskies/handlers/create.py +0 -35
  315. clearskies/handlers/crud_by_method.py +0 -18
  316. clearskies/handlers/database_connector.py +0 -32
  317. clearskies/handlers/delete.py +0 -61
  318. clearskies/handlers/exceptions/__init__.py +0 -5
  319. clearskies/handlers/exceptions/not_found.py +0 -3
  320. clearskies/handlers/get.py +0 -156
  321. clearskies/handlers/health_check.py +0 -59
  322. clearskies/handlers/input_processing.py +0 -79
  323. clearskies/handlers/list.py +0 -530
  324. clearskies/handlers/mygrations.py +0 -82
  325. clearskies/handlers/request_method_routing.py +0 -47
  326. clearskies/handlers/restful_api.py +0 -218
  327. clearskies/handlers/routing.py +0 -62
  328. clearskies/handlers/schema_helper.py +0 -128
  329. clearskies/handlers/simple_routing.py +0 -204
  330. clearskies/handlers/simple_routing_route.py +0 -192
  331. clearskies/handlers/simple_search.py +0 -136
  332. clearskies/handlers/update.py +0 -96
  333. clearskies/handlers/write.py +0 -193
  334. clearskies/input_requirements/__init__.py +0 -68
  335. clearskies/input_requirements/after.py +0 -36
  336. clearskies/input_requirements/before.py +0 -36
  337. clearskies/input_requirements/in_the_future_at_least.py +0 -19
  338. clearskies/input_requirements/in_the_future_at_most.py +0 -19
  339. clearskies/input_requirements/in_the_past_at_least.py +0 -19
  340. clearskies/input_requirements/in_the_past_at_most.py +0 -19
  341. clearskies/input_requirements/maximum_length.py +0 -19
  342. clearskies/input_requirements/minimum_length.py +0 -22
  343. clearskies/input_requirements/requirement.py +0 -25
  344. clearskies/input_requirements/time_delta.py +0 -38
  345. clearskies/input_requirements/unique.py +0 -18
  346. clearskies/mocks/__init__.py +0 -7
  347. clearskies/mocks/input_output.py +0 -124
  348. clearskies/mocks/models.py +0 -142
  349. clearskies/models.py +0 -345
  350. clearskies/security_headers/base.py +0 -12
  351. clearskies/tests/simple_api/models/__init__.py +0 -2
  352. clearskies/tests/simple_api/models/status.py +0 -23
  353. clearskies/tests/simple_api/models/user.py +0 -21
  354. clearskies/tests/simple_api/users_api.py +0 -64
  355. {clear_skies-1.19.22.dist-info → clear_skies-2.0.23.dist-info/licenses}/LICENSE +0 -0
  356. /clearskies/{contexts/bash.py → autodoc/py.typed} +0 -0
  357. /clearskies/{handlers/exceptions → exceptions}/authentication.py +0 -0
  358. /clearskies/{handlers/exceptions → exceptions}/authorization.py +0 -0
  359. /clearskies/{handlers/exceptions → exceptions}/client_error.py +0 -0
  360. /clearskies/{secrets/exceptions → exceptions}/not_found.py +0 -0
  361. /clearskies/{tests/__init__.py → input_outputs/py.typed} +0 -0
  362. /clearskies/{tests/simple_api/__init__.py → py.typed} +0 -0
clearskies/models.py DELETED
@@ -1,345 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from .condition_parser import ConditionParser
3
- from typing import Any, Callable, Dict, List, Tuple
4
-
5
-
6
- class Models(ABC, ConditionParser):
7
- # The database connection
8
- _backend = None
9
- _columns = None
10
- _model_columns = None
11
- _next_page_data = None
12
-
13
- query_wheres = None
14
- query_sorts = None
15
- query_group_by_column = None
16
- query_limit = None
17
- query_pagination = None
18
- query_selects = None
19
- query_select_all = None
20
- must_rexecute = True
21
- must_recount = True
22
- count = None
23
- _table_name = None
24
- _id_column_name = None
25
- _query_configuration = None
26
-
27
- def __init__(self, backend, columns):
28
- self._model_columns = None
29
- self._backend = backend
30
- self._columns = columns
31
- self.must_rexecute = True
32
- self._next_page_data = None
33
- self.must_recount = True
34
-
35
- self.query_wheres = []
36
- self.query_sorts = []
37
- self.query_group_by_column = None
38
- self.query_joins = []
39
- self.query_limit = None
40
- self.query_pagination = {}
41
- self.query_selects = []
42
- self.query_select_all = True
43
-
44
- @abstractmethod
45
- def model_class(self):
46
- """Return the model class that this models object will find/return instances of"""
47
- pass
48
-
49
- def clone(self):
50
- clone = self.blank()
51
- clone.query_configuration = self.query_configuration
52
- return clone
53
-
54
- def blank(self):
55
- return self._build_model()
56
-
57
- def get_table_name(self):
58
- if self._table_name is None:
59
- self._table_name = self.model_class().table_name()
60
- return self._table_name
61
-
62
- def get_id_column_name(self):
63
- if self._id_column_name is None:
64
- self._id_column_name = self.empty_model().id_column_name
65
- return self._id_column_name
66
-
67
- @property
68
- def query_configuration(self):
69
- return {
70
- "wheres": [*self.query_wheres],
71
- "sorts": [*self.query_sorts],
72
- "group_by_column": self.query_group_by_column,
73
- "joins": [*self.query_joins],
74
- "limit": self.query_limit,
75
- "pagination": self.query_pagination,
76
- "selects": self.query_selects,
77
- "select_all": self.query_select_all,
78
- "table_name": self.get_table_name(),
79
- "model_columns": self._model_columns,
80
- }
81
-
82
- @query_configuration.setter
83
- def query_configuration(self, configuration):
84
- self.query_wheres = configuration["wheres"]
85
- self.query_sorts = configuration["sorts"]
86
- self.query_group_by_column = configuration["group_by_column"]
87
- self.query_joins = configuration["joins"]
88
- self.query_limit = configuration["limit"]
89
- self.query_pagination = configuration["pagination"]
90
- self.query_selects = configuration["selects"]
91
- self.query_select_all = configuration["select_all"]
92
- self._model_columns = configuration["model_columns"]
93
-
94
- @property
95
- def model_columns(self):
96
- if self._model_columns is None:
97
- self._model_columns = self.empty_model().columns()
98
- return self._model_columns
99
-
100
- def select(self, selects):
101
- return self.clone().select_in_place(selects)
102
-
103
- def select_in_place(self, selects):
104
- self.query_selects.append(selects)
105
- self.must_rexecute = True
106
- self._next_page_data = None
107
- return self
108
-
109
- def select_all(self, select_all=True):
110
- return self.clone().select_all_in_place(select_all=select_all)
111
-
112
- def select_all_in_place(self, select_all=True):
113
- self.query_select_all = select_all
114
- self.must_rexecute = True
115
- self._next_page_data = None
116
- return self
117
-
118
- def where(self, where):
119
- """Adds the given condition to the query and returns a new Models object"""
120
- return self.clone().where_in_place(where)
121
-
122
- def where_in_place(self, where):
123
- """Adds the given condition to the query for the current Models object"""
124
- condition = self.parse_condition(where)
125
- self._validate_column(condition["column"], "filter", table=condition["table"])
126
- self.query_wheres.append(self.parse_condition(where))
127
- self.must_rexecute = True
128
- self._next_page_data = None
129
- self.must_recount = True
130
- return self
131
-
132
- def join(self, join):
133
- return self.clone().join_in_place(join)
134
-
135
- def join_in_place(self, join):
136
- self.query_joins.append(self.parse_join(join))
137
- self.must_rexecute = True
138
- self._next_page_data = None
139
- self.must_recount = True
140
- return self
141
-
142
- def is_joined(self, table_name, alias=None):
143
- for join in self.query_joins:
144
- if join["table"] != table_name:
145
- continue
146
-
147
- if alias and join["alias"] != alias:
148
- continue
149
-
150
- return join["alias"] if join["alias"] else join["table"]
151
- return False
152
-
153
- def group_by(self, group_column):
154
- return self.clone().group_by_in_place(group_column)
155
-
156
- def group_by_in_place(self, group_column):
157
- self._validate_column(group_column, "group")
158
- self.query_group_by_column = group_column
159
- self.must_rexecute = True
160
- self._next_page_data = None
161
- self.must_recount = True
162
- return self
163
-
164
- def sort_by(
165
- self,
166
- primary_column,
167
- primary_direction,
168
- primary_table=None,
169
- secondary_column=None,
170
- secondary_direction=None,
171
- secondary_table=None,
172
- ):
173
- return self.clone().sort_by_in_place(
174
- primary_column,
175
- primary_direction,
176
- primary_table=primary_table,
177
- secondary_column=secondary_column,
178
- secondary_direction=secondary_direction,
179
- secondary_table=secondary_table,
180
- )
181
-
182
- def sort_by_in_place(
183
- self,
184
- primary_column,
185
- primary_direction,
186
- primary_table=None,
187
- secondary_column=None,
188
- secondary_direction=None,
189
- secondary_table=None,
190
- ):
191
- sorts = [
192
- {"table": primary_table, "column": primary_column, "direction": primary_direction},
193
- {"table": secondary_table, "column": secondary_column, "direction": secondary_direction},
194
- ]
195
- sorts = filter(lambda sort: sort["column"] is not None and sort["direction"] is not None, sorts)
196
- self.query_sorts = list(map(lambda sort: self._normalize_and_validate_sort(sort), sorts))
197
- if len(self.query_sorts) == 0:
198
- raise ValueError("Missing primary column or direction in call to sort_by")
199
- self.must_rexecute = True
200
- self._next_page_data = None
201
- return self
202
-
203
- def _normalize_and_validate_sort(self, sort):
204
- if "column" not in sort or not sort["column"]:
205
- raise ValueError("Missing 'column' for sort")
206
- if "direction" not in sort or not sort["direction"]:
207
- raise ValueError("Missing 'direction' for sort: should be ASC or DESC")
208
- direction = sort["direction"].upper().strip()
209
- if direction != "ASC" and direction != "DESC":
210
- raise ValueError(f"Invalid sort direction: should be ASC or DESC, not '{direction}'")
211
- self._validate_column(sort["column"], "sort", table=sort.get("table"))
212
-
213
- # down the line we may ask the model class what columns we can sort on, but we're good for now
214
- return {"column": sort["column"], "direction": sort["direction"], "table": sort.get("table")}
215
-
216
- def _validate_column(self, column_name, action, table=None):
217
- """
218
- Down the line we may use the model configuration to check what columns are valid sort/group/search targets
219
- """
220
- # for now, only validate columns that belong to *our* table.
221
- # in some cases we are explicitly told the column name
222
- if table is not None:
223
- # note that table may be '', in which case it is implicitly "our" table
224
- if table != "" and table != self.get_table_name():
225
- return
226
-
227
- # but in some cases we should check and see if it is included with the column name
228
- column_name = column_name.replace("`", "")
229
- if "." in column_name:
230
- parts = column_name.split(".")
231
- if parts[0] != self.get_table_name():
232
- return
233
- column_name = column_name.split(".")[1]
234
-
235
- model_columns = self.model_columns
236
- if column_name not in model_columns:
237
- model_class = self.model_class()
238
- raise KeyError(
239
- f"Cannot {action} by column '{column_name}' for model class {model_class.__name__} because this "
240
- + "column does not exist for the model. You can suppress this error by adding a matching column "
241
- + "to your model definition"
242
- )
243
-
244
- def limit(self, limit):
245
- return self.clone().limit_in_place(limit)
246
-
247
- def limit_in_place(self, limit):
248
- self.query_limit = limit
249
- self.must_rexecute = True
250
- self._next_page_data = None
251
- return self
252
-
253
- def pagination(self, **kwargs):
254
- return self.clone().pagination_in_place(**kwargs)
255
-
256
- def pagination_in_place(self, **kwargs):
257
- error = self._backend.validate_pagination_kwargs(kwargs, str)
258
- if error:
259
- raise ValueError(
260
- f"Invalid pagination data for model {self.__class__.__name__} with backend "
261
- + f"{self._backend.__class__.__name__}. {error}"
262
- )
263
- self.query_pagination = kwargs
264
- self.must_rexecute = True
265
- self._next_page_data = None
266
- return self
267
-
268
- def find(self, where):
269
- """Returns the first model where condition"""
270
- return self.clone().where(where).first()
271
-
272
- def __len__(self):
273
- if self.must_recount:
274
- self.count = self._backend.count(self.query_configuration, self.empty_model())
275
- self.must_recount = False
276
- return self.count
277
-
278
- def __iter__(self):
279
- self._next_page_data = {}
280
- raw_rows = self._backend.records(
281
- self.query_configuration,
282
- self.empty_model(),
283
- next_page_data=self._next_page_data,
284
- )
285
- models = iter([self.model(row) for row in raw_rows])
286
- return models
287
-
288
- def paginate_all(self):
289
- next_models = self.clone()
290
- results = list(next_models.__iter__())
291
- next_page_data = next_models.next_page_data()
292
- while next_page_data:
293
- next_models = next_models.clone().pagination(**next_page_data)
294
- results.extend(next_models.__iter__())
295
- next_page_data = next_models.next_page_data()
296
- return results
297
-
298
- def model(self, data):
299
- model = self._build_model()
300
- model.data = data
301
- return model
302
-
303
- def _build_model(self):
304
- model_class = self.model_class()
305
- return model_class(self._backend, self._columns)
306
-
307
- def empty_model(self):
308
- return self.model({})
309
-
310
- def create(self, data):
311
- empty = self.empty_model()
312
- empty.save(data)
313
- return empty
314
-
315
- def first(self):
316
- iter = self.__iter__()
317
- try:
318
- return iter.__next__()
319
- except StopIteration:
320
- return self.empty_model()
321
-
322
- def columns(self, overrides=None):
323
- model = self.model({})
324
- return model.columns(overrides=None)
325
-
326
- def raw_columns_configuration(self):
327
- return self.model({}).all_columns()
328
-
329
- def allowed_pagination_keys(self) -> List[str]:
330
- return self._backend.allowed_pagination_keys()
331
-
332
- def validate_pagination_kwargs(self, kwargs: Dict[str, Any], case_mapping: Callable) -> str:
333
- return self._backend.validate_pagination_kwargs(kwargs, case_mapping)
334
-
335
- def next_page_data(self):
336
- return self._next_page_data
337
-
338
- def documentation_pagination_next_page_response(self, case_mapping: Callable) -> List[Any]:
339
- return self._backend.documentation_pagination_next_page_response(case_mapping)
340
-
341
- def documentation_pagination_next_page_example(self, case_mapping: Callable) -> Dict[str, Any]:
342
- return self._backend.documentation_pagination_next_page_example(case_mapping)
343
-
344
- def documentation_pagination_parameters(self, case_mapping: Callable) -> List[Tuple[Any]]:
345
- return self._backend.documentation_pagination_parameters(case_mapping)
@@ -1,12 +0,0 @@
1
- class Base:
2
- environment = None
3
- is_cors = False
4
-
5
- def __init__(self, environment):
6
- self.environment = environment
7
-
8
- def configure(self):
9
- pass
10
-
11
- def set_headers_for_input_output(self, input_output):
12
- pass
@@ -1,2 +0,0 @@
1
- from .user import User
2
- from .status import Status
@@ -1,23 +0,0 @@
1
- from collections import OrderedDict
2
- from clearskies import Model
3
- from clearskies.column_types import string, has_many
4
- from clearskies.input_requirements import required, maximum_length
5
- from . import user
6
-
7
-
8
- class Status(Model):
9
- def __init__(self, cursor_backend, columns):
10
- super().__init__(cursor_backend, columns)
11
-
12
- def columns_configuration(self):
13
- return OrderedDict(
14
- [
15
- string("name"),
16
- has_many(
17
- "users",
18
- child_models_class=user.User,
19
- is_readable=True,
20
- readable_child_columns=["status_id", "name", "email"],
21
- ),
22
- ]
23
- )
@@ -1,21 +0,0 @@
1
- from collections import OrderedDict
2
- from clearskies import Model
3
- from clearskies.column_types import belongs_to, email, string, integer, created, updated
4
- from clearskies.input_requirements import required, maximum_length
5
- from . import status
6
-
7
-
8
- class User(Model):
9
- def __init__(self, cursor_backend, columns):
10
- super().__init__(cursor_backend, columns)
11
-
12
- def columns_configuration(self):
13
- return OrderedDict(
14
- [
15
- belongs_to("status_id", parent_models_class=status.Status, input_requirements=[required()]),
16
- string("name", input_requirements=[required(), maximum_length(255)]),
17
- email("email", input_requirements=[required(), maximum_length(255)]),
18
- created("created"),
19
- updated("updated"),
20
- ]
21
- )
@@ -1,64 +0,0 @@
1
- import clearskies
2
- from . import models
3
-
4
-
5
- def restart_user(user_id, input_output):
6
- return {"user_id": user_id}
7
-
8
-
9
- users_api = clearskies.Application(
10
- clearskies.handlers.SimpleRouting,
11
- {
12
- "authentication": clearskies.authentication.public(),
13
- "routes": [
14
- {
15
- "path": "users/{user_id}/restart",
16
- "handler_class": clearskies.handlers.Callable,
17
- "handler_config": {
18
- "callable": restart_user,
19
- },
20
- },
21
- {
22
- "path": "users",
23
- "handler_class": clearskies.handlers.RestfulAPI,
24
- "handler_config": {
25
- "model_class": models.User,
26
- "readable_columns": ["id", "status_id", "name", "email", "created", "updated"],
27
- "writeable_columns": ["status_id", "name", "email"],
28
- "searchable_columns": ["status_id", "name", "email"],
29
- "default_sort_column": "name",
30
- },
31
- },
32
- {
33
- "path": "statuses",
34
- "handler_class": clearskies.handlers.RestfulAPI,
35
- "handler_config": {
36
- "model_class": models.Status,
37
- "read_only": True,
38
- "readable_columns": ["id", "name", "users"],
39
- "searchable_columns": ["name", "users"],
40
- "default_sort_column": "name",
41
- },
42
- },
43
- {
44
- "path": "v1",
45
- "handler_class": clearskies.handlers.SimpleRouting,
46
- "handler_config": {
47
- "routes": [
48
- {
49
- "path": "users",
50
- "handler_class": clearskies.handlers.RestfulAPI,
51
- "handler_config": {
52
- "read_only": True,
53
- "model_class": models.User,
54
- "readable_columns": ["id", "status_id", "name"],
55
- "searchable_columns": ["status_id", "name"],
56
- "default_sort_column": "name",
57
- },
58
- },
59
- ]
60
- },
61
- },
62
- ],
63
- },
64
- )
File without changes
File without changes