clear-skies 1.21.4__tar.gz → 1.22.0__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 (212) hide show
  1. {clear_skies-1.21.4 → clear_skies-1.22.0}/PKG-INFO +1 -1
  2. {clear_skies-1.21.4 → clear_skies-1.22.0}/pyproject.toml +1 -1
  3. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/api_backend.py +129 -5
  4. clear_skies-1.22.0/src/clearskies/backends/restful_api_advanced_search_backend.py +103 -0
  5. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/models.py +1 -1
  6. clear_skies-1.21.4/src/clearskies/backends/restful_api_advanced_search_backend.py +0 -138
  7. {clear_skies-1.21.4 → clear_skies-1.22.0}/LICENSE +0 -0
  8. {clear_skies-1.21.4 → clear_skies-1.22.0}/README.md +0 -0
  9. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/__init__.py +0 -0
  10. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/application.py +0 -0
  11. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/__init__.py +0 -0
  12. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/auth0_jwks.py +0 -0
  13. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/auth_exception.py +0 -0
  14. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/authorization.py +0 -0
  15. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/jwks.py +0 -0
  16. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/jwks_jwcrypto.py +0 -0
  17. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/public.py +0 -0
  18. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/authentication/secret_bearer.py +0 -0
  19. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/__init__.py +0 -0
  20. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/__init__.py +0 -0
  21. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/__init__.py +0 -0
  22. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/oai3_json.py +0 -0
  23. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/oai3_schema_resolver.py +0 -0
  24. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/parameter.py +0 -0
  25. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/request.py +0 -0
  26. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/response.py +0 -0
  27. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/schema/__init__.py +0 -0
  28. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/schema/array.py +0 -0
  29. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/schema/default.py +0 -0
  30. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/schema/enum.py +0 -0
  31. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/schema/object.py +0 -0
  32. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/formats/oai3_json/test.json +0 -0
  33. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/request/__init__.py +0 -0
  34. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/request/header.py +0 -0
  35. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/request/json_body.py +0 -0
  36. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/request/request.py +0 -0
  37. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/request/url_parameter.py +0 -0
  38. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/request/url_path.py +0 -0
  39. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/response/__init__.py +0 -0
  40. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/response/response.py +0 -0
  41. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/__init__.py +0 -0
  42. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/array.py +0 -0
  43. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/base64.py +0 -0
  44. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/boolean.py +0 -0
  45. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/date.py +0 -0
  46. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/datetime.py +0 -0
  47. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/double.py +0 -0
  48. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/enum.py +0 -0
  49. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/integer.py +0 -0
  50. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/long.py +0 -0
  51. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/number.py +0 -0
  52. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/object.py +0 -0
  53. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/password.py +0 -0
  54. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/autodoc/schema/string.py +0 -0
  55. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/__init__.py +0 -0
  56. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/backend.py +0 -0
  57. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/cursor_backend.py +0 -0
  58. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/example_backend.py +0 -0
  59. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/file_backend.py +0 -0
  60. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/json_backend.py +0 -0
  61. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/memory_backend.py +0 -0
  62. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/backends/secrets_backend.py +0 -0
  63. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/binding_config.py +0 -0
  64. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/__init__.py +0 -0
  65. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/audit.py +0 -0
  66. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/belongs_to.py +0 -0
  67. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/boolean.py +0 -0
  68. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/category_tree.py +0 -0
  69. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/column.py +0 -0
  70. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/created.py +0 -0
  71. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/created_by_authorization_data.py +0 -0
  72. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/created_by_header.py +0 -0
  73. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/created_by_ip.py +0 -0
  74. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/created_by_routing_data.py +0 -0
  75. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/created_by_user_agent.py +0 -0
  76. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/created_micro.py +0 -0
  77. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/datetime.py +0 -0
  78. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/datetime_micro.py +0 -0
  79. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/email.py +0 -0
  80. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/float.py +0 -0
  81. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/has_many.py +0 -0
  82. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/has_one.py +0 -0
  83. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/integer.py +0 -0
  84. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/json.py +0 -0
  85. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/many_to_many.py +0 -0
  86. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/many_to_many_with_data.py +0 -0
  87. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/phone.py +0 -0
  88. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/select.py +0 -0
  89. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/string.py +0 -0
  90. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/timestamp.py +0 -0
  91. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/updated.py +0 -0
  92. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/updated_micro.py +0 -0
  93. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/column_types/uuid.py +0 -0
  94. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/columns.py +0 -0
  95. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/condition_parser.py +0 -0
  96. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/__init__.py +0 -0
  97. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/bash.py +0 -0
  98. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/build_context.py +0 -0
  99. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/cli.py +0 -0
  100. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/context.py +0 -0
  101. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/convert_to_application.py +0 -0
  102. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/extract_handler.py +0 -0
  103. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/test.py +0 -0
  104. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/contexts/wsgi.py +0 -0
  105. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/__init__.py +0 -0
  106. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/auth0_jwks.py +0 -0
  107. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/authorization.py +0 -0
  108. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/binding_classes.py +0 -0
  109. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/binding_modules.py +0 -0
  110. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/bindings.py +0 -0
  111. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/create.py +0 -0
  112. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/delete.py +0 -0
  113. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/docs.py +0 -0
  114. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/get.py +0 -0
  115. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/jwks.py +0 -0
  116. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/merge.py +0 -0
  117. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/patch.py +0 -0
  118. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/post.py +0 -0
  119. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/public.py +0 -0
  120. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/response_headers.py +0 -0
  121. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/return_raw_response.py +0 -0
  122. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/schema.py +0 -0
  123. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/secret_bearer.py +0 -0
  124. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/decorators/security_headers.py +0 -0
  125. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/__init__.py +0 -0
  126. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/additional_config.py +0 -0
  127. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/additional_config_auto_import.py +0 -0
  128. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/di.py +0 -0
  129. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/standard_dependencies.py +0 -0
  130. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/test_module/__init__.py +0 -0
  131. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/test_module/another_module/__init__.py +0 -0
  132. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/di/test_module/module_class.py +0 -0
  133. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/environment.py +0 -0
  134. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/functional/__init__.py +0 -0
  135. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/functional/string.py +0 -0
  136. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/functional/validations.py +0 -0
  137. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/__init__.py +0 -0
  138. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/advanced_search.py +0 -0
  139. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/base.py +0 -0
  140. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/callable.py +0 -0
  141. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/create.py +0 -0
  142. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/crud_by_method.py +0 -0
  143. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/database_connector.py +0 -0
  144. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/delete.py +0 -0
  145. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/exceptions/__init__.py +0 -0
  146. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/exceptions/authentication.py +0 -0
  147. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/exceptions/authorization.py +0 -0
  148. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/exceptions/client_error.py +0 -0
  149. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/exceptions/input_error.py +0 -0
  150. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/exceptions/not_found.py +0 -0
  151. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/get.py +0 -0
  152. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/health_check.py +0 -0
  153. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/input_processing.py +0 -0
  154. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/list.py +0 -0
  155. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/mygrations.py +0 -0
  156. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/request_method_routing.py +0 -0
  157. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/restful_api.py +0 -0
  158. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/routing.py +0 -0
  159. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/schema_helper.py +0 -0
  160. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/simple_routing.py +0 -0
  161. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/simple_routing_route.py +0 -0
  162. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/simple_search.py +0 -0
  163. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/update.py +0 -0
  164. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/handlers/write.py +0 -0
  165. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_outputs/__init__.py +0 -0
  166. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_outputs/cli.py +0 -0
  167. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_outputs/exceptions/__init__.py +0 -0
  168. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_outputs/exceptions/cli_input_error.py +0 -0
  169. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_outputs/exceptions/cli_not_found.py +0 -0
  170. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_outputs/input_output.py +0 -0
  171. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_outputs/wsgi.py +0 -0
  172. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/__init__.py +0 -0
  173. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/after.py +0 -0
  174. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/before.py +0 -0
  175. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/in_the_future_at_least.py +0 -0
  176. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/in_the_future_at_most.py +0 -0
  177. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/in_the_past_at_least.py +0 -0
  178. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/in_the_past_at_most.py +0 -0
  179. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/maximum_length.py +0 -0
  180. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/maximum_value.py +0 -0
  181. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/minimum_length.py +0 -0
  182. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/minimum_value.py +0 -0
  183. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/required.py +0 -0
  184. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/requirement.py +0 -0
  185. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/time_delta.py +0 -0
  186. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/input_requirements/unique.py +0 -0
  187. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/mocks/__init__.py +0 -0
  188. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/mocks/input_output.py +0 -0
  189. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/mocks/models.py +0 -0
  190. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/model.py +0 -0
  191. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/__init__.py +0 -0
  192. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/additional_configs/__init__.py +0 -0
  193. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/additional_configs/mysql_connection_dynamic_producer.py +0 -0
  194. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssh_cert_bastion.py +0 -0
  195. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/akeyless.py +0 -0
  196. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/exceptions/__init__.py +0 -0
  197. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/exceptions/not_found.py +0 -0
  198. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/secrets/secrets.py +0 -0
  199. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/__init__.py +0 -0
  200. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/base.py +0 -0
  201. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/cache_control.py +0 -0
  202. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/cors.py +0 -0
  203. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/csp.py +0 -0
  204. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/hsts.py +0 -0
  205. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/x_content_type_options.py +0 -0
  206. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/security_headers/x_frame_options.py +0 -0
  207. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/tests/__init__.py +0 -0
  208. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/tests/simple_api/__init__.py +0 -0
  209. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/tests/simple_api/models/__init__.py +0 -0
  210. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/tests/simple_api/models/status.py +0 -0
  211. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/tests/simple_api/models/user.py +0 -0
  212. {clear_skies-1.21.4 → clear_skies-1.22.0}/src/clearskies/tests/simple_api/users_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: clear-skies
