velocity-python 0.1.129__tar.gz → 0.1.133__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.
Files changed (367) hide show
  1. {velocity_python-0.1.129 → velocity_python-0.1.133}/PKG-INFO +73 -32
  2. {velocity_python-0.1.129 → velocity_python-0.1.133}/README.md +66 -27
  3. {velocity_python-0.1.129 → velocity_python-0.1.133}/pyproject.toml +15 -7
  4. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/__init__.py +1 -1
  5. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/__init__.py +11 -36
  6. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/amplify.py +67 -36
  7. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/__init__.py +6 -2
  8. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/backfill.py +3 -16
  9. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/indexing.py +40 -0
  10. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/service.py +30 -0
  11. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/dispatch.py +2 -2
  12. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/provisioning.py +37 -4
  13. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/security.py +2 -2
  14. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/__init__.py +44 -3
  15. velocity_python-0.1.133/src/velocity/aws/deploy/ci_gate.py +660 -0
  16. velocity_python-0.1.133/src/velocity/aws/deploy/config.py +374 -0
  17. velocity_python-0.1.133/src/velocity/aws/deploy/frontend_checks.py +200 -0
  18. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/operations.py +205 -20
  19. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/policies.py +74 -1
  20. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/reconcile.py +249 -12
  21. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/dirty_pipeline.py +6 -1
  22. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/failures.py +258 -28
  23. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/feature_flags.py +4 -0
  24. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/base_handler.py +22 -18
  25. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/exceptions.py +17 -0
  26. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/lambda_handler.py +49 -1
  27. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/__init__.py +10 -0
  28. velocity_python-0.1.133/src/velocity/aws/handlers/mixins/client_errors.py +425 -0
  29. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/client_input.py +51 -0
  30. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/data_service.py +242 -86
  31. velocity_python-0.1.133/src/velocity/aws/handlers/mixins/row_scoped.py +287 -0
  32. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/session_control.py +26 -0
  33. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/web_handler.py +84 -1
  34. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/sqs_handler.py +7 -2
  35. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/job_lifecycle.py +25 -0
  36. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/job_results.py +10 -0
  37. velocity_python-0.1.133/src/velocity/aws/queue_defaults.py +13 -0
  38. velocity_python-0.1.133/src/velocity/aws/s3.py +777 -0
  39. velocity_python-0.1.133/src/velocity/aws/schema.py +124 -0
  40. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/ssm_config.py +35 -0
  41. velocity_python-0.1.129/src/velocity/aws/tests/test_amplify_build_policy_size.py → velocity_python-0.1.133/src/velocity/aws/tests/test_deploy_policy_size.py +5 -3
  42. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/table.py +203 -6
  43. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/migrations.py +14 -8
  44. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/initializer.py +26 -1
  45. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/types.py +93 -0
  46. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/__init__.py +82 -7
  47. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/types.py +93 -0
  48. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/types.py +90 -0
  49. velocity_python-0.1.133/src/velocity/db/servers/sqlserver/types.py +209 -0
  50. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tunnel.py +5 -2
  51. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/conv/iconv.py +42 -17
  52. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/dynamodb/__init__.py +4 -1
  53. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/__init__.py +9 -2
  54. velocity_python-0.1.133/src/velocity/payment/_mirror_core.py +162 -0
  55. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/authorizenet_adapter.py +22 -22
  56. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/authorizenet_mirror.py +10 -14
  57. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/braintree_adapter.py +49 -29
  58. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/braintree_mirror.py +11 -20
  59. velocity_python-0.1.133/src/velocity/payment/plaid_webhook.py +361 -0
  60. velocity_python-0.1.133/src/velocity/payment/schema.py +253 -0
  61. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/stripe_adapter.py +18 -23
  62. velocity_python-0.1.133/src/velocity/payment/stripe_mirror.py +303 -0
  63. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/PKG-INFO +73 -32
  64. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/SOURCES.txt +34 -4
  65. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/requires.txt +6 -1
  66. velocity_python-0.1.133/tests/test_amplify_redirects.py +84 -0
  67. velocity_python-0.1.133/tests/test_aws_package_hygiene.py +223 -0
  68. velocity_python-0.1.133/tests/test_ci_gate.py +772 -0
  69. velocity_python-0.1.133/tests/test_client_errors_mixin.py +588 -0
  70. velocity_python-0.1.133/tests/test_client_input_contract_export.py +109 -0
  71. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_connection_resilience.py +12 -3
  72. velocity_python-0.1.133/tests/test_data_service_row_number.py +435 -0
  73. velocity_python-0.1.133/tests/test_declared_column_types.py +481 -0
  74. velocity_python-0.1.133/tests/test_deploy_config_fields.py +650 -0
  75. velocity_python-0.1.129/tests/test_amplify_build.py → velocity_python-0.1.133/tests/test_deploy_engine.py +34 -37
  76. velocity_python-0.1.133/tests/test_deploy_frontend_checks.py +163 -0
  77. velocity_python-0.1.133/tests/test_deploy_operations_queue.py +217 -0
  78. velocity_python-0.1.133/tests/test_dlq_constant.py +35 -0
  79. velocity_python-0.1.133/tests/test_docs_snippets.py +175 -0
  80. velocity_python-0.1.133/tests/test_ensure_infrastructure.py +596 -0
  81. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_failures.py +168 -0
  82. velocity_python-0.1.133/tests/test_iconv_money_to_cents.py +113 -0
  83. velocity_python-0.1.133/tests/test_mirror_upsert_public.py +252 -0
  84. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_dynamodb.py +16 -0
  85. velocity_python-0.1.133/tests/test_on_action_default.py +96 -0
  86. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_authorizenet_adapter.py +36 -11
  87. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_braintree_adapter.py +92 -11
  88. velocity_python-0.1.133/tests/test_payment_business_agnostic.py +225 -0
  89. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_stripe_adapter.py +61 -14
  90. velocity_python-0.1.133/tests/test_pgserver_ensure_infrastructure.py +122 -0
  91. velocity_python-0.1.133/tests/test_plaid_webhook.py +418 -0
  92. velocity_python-0.1.133/tests/test_postgres_initializer_config.py +197 -0
  93. velocity_python-0.1.133/tests/test_readme_imports.py +59 -0
  94. velocity_python-0.1.133/tests/test_row_scoped_data_service.py +679 -0
  95. velocity_python-0.1.133/tests/test_s3_upload.py +551 -0
  96. velocity_python-0.1.133/tests/test_ssm_config_require.py +96 -0
  97. velocity_python-0.1.133/tests/test_user_not_provisioned.py +257 -0
  98. velocity_python-0.1.129/src/velocity/aws/amplify_build.py +0 -144
  99. velocity_python-0.1.129/src/velocity/aws/deploy/config.py +0 -115
  100. velocity_python-0.1.129/src/velocity/aws/s3.py +0 -269
  101. velocity_python-0.1.129/src/velocity/aws/tests/test_amplify_build_shim.py +0 -74
  102. velocity_python-0.1.129/src/velocity/db/servers/sqlserver/types.py +0 -114
  103. velocity_python-0.1.129/src/velocity/payment/_mirror_core.py +0 -107
  104. velocity_python-0.1.129/src/velocity/payment/stripe_mirror.py +0 -307
  105. velocity_python-0.1.129/tests/test_iconv_money_to_cents.py +0 -20
  106. {velocity_python-0.1.129 → velocity_python-0.1.133}/LICENSE +0 -0
  107. {velocity_python-0.1.129 → velocity_python-0.1.133}/setup.cfg +0 -0
  108. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/references.py +0 -0
  109. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/usage_index.py +0 -0
  110. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/blobs.py +0 -0
  111. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/__init__.py +0 -0
  112. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/base.py +0 -0
  113. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/infra.py +0 -0
  114. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/jobs.py +0 -0
  115. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/retention.py +0 -0
  116. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/single_session.py +0 -0
  117. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/targets.py +0 -0
  118. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/email.py +0 -0
  119. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/facets.py +0 -0
  120. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/__init__.py +0 -0
  121. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/context.py +0 -0
  122. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/context_factory.py +0 -0
  123. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/masquerade.py +0 -0
  124. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/job_handler.py +0 -0
  125. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/perf.py +0 -0
  126. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/response.py +0 -0
  127. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/mirror.py +0 -0
  128. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/ops.py +0 -0
  129. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/sms.py +0 -0
  130. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/__init__.py +0 -0
  131. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
  132. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_deploy_least_privilege.py +0 -0
  133. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_deploy_policies.py +0 -0
  134. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_deploy_reconcile.py +0 -0
  135. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_email.py +0 -0
  136. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
  137. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_response.py +0 -0
  138. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_sms.py +0 -0
  139. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/cache.py +0 -0
  140. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/__init__.py +0 -0
  141. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/__init__.py +0 -0
  142. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/async_support.py +0 -0
  143. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/column.py +0 -0
  144. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/database.py +0 -0
  145. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/decorators.py +0 -0
  146. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/engine.py +0 -0
  147. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/jsonproxy.py +0 -0
  148. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/lazy_engine.py +0 -0
  149. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/result.py +0 -0
  150. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/row.py +0 -0
  151. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/sequence.py +0 -0
  152. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/transaction.py +0 -0
  153. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/view.py +0 -0
  154. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/exceptions.py +0 -0
  155. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/fragments.py +0 -0
  156. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/maintenance.py +0 -0
  157. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/__init__.py +0 -0
  158. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/__init__.py +0 -0
  159. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/operators.py +0 -0
  160. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/sql.py +0 -0
  161. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/types.py +0 -0
  162. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/__init__.py +0 -0
  163. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/operators.py +0 -0
  164. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/reserved.py +0 -0
  165. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/sql.py +0 -0
  166. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/operators.py +0 -0
  167. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/reserved.py +0 -0
  168. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/sql.py +0 -0
  169. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/__init__.py +0 -0
  170. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/operators.py +0 -0
  171. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/reserved.py +0 -0
  172. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/sql.py +0 -0
  173. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
  174. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/operators.py +0 -0
  175. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
  176. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/sql.py +0 -0
  177. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/tablehelper.py +0 -0
  178. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/__init__.py +0 -0
  179. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/common_db_test.py +0 -0
  180. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/__init__.py +0 -0
  181. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/common.py +0 -0
  182. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/conftest.py +0 -0
  183. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_column.py +0 -0
  184. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_connections.py +0 -0
  185. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_database.py +0 -0
  186. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_engine.py +0 -0
  187. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
  188. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_imports.py +0 -0
  189. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_result.py +0 -0
  190. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_row.py +0 -0
  191. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
  192. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
  193. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
  194. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
  195. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
  196. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_table.py +0 -0
  197. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
  198. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
  199. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/__init__.py +0 -0
  200. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/common.py +0 -0
  201. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
  202. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
  203. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
  204. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_db_utils.py +0 -0
  205. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_postgres.py +0 -0
  206. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
  207. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
  208. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_result_caching.py +0 -0
  209. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
  210. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
  211. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
  212. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
  213. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_sql_builder.py +0 -0
  214. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_tablehelper.py +0 -0
  215. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_view_helper.py +0 -0
  216. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/utils.py +0 -0
  217. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/logging.py +0 -0
  218. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/__init__.py +0 -0
  219. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/conv/__init__.py +0 -0
  220. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/conv/oconv.py +0 -0
  221. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/db.py +0 -0
  222. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/export.py +0 -0
  223. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/format.py +0 -0
  224. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/mail.py +0 -0
  225. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/merge.py +0 -0
  226. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/pdf.py +0 -0
  227. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/__init__.py +0 -0
  228. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_db.py +0 -0
  229. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_fix.py +0 -0
  230. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_format.py +0 -0
  231. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_iconv.py +0 -0
  232. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_mail_send.py +0 -0
  233. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_merge.py +0 -0
  234. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_oconv.py +0 -0
  235. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_original_error.py +0 -0
  236. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_timer.py +0 -0
  237. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/timer.py +0 -0
  238. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tools.py +0 -0
  239. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/__init__.py +0 -0
  240. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/__init__.py +0 -0
  241. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/capabilities.py +0 -0
  242. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/store.py +0 -0
  243. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/where.py +0 -0
  244. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/exceptions.py +0 -0
  245. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/__init__.py +0 -0
  246. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/base/__init__.py +0 -0
  247. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/cassandra/__init__.py +0 -0
  248. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/cassandra/translation.py +0 -0
  249. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/couchbase/__init__.py +0 -0
  250. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/couchbase/translation.py +0 -0
  251. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/dynamodb/translation.py +0 -0
  252. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/elasticsearch/__init__.py +0 -0
  253. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/elasticsearch/translation.py +0 -0
  254. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/memory/__init__.py +0 -0
  255. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/mongodb/__init__.py +0 -0
  256. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/mongodb/translation.py +0 -0
  257. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/redis/__init__.py +0 -0
  258. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/base_adapter.py +0 -0
  259. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/charge_rules.py +0 -0
  260. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/money.py +0 -0
  261. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/redact.py +0 -0
  262. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/dependency_links.txt +0 -0
  263. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/entry_points.txt +0 -0
  264. {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/top_level.txt +0 -0
  265. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_access_error_403.py +0 -0
  266. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_activity_tracking_aborted_tx.py +0 -0
  267. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_asset_indexing.py +0 -0
  268. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_asset_references.py +0 -0
  269. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_assets_service.py +0 -0
  270. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_async_support.py +0 -0
  271. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_batch_operations.py +0 -0
  272. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_blob_store.py +0 -0
  273. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_capabilities.py +0 -0
  274. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_capability_catalog.py +0 -0
  275. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_client_sql_boundary.py +0 -0
  276. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_cognito_user_cache.py +0 -0
  277. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_column_tx_arg.py +0 -0
  278. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_concurrency_safety.py +0 -0
  279. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_connection_pool.py +0 -0
  280. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_context_flags_loader.py +0 -0
  281. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_context_job_descriptions.py +0 -0
  282. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_data_service_query_cap.py +0 -0
  283. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_data_service_renumber.py +0 -0
  284. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_data_service_save_as.py +0 -0
  285. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_db_credentials_ssm_cascade.py +0 -0
  286. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_db_maintenance.py +0 -0
  287. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_db_tunnel.py +0 -0
  288. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_decorators.py +0 -0
  289. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_delete_hook_fk_blocked.py +0 -0
  290. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_dirty_pipeline_fast_path.py +0 -0
  291. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_email_processing.py +0 -0
  292. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_enqueue_metric_namespace.py +0 -0
  293. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_enqueue_send_failures.py +0 -0
  294. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_facets.py +0 -0
  295. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_feature_flags.py +0 -0
  296. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_get_cognito_user_provider.py +0 -0
  297. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_http_handler_rollback.py +0 -0
  298. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_identifier_injection_guard.py +0 -0
  299. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_job_handler.py +0 -0
  300. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_job_lifecycle.py +0 -0
  301. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_job_results.py +0 -0
  302. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_json_columns.py +0 -0
  303. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_jsonb_dict_adapter.py +0 -0
  304. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler.py +0 -0
  305. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler_auth.py +0 -0
  306. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler_masquerade.py +0 -0
  307. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler_user_cache.py +0 -0
  308. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lazy_engine.py +0 -0
  309. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_masquerade_grant.py +0 -0
  310. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_mirror.py +0 -0
  311. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_mixins_import.py +0 -0
  312. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_n_plus_one.py +0 -0
  313. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_memory.py +0 -0
  314. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_mongodb.py +0 -0
  315. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_redis.py +0 -0
  316. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_translation.py +0 -0
  317. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_where.py +0 -0
  318. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_observability.py +0 -0
  319. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_on_commit.py +0 -0
  320. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_ops.py +0 -0
  321. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_audit_fixes.py +0 -0
  322. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_braintree_mirror.py +0 -0
  323. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_mirror_empty_table.py +0 -0
  324. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_profile_sorting.py +0 -0
  325. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pdf.py +0 -0
  326. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pgserver_bulk_cache.py +0 -0
  327. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pgserver_pointer_joins.py +0 -0
  328. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pointer_join_sql.py +0 -0
  329. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_prepared_statements.py +0 -0
  330. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_psycopg3_upgrade.py +0 -0
  331. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_query_cache.py +0 -0
  332. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_query_missing_table_unlocked.py +0 -0
  333. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_raw_sql_prefix_policy.py +0 -0
  334. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_read_cache.py +0 -0
  335. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_response.py +0 -0
  336. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_restricted_direct_tables.py +0 -0
  337. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_result_returning.py +0 -0
  338. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_retry_side_effect_guard.py +0 -0
  339. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_return_default_safety.py +0 -0
  340. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_row_batch_update.py +0 -0
  341. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_row_cache_staleness.py +0 -0
  342. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_s3_bucket_config.py +0 -0
  343. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_s3_list_client_files.py +0 -0
  344. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_schema_migrations.py +0 -0
  345. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_security_capability.py +0 -0
  346. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_security_hardening.py +0 -0
  347. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_server_cursor.py +0 -0
  348. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_session_control.py +0 -0
  349. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_single_autocommit_safety.py +0 -0
  350. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_single_session_capability.py +0 -0
  351. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_spreadsheet_functions.py +0 -0
  352. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_sqlite_backend.py +0 -0
  353. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_sqs_per_record_transactions.py +0 -0
  354. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_ssm_config.py +0 -0
  355. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_store_user_data.py +0 -0
  356. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_sys_modified_count_postgres_demo.py +0 -0
  357. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_table_alter.py +0 -0
  358. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_table_find_cache.py +0 -0
  359. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_table_purge.py +0 -0
  360. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_transaction_class_wrapping.py +0 -0
  361. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_transaction_commit_and_ownership.py +0 -0
  362. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_transaction_edge_cases.py +0 -0
  363. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_tx_lifecycle_retry.py +0 -0
  364. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_tx_read_cache_and_bulk.py +0 -0
  365. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_where_clause_validation.py +0 -0
  366. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_write_hook_create_flow.py +0 -0
  367. {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_write_hook_empty_strings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.1.129
3
+ Version: 0.1.133
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -13,12 +13,10 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: Topic :: Database
14
14
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
15
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
16
  Classifier: Programming Language :: Python :: 3.11
19
17
  Classifier: Programming Language :: Python :: 3.12
20
18
  Classifier: Operating System :: OS Independent
21
- Requires-Python: >=3.9
19
+ Requires-Python: >=3.11
22
20
  Description-Content-Type: text/markdown
23
21
  License-File: LICENSE
24
22
  Requires-Dist: sqlparse>=0.5.0
@@ -57,8 +55,11 @@ Provides-Extra: payment
57
55
  Requires-Dist: stripe>=12.0.0; extra == "payment"
58
56
  Requires-Dist: braintree>=4.30.0; extra == "payment"
59
57
  Requires-Dist: xmltodict>=0.13.0; extra == "payment"
58
+ Provides-Extra: plaid
59
+ Requires-Dist: velocity-python[payment]; extra == "plaid"
60
+ Requires-Dist: ecdsa>=0.19.0; extra == "plaid"
60
61
  Provides-Extra: all
61
- Requires-Dist: velocity-python[aws,excel,http,payment,pdf,postgres,templates]; extra == "all"
62
+ Requires-Dist: velocity-python[aws,excel,http,payment,pdf,plaid,postgres,templates]; extra == "all"
62
63
  Provides-Extra: dev
63
64
  Requires-Dist: pytest>=8.0.0; extra == "dev"
64
65
  Requires-Dist: pytest-cov>=6.0.0; extra == "dev"
@@ -79,6 +80,7 @@ Requires-Dist: stripe>=12.0.0; extra == "test"
79
80
  Requires-Dist: braintree>=4.30.0; extra == "test"
80
81
  Requires-Dist: xmltodict>=0.13.0; extra == "test"
81
82
  Requires-Dist: authorizenet>=1.1.3; extra == "test"
83
+ Requires-Dist: ecdsa>=0.19.0; extra == "test"
82
84
  Requires-Dist: openpyxl>=3.1.0; extra == "test"
83
85
  Requires-Dist: redis>=5.0.0; extra == "test"
84
86
  Requires-Dist: fakeredis>=2.23.0; extra == "test"
@@ -163,12 +165,16 @@ pip install velocity-python[all]
163
165
  | `postgres` | `psycopg[binary]>=3.2.0` | PostgreSQL connections |
164
166
  | `aws` | `boto3`, `requests` | Lambda handlers, SQS, Amplify |
165
167
  | `excel` | `openpyxl` | Excel export |
168
+ | `parquet` | `pyarrow` | Parquet export |
169
+ | `ods` | `odfpy` | OpenDocument spreadsheet export |
166
170
  | `templates` | `jinja2` | Template rendering |
171
+ | `pdf` | `weasyprint` | HTML → PDF rendering (native Pango/Cairo from the OS or a layer) |
167
172
  | `http` | `requests` | HTTP utilities |
168
- | `payment` | `stripe`, `braintree` | Payment processing |
173
+ | `payment` | `stripe`, `braintree`, `xmltodict` | Stripe and Braintree adapters (Authorize.Net additionally needs `authorizenet`, installed separately — see `docs/payment.md`) |
169
174
  | `mysql` | `mysql-connector-python` | MySQL connections |
170
175
  | `sqlserver` | `python-tds` | SQL Server connections |
171
- | `all` | All of the above | Full install |
176
+ | `redis`, `mongodb`, `elasticsearch`, `cassandra`, `couchbase` | the matching client | NoSQL adapters (`docs/nosql.md`) |
177
+ | `all` | `postgres`, `aws`, `excel`, `templates`, `http`, `payment`, `pdf` | Typical full install |
172
178
 
173
179
  **Requires Python 3.9+** and uses **psycopg v3** (not psycopg2) for PostgreSQL.
174
180
 
@@ -244,16 +250,19 @@ Full documentation is included in the `docs/` directory of the source distributi
244
250
 
245
251
  | Guide | File | Description |
246
252
  |-------|------|-------------|
247
- | Database ORM | `docs/database.md` | Connections, transactions, tables, rows, results, queries, schema management |
253
+ | Database ORM | `docs/database.md` | Connections, `DB_TUNNEL`, transactions, tables, rows, results, queries, purge, schema management |
254
+ | Schema Management | `docs/schema-management.md` | Runtime auto-heal, declarative `ensure_schema()`, schema locking, conflict handling |
248
255
  | Performance & Optimization | `docs/performance.md` | Connection pooling, batch operations, query caching, prepared statements, N+1 prevention, observability |
249
256
  | Async Support | `docs/async.md` | AsyncTransaction, AsyncTable, AsyncResult, parallel queries with gather() |
250
- | Configuration Reference | `docs/configuration.md` | All environment variables, engine options, and connection settings |
251
- | AWS Lambda Handlers | `docs/aws-handlers.md` | LambdaHandler, SqsHandler, auth modes, per-record transactions, async jobs (JobHandler + job result stores) |
257
+ | Configuration Reference | `docs/configuration.md` | Every environment variable and SSM config key velocity reads, `ssm_config`, S3 buckets, engine options |
258
+ | AWS Lambda Handlers | `docs/aws-handlers.md` | LambdaHandler, SqsHandler, auth modes, per-record transactions, DataService client boundary, async jobs (JobHandler + job result stores), failure events |
259
+ | AWS Auth Modes | `docs/AWS_HANDLERS_AUTH.md` | Cognito auth, public endpoints, webhooks |
260
+ | Deployment | `docs/deploy.md` | `velocity.aws.deploy`: least-privilege IAM, function settings, layers, SQS queue reconcile |
252
261
  | Cross-database Mirroring | `docs/mirroring.md` | Keep a table identical in two databases (demo ↔ production) by natural key; rwx hooks, FK translation, reconcile |
253
262
  | Operations Dashboard | `docs/operations.md` | What the automation is doing: schedules, jobs, failures, stuck work, with drill-down (`velocity.aws.ops` + velocity-react `OpsDashboard`) |
254
263
  | NoSQL Adapters | `docs/nosql.md` | Redis, DynamoDB, MongoDB, Elasticsearch, Cassandra, Couchbase behind one capability-honest contract |
255
- | Payment Processing | `docs/payment.md` | Stripe and Braintree adapters, payment lifecycle |
256
- | Utilities | `docs/utilities.md` | Excel export, data conversion, formatting, timers, email parsing and SMTP sending |
264
+ | Payment Processing | `docs/payment.md` | Stripe, Braintree and Authorize.Net adapters, processor mirrors, payment lifecycle |
265
+ | Utilities | `docs/utilities.md` | Excel/PDF export, data conversion, formatting, timers, email parsing and SMTP sending |
257
266
  | Testing Guide | `docs/TESTING.md` | Running tests, markers, coverage |
258
267
  | Security | `docs/SECURITY.md` | Pre-commit hooks, credential scanning |
259
268
 
@@ -266,7 +275,7 @@ Engine (singleton — survives Lambda warm starts)
266
275
  ├── ConnectionPool (thread-safe, configurable min/max)
267
276
  └── Transaction (one per request, borrows from pool)
268
277
  ├── Table (CRUD, batch ops, schema management)
269
- │ ├── Row (dict-like, lazy-cache, write-through, batch_update)
278
+ │ ├── Row (dict-like, lazy-cache, write-through, batch_update())
270
279
  │ └── Result (streaming cursor iteration, transforms)
271
280
  ├── View (create, grant, ensure)
272
281
  └── Sequence (create, next, current, configure)
@@ -299,7 +308,7 @@ from velocity.db.servers.sqlite import initialize
299
308
  engine = initialize(config={"database": "myapp.db"})
300
309
 
301
310
  # SQL Server
302
- from velocity.db.servers.mssql import initialize
311
+ from velocity.db.servers.sqlserver import initialize
303
312
  engine = initialize()
304
313
  ```
305
314
 
@@ -310,32 +319,61 @@ engine = initialize()
310
319
  ```
311
320
  velocity-python/
312
321
  ├── src/velocity/
322
+ │ ├── cache.py # Process-level read cache (cache_ttl / memo)
323
+ │ ├── logging.py # Logging setup (JSON in Lambda, text elsewhere)
313
324
  │ ├── db/
314
325
  │ │ ├── core/
315
- │ │ │ ├── engine.py # Engine, ConnectionPool
316
- │ │ │ ├── transaction.py # Transaction, query timing, caching
317
- │ │ │ ├── table.py # Table CRUD, batch ops, schema
318
- │ │ │ ├── row.py # Row (dict-like ORM object)
326
+ │ │ │ ├── engine.py # Engine, ConnectionPool, @engine.transaction
327
+ │ │ │ ├── lazy_engine.py # LazyEngine (build on first use)
328
+ │ │ │ ├── transaction.py # Transaction, query timing, caching, on_commit
329
+ │ │ │ ├── table.py # Table CRUD, batch ops, purge, schema
330
+ │ │ │ ├── row.py # Row (dict-like, write-through, batch_update())
319
331
  │ │ │ ├── result.py # Result (cursor wrapper, transforms)
332
+ │ │ │ ├── column.py # Column helpers
333
+ │ │ │ ├── database.py # Database-level operations
334
+ │ │ │ ├── jsonproxy.py # Live list/dict values for JSON columns
320
335
  │ │ │ ├── async_support.py # Async versions of core classes
321
336
  │ │ │ ├── view.py # View management
322
337
  │ │ │ ├── sequence.py # Sequence management
323
- │ │ │ └── decorators.py # @create_missing, @return_default, etc.
324
- │ │ └── servers/
325
- │ │ ├── postgres/ # PostgreSQL dialect + initializer
326
- │ │ ├── mysql/ # MySQL dialect
327
- │ │ ├── sqlite/ # SQLite dialect
328
- │ │ └── mssql/ # SQL Server dialect
338
+ │ │ │ └── decorators.py # @create_missing, @return_default, retries
339
+ │ │ ├── servers/
340
+ │ │ │ ├── postgres/ # PostgreSQL dialect + initializer (primary)
341
+ │ │ │ ├── mysql/ # MySQL dialect
342
+ │ │ │ ├── sqlite/ # SQLite dialect
343
+ │ │ │ ├── sqlserver/ # SQL Server dialect
344
+ │ │ │ └── tablehelper.py # Where/column/pointer-join compiler
345
+ │ │ ├── fragments.py # Literal / @@ token handling
346
+ │ │ ├── maintenance.py # DatabaseMaintenance (clone, snapshot, prune)
347
+ │ │ ├── migrations.py # `velocity` CLI: migration runner
348
+ │ │ ├── tunnel.py # DB_TUNNEL support
349
+ │ │ └── exceptions.py # Db* exception hierarchy
329
350
  │ ├── aws/
330
- │ │ └── handlers/
331
- │ │ ├── lambda_handler.py # HTTP Lambda handler
332
- │ │ └── sqs_handler.py # SQS batch handler
351
+ │ │ ├── handlers/ # LambdaHandler, SqsHandler, context, mixins
352
+ │ │ │ └── mixins/ # DataService, client-input guard, jobs, sessions, web
353
+ │ │ ├── capabilities/ # Per-site capability registry and provisioning
354
+ │ │ ├── assets/ # Asset store: indexing, references, usage
355
+ │ │ ├── deploy/ # Platform-neutral deployment engine
356
+ │ │ ├── ssm_config.py # SSM-backed config (project, then /Global)
357
+ │ │ ├── s3.py # Presigned URLs, configured buckets
358
+ │ │ ├── failures.py # Failure events (SNS)
359
+ │ │ ├── feature_flags.py # sys_feature_flags cache + mirror
360
+ │ │ ├── mirror.py # Cross-database table mirroring
361
+ │ │ ├── job_lifecycle.py # Job status tracking
362
+ │ │ ├── job_results.py # Job result stores
363
+ │ │ ├── dirty_pipeline.py # sys_dirty / on_dirty pipeline
364
+ │ │ ├── ops.py # Operations dashboard data
365
+ │ │ ├── email.py / sms.py # SES email, SMS
366
+ │ │ └── amplify.py, amplify_build.py, blobs.py, facets.py
367
+ │ ├── nosql/ # NoSQL store contract + adapters
333
368
  │ ├── payment/
334
369
  │ │ ├── base_adapter.py # Abstract payment interface
335
- │ │ ├── stripe_adapter.py # Stripe implementation
336
- │ │ └── braintree_adapter.py # Braintree implementation
337
- │ └── misc/ # Utility modules
338
- ├── tests/ # 400+ unit tests
370
+ │ │ ├── stripe_adapter.py # Stripe
371
+ │ │ ├── braintree_adapter.py # Braintree
372
+ │ │ ├── authorizenet_adapter.py # Authorize.Net (CIM)
373
+ │ │ ├── *_mirror.py # Processor mirror tables
374
+ │ │ └── money.py, charge_rules.py, redact.py
375
+ │ └── misc/ # conv (iconv/oconv), export, format, mail, pdf, timer, ...
376
+ ├── tests/ # Unit tests (make test-unit)
339
377
  ├── docs/ # Detailed documentation
340
378
  └── pyproject.toml
341
379
  ```
@@ -348,7 +386,10 @@ velocity-python/
348
386
  # Install with dev dependencies
349
387
  pip install -e ".[dev,test,postgres]"
350
388
 
351
- # Run tests
389
+ # Run the unit suite (no database needed)
390
+ make test-unit
391
+
392
+ # Or directly
352
393
  pytest
353
394
 
354
395
  # Run with coverage
@@ -71,12 +71,16 @@ pip install velocity-python[all]
71
71
  | `postgres` | `psycopg[binary]>=3.2.0` | PostgreSQL connections |
72
72
  | `aws` | `boto3`, `requests` | Lambda handlers, SQS, Amplify |
73
73
  | `excel` | `openpyxl` | Excel export |
74
+ | `parquet` | `pyarrow` | Parquet export |
75
+ | `ods` | `odfpy` | OpenDocument spreadsheet export |
74
76
  | `templates` | `jinja2` | Template rendering |
77
+ | `pdf` | `weasyprint` | HTML → PDF rendering (native Pango/Cairo from the OS or a layer) |
75
78
  | `http` | `requests` | HTTP utilities |
76
- | `payment` | `stripe`, `braintree` | Payment processing |
79
+ | `payment` | `stripe`, `braintree`, `xmltodict` | Stripe and Braintree adapters (Authorize.Net additionally needs `authorizenet`, installed separately — see `docs/payment.md`) |
77
80
  | `mysql` | `mysql-connector-python` | MySQL connections |
78
81
  | `sqlserver` | `python-tds` | SQL Server connections |
79
- | `all` | All of the above | Full install |
82
+ | `redis`, `mongodb`, `elasticsearch`, `cassandra`, `couchbase` | the matching client | NoSQL adapters (`docs/nosql.md`) |
83
+ | `all` | `postgres`, `aws`, `excel`, `templates`, `http`, `payment`, `pdf` | Typical full install |
80
84
 
81
85
  **Requires Python 3.9+** and uses **psycopg v3** (not psycopg2) for PostgreSQL.
82
86
 
@@ -152,16 +156,19 @@ Full documentation is included in the `docs/` directory of the source distributi
152
156
 
153
157
  | Guide | File | Description |
154
158
  |-------|------|-------------|
155
- | Database ORM | `docs/database.md` | Connections, transactions, tables, rows, results, queries, schema management |
159
+ | Database ORM | `docs/database.md` | Connections, `DB_TUNNEL`, transactions, tables, rows, results, queries, purge, schema management |
160
+ | Schema Management | `docs/schema-management.md` | Runtime auto-heal, declarative `ensure_schema()`, schema locking, conflict handling |
156
161
  | Performance & Optimization | `docs/performance.md` | Connection pooling, batch operations, query caching, prepared statements, N+1 prevention, observability |
157
162
  | Async Support | `docs/async.md` | AsyncTransaction, AsyncTable, AsyncResult, parallel queries with gather() |
158
- | Configuration Reference | `docs/configuration.md` | All environment variables, engine options, and connection settings |
159
- | AWS Lambda Handlers | `docs/aws-handlers.md` | LambdaHandler, SqsHandler, auth modes, per-record transactions, async jobs (JobHandler + job result stores) |
163
+ | Configuration Reference | `docs/configuration.md` | Every environment variable and SSM config key velocity reads, `ssm_config`, S3 buckets, engine options |
164
+ | AWS Lambda Handlers | `docs/aws-handlers.md` | LambdaHandler, SqsHandler, auth modes, per-record transactions, DataService client boundary, async jobs (JobHandler + job result stores), failure events |
165
+ | AWS Auth Modes | `docs/AWS_HANDLERS_AUTH.md` | Cognito auth, public endpoints, webhooks |
166
+ | Deployment | `docs/deploy.md` | `velocity.aws.deploy`: least-privilege IAM, function settings, layers, SQS queue reconcile |
160
167
  | Cross-database Mirroring | `docs/mirroring.md` | Keep a table identical in two databases (demo ↔ production) by natural key; rwx hooks, FK translation, reconcile |
161
168
  | Operations Dashboard | `docs/operations.md` | What the automation is doing: schedules, jobs, failures, stuck work, with drill-down (`velocity.aws.ops` + velocity-react `OpsDashboard`) |
162
169
  | NoSQL Adapters | `docs/nosql.md` | Redis, DynamoDB, MongoDB, Elasticsearch, Cassandra, Couchbase behind one capability-honest contract |
163
- | Payment Processing | `docs/payment.md` | Stripe and Braintree adapters, payment lifecycle |
164
- | Utilities | `docs/utilities.md` | Excel export, data conversion, formatting, timers, email parsing and SMTP sending |
170
+ | Payment Processing | `docs/payment.md` | Stripe, Braintree and Authorize.Net adapters, processor mirrors, payment lifecycle |
171
+ | Utilities | `docs/utilities.md` | Excel/PDF export, data conversion, formatting, timers, email parsing and SMTP sending |
165
172
  | Testing Guide | `docs/TESTING.md` | Running tests, markers, coverage |
166
173
  | Security | `docs/SECURITY.md` | Pre-commit hooks, credential scanning |
167
174
 
@@ -174,7 +181,7 @@ Engine (singleton — survives Lambda warm starts)
174
181
  ├── ConnectionPool (thread-safe, configurable min/max)
175
182
  └── Transaction (one per request, borrows from pool)
176
183
  ├── Table (CRUD, batch ops, schema management)
177
- │ ├── Row (dict-like, lazy-cache, write-through, batch_update)
184
+ │ ├── Row (dict-like, lazy-cache, write-through, batch_update())
178
185
  │ └── Result (streaming cursor iteration, transforms)
179
186
  ├── View (create, grant, ensure)
180
187
  └── Sequence (create, next, current, configure)
@@ -207,7 +214,7 @@ from velocity.db.servers.sqlite import initialize
207
214
  engine = initialize(config={"database": "myapp.db"})
208
215
 
209
216
  # SQL Server
210
- from velocity.db.servers.mssql import initialize
217
+ from velocity.db.servers.sqlserver import initialize
211
218
  engine = initialize()
212
219
  ```
213
220
 
@@ -218,32 +225,61 @@ engine = initialize()
218
225
  ```
219
226
  velocity-python/
220
227
  ├── src/velocity/
228
+ │ ├── cache.py # Process-level read cache (cache_ttl / memo)
229
+ │ ├── logging.py # Logging setup (JSON in Lambda, text elsewhere)
221
230
  │ ├── db/
222
231
  │ │ ├── core/
223
- │ │ │ ├── engine.py # Engine, ConnectionPool
224
- │ │ │ ├── transaction.py # Transaction, query timing, caching
225
- │ │ │ ├── table.py # Table CRUD, batch ops, schema
226
- │ │ │ ├── row.py # Row (dict-like ORM object)
232
+ │ │ │ ├── engine.py # Engine, ConnectionPool, @engine.transaction
233
+ │ │ │ ├── lazy_engine.py # LazyEngine (build on first use)
234
+ │ │ │ ├── transaction.py # Transaction, query timing, caching, on_commit
235
+ │ │ │ ├── table.py # Table CRUD, batch ops, purge, schema
236
+ │ │ │ ├── row.py # Row (dict-like, write-through, batch_update())
227
237
  │ │ │ ├── result.py # Result (cursor wrapper, transforms)
238
+ │ │ │ ├── column.py # Column helpers
239
+ │ │ │ ├── database.py # Database-level operations
240
+ │ │ │ ├── jsonproxy.py # Live list/dict values for JSON columns
228
241
  │ │ │ ├── async_support.py # Async versions of core classes
229
242
  │ │ │ ├── view.py # View management
230
243
  │ │ │ ├── sequence.py # Sequence management
231
- │ │ │ └── decorators.py # @create_missing, @return_default, etc.
232
- │ │ └── servers/
233
- │ │ ├── postgres/ # PostgreSQL dialect + initializer
234
- │ │ ├── mysql/ # MySQL dialect
235
- │ │ ├── sqlite/ # SQLite dialect
236
- │ │ └── mssql/ # SQL Server dialect
244
+ │ │ │ └── decorators.py # @create_missing, @return_default, retries
245
+ │ │ ├── servers/
246
+ │ │ │ ├── postgres/ # PostgreSQL dialect + initializer (primary)
247
+ │ │ │ ├── mysql/ # MySQL dialect
248
+ │ │ │ ├── sqlite/ # SQLite dialect
249
+ │ │ │ ├── sqlserver/ # SQL Server dialect
250
+ │ │ │ └── tablehelper.py # Where/column/pointer-join compiler
251
+ │ │ ├── fragments.py # Literal / @@ token handling
252
+ │ │ ├── maintenance.py # DatabaseMaintenance (clone, snapshot, prune)
253
+ │ │ ├── migrations.py # `velocity` CLI: migration runner
254
+ │ │ ├── tunnel.py # DB_TUNNEL support
255
+ │ │ └── exceptions.py # Db* exception hierarchy
237
256
  │ ├── aws/
238
- │ │ └── handlers/
239
- │ │ ├── lambda_handler.py # HTTP Lambda handler
240
- │ │ └── sqs_handler.py # SQS batch handler
257
+ │ │ ├── handlers/ # LambdaHandler, SqsHandler, context, mixins
258
+ │ │ │ └── mixins/ # DataService, client-input guard, jobs, sessions, web
259
+ │ │ ├── capabilities/ # Per-site capability registry and provisioning
260
+ │ │ ├── assets/ # Asset store: indexing, references, usage
261
+ │ │ ├── deploy/ # Platform-neutral deployment engine
262
+ │ │ ├── ssm_config.py # SSM-backed config (project, then /Global)
263
+ │ │ ├── s3.py # Presigned URLs, configured buckets
264
+ │ │ ├── failures.py # Failure events (SNS)
265
+ │ │ ├── feature_flags.py # sys_feature_flags cache + mirror
266
+ │ │ ├── mirror.py # Cross-database table mirroring
267
+ │ │ ├── job_lifecycle.py # Job status tracking
268
+ │ │ ├── job_results.py # Job result stores
269
+ │ │ ├── dirty_pipeline.py # sys_dirty / on_dirty pipeline
270
+ │ │ ├── ops.py # Operations dashboard data
271
+ │ │ ├── email.py / sms.py # SES email, SMS
272
+ │ │ └── amplify.py, amplify_build.py, blobs.py, facets.py
273
+ │ ├── nosql/ # NoSQL store contract + adapters
241
274
  │ ├── payment/
242
275
  │ │ ├── base_adapter.py # Abstract payment interface
243
- │ │ ├── stripe_adapter.py # Stripe implementation
244
- │ │ └── braintree_adapter.py # Braintree implementation
245
- │ └── misc/ # Utility modules
246
- ├── tests/ # 400+ unit tests
276
+ │ │ ├── stripe_adapter.py # Stripe
277
+ │ │ ├── braintree_adapter.py # Braintree
278
+ │ │ ├── authorizenet_adapter.py # Authorize.Net (CIM)
279
+ │ │ ├── *_mirror.py # Processor mirror tables
280
+ │ │ └── money.py, charge_rules.py, redact.py
281
+ │ └── misc/ # conv (iconv/oconv), export, format, mail, pdf, timer, ...
282
+ ├── tests/ # Unit tests (make test-unit)
247
283
  ├── docs/ # Detailed documentation
248
284
  └── pyproject.toml
249
285
  ```
@@ -256,7 +292,10 @@ velocity-python/
256
292
  # Install with dev dependencies
257
293
  pip install -e ".[dev,test,postgres]"
258
294
 
259
- # Run tests
295
+ # Run the unit suite (no database needed)
296
+ make test-unit
297
+
298
+ # Or directly
260
299
  pytest
261
300
 
262
301
  # Run with coverage
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "velocity-python"
7
- version = "0.1.129"
7
+ version = "0.1.133"
8
8
  authors = [
9
9
  { name="Velocity Team", email="info@codeclubs.org" },
10
10
  ]
11
11
  description = "A rapid application development library for interfacing with data storage"
12
12
  readme = "README.md"
13
13
  license = "MIT"
14
- requires-python = ">=3.9"
14
+ requires-python = ">=3.11"
15
15
  keywords = ["database", "orm", "sql", "rapid-development", "data-storage"]
16
16
  classifiers = [
17
17
  "Development Status :: 4 - Beta",
@@ -19,8 +19,6 @@ classifiers = [
19
19
  "Topic :: Database",
20
20
  "Topic :: Software Development :: Libraries :: Python Modules",
21
21
  "Programming Language :: Python :: 3",
22
- "Programming Language :: Python :: 3.9",
23
- "Programming Language :: Python :: 3.10",
24
22
  "Programming Language :: Python :: 3.11",
25
23
  "Programming Language :: Python :: 3.12",
26
24
  "Operating System :: OS Independent",
@@ -90,8 +88,17 @@ payment = [
90
88
  "braintree>=4.30.0",
91
89
  "xmltodict>=0.13.0",
92
90
  ]
91
+ # Plaid webhook ES256 verification (velocity.payment.plaid_webhook). ecdsa is
92
+ # pure Python, so it fits a Lambda layer where `cryptography` does not.
93
+ # Includes [payment] because importing velocity.payment.plaid_webhook runs
94
+ # velocity/payment/__init__.py, which imports stripe and braintree eagerly;
95
+ # drop it once those package-level imports are lazy or guarded.
96
+ plaid = [
97
+ "velocity-python[payment]",
98
+ "ecdsa>=0.19.0",
99
+ ]
93
100
  all = [
94
- "velocity-python[postgres,aws,excel,templates,http,payment,pdf]",
101
+ "velocity-python[postgres,aws,excel,templates,http,payment,plaid,pdf]",
95
102
  ]
96
103
  dev = [
97
104
  "pytest>=8.0.0",
@@ -117,6 +124,7 @@ test = [
117
124
  "braintree>=4.30.0",
118
125
  "xmltodict>=0.13.0",
119
126
  "authorizenet>=1.1.3",
127
+ "ecdsa>=0.19.0",
120
128
  "openpyxl>=3.1.0",
121
129
  # NoSQL adapter unit tests run against in-process fakes (real clients for
122
130
  # the wire formats, fakes for the servers). ES/Cassandra/Couchbase have
@@ -140,7 +148,7 @@ where = ["src"]
140
148
 
141
149
  [tool.black]
142
150
  line-length = 88
143
- target-version = ['py39', 'py310', 'py311', 'py312']
151
+ target-version = ['py311', 'py312']
144
152
  include = '\.pyi?$'
145
153
  extend-exclude = '''
146
154
  /(
@@ -163,7 +171,7 @@ line_length = 88
163
171
  known_first_party = ["velocity"]
164
172
 
165
173
  [tool.mypy]
166
- python_version = "3.9"
174
+ python_version = "3.11"
167
175
  mypy_path = "src"
168
176
  explicit_package_bases = true
169
177
  exclude = "(?x)(^src/velocity/.*/tests/)"
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.1.129"
1
+ __version__ = version = "0.1.133"
2
2
 
3
3
  import importlib as _importlib
4
4
 
@@ -1,37 +1,18 @@
1
- import importlib as _importlib
2
- import os
3
-
4
- _APP_STAGE = os.environ.get("AppStage") or os.environ.get("AWS_BRANCH") or "demo"
5
- DEBUG = (_APP_STAGE != "production") or (os.environ.get("DEBUG") == "Y")
6
-
7
-
8
- # This is helpful for running HTTPS clients on lambda.
9
- if os.path.exists("/opt/python/ca-certificates.crt"):
10
- os.environ["REQUESTS_CA_BUNDLE"] = "/opt/python/ca-certificates.crt"
1
+ """AWS helpers for velocity: handlers, SSM config, deploy, S3 and assets.
11
2
 
3
+ Importing this package has no side effects: stage resolution lives in
4
+ ``velocity.aws.ssm_config`` and the Lambda CA bundle is exported as
5
+ ``REQUESTS_CA_BUNDLE`` when a handler is constructed (``BaseHandler.__init__``
6
+ via ``_update_lambda_ca_certificates``; override the path with
7
+ ``VELOCITY_CA_BUNDLE``).
8
+ """
12
9
 
13
- class AWS(object):
14
- # Get AWS EC2 Instance ID. Must run this from the EC2 instance itself to get the ID
15
- @staticmethod
16
- def instance_id(cls):
17
- import requests
18
-
19
- response = requests.get("http://169.254.169.254/latest/meta-data/instance-id")
20
- instance_id = response.text
21
- return instance_id
22
-
10
+ import importlib as _importlib
23
11
 
24
12
  # Lazy-load heavy modules (boto3-dependent) on first access
25
13
  _LAZY_ATTRS = {
26
14
  "AmplifyProject": "velocity.aws.amplify",
27
- # Legacy deployment API (shim over velocity.aws.deploy; legacy-union
28
- # policy mode). New projects: import from velocity.aws.deploy directly.
29
- "BackendDeploymentConfig": "velocity.aws.amplify_build",
30
- "get_amplify_app_id_and_branch": "velocity.aws.amplify_build",
31
- "initialize_build_environment": "velocity.aws.amplify_build",
32
- "run_backend_deployment": "velocity.aws.amplify_build",
33
- "update_lambda_layers_to_latest": "velocity.aws.amplify_build",
34
- # Platform-neutral deployment API
15
+ # Platform-neutral deployment API (the full set is in velocity.aws.deploy)
35
16
  "AmplifyTarget": "velocity.aws.deploy",
36
17
  "DeploymentConfig": "velocity.aws.deploy",
37
18
  "PlainTarget": "velocity.aws.deploy",
@@ -39,6 +20,7 @@ _LAZY_ATTRS = {
39
20
  # S3 utilities
40
21
  "generate_presigned_get": "velocity.aws.s3",
41
22
  "generate_presigned_put": "velocity.aws.s3",
23
+ "iter_objects": "velocity.aws.s3",
42
24
  "list_client_files": "velocity.aws.s3",
43
25
  "normalize_client_prefix": "velocity.aws.s3",
44
26
  "CLIENT_FILES_BUCKET": "velocity.aws.s3",
@@ -62,7 +44,6 @@ _LAZY_ATTRS = {
62
44
  "extract_asset_references_from_html": "velocity.aws.assets",
63
45
  "extract_asset_references_from_record": "velocity.aws.assets",
64
46
  "extract_asset_references_from_value": "velocity.aws.assets",
65
- "iter_s3_objects": "velocity.aws.assets",
66
47
  "list_assets": "velocity.aws.assets",
67
48
  "normalize_asset_record": "velocity.aws.assets",
68
49
  "reconcile_asset_usages": "velocity.aws.assets",
@@ -80,18 +61,13 @@ def __getattr__(name: str):
80
61
  __all__ = [
81
62
  "AmplifyProject",
82
63
  "AmplifyTarget",
83
- "AWS",
84
- "BackendDeploymentConfig",
85
64
  "DeploymentConfig",
86
65
  "PlainTarget",
87
- "get_amplify_app_id_and_branch",
88
- "initialize_build_environment",
89
- "run_backend_deployment",
90
66
  "run_deployment",
91
- "update_lambda_layers_to_latest",
92
67
  # S3 utilities
93
68
  "generate_presigned_get",
94
69
  "generate_presigned_put",
70
+ "iter_objects",
95
71
  "list_client_files",
96
72
  "normalize_client_prefix",
97
73
  "CLIENT_FILES_BUCKET",
@@ -114,7 +90,6 @@ __all__ = [
114
90
  "extract_asset_references_from_record",
115
91
  "extract_asset_references_from_value",
116
92
  "find_existing_asset",
117
- "iter_s3_objects",
118
93
  "list_assets",
119
94
  "normalize_asset_record",
120
95
  "reconcile_asset_usages",
@@ -1,6 +1,65 @@
1
- import boto3
1
+ import re
2
2
  from collections.abc import Mapping, Sequence
3
3
 
4
+ import boto3
5
+
6
+ # Extensions served as real files by the SPA rewrite; every other path is
7
+ # rewritten to the SPA. Anything NOT listed (and not passed as an extra) is
8
+ # invisible on the deployed site — e.g. a static .html page in public/.
9
+ # One canonical list: apps add to it via extra_extensions, never copy it.
10
+ SPA_STATIC_EXTENSIONS = (
11
+ "css",
12
+ "gif",
13
+ "html",
14
+ "ico",
15
+ "jpeg",
16
+ "jpg",
17
+ "js",
18
+ "json",
19
+ "map",
20
+ "otf",
21
+ "pdf",
22
+ "png",
23
+ "svg",
24
+ "ttf",
25
+ "txt",
26
+ "webp",
27
+ "woff",
28
+ "xml",
29
+ )
30
+
31
+ _EXTENSION_RE = re.compile(r"^[a-z0-9]+$")
32
+
33
+
34
+ def spa_static_extensions(extra_extensions: Sequence[str] = ()) -> tuple:
35
+ """``SPA_STATIC_EXTENSIONS`` plus ``extra_extensions`` (leading dots and
36
+ case ignored), de-duplicated, canonical entries first."""
37
+ if isinstance(extra_extensions, str):
38
+ extra_extensions = (extra_extensions,)
39
+ extensions = list(SPA_STATIC_EXTENSIONS)
40
+ for raw in extra_extensions:
41
+ ext = str(raw).strip().lstrip(".").lower()
42
+ if not _EXTENSION_RE.match(ext):
43
+ raise ValueError(f"invalid static file extension: {raw!r}")
44
+ if ext not in extensions:
45
+ extensions.append(ext)
46
+ return tuple(extensions)
47
+
48
+
49
+ def spa_custom_rules(extra_extensions: Sequence[str] = ()) -> list:
50
+ """Amplify customRules for a single-page app: 404s fall back to
51
+ /index.html, and every extension-less path or path whose extension is not
52
+ a served static type is rewritten to /."""
53
+ joined = "|".join(spa_static_extensions(extra_extensions))
54
+ return [
55
+ {"source": "/<*>", "target": "/index.html", "status": "404-200"},
56
+ {
57
+ "source": f"</^[^.]+$|\\.(?!({joined})$)([^.]+$)/>",
58
+ "target": "/",
59
+ "status": "200",
60
+ },
61
+ ]
62
+
4
63
 
5
64
  class AmplifyProject:
6
65
  def __init__(self, app_id: str):
@@ -108,41 +167,13 @@ class AmplifyProject:
108
167
  appId=self.app_id, environmentVariables=env_vars
109
168
  )
110
169
 
111
- def update_custom_redirect_rules(self):
112
- # Extensions served as real files; every other path is rewritten to the
113
- # SPA. Anything NOT listed here (including static .html pages in
114
- # public/) is invisible on the deployed site.
115
- srv_list = [
116
- "css",
117
- "gif",
118
- "html",
119
- "ico",
120
- "jpeg",
121
- "jpg",
122
- "js",
123
- "json",
124
- "map",
125
- "otf",
126
- "png",
127
- "svg",
128
- "ttf",
129
- "txt",
130
- "webp",
131
- "woff",
132
- "xml",
133
- "pdf",
134
- ]
135
- self.amplify_client.update_app(
136
- appId=self.app_id,
137
- customRules=[
138
- {"source": "/<*>", "target": "/index.html", "status": "404-200"},
139
- {
140
- "source": f'</^[^.]+$|\\.(?!({"|".join(srv_list)})$)([^.]+$)/>',
141
- "target": "/",
142
- "status": "200",
143
- },
144
- ],
145
- )
170
+ def update_custom_redirect_rules(self, extra_extensions: Sequence[str] = ()):
171
+ """Apply the canonical SPA rewrite rules (``spa_custom_rules``) to the
172
+ app, serving ``SPA_STATIC_EXTENSIONS`` plus ``extra_extensions`` as
173
+ real files. Returns the rules applied."""
174
+ rules = spa_custom_rules(extra_extensions)
175
+ self.amplify_client.update_app(appId=self.app_id, customRules=rules)
176
+ return rules
146
177
 
147
178
  def get_sqs_policy_template(
148
179
  self,