clear-skies 0.0.3a0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of clear-skies might be problematic. Click here for more details.

Files changed (248) hide show
  1. clear_skies-0.0.3a0/LICENSE +7 -0
  2. clear_skies-0.0.3a0/PKG-INFO +46 -0
  3. clear_skies-0.0.3a0/README.md +15 -0
  4. clear_skies-0.0.3a0/pyproject.toml +73 -0
  5. clear_skies-0.0.3a0/src/clearskies/__init__.py +62 -0
  6. clear_skies-0.0.3a0/src/clearskies/action.py +7 -0
  7. clear_skies-0.0.3a0/src/clearskies/authentication/__init__.py +15 -0
  8. clear_skies-0.0.3a0/src/clearskies/authentication/authentication.py +42 -0
  9. clear_skies-0.0.3a0/src/clearskies/authentication/authorization.py +12 -0
  10. clear_skies-0.0.3a0/src/clearskies/authentication/authorization_pass_through.py +20 -0
  11. clear_skies-0.0.3a0/src/clearskies/authentication/jwks.py +158 -0
  12. clear_skies-0.0.3a0/src/clearskies/authentication/public.py +5 -0
  13. clear_skies-0.0.3a0/src/clearskies/authentication/secret_bearer.py +553 -0
  14. clear_skies-0.0.3a0/src/clearskies/autodoc/__init__.py +8 -0
  15. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/__init__.py +5 -0
  16. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/__init__.py +7 -0
  17. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/oai3_json.py +87 -0
  18. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/oai3_schema_resolver.py +15 -0
  19. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/parameter.py +35 -0
  20. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/request.py +68 -0
  21. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/response.py +28 -0
  22. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/schema/__init__.py +11 -0
  23. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/schema/array.py +9 -0
  24. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/schema/default.py +13 -0
  25. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/schema/enum.py +7 -0
  26. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/schema/object.py +29 -0
  27. clear_skies-0.0.3a0/src/clearskies/autodoc/formats/oai3_json/test.json +1985 -0
  28. clear_skies-0.0.3a0/src/clearskies/autodoc/py.typed +0 -0
  29. clear_skies-0.0.3a0/src/clearskies/autodoc/request/__init__.py +15 -0
  30. clear_skies-0.0.3a0/src/clearskies/autodoc/request/header.py +6 -0
  31. clear_skies-0.0.3a0/src/clearskies/autodoc/request/json_body.py +6 -0
  32. clear_skies-0.0.3a0/src/clearskies/autodoc/request/parameter.py +8 -0
  33. clear_skies-0.0.3a0/src/clearskies/autodoc/request/request.py +38 -0
  34. clear_skies-0.0.3a0/src/clearskies/autodoc/request/url_parameter.py +6 -0
  35. clear_skies-0.0.3a0/src/clearskies/autodoc/request/url_path.py +6 -0
  36. clear_skies-0.0.3a0/src/clearskies/autodoc/response/__init__.py +5 -0
  37. clear_skies-0.0.3a0/src/clearskies/autodoc/response/response.py +9 -0
  38. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/__init__.py +31 -0
  39. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/array.py +10 -0
  40. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/base64.py +8 -0
  41. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/boolean.py +5 -0
  42. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/date.py +5 -0
  43. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/datetime.py +5 -0
  44. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/double.py +5 -0
  45. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/enum.py +17 -0
  46. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/integer.py +6 -0
  47. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/long.py +5 -0
  48. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/number.py +6 -0
  49. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/object.py +13 -0
  50. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/password.py +5 -0
  51. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/schema.py +11 -0
  52. clear_skies-0.0.3a0/src/clearskies/autodoc/schema/string.py +5 -0
  53. clear_skies-0.0.3a0/src/clearskies/backends/__init__.py +65 -0
  54. clear_skies-0.0.3a0/src/clearskies/backends/api_backend.py +1178 -0
  55. clear_skies-0.0.3a0/src/clearskies/backends/backend.py +123 -0
  56. clear_skies-0.0.3a0/src/clearskies/backends/cursor_backend.py +335 -0
  57. clear_skies-0.0.3a0/src/clearskies/backends/memory_backend.py +797 -0
  58. clear_skies-0.0.3a0/src/clearskies/backends/secrets_backend.py +107 -0
  59. clear_skies-0.0.3a0/src/clearskies/column.py +1232 -0
  60. clear_skies-0.0.3a0/src/clearskies/columns/__init__.py +71 -0
  61. clear_skies-0.0.3a0/src/clearskies/columns/audit.py +205 -0
  62. clear_skies-0.0.3a0/src/clearskies/columns/belongs_to_id.py +483 -0
  63. clear_skies-0.0.3a0/src/clearskies/columns/belongs_to_model.py +128 -0
  64. clear_skies-0.0.3a0/src/clearskies/columns/belongs_to_self.py +105 -0
  65. clear_skies-0.0.3a0/src/clearskies/columns/boolean.py +109 -0
  66. clear_skies-0.0.3a0/src/clearskies/columns/category_tree.py +275 -0
  67. clear_skies-0.0.3a0/src/clearskies/columns/category_tree_ancestors.py +51 -0
  68. clear_skies-0.0.3a0/src/clearskies/columns/category_tree_children.py +127 -0
  69. clear_skies-0.0.3a0/src/clearskies/columns/category_tree_descendants.py +48 -0
  70. clear_skies-0.0.3a0/src/clearskies/columns/created.py +94 -0
  71. clear_skies-0.0.3a0/src/clearskies/columns/created_by_authorization_data.py +116 -0
  72. clear_skies-0.0.3a0/src/clearskies/columns/created_by_header.py +99 -0
  73. clear_skies-0.0.3a0/src/clearskies/columns/created_by_ip.py +92 -0
  74. clear_skies-0.0.3a0/src/clearskies/columns/created_by_routing_data.py +96 -0
  75. clear_skies-0.0.3a0/src/clearskies/columns/created_by_user_agent.py +92 -0
  76. clear_skies-0.0.3a0/src/clearskies/columns/date.py +230 -0
  77. clear_skies-0.0.3a0/src/clearskies/columns/datetime.py +278 -0
  78. clear_skies-0.0.3a0/src/clearskies/columns/email.py +76 -0
  79. clear_skies-0.0.3a0/src/clearskies/columns/float.py +149 -0
  80. clear_skies-0.0.3a0/src/clearskies/columns/has_many.py +505 -0
  81. clear_skies-0.0.3a0/src/clearskies/columns/has_many_self.py +56 -0
  82. clear_skies-0.0.3a0/src/clearskies/columns/has_one.py +14 -0
  83. clear_skies-0.0.3a0/src/clearskies/columns/integer.py +156 -0
  84. clear_skies-0.0.3a0/src/clearskies/columns/json.py +122 -0
  85. clear_skies-0.0.3a0/src/clearskies/columns/many_to_many_ids.py +333 -0
  86. clear_skies-0.0.3a0/src/clearskies/columns/many_to_many_ids_with_data.py +270 -0
  87. clear_skies-0.0.3a0/src/clearskies/columns/many_to_many_models.py +154 -0
  88. clear_skies-0.0.3a0/src/clearskies/columns/many_to_many_pivots.py +133 -0
  89. clear_skies-0.0.3a0/src/clearskies/columns/phone.py +158 -0
  90. clear_skies-0.0.3a0/src/clearskies/columns/select.py +91 -0
  91. clear_skies-0.0.3a0/src/clearskies/columns/string.py +98 -0
  92. clear_skies-0.0.3a0/src/clearskies/columns/timestamp.py +160 -0
  93. clear_skies-0.0.3a0/src/clearskies/columns/updated.py +110 -0
  94. clear_skies-0.0.3a0/src/clearskies/columns/uuid.py +86 -0
  95. clear_skies-0.0.3a0/src/clearskies/configs/README.md +105 -0
  96. clear_skies-0.0.3a0/src/clearskies/configs/__init__.py +159 -0
  97. clear_skies-0.0.3a0/src/clearskies/configs/actions.py +43 -0
  98. clear_skies-0.0.3a0/src/clearskies/configs/any.py +13 -0
  99. clear_skies-0.0.3a0/src/clearskies/configs/any_dict.py +22 -0
  100. clear_skies-0.0.3a0/src/clearskies/configs/any_dict_or_callable.py +23 -0
  101. clear_skies-0.0.3a0/src/clearskies/configs/authentication.py +23 -0
  102. clear_skies-0.0.3a0/src/clearskies/configs/authorization.py +23 -0
  103. clear_skies-0.0.3a0/src/clearskies/configs/boolean.py +16 -0
  104. clear_skies-0.0.3a0/src/clearskies/configs/boolean_or_callable.py +18 -0
  105. clear_skies-0.0.3a0/src/clearskies/configs/callable_config.py +18 -0
  106. clear_skies-0.0.3a0/src/clearskies/configs/columns.py +34 -0
  107. clear_skies-0.0.3a0/src/clearskies/configs/conditions.py +30 -0
  108. clear_skies-0.0.3a0/src/clearskies/configs/config.py +21 -0
  109. clear_skies-0.0.3a0/src/clearskies/configs/datetime.py +18 -0
  110. clear_skies-0.0.3a0/src/clearskies/configs/datetime_or_callable.py +19 -0
  111. clear_skies-0.0.3a0/src/clearskies/configs/endpoint.py +23 -0
  112. clear_skies-0.0.3a0/src/clearskies/configs/float.py +16 -0
  113. clear_skies-0.0.3a0/src/clearskies/configs/float_or_callable.py +18 -0
  114. clear_skies-0.0.3a0/src/clearskies/configs/integer.py +16 -0
  115. clear_skies-0.0.3a0/src/clearskies/configs/integer_or_callable.py +18 -0
  116. clear_skies-0.0.3a0/src/clearskies/configs/joins.py +30 -0
  117. clear_skies-0.0.3a0/src/clearskies/configs/list_any_dict.py +30 -0
  118. clear_skies-0.0.3a0/src/clearskies/configs/list_any_dict_or_callable.py +31 -0
  119. clear_skies-0.0.3a0/src/clearskies/configs/model_class.py +35 -0
  120. clear_skies-0.0.3a0/src/clearskies/configs/model_column.py +65 -0
  121. clear_skies-0.0.3a0/src/clearskies/configs/model_columns.py +56 -0
  122. clear_skies-0.0.3a0/src/clearskies/configs/model_destination_name.py +25 -0
  123. clear_skies-0.0.3a0/src/clearskies/configs/model_to_id_column.py +43 -0
  124. clear_skies-0.0.3a0/src/clearskies/configs/readable_model_column.py +9 -0
  125. clear_skies-0.0.3a0/src/clearskies/configs/readable_model_columns.py +9 -0
  126. clear_skies-0.0.3a0/src/clearskies/configs/schema.py +23 -0
  127. clear_skies-0.0.3a0/src/clearskies/configs/searchable_model_columns.py +9 -0
  128. clear_skies-0.0.3a0/src/clearskies/configs/security_headers.py +39 -0
  129. clear_skies-0.0.3a0/src/clearskies/configs/select.py +26 -0
  130. clear_skies-0.0.3a0/src/clearskies/configs/select_list.py +47 -0
  131. clear_skies-0.0.3a0/src/clearskies/configs/string.py +29 -0
  132. clear_skies-0.0.3a0/src/clearskies/configs/string_dict.py +32 -0
  133. clear_skies-0.0.3a0/src/clearskies/configs/string_list.py +32 -0
  134. clear_skies-0.0.3a0/src/clearskies/configs/string_list_or_callable.py +35 -0
  135. clear_skies-0.0.3a0/src/clearskies/configs/string_or_callable.py +18 -0
  136. clear_skies-0.0.3a0/src/clearskies/configs/timedelta.py +18 -0
  137. clear_skies-0.0.3a0/src/clearskies/configs/timezone.py +18 -0
  138. clear_skies-0.0.3a0/src/clearskies/configs/url.py +23 -0
  139. clear_skies-0.0.3a0/src/clearskies/configs/validators.py +45 -0
  140. clear_skies-0.0.3a0/src/clearskies/configs/writeable_model_column.py +9 -0
  141. clear_skies-0.0.3a0/src/clearskies/configs/writeable_model_columns.py +9 -0
  142. clear_skies-0.0.3a0/src/clearskies/configurable.py +76 -0
  143. clear_skies-0.0.3a0/src/clearskies/contexts/__init__.py +11 -0
  144. clear_skies-0.0.3a0/src/clearskies/contexts/cli.py +7 -0
  145. clear_skies-0.0.3a0/src/clearskies/contexts/context.py +84 -0
  146. clear_skies-0.0.3a0/src/clearskies/contexts/wsgi.py +16 -0
  147. clear_skies-0.0.3a0/src/clearskies/contexts/wsgi_ref.py +49 -0
  148. clear_skies-0.0.3a0/src/clearskies/di/__init__.py +14 -0
  149. clear_skies-0.0.3a0/src/clearskies/di/additional_config.py +130 -0
  150. clear_skies-0.0.3a0/src/clearskies/di/additional_config_auto_import.py +17 -0
  151. clear_skies-0.0.3a0/src/clearskies/di/di.py +968 -0
  152. clear_skies-0.0.3a0/src/clearskies/di/inject/__init__.py +23 -0
  153. clear_skies-0.0.3a0/src/clearskies/di/inject/by_class.py +21 -0
  154. clear_skies-0.0.3a0/src/clearskies/di/inject/by_name.py +18 -0
  155. clear_skies-0.0.3a0/src/clearskies/di/inject/di.py +13 -0
  156. clear_skies-0.0.3a0/src/clearskies/di/inject/environment.py +14 -0
  157. clear_skies-0.0.3a0/src/clearskies/di/inject/input_output.py +20 -0
  158. clear_skies-0.0.3a0/src/clearskies/di/inject/now.py +13 -0
  159. clear_skies-0.0.3a0/src/clearskies/di/inject/requests.py +13 -0
  160. clear_skies-0.0.3a0/src/clearskies/di/inject/secrets.py +14 -0
  161. clear_skies-0.0.3a0/src/clearskies/di/inject/utcnow.py +13 -0
  162. clear_skies-0.0.3a0/src/clearskies/di/inject/uuid.py +15 -0
  163. clear_skies-0.0.3a0/src/clearskies/di/injectable.py +29 -0
  164. clear_skies-0.0.3a0/src/clearskies/di/injectable_properties.py +131 -0
  165. clear_skies-0.0.3a0/src/clearskies/di/test_module/__init__.py +6 -0
  166. clear_skies-0.0.3a0/src/clearskies/di/test_module/another_module/__init__.py +2 -0
  167. clear_skies-0.0.3a0/src/clearskies/di/test_module/module_class.py +5 -0
  168. clear_skies-0.0.3a0/src/clearskies/end.py +183 -0
  169. clear_skies-0.0.3a0/src/clearskies/endpoint.py +1309 -0
  170. clear_skies-0.0.3a0/src/clearskies/endpoint_group.py +297 -0
  171. clear_skies-0.0.3a0/src/clearskies/endpoints/__init__.py +23 -0
  172. clear_skies-0.0.3a0/src/clearskies/endpoints/advanced_search.py +526 -0
  173. clear_skies-0.0.3a0/src/clearskies/endpoints/callable.py +387 -0
  174. clear_skies-0.0.3a0/src/clearskies/endpoints/create.py +202 -0
  175. clear_skies-0.0.3a0/src/clearskies/endpoints/delete.py +139 -0
  176. clear_skies-0.0.3a0/src/clearskies/endpoints/get.py +275 -0
  177. clear_skies-0.0.3a0/src/clearskies/endpoints/health_check.py +181 -0
  178. clear_skies-0.0.3a0/src/clearskies/endpoints/list.py +573 -0
  179. clear_skies-0.0.3a0/src/clearskies/endpoints/restful_api.py +427 -0
  180. clear_skies-0.0.3a0/src/clearskies/endpoints/simple_search.py +286 -0
  181. clear_skies-0.0.3a0/src/clearskies/endpoints/update.py +190 -0
  182. clear_skies-0.0.3a0/src/clearskies/environment.py +104 -0
  183. clear_skies-0.0.3a0/src/clearskies/exceptions/__init__.py +17 -0
  184. clear_skies-0.0.3a0/src/clearskies/exceptions/authentication.py +2 -0
  185. clear_skies-0.0.3a0/src/clearskies/exceptions/authorization.py +2 -0
  186. clear_skies-0.0.3a0/src/clearskies/exceptions/client_error.py +2 -0
  187. clear_skies-0.0.3a0/src/clearskies/exceptions/input_errors.py +4 -0
  188. clear_skies-0.0.3a0/src/clearskies/exceptions/moved_permanently.py +3 -0
  189. clear_skies-0.0.3a0/src/clearskies/exceptions/moved_temporarily.py +3 -0
  190. clear_skies-0.0.3a0/src/clearskies/exceptions/not_found.py +2 -0
  191. clear_skies-0.0.3a0/src/clearskies/functional/__init__.py +7 -0
  192. clear_skies-0.0.3a0/src/clearskies/functional/routing.py +92 -0
  193. clear_skies-0.0.3a0/src/clearskies/functional/string.py +112 -0
  194. clear_skies-0.0.3a0/src/clearskies/functional/validations.py +76 -0
  195. clear_skies-0.0.3a0/src/clearskies/input_outputs/__init__.py +13 -0
  196. clear_skies-0.0.3a0/src/clearskies/input_outputs/cli.py +170 -0
  197. clear_skies-0.0.3a0/src/clearskies/input_outputs/exceptions/__init__.py +2 -0
  198. clear_skies-0.0.3a0/src/clearskies/input_outputs/exceptions/cli_input_error.py +2 -0
  199. clear_skies-0.0.3a0/src/clearskies/input_outputs/exceptions/cli_not_found.py +2 -0
  200. clear_skies-0.0.3a0/src/clearskies/input_outputs/headers.py +45 -0
  201. clear_skies-0.0.3a0/src/clearskies/input_outputs/input_output.py +138 -0
  202. clear_skies-0.0.3a0/src/clearskies/input_outputs/programmatic.py +69 -0
  203. clear_skies-0.0.3a0/src/clearskies/input_outputs/py.typed +0 -0
  204. clear_skies-0.0.3a0/src/clearskies/input_outputs/wsgi.py +77 -0
  205. clear_skies-0.0.3a0/src/clearskies/model.py +662 -0
  206. clear_skies-0.0.3a0/src/clearskies/parameters_to_properties.py +31 -0
  207. clear_skies-0.0.3a0/src/clearskies/py.typed +0 -0
  208. clear_skies-0.0.3a0/src/clearskies/query/__init__.py +12 -0
  209. clear_skies-0.0.3a0/src/clearskies/query/condition.py +223 -0
  210. clear_skies-0.0.3a0/src/clearskies/query/join.py +136 -0
  211. clear_skies-0.0.3a0/src/clearskies/query/query.py +196 -0
  212. clear_skies-0.0.3a0/src/clearskies/query/sort.py +27 -0
  213. clear_skies-0.0.3a0/src/clearskies/schema.py +82 -0
  214. clear_skies-0.0.3a0/src/clearskies/secrets/__init__.py +6 -0
  215. clear_skies-0.0.3a0/src/clearskies/secrets/additional_configs/__init__.py +32 -0
  216. clear_skies-0.0.3a0/src/clearskies/secrets/additional_configs/mysql_connection_dynamic_producer.py +61 -0
  217. clear_skies-0.0.3a0/src/clearskies/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssh_cert_bastion.py +160 -0
  218. clear_skies-0.0.3a0/src/clearskies/secrets/akeyless.py +182 -0
  219. clear_skies-0.0.3a0/src/clearskies/secrets/exceptions/__init__.py +1 -0
  220. clear_skies-0.0.3a0/src/clearskies/secrets/exceptions/not_found.py +2 -0
  221. clear_skies-0.0.3a0/src/clearskies/secrets/secrets.py +38 -0
  222. clear_skies-0.0.3a0/src/clearskies/security_header.py +8 -0
  223. clear_skies-0.0.3a0/src/clearskies/security_headers/__init__.py +11 -0
  224. clear_skies-0.0.3a0/src/clearskies/security_headers/cache_control.py +67 -0
  225. clear_skies-0.0.3a0/src/clearskies/security_headers/cors.py +50 -0
  226. clear_skies-0.0.3a0/src/clearskies/security_headers/csp.py +94 -0
  227. clear_skies-0.0.3a0/src/clearskies/security_headers/hsts.py +22 -0
  228. clear_skies-0.0.3a0/src/clearskies/security_headers/x_content_type_options.py +0 -0
  229. clear_skies-0.0.3a0/src/clearskies/security_headers/x_frame_options.py +0 -0
  230. clear_skies-0.0.3a0/src/clearskies/test_base.py +8 -0
  231. clear_skies-0.0.3a0/src/clearskies/typing.py +11 -0
  232. clear_skies-0.0.3a0/src/clearskies/validator.py +25 -0
  233. clear_skies-0.0.3a0/src/clearskies/validators/__init__.py +33 -0
  234. clear_skies-0.0.3a0/src/clearskies/validators/after_column.py +62 -0
  235. clear_skies-0.0.3a0/src/clearskies/validators/before_column.py +13 -0
  236. clear_skies-0.0.3a0/src/clearskies/validators/in_the_future.py +32 -0
  237. clear_skies-0.0.3a0/src/clearskies/validators/in_the_future_at_least.py +11 -0
  238. clear_skies-0.0.3a0/src/clearskies/validators/in_the_future_at_most.py +10 -0
  239. clear_skies-0.0.3a0/src/clearskies/validators/in_the_past.py +32 -0
  240. clear_skies-0.0.3a0/src/clearskies/validators/in_the_past_at_least.py +10 -0
  241. clear_skies-0.0.3a0/src/clearskies/validators/in_the_past_at_most.py +10 -0
  242. clear_skies-0.0.3a0/src/clearskies/validators/maximum_length.py +26 -0
  243. clear_skies-0.0.3a0/src/clearskies/validators/maximum_value.py +29 -0
  244. clear_skies-0.0.3a0/src/clearskies/validators/minimum_length.py +26 -0
  245. clear_skies-0.0.3a0/src/clearskies/validators/minimum_value.py +29 -0
  246. clear_skies-0.0.3a0/src/clearskies/validators/required.py +35 -0
  247. clear_skies-0.0.3a0/src/clearskies/validators/timedelta.py +59 -0
  248. clear_skies-0.0.3a0/src/clearskies/validators/unique.py +31 -0