3
- Version: 1.21.4
3
+ Version: 1.22.0
4
4
  Summary: A framework for building backends in the cloud
5
5
  Home-page: https://github.com/cmancone/clearskies
6
6
  License: MIT
@@ -2,7 +2,7 @@
2
2
 
3
3
  [tool.poetry]
4
4
  name = "clear-skies"
5
- version = "1.21.4"
5
+ version = "1.22.0"
6
6
  description = "A framework for building backends in the cloud"
7
7
  authors = [
8
8
  "Conor Mancone <cmancone@gmail.com>",
@@ -3,6 +3,7 @@ from typing import Any, Callable, Dict, List, Tuple
3
3
  from ..autodoc.schema import Integer as AutoDocInteger
4
4
  from .. import model
5
5
  from ..column_types import JSON, DateTime
6
+ import re
6
7
 
7
8
 
8
9
  class ApiBackend(Backend):
@@ -34,6 +35,36 @@ class ApiBackend(Backend):
34
35
  self.url = url
35
36
  self._auth = auth
36
37
 
38
+ def records_url(self, configuration: Dict[str, Any]) -> str:
39
+ return self.url
40
+
41
+ def count_url(self, configuration: Dict[str, Any]) -> str:
42
+ return self.records_url(configuration)
43
+
44
+ def delete_url(self, id: str, model: model.Model) -> str:
45
+ return self.url
46
+
47
+ def update_url(self, id: str, model: model.Model) -> str:
48
+ return self.url
49
+
50
+ def create_url(self, data: Dict[str, Any], model: model.Model) -> str:
51
+ return self.url
52
+
53
+ def records_method(self, configuration: Dict[str, Any]) -> str:
54
+ return "GET"
55
+
56
+ def count_method(self, configuration: Dict[str, Any]) -> str:
57
+ return "GET"
58
+
59
+ def delete_method(self, id: str, model: model.Model) -> str:
60
+ return "DELETE"
61
+
62
+ def update_method(self, id: str, model: model.Model) -> str:
63
+ return "PATCH"
64
+
65
+ def create_method(self, data: Dict[str, Any], model: model.Model) -> str:
66
+ return "POST"
67
+
37
68
  def update(self, id, data, model):
38
69
  [url, method, json_data, headers] = self._build_update_request(id, data, model)
39
70
  response = self._execute_request(url, method, json=json_data, headers=headers)
@@ -42,7 +73,8 @@ class ApiBackend(Backend):
42
73
  return self._map_update_response(response.json())
43
74
 
44
75
  def _build_update_request(self, id, data, model):
45
- return [self.url, "PATCH", data, {}]
76
+ (url, data) = self._finalize_url_and_data(self.update_url(id, model), data)
77
+ return [url, self.update_method(id, model), data, {}]
46
78
 
47
79
  def _map_update_response(self, json):
48
80
  if not "data" in json:
@@ -55,7 +87,8 @@ class ApiBackend(Backend):
55
87
  return self._map_create_response(response.json())
56
88
 
57
89
  def _build_create_request(self, data, model):
58
- return [self.url, "POST", data, {}]
90
+ (url, data) = self._finalize_url_and_data(self.create_url(data, model), data)
91
+ return [url, self.create_method(data, model), data, {}]
59
92
 
60
93
  def _map_create_response(self, json):
61
94
  if not "data" in json:
@@ -68,7 +101,9 @@ class ApiBackend(Backend):
68
101
  return self._validate_delete_response(response.json())
69
102
 
70
103
  def _build_delete_request(self, id, model):
71
- return [self.url, "DELETE", {model.id_column_name: id}, {}]
104
+ data = model.data
105
+ (url, data) = self._finalize_url_and_data(self.delete_url(id, model), data)
106
+ return [url, self.delete_method(id, model), {model.id_column_name: id}, {}]
72
107
 
73
108
  def _validate_delete_response(self, json):
74
109
  if "status" not in json:
@@ -82,7 +117,13 @@ class ApiBackend(Backend):
82
117
  return self._map_count_response(response.json())
83
118
 
84
119
  def _build_count_request(self, configuration):
85
- return [self.url, "GET", {**{"count_only": True}, **self._as_post_data(configuration)}, {}]
120
+ (url, configuration) = self._finalize_url_and_configuration(self.count_url(configuration), configuration)
121
+ return [
122
+ url,
123
+ self.count_method(configuration),
124
+ {**{"count_only": True}, **self._as_post_data(configuration)},
125
+ {},
126
+ ]
86
127
 
87
128
  def _map_count_response(self, json):
88
129
  if not "total_matches" in json:
@@ -102,7 +143,8 @@ class ApiBackend(Backend):
102
143
  return records
103
144
 
104
145
  def _build_records_request(self, configuration):
105
- return [self.url, "GET", self._as_post_data(configuration), {}]
146
+ (url, configuration) = self._finalize_url_and_configuration(self.records_url(configuration), configuration)
147
+ return [url, self.records_method(configuration), self._as_post_data(configuration), {}]
106
148
 
107
149
  def _map_records_response(self, json):
108
150
  if not "data" in json:
@@ -224,3 +266,85 @@ class ApiBackend(Backend):
224
266
  )
225
267
  return {**backend_data, **{column.name: as_date}}
226
268
  return column.to_backend(backend_data)
269
+
270
+ def _finalize_url_and_data(self, url: str, data: Dict[str, Any]) -> Tuple[str, Dict[str, Any]]:
271
+ (url, used_columns) = self._finalize_url(url, data, model)
272
+ for used_column in used_columns:
273
+ del data[used_column]
274
+ return (url, data)
275
+
276
+ def _finalize_url_and_configuration(self, url: str, configuration: Dict[str, Any]) -> Tuple[str, Dict[str, Any]]:
277
+ # we need to convert the wheres in the configuration to a dictionary of key/values, but
278
+ # *only* for cases where we have performed an equals search.
279
+ filters_by_equals = {}
280
+ index_lookup = {}
281
+ for index, where in enumerate(configuration["wheres"]):
282
+ if where["operator"] != "=":
283
+ continue
284
+ filters_by_equals[where["column"]] = where["values"][0]
285
+ index_lookup[where["column"]] = index
286
+
287
+ # always call _finalize_url, even if we don't have any search columns,
288
+ # because if there are placeholders in the URL but we don't have any values,
289
+ # then we need to throw an exception.
290
+ (url, used_columns) = self._finalize_url(url, filters_by_equals, model)
291
+ # we need to remove the used entries from the wheres but in doing so we start at the end
292
+ # of the array so our indexes stay valid.
293
+ to_delete = [index_lookup[used_column] for used_column in used_columns]
294
+ to_delete.sort(reverse=True)
295
+ for index_to_delete in to_delete:
296
+ del configuration["wheres"][index_to_delete]
297
+
298
+ return (url, configuration)
299
+
300
+ def _finalize_url(self, url: str, data: Dict[str, Any], model: model.Models) -> Tuple[str, List[str]]:
301
+ """
302
+ This function is what gives support for placeholders in URLs. We support two formats:
303
+
304
+ 1. /some/path/{some_field}/blah
305
+ 2. /some/path/:some_field/blah
306
+
307
+ The url comes from the `my_url` function, which (by default) is just self.url. You can
308
+ always extend `my_url` to pull the URL from something else (the `model.table_name()` for instance).
309
+
310
+ You would then:
311
+
312
+ ```
313
+ models.where("some_field=some_value")
314
+ ```
315
+
316
+ and when the API backend makes the call it will then build the appropriate URL. Naturally,
317
+ you'll want to add a corresponding column to your model, otherwise the model will complain
318
+ that "some_field is not an allowed column in model class 'BLAH'" (since all search columns
319
+ used in a `where` query go through strict input validation).
320
+ """
321
+ # many Snyk API calls require a resource id in the URL. Let's check if that is the case here,
322
+ # and if so, get it out of the query configuration
323
+ used_columns = []
324
+ resource_references = self._find_resource_references_in_url(url)
325
+ for resource_reference in resource_references:
326
+ resource_name = resource_reference["name"]
327
+ placeholder = resource_reference["placeholder"]
328
+ if not data.get(resource_name):
329
+ raise ValueError(
330
+ f"Error building a request with {self.__class__.__name__}: my url, '{url}', has a URL resource named '{resource_name}' but a request was made without providing a value for this resource. All URL parameters are implicitly required. Also note that only where clauses with an 'equals' operator will be used when providing search terms for the URL. So, make sure you add an appropriate: `models.where('{resource_name}=some_value')` search when using the corresponding models class. Alternatively, if executing a create/delete/update operation, make sure the model and/or save has a value for this column"
331
+ )
332
+
333
+ url = url.replace(placeholder, str(data.get(resource_name)))
334
+ used_columns.append(resource_name)
335
+ return (url, used_columns)
336
+
337
+ def _find_resource_references_in_url(self, url: str) -> list[str]:
338
+ if not url:
339
+ return []
340
+ # To help with the regexp matching, it helps if the URL both starts and ends with a "/".
341
+ # We don't need to modify the URL at all - we just need it for our matching, so it's fine
342
+ # that our changes aren't propogated back to the calling function.
343
+ if url[-1] != "/":
344
+ url += "/"
345
+ if url[0] != "/":
346
+ url = f"/{url}"
347
+ return [
348
+ *[{"name": reference, "placeholder": "{" + reference + "}"} for reference in re.findall(r"{(\w+)}", url)],
349
+ *[{"name": reference, "placeholder": f":{reference}"} for reference in re.findall(r"/:([^/]+)/", url)],
350
+ ]
@@ -0,0 +1,103 @@
1
+ from .api_backend import ApiBackend
2
+ from typing import Any, Callable, Dict, List, Tuple
3
+ from .. import model
4
+ from ..autodoc.schema import Integer as AutoDocInteger
5
+
6
+
7
+ class RestfulApiAdvancedSearchBackend(ApiBackend):
8
+ _requests = None
9
+ _auth = None
10
+ _records = None
11
+
12
+ _allowed_configs = [
13
+ "wheres",
14
+ "sorts",
15
+ "limit",
16
+ "pagination",
17
+ "table_name",
18
+ "model_columns",
19
+ "select_all",
20
+ ]
21
+
22
+ _empty_configs = [
23
+ "group_by_column",
24
+ "selects",
25
+ "joins",
26
+ ]
27
+
28
+ def __init__(self, requests):
29
+ self._requests = requests
30
+
31
+ def configure(self, auth=None):
32
+ self._auth = auth
33
+
34
+ def records_url(self, configuration: Dict[str, Any]) -> str:
35
+ return configuration["table_name"].rstrip("/") + "/search"
36
+
37
+ def delete_url(self, id: str, model: model.Model) -> str:
38
+ table_name = model.table_name().rstrip("/")
39
+ return f"{table_name}/{id}"
40
+
41
+ def update_url(self, id: str, model: model.Model) -> str:
42
+ table_name = model.table_name().rstrip("/")
43
+ return f"{table_name}/{id}"
44
+
45
+ def create_url(self, data: Dict[str, Any], model: model.Model) -> str:
46
+ return model.table_name().rstrip("/")
47
+
48
+ def records_method(self, configuration: Dict[str, Any]) -> str:
49
+ return "POST"
50
+
51
+ def count_method(self, configuration: Dict[str, Any]) -> str:
52
+ return "POST"
53
+
54
+ def _build_delete_request(self, id, model):
55
+ data = model.data
56
+ (url, data) = self._finalize_url_and_data(self.delete_url(id, model), data)
57
+ return [url, self.delete_method(id, model), {}, {}]
58
+
59
+ def _build_count_request(self, configuration):
60
+ [url, method, json_data, headers] = super()._build_count_request(configuration)
61
+ json_data["count_only"] = True
62
+ return [url, method, json_data, headers]
63
+
64
+ def records(self, configuration, model, next_page_data={}):
65
+ configuration = self._check_query_configuration(configuration)
66
+ [url, method, json_data, headers] = self._build_records_request(configuration)
67
+ response = self._execute_request(url, method, json=json_data, headers=headers).json()
68
+ records = self._map_records_response(response)
69
+ for next_page_key in ["nextPage", "NextPage", "next_page"]:
70
+ if response.get("pagination", {}).get(next_page_key):
71
+ for key, value in response["pagination"][next_page_key].items():
72
+ next_page_data[key] = value
73
+ return records
74
+
75
+ def _as_post_data(self, configuration):
76
+ data = {
77
+ "where": list(
78
+ map(lambda where: self._where_for_post(where, configuration["model_columns"]), configuration["wheres"])
79
+ ),
80
+ "sort": configuration["sorts"],
81
+ "start": configuration["pagination"].get("start", 0),
82
+ "limit": configuration["limit"],
83
+ }
84
+ return {key: value for (key, value) in data.items() if value}
85
+
86
+ def _where_for_post(self, where, columns):
87
+ prefix = ""
88
+ if where.get("table"):
89
+ prefix = where["table"] + "."
90
+ return {
91
+ "column": prefix + where["column"],
92
+ "operator": where["operator"],
93
+ "value": self.normalize_outgoing_value(where, columns, where["values"][0]),
94
+ }
95
+
96
+ def normalize_outgoing_value(self, where, columns, value):
97
+ column_name = where["column"]
98
+ if where.get("table") or column_name not in columns:
99
+ return value
100
+ normalized_data = self.column_to_backend(columns[column_name], {column_name: value})
101
+ if column_name in normalized_data:
102
+ return normalized_data[column_name]
103
+ return value
@@ -81,7 +81,7 @@ class Models(ABC, ConditionParser):
81
81
  "selects": self.query_selects,