@@ -0,0 +1,7 @@
1
+ Copyright 2021 Conor Mancone
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.3
2
+ Name: clear-skies
3
+ Version: 0.0.3a0
4
+ Summary: A framework for building backends in the cloud
5
+ License: MIT
6
+ Author: Conor Mancone
7
+ Author-email: cmancone@gmail.com
8
+ Requires-Python: >=3.11,<4.0
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
17
+ Provides-Extra: jwcrypto
18
+ Provides-Extra: mysql
19
+ Provides-Extra: secrets
20
+ Requires-Dist: akeyless (>=4.0.0,<5.0.0) ; extra == "secrets"
21
+ Requires-Dist: akeyless-cloud-id (>=0.2.3,<0.3.0) ; extra == "secrets"
22
+ Requires-Dist: dateparser (>=1.1.8,<2.0.0)
23
+ Requires-Dist: jwcrypto (>=1.5.6,<2.0.0) ; extra == "jwcrypto"
24
+ Requires-Dist: pymysql (>=1.1.0,<2.0.0) ; extra == "mysql"
25
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
26
+ Requires-Dist: typing-extensions (>=4.12.0,<5.0.0) ; python_version == "3.10"
27
+ Requires-Dist: wrapt (>=1.16.0,<2.0.0)
28
+ Project-URL: Repository, https://github.com/cmancone/clearskies
29
+ Description-Content-Type: text/markdown
30
+
31
+ # clearskies
32
+
33
+ clearskies is a very opinionated Python framework intended for developing microservices in the cloud via declarative programming principles. It is mainly intended for backend services and so is designed for RESTful API endpoints, queue listeners, scheduled tasks, and the like.
34
+
35
+ ## Installation, Documentation, and Usage
36
+
37
+ To install:
38
+
39
+ ```bash
40
+ pip3 install clear-skies
41
+ ```
42
+
43
+ Documentation is under construction here:
44
+
45
+ [https://clearskies.info](https://clearskies.info)
46
+
@@ -0,0 +1,15 @@
1
+ # clearskies
2
+
3
+ clearskies is a very opinionated Python framework intended for developing microservices in the cloud via declarative programming principles. It is mainly intended for backend services and so is designed for RESTful API endpoints, queue listeners, scheduled tasks, and the like.
4
+
5
+ ## Installation, Documentation, and Usage
6
+
7
+ To install:
8
+
9
+ ```bash
10
+ pip3 install clear-skies
11
+ ```
12
+
13
+ Documentation is under construction here:
14
+
15
+ [https://clearskies.info](https://clearskies.info)
@@ -0,0 +1,73 @@
1
+ [project]
2
+ name = "clear-skies"
3
+ description = "A framework for building backends in the cloud"
4
+ version = "v0.0.3-alpha"
5
+ license = "MIT"
6
+ dynamic = ["classifiers"]
7
+ readme = "./README.md"
8
+ authors = [{name = "Conor Mancone", email = "cmancone@gmail.com"}]
9
+ requires-python = '>=3.11,<4.0'
10
+ dependencies = ['dateparser (>=1.1.8,<2.0.0)', 'requests (>=2.31.0,<3.0.0)', 'typing-extensions (>=4.12.0,<5.0.0) ; python_version >= "3.10" and python_version < "3.11"', 'wrapt (>=1.16.0,<2.0.0)']
11
+
12
+ [project.urls]
13
+ repository = "https://github.com/cmancone/clearskies"
14
+
15
+ [project.optional-dependencies]
16
+ secrets = ['akeyless (>=4.0.0,<5.0.0)', 'akeyless-cloud-id (>=0.2.3,<0.3.0)']
17
+ mysql = ['pymysql (>=1.1.0,<2.0.0)']
18
+ jwcrypto = ['jwcrypto (>=1.5.6,<2.0.0)']
19
+
20
+ [tool.poetry]
21
+ packages = [
22
+ { include = "clearskies", from = "src" }
23
+ ]
24
+ exclude = [
25
+ "src/clearskies/*_test.py",
26
+ "src/clearskies/**/*_test.py",
27
+ "src/clearskies/integration_tests/*"
28
+ ]
29
+ classifiers = [
30
+ "Development Status :: 5 - Production/Stable",
31
+ "Programming Language :: Python :: 3",
32
+ "License :: OSI Approved :: MIT License",
33
+ "Intended Audience :: Developers",
34
+ "Topic :: Software Development :: Libraries :: Application Frameworks"
35
+ ]
36
+ requires-poetry = '>=2.0,<3.0'
37
+
38
+ [[tool.poetry.source]]
39
+ name = "PyPI"
40
+ priority = "primary"
41
+
42
+ [tool.poetry.group.dev.dependencies]
43
+ black = "^25.1.0"
44
+ mypy = "^1.16.1"
45
+ pre-commit = "^3.8.0"
46
+ pytest = "^8.4.1"
47
+ ruff = "^0.12.1"
48
+ types-dateparser = "^1.2.2.20250627"
49
+ types-jwcrypto = "^1.5.0.20250516"
50
+ types-pymysql = "^1.1.0.20250516"
51
+ types-requests = "^2.32.4.20250611"
52
+
53
+ [tool.pytest]
54
+ addopts = "--ignore=src/clearskies/contexts/test.py --cache-clear"
55
+
56
+ [build-system]
57
+ requires = ['poetry-core (>=2.0,<3.0)']
58
+ build-backend = "poetry.core.masonry.api"
59
+
60
+ [tool.black]
61
+ line-length = 120
62
+ # The following is Black's default, but it's good to be explicit
63
+ # to match your Ruff config.
64
+ skip-magic-trailing-comma = false
65
+ preview = true
66
+
67
+ [tool.mypy]
68
+ python_version = "3.11"
69
+
70
+ exclude = [
71
+ ".*_test\\.py$"
72
+ ]
73
+
@@ -0,0 +1,62 @@
1
+ from . import (
2
+ authentication,
3
+ autodoc,
4
+ backends,
5
+ columns,
6
+ configs,
7
+ contexts,
8
+ di,
9
+ endpoints,
10
+ exceptions,
11
+ functional,
12
+ query,
13
+ # secrets,
14
+ security_headers,
15
+ typing,
16
+ validators,
17
+ )
18
+ from . import parameters_to_properties as parameters_to_properties_module
19
+ from .column import Column
20
+ from .configurable import Configurable
21
+ from .end import End # type: ignore
22
+ from .endpoint import Endpoint
23
+ from .endpoint_group import EndpointGroup
24
+ from .schema import Schema
25
+
26
+ parameters_to_properties = parameters_to_properties_module.parameters_to_properties
27
+
28
+ from .action import Action
29
+ from .environment import Environment
30
+ from .model import Model
31
+ from .security_header import SecurityHeader
32
+ from .validator import Validator
33
+
34
+ __all__ = [
35
+ "Action",
36
+ "Authentication",
37
+ "autodoc",
38
+ "backends",
39
+ "Column",
40
+ "columns",
41
+ "configs",
42
+ "Configurable",
43
+ "contexts",
44
+ "di",
45
+ "End",
46
+ "Endpoint",
47
+ "EndpointGroup",
48
+ "endpoints",
49
+ "Environment",
50
+ "exceptions",
51
+ "functional",
52
+ "Model",
53
+ "parameters_to_properties",
54
+ "Schema",
55
+ "typing",
56
+ "Validator",
57
+ "query",
58
+ # "secrets",
59
+ "SecurityHeader",
60
+ "security_headers",
61
+ "validators",
62
+ ]
@@ -0,0 +1,7 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class Action(ABC):
5
+ @abstractmethod
6
+ def __call__(self, model):
7
+ pass
@@ -0,0 +1,15 @@
1
+ from clearskies.authentication.authentication import Authentication
2
+ from clearskies.authentication.authorization import Authorization
3
+ from clearskies.authentication.authorization_pass_through import AuthorizationPassThrough
4
+ from clearskies.authentication.jwks import Jwks
5
+ from clearskies.authentication.public import Public
6
+ from clearskies.authentication.secret_bearer import SecretBearer
7
+
8
+ __all__ = [
9
+ "Authentication",
10
+ "Authorization",
11
+ "AuthorizationPassThrough",
12
+ "Jwks",
13
+ "Public",
14
+ "SecretBearer",
15
+ ]
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ import requests
6
+
7
+ import clearskies.configurable
8
+ from clearskies.authentication.authorization import Authorization
9
+
10
+ if TYPE_CHECKING:
11
+ from clearskies.security_headers.cors import Cors
12
+
13
+
14
+ class Authentication(clearskies.configurable.Configurable, requests.auth.AuthBase):
15
+ is_public = True
16
+ can_authorize = False
17
+ has_dynamic_credentials = False
18
+
19
+ def clear_credential_cache(self) -> None:
20
+ pass
21
+
22
+ def headers(self, retry_auth: bool = False) -> dict[str, str]:
23
+ return {}
24
+
25
+ def authenticate(self, input_output) -> bool:
26
+ return True
27
+
28
+ def authorize(self, authorization: Authorization):
29
+ raise ValueError("Public endpoints do not support authorization")
30
+
31
+ def set_headers_for_cors(self, cors: Cors):
32
+ pass
33
+
34
+ def documentation_security_scheme(self) -> dict[str, Any]:
35
+ return {}
36
+
37
+ def documentation_security_scheme_name(self) -> str:
38
+ return ""
39
+
40
+ def __call__(self, request: requests.models.PreparedRequest) -> requests.models.PreparedRequest:
41
+ request.headers = {**request.headers, **self.headers()} # type: ignore
42
+ return request
@@ -0,0 +1,12 @@
1
+ class Authorization:
2
+ def gate(self, authorization_data, input_output):
3
+ """
4
+ Return True/False to denote if the given user, as represented by the authorization data, should be allowed access.
5
+
6
+ Raise clearskies.exceptions.ClientError if you want to raise a specific error message.
7
+ """
8
+ return True
9
+
10
+ def filter_model(self, model, authorization_data, input_output):
11
+ """Return a models object with additional filters applied to account for authorization needs."""
12
+ return model
@@ -0,0 +1,20 @@
1
+ import clearskies.di
2
+
3
+ from .jwks import Jwks
4
+
5
+
6
+ class AuthorizationPassThrough(Jwks):
7
+ """
8
+ Authentication class with pass through.
9
+
10
+ This authentication class takes the authentication header from the incoming request and reflects
11
+ it on outgoing requests.
12
+ """
13
+
14
+ """
15
+ The input output helper
16
+ """
17
+ input_output = clearskies.di.inject.InputOutput()
18
+
19
+ def headers(self, retry_auth=False):
20
+ return {"Authorization": self.input_output.request_headers.get("authorization", True)}
@@ -0,0 +1,158 @@
1
+ import json
2
+ from typing import Any
3
+
4
+ import clearskies.configs
5
+ import clearskies.di
6
+ import clearskies.parameters_to_properties
7
+ from clearskies.authentication.authentication import Authentication
8
+ from clearskies.exceptions import ClientError
9
+ from clearskies.security_headers.cors import Cors
10
+
11
+
12
+ class Jwks(Authentication, clearskies.di.InjectableProperties):
13
+ """The URL where the JWKS can be found."""
14
+
15
+ jwks_url = clearskies.configs.String(required=True)
16
+
17
+ """
18
+ The audience to accept JWTs for.
19
+ """
20
+ audience = clearskies.configs.StringList(default=[])
21
+
22
+ """
23
+ The expected issuer of the JWTs.
24
+ """
25
+ issuer = clearskies.configs.String(default="")
26
+
27
+ """
28
+ The allowed algorithms
29
+ """
30
+ algorithms = clearskies.configs.StringList(default=["RS256"])
31
+
32
+ """
33
+ The number of seconds for which the JWKS URL contents can be cached
34
+ """
35
+ jwks_cache_time = clearskies.configs.Integer(default=86400)
36
+
37
+ """
38
+ The Authorization URL (used in the auto-generated documentation)
39
+ """
40
+ authorization_url = clearskies.configs.String()
41
+
42
+ """
43
+ The name of the security scheme in the auto-generated documentation.
44
+ """
45
+ documentation_security_name = clearskies.configs.String(default="jwt")
46
+
47
+ """
48
+ The environment helper.
49
+ """
50
+ environment = clearskies.di.inject.Environment()
51
+
52
+ """
53
+ The requests object.
54
+ """
55
+ requests = clearskies.di.inject.Requests()
56
+
57
+ """
58
+ The JoseJwt library
59
+ """
60
+ jose_jwt = clearskies.di.inject.ByName("jose_jwt")
61
+
62
+ """
63
+ The current time
64
+ """
65
+ now = clearskies.di.inject.Now()
66
+
67
+ """
68
+ Local cache of the JWKS
69
+ """
70
+ _jwks = None
71
+
72
+ """
73
+ The time when the JWKS was last fetched
74
+ """
75
+ _jwks_fetched = None
76
+
77
+ @clearskies.parameters_to_properties.parameters_to_properties
78
+ def __init__(
79
+ self,
80
+ jwks_url: str,
81
+ audience: str = "",
82
+ issuer: str = "",
83
+ algorithms: list[str] = ["RS256"],
84
+ jwks_cache_time: int = 86400,
85
+ authorization_url: str = "",
86
+ documentation_security_name: str = "jwt",
87
+ ):
88
+ self.finalize_and_validate_configuration()
89
+
90
+ def authenticate(self, input_output) -> bool:
91
+ auth_header = input_output.get_request_header("authorization", True)
92
+ if not auth_header:
93
+ raise ClientError("Missing 'Authorization' header in request")
94
+ if auth_header[:7].lower() != "bearer ":
95
+ raise ClientError("Missing 'Bearer ' prefix in authorization header")
96
+ self.validate_jwt(auth_header[7:])
97
+ input_output.authorization_data = self.jwt_claims
98
+ return True
99
+
100
+ def validate_jwt(self, raw_jwt):
101
+ try:
102
+ from jwcrypto import jwk, jws, jwt # type: ignore
103
+ from jwcrypto.common import JWException # type: ignore
104
+ except:
105
+ raise ValueError(
106
+ "The JWKS authentication method requires the jwcrypto libraries to be installed. These are optional dependencies of clearskies, so to include them do a `pip install 'clear-skies[jwcrypto]'`"
107
+ )
108
+
109
+ keys = jwk.JWKSet()
110
+ keys.import_keyset(json.dumps(self._get_jwks()))
111
+
112
+ client_jwt = jwt.JWT()
113
+ try:
114
+ client_jwt.deserialize(raw_jwt)
115
+ except Exception as e:
116
+ raise ClientError(str(e))
117
+
118
+ try:
119
+ client_jwt.validate(keys)
120
+ self.jwt_claims = json.loads(client_jwt.claims)
121
+ except JWException as e:
122
+ raise ClientError(str(e))
123
+
124
+ if self.issuer and self.jwt_claims.get("iss") != self.issuer:
125
+ raise ClientError("Issuer does not match")
126
+
127
+ if self.audience:
128
+ jwt_audience = self.jwt_claims.get("aud")
129
+ if not jwt_audience:
130
+ raise ClientError("Audience required, but missing in JWT")
131
+ has_match = False
132
+ for audience in jwt_audience:
133
+ if audience == self.audience:
134
+ has_match = True
135
+ if not has_match:
136
+ raise ClientError("Audience does not match")
137
+
138
+ return True
139
+
140
+ def _get_jwks(self):
141
+ if self._jwks is None or ((self.now - self._jwks_fetched).total_seconds() > self.jwks_cache_time):
142
+ self._jwks = self.requests.get(self.jwks_url).json()
143
+ self._jwks_fetched = self.now
144
+
145
+ return self._jwks
146
+
147
+ def documentation_security_scheme(self) -> dict[str, Any]:
148
+ return {
149
+ "type": "oauth2",
150
+ "description": "JWT based authentication",
151
+ "flows": {"implicit": {"authorizationUrl": self.authorization_url, "scopes": {}}},
152
+ }
153
+
154
+ def documentation_security_scheme_name(self) -> str:
155
+ return self.documentation_security_name
156
+
157
+ def set_headers_for_cors(self, cors: Cors):
158
+ cors.add_header("Authorization")
@@ -0,0 +1,5 @@
1
+ from .authentication import Authentication
2
+
3
+
4
+ class Public(Authentication):
5
+ pass