82
82
  "select_all": self.query_select_all,
83
83
  "table_name": self.get_table_name(),
84
- "model_columns": self._model_columns,
84
+ "model_columns": self.model_columns,
85
85
  }
86
86
 
87
87
  @query_configuration.setter
@@ -1,138 +0,0 @@
1
- from .api_backend import ApiBackend
2
- from typing import Any, Callable, Dict, List, Tuple
3
- from ..autodoc.schema import Integer as AutoDocInteger
4
-
5
-
6
- class RestfulApiAdvancedSearchBackend(ApiBackend):
7
- _requests = None
8
- _auth = None
9
- _records = None
10
-
11
- _allowed_configs = [
12
- "wheres",
13
- "sorts",
14
- "limit",
15
- "pagination",
16
- "table_name",
17
- "model_columns",
18
- "select_all",
19
- ]
20
-
21
- _empty_configs = [
22
- "group_by_column",
23
- "selects",
24
- "joins",
25
- ]
26
-
27
- def __init__(self, requests):
28
- self._requests = requests
29
-
30
- def configure(self, auth=None):
31
- self._auth = auth
32
-
33
- def update(self, id, data, model):
34
- [url, method, json_data, headers] = self._build_update_request(id, data, model)
35
- response = self._execute_request(url, method, json=json_data, headers=headers)
36
- if not response.content:
37
- return {**model.data, **data}
38
- return self._map_update_response(response.json())
39
-
40
- def _build_update_request(self, id, data, model):
41
- url = model.table_name().rstrip("/")
42
- return [f"{url}/{id}", "PATCH", data, {}]
43
-
44
- def _map_update_response(self, json):
45
- if not "data" in json:
46
- raise ValueError("Unexpected API response to update request")
47
- return json["data"]
48
-
49
- def create(self, data, model):
50
- [url, method, json_data, headers] = self._build_create_request(data, model)
51
- response = self._execute_request(url, method, json=json_data, headers=headers)
52
- return self._map_create_response(response.json())
53
-
54
- def _build_create_request(self, data, model):
55
- return [model.table_name().rstrip("/"), "POST", data, {}]
56
-
57
- def _map_create_response(self, json):
58
- if not "data" in json:
59
- raise ValueError("Unexpected API response to create request")
60
- return json["data"]
61
-
62
- def delete(self, id, model):
63
- [url, method, json_data, headers] = self._build_delete_request(id, model)
64
- response = self._execute_request(url, method, json=json_data, headers=headers)
65
- return self._validate_delete_response(response.json())
66
-
67
- def _build_delete_request(self, id, model):
68
- url = model.table_name().rstrip("/")
69
- return [f"{url}/{id}", "DELETE", {}, {}]
70
-
71
- def _validate_delete_response(self, json):
72
- if "status" not in json:
73
- raise ValueError("Unexpected response to delete API request")
74
- return json["status"] == "success"
75
-
76
- def count(self, configuration, model):
77
- configuration = self._check_query_configuration(configuration)
78
- [url, method, json_data, headers] = self._build_count_request(configuration, model)
79
- response = self._execute_request(url, method, json=json_data, headers=headers)
80
- return self._map_count_response(response.json())
81
-
82
- def _build_count_request(self, configuration, model):
83
- url = model.table_name().rstrip("/") + "/search"
84
- return [url, "POST", {**{"count_only": True}, **self._as_post_data(configuration, model)}, {}]
85
-
86
- def _map_count_response(self, json):
87
- if not "total_matches" in json:
88
- raise ValueError("Unexpected API response when executing count request")
89
- return json["total_matches"]
90
-
91
- def records(self, configuration, model, next_page_data={}):
92
- configuration = self._check_query_configuration(configuration)
93
- [url, method, json_data, headers] = self._build_records_request(configuration, model)
94
- response = self._execute_request(url, method, json=json_data, headers=headers).json()
95
- records = self._map_records_response(response)
96
- for next_page_key in ["nextPage", "NextPage", "next_page"]:
97
- if response.get("pagination", {}).get(next_page_key):
98
- for key, value in response["pagination"][next_page_key].items():
99
- next_page_data[key] = value
100
- return records
101
-
102
- def _build_records_request(self, configuration, model):
103
- url = model.table_name().rstrip("/") + "/search"
104
- return [url, "POST", self._as_post_data(configuration, model), {}]
105
-
106
- def _map_records_response(self, json):
107
- if not "data" in json:
108
- raise ValueError("Unexpected response from records request")
109
- return json["data"]
110
-
111
- def _as_post_data(self, configuration, model):
112
- data = {
113
- "where": list(map(lambda where: self._where_for_post(where, model), configuration["wheres"])),
114
- "sort": configuration["sorts"],
115
- "start": configuration["pagination"].get("start", 0),
116
- "limit": configuration["limit"],
117
- }
118
- return {key: value for (key, value) in data.items() if value}
119
-
120
- def _where_for_post(self, where, model):
121
- prefix = ""
122
- if where.get("table"):
123
- prefix = where["table"] + "."
124
- return {
125
- "column": prefix + where["column"],
126
- "operator": where["operator"],
127
- "value": self.normalize_outgoing_value(where, model, where["values"][0]),
128
- }
129
-
130
- def normalize_outgoing_value(self, where, model, value):
131
- column_name = where["column"]
132
- columns = model.columns()
133
- if where.get("table") or column_name not in columns:
134
- return value
135
- normalized_data = self.column_to_backend(columns[column_name], {column_name: value})
136
- if column_name in normalized_data:
137
- return normalized_data[column_name]
138
- return value
File without changes
File without changes