velocity-python 0.1.85__tar.gz → 0.1.87__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 (256) hide show
  1. {velocity_python-0.1.85/src/velocity_python.egg-info → velocity_python-0.1.87}/PKG-INFO +1 -1
  2. {velocity_python-0.1.85 → velocity_python-0.1.87}/pyproject.toml +1 -1
  3. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/__init__.py +1 -1
  4. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/__init__.py +11 -2
  5. velocity_python-0.1.87/src/velocity/aws/amplify.py +234 -0
  6. velocity_python-0.1.87/src/velocity/aws/amplify_build.py +160 -0
  7. velocity_python-0.1.87/src/velocity/aws/deploy/__init__.py +75 -0
  8. velocity_python-0.1.87/src/velocity/aws/deploy/config.py +65 -0
  9. velocity_python-0.1.87/src/velocity/aws/deploy/operations.py +742 -0
  10. velocity_python-0.1.87/src/velocity/aws/deploy/policies.py +303 -0
  11. velocity_python-0.1.87/src/velocity/aws/deploy/reconcile.py +220 -0
  12. velocity_python-0.1.87/src/velocity/aws/deploy/targets.py +189 -0
  13. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/mixins/data_service.py +36 -1
  14. velocity_python-0.1.87/src/velocity/aws/tests/test_amplify_build_policy_size.py +108 -0
  15. velocity_python-0.1.87/src/velocity/aws/tests/test_amplify_build_shim.py +65 -0
  16. velocity_python-0.1.87/src/velocity/aws/tests/test_deploy_policies.py +117 -0
  17. velocity_python-0.1.87/src/velocity/aws/tests/test_deploy_reconcile.py +198 -0
  18. {velocity_python-0.1.85 → velocity_python-0.1.87/src/velocity_python.egg-info}/PKG-INFO +1 -1
  19. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity_python.egg-info/SOURCES.txt +11 -0
  20. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_amplify_build.py +40 -51
  21. velocity_python-0.1.87/tests/test_delete_hook_fk_blocked.py +154 -0
  22. velocity_python-0.1.85/src/velocity/aws/amplify.py +0 -478
  23. velocity_python-0.1.85/src/velocity/aws/amplify_build.py +0 -761
  24. {velocity_python-0.1.85 → velocity_python-0.1.87}/LICENSE +0 -0
  25. {velocity_python-0.1.85 → velocity_python-0.1.87}/README.md +0 -0
  26. {velocity_python-0.1.85 → velocity_python-0.1.87}/setup.cfg +0 -0
  27. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/assets/__init__.py +0 -0
  28. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/assets/backfill.py +0 -0
  29. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/assets/indexing.py +0 -0
  30. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/assets/references.py +0 -0
  31. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/assets/service.py +0 -0
  32. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/assets/usage_index.py +0 -0
  33. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/dirty_pipeline.py +0 -0
  34. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/__init__.py +0 -0
  35. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/base_handler.py +0 -0
  36. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/context.py +0 -0
  37. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/context_factory.py +0 -0
  38. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/exceptions.py +0 -0
  39. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/lambda_handler.py +0 -0
  40. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/masquerade.py +0 -0
  41. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/mixins/__init__.py +0 -0
  42. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/mixins/web_handler.py +0 -0
  43. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/perf.py +0 -0
  44. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/response.py +0 -0
  45. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/handlers/sqs_handler.py +0 -0
  46. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/s3.py +0 -0
  47. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/ssm_config.py +0 -0
  48. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/tests/__init__.py +0 -0
  49. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
  50. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
  51. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/aws/tests/test_response.py +0 -0
  52. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/__init__.py +0 -0
  53. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/__init__.py +0 -0
  54. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/async_support.py +0 -0
  55. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/column.py +0 -0
  56. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/database.py +0 -0
  57. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/decorators.py +0 -0
  58. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/engine.py +0 -0
  59. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/jsonproxy.py +0 -0
  60. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/result.py +0 -0
  61. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/row.py +0 -0
  62. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/sequence.py +0 -0
  63. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/table.py +0 -0
  64. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/transaction.py +0 -0
  65. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/core/view.py +0 -0
  66. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/exceptions.py +0 -0
  67. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/maintenance.py +0 -0
  68. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/migrations.py +0 -0
  69. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/__init__.py +0 -0
  70. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/base/__init__.py +0 -0
  71. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/base/initializer.py +0 -0
  72. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/base/operators.py +0 -0
  73. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/base/sql.py +0 -0
  74. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/base/types.py +0 -0
  75. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/mysql/__init__.py +0 -0
  76. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/mysql/operators.py +0 -0
  77. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/mysql/reserved.py +0 -0
  78. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/mysql/sql.py +0 -0
  79. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/mysql/types.py +0 -0
  80. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/postgres/__init__.py +0 -0
  81. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/postgres/operators.py +0 -0
  82. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/postgres/reserved.py +0 -0
  83. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/postgres/sql.py +0 -0
  84. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/postgres/types.py +0 -0
  85. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlite/__init__.py +0 -0
  86. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlite/operators.py +0 -0
  87. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlite/reserved.py +0 -0
  88. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlite/sql.py +0 -0
  89. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlite/types.py +0 -0
  90. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
  91. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlserver/operators.py +0 -0
  92. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
  93. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlserver/sql.py +0 -0
  94. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/sqlserver/types.py +0 -0
  95. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/servers/tablehelper.py +0 -0
  96. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/__init__.py +0 -0
  97. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/common_db_test.py +0 -0
  98. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/__init__.py +0 -0
  99. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/common.py +0 -0
  100. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/conftest.py +0 -0
  101. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_column.py +0 -0
  102. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_connections.py +0 -0
  103. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_database.py +0 -0
  104. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_engine.py +0 -0
  105. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
  106. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_imports.py +0 -0
  107. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_result.py +0 -0
  108. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_row.py +0 -0
  109. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
  110. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
  111. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
  112. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
  113. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
  114. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_table.py +0 -0
  115. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
  116. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
  117. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/sql/__init__.py +0 -0
  118. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/sql/common.py +0 -0
  119. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
  120. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
  121. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
  122. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_db_utils.py +0 -0
  123. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_postgres.py +0 -0
  124. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
  125. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
  126. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_result_caching.py +0 -0
  127. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
  128. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
  129. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
  130. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
  131. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_sql_builder.py +0 -0
  132. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_tablehelper.py +0 -0
  133. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/tests/test_view_helper.py +0 -0
  134. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/db/utils.py +0 -0
  135. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/logging.py +0 -0
  136. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/__init__.py +0 -0
  137. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/conv/__init__.py +0 -0
  138. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/conv/iconv.py +0 -0
  139. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/conv/oconv.py +0 -0
  140. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/db.py +0 -0
  141. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/export.py +0 -0
  142. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/format.py +0 -0
  143. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/mail.py +0 -0
  144. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/merge.py +0 -0
  145. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/pdf.py +0 -0
  146. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/__init__.py +0 -0
  147. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_db.py +0 -0
  148. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_fix.py +0 -0
  149. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_format.py +0 -0
  150. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_iconv.py +0 -0
  151. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_merge.py +0 -0
  152. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_oconv.py +0 -0
  153. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_original_error.py +0 -0
  154. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tests/test_timer.py +0 -0
  155. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/timer.py +0 -0
  156. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/misc/tools.py +0 -0
  157. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/__init__.py +0 -0
  158. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/core/__init__.py +0 -0
  159. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/core/capabilities.py +0 -0
  160. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/core/store.py +0 -0
  161. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/core/where.py +0 -0
  162. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/exceptions.py +0 -0
  163. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/__init__.py +0 -0
  164. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/base/__init__.py +0 -0
  165. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/cassandra/__init__.py +0 -0
  166. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/cassandra/translation.py +0 -0
  167. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/couchbase/__init__.py +0 -0
  168. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/couchbase/translation.py +0 -0
  169. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/dynamodb/__init__.py +0 -0
  170. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/dynamodb/translation.py +0 -0
  171. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/elasticsearch/__init__.py +0 -0
  172. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/elasticsearch/translation.py +0 -0
  173. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/memory/__init__.py +0 -0
  174. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/mongodb/__init__.py +0 -0
  175. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/mongodb/translation.py +0 -0
  176. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/nosql/servers/redis/__init__.py +0 -0
  177. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/__init__.py +0 -0
  178. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/authorizenet_adapter.py +0 -0
  179. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/authorizenet_mirror.py +0 -0
  180. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/base_adapter.py +0 -0
  181. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/braintree_adapter.py +0 -0
  182. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/braintree_mirror.py +0 -0
  183. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/charge_rules.py +0 -0
  184. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/stripe_adapter.py +0 -0
  185. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity/payment/stripe_mirror.py +0 -0
  186. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity_python.egg-info/dependency_links.txt +0 -0
  187. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity_python.egg-info/entry_points.txt +0 -0
  188. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity_python.egg-info/requires.txt +0 -0
  189. {velocity_python-0.1.85 → velocity_python-0.1.87}/src/velocity_python.egg-info/top_level.txt +0 -0
  190. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_activity_tracking_aborted_tx.py +0 -0
  191. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_asset_indexing.py +0 -0
  192. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_asset_references.py +0 -0
  193. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_assets_service.py +0 -0
  194. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_async_support.py +0 -0
  195. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_batch_operations.py +0 -0
  196. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_column_tx_arg.py +0 -0
  197. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_concurrency_safety.py +0 -0
  198. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_connection_pool.py +0 -0
  199. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_connection_resilience.py +0 -0
  200. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_context_job_descriptions.py +0 -0
  201. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_db_credentials_ssm_cascade.py +0 -0
  202. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_db_maintenance.py +0 -0
  203. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_decorators.py +0 -0
  204. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_dirty_pipeline_fast_path.py +0 -0
  205. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_email_processing.py +0 -0
  206. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_enqueue_send_failures.py +0 -0
  207. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_get_cognito_user_provider.py +0 -0
  208. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_http_handler_rollback.py +0 -0
  209. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_iconv_money_to_cents.py +0 -0
  210. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_identifier_injection_guard.py +0 -0
  211. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_json_columns.py +0 -0
  212. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_jsonb_dict_adapter.py +0 -0
  213. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_lambda_handler.py +0 -0
  214. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_lambda_handler_auth.py +0 -0
  215. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_lambda_handler_masquerade.py +0 -0
  216. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_masquerade_grant.py +0 -0
  217. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_mixins_import.py +0 -0
  218. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_n_plus_one.py +0 -0
  219. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_nosql_dynamodb.py +0 -0
  220. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_nosql_memory.py +0 -0
  221. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_nosql_mongodb.py +0 -0
  222. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_nosql_redis.py +0 -0
  223. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_nosql_translation.py +0 -0
  224. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_nosql_where.py +0 -0
  225. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_observability.py +0 -0
  226. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_payment_authorizenet_adapter.py +0 -0
  227. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_payment_braintree_adapter.py +0 -0
  228. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_payment_braintree_mirror.py +0 -0
  229. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_payment_mirror_empty_table.py +0 -0
  230. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_payment_profile_sorting.py +0 -0
  231. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_payment_stripe_adapter.py +0 -0
  232. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_pdf.py +0 -0
  233. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_prepared_statements.py +0 -0
  234. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_psycopg3_upgrade.py +0 -0
  235. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_query_cache.py +0 -0
  236. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_restricted_direct_tables.py +0 -0
  237. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_retry_side_effect_guard.py +0 -0
  238. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_return_default_safety.py +0 -0
  239. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_row_batch_update.py +0 -0
  240. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_row_cache_staleness.py +0 -0
  241. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_schema_migrations.py +0 -0
  242. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_security_hardening.py +0 -0
  243. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_server_cursor.py +0 -0
  244. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_single_autocommit_safety.py +0 -0
  245. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_spreadsheet_functions.py +0 -0
  246. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_sqlite_backend.py +0 -0
  247. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_sqs_per_record_transactions.py +0 -0
  248. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_ssm_config.py +0 -0
  249. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_store_user_data.py +0 -0
  250. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_sys_modified_count_postgres_demo.py +0 -0
  251. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_table_alter.py +0 -0
  252. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_transaction_class_wrapping.py +0 -0
  253. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_transaction_commit_and_ownership.py +0 -0
  254. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_transaction_edge_cases.py +0 -0
  255. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_where_clause_validation.py +0 -0
  256. {velocity_python-0.1.85 → velocity_python-0.1.87}/tests/test_write_hook_create_flow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.1.85
3
+ Version: 0.1.87
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "velocity-python"
7
- version = "0.1.85"
7
+ version = "0.1.87"
8
8
  authors = [
9
9
  { name="Velocity Team", email="info@codeclubs.org" },
10
10
  ]
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.1.85"
1
+ __version__ = version = "0.1.87"
2
2
 
3
3
  import importlib as _importlib
4
4
 
@@ -23,12 +23,18 @@ class AWS(object):
23
23
  # Lazy-load heavy modules (boto3-dependent) on first access
24
24
  _LAZY_ATTRS = {
25
25
  "AmplifyProject": "velocity.aws.amplify",
26
+ # Legacy deployment API (shim over velocity.aws.deploy; legacy-union
27
+ # policy mode). New projects: import from velocity.aws.deploy directly.
26
28
  "BackendDeploymentConfig": "velocity.aws.amplify_build",
27
- "build_environment_variables": "velocity.aws.amplify_build",
28
29
  "get_amplify_app_id_and_branch": "velocity.aws.amplify_build",
29
30
  "initialize_build_environment": "velocity.aws.amplify_build",
30
31
  "run_backend_deployment": "velocity.aws.amplify_build",
31
32
  "update_lambda_layers_to_latest": "velocity.aws.amplify_build",
33
+ # Platform-neutral deployment API
34
+ "AmplifyTarget": "velocity.aws.deploy",
35
+ "DeploymentConfig": "velocity.aws.deploy",
36
+ "PlainTarget": "velocity.aws.deploy",
37
+ "run_deployment": "velocity.aws.deploy",
32
38
  # S3 utilities
33
39
  "generate_presigned_get": "velocity.aws.s3",
34
40
  "generate_presigned_put": "velocity.aws.s3",
@@ -71,12 +77,15 @@ def __getattr__(name: str):
71
77
 
72
78
  __all__ = [
73
79
  "AmplifyProject",
80
+ "AmplifyTarget",
74
81
  "AWS",
75
82
  "BackendDeploymentConfig",
76
- "build_environment_variables",
83
+ "DeploymentConfig",
84
+ "PlainTarget",
77
85
  "get_amplify_app_id_and_branch",
78
86
  "initialize_build_environment",
79
87
  "run_backend_deployment",
88
+ "run_deployment",
80
89
  "update_lambda_layers_to_latest",
81
90
  # S3 utilities
82
91
  "generate_presigned_get",
@@ -0,0 +1,234 @@
1
+ import boto3
2
+ import time
3
+ from collections.abc import Mapping, Sequence
4
+
5
+
6
+ class AmplifyProject:
7
+ def __init__(self, app_id: str):
8
+ self.app_id = app_id
9
+ self.amplify_client = boto3.client("amplify")
10
+ self.lambda_client = boto3.client("lambda")
11
+ self.sqs_client = boto3.client("sqs")
12
+ self.sqs_resource = boto3.resource("sqs")
13
+
14
+ # Verify app exists
15
+ try:
16
+ response = self.amplify_client.get_app(appId=self.app_id)
17
+ self.app_name = response["app"]["name"]
18
+ except self.amplify_client.exceptions.NotFoundException:
19
+ raise ValueError(f"Amplify app with ID '{self.app_id}' does not exist.")
20
+
21
+ def get_app_name(self):
22
+ return self.app_name
23
+
24
+ def get_region(self):
25
+ return self.amplify_client.meta.region_name
26
+
27
+ def get_account_id(self):
28
+ sts_client = boto3.client("sts")
29
+ return sts_client.get_caller_identity()["Account"]
30
+
31
+ def list_backend_branches(self):
32
+ branches = []
33
+ paginator = self.amplify_client.get_paginator("list_branches")
34
+ for page in paginator.paginate(appId=self.app_id):
35
+ for branch in page.get("branches", []):
36
+ branches.append(branch["branchName"])
37
+ return branches
38
+
39
+ def filtered_env_vars(self, raw_env_vars):
40
+ return {k: v for k, v in raw_env_vars.items() if not k.startswith("_")}
41
+
42
+ def get_merged_env_vars(self, branch):
43
+ all_vars = {}
44
+
45
+ # Global env vars
46
+ app_response = self.amplify_client.get_app(appId=self.app_id)
47
+ global_vars = self.filtered_env_vars(
48
+ app_response["app"].get("environmentVariables", {})
49
+ )
50
+ # print("📦 Global env vars (All branches):")
51
+ # for k, v in global_vars.items():
52
+ # print(f" {k}: {v}")
53
+ all_vars.update(global_vars)
54
+
55
+ # Branch-specific vars
56
+ try:
57
+ branch_response = self.amplify_client.get_branch(
58
+ appId=self.app_id, branchName=branch
59
+ )
60
+ branch_vars = self.filtered_env_vars(
61
+ branch_response["branch"].get("environmentVariables", {})
62
+ )
63
+ # print(f"🌿 Branch-specific env vars for '{branch}':")
64
+ # for k, v in branch_vars.items():
65
+ # print(f" {k}: {v}")
66
+ all_vars.update(branch_vars)
67
+ except self.amplify_client.exceptions.BadRequestException:
68
+ print(f"⚠️ Branch '{branch}' not found. Skipping branch-level overrides.")
69
+
70
+ return all_vars
71
+
72
+ def list_lambda_functions_filtered(self, env_name):
73
+ """
74
+ List Lambda functions that belong to this Amplify app and environment.
75
+ Filters by user:Application tag, checking both exact app name and sanitized version.
76
+ """
77
+ from velocity.aws.deploy.operations import list_functions_by_tag
78
+
79
+ return list_functions_by_tag(
80
+ self.lambda_client, app_name=self.app_name, stage=env_name
81
+ )
82
+
83
+ def update_lambda_function(
84
+ self,
85
+ function_name,
86
+ **kwargs,
87
+ ):
88
+ from velocity.aws.deploy.operations import update_lambda_function_config
89
+
90
+ return update_lambda_function_config(
91
+ self.lambda_client, function_name, **kwargs
92
+ )
93
+
94
+ def set_environment_variable(self, key: str, value: str, branch: str = None):
95
+ if branch:
96
+ response = self.amplify_client.get_branch(
97
+ appId=self.app_id, branchName=branch
98
+ )
99
+ env_vars = response["branch"].get("environmentVariables", {})
100
+ env_vars[key] = value
101
+ self.amplify_client.update_branch(
102
+ appId=self.app_id, branchName=branch, environmentVariables=env_vars
103
+ )
104
+ else:
105
+ response = self.amplify_client.get_app(appId=self.app_id)
106
+ env_vars = response["app"].get("environmentVariables", {})
107
+ env_vars[key] = value
108
+ self.amplify_client.update_app(
109
+ appId=self.app_id, environmentVariables=env_vars
110
+ )
111
+
112
+ def update_custom_redirect_rules(self):
113
+ # Extensions served as real files; every other path is rewritten to the
114
+ # SPA. Anything NOT listed here (including static .html pages in
115
+ # public/) is invisible on the deployed site.
116
+ srv_list = [
117
+ "css",
118
+ "gif",
119
+ "html",
120
+ "ico",
121
+ "jpeg",
122
+ "jpg",
123
+ "js",
124
+ "json",
125
+ "map",
126
+ "otf",
127
+ "png",
128
+ "svg",
129
+ "ttf",
130
+ "txt",
131
+ "webp",
132
+ "woff",
133
+ "xml",
134
+ "pdf",
135
+ ]
136
+ self.amplify_client.update_app(
137
+ appId=self.app_id,
138
+ customRules=[
139
+ {"source": "/<*>", "target": "/index.html", "status": "404-200"},
140
+ {
141
+ "source": f'</^[^.]+$|\\.(?!({"|".join(srv_list)})$)([^.]+$)/>',
142
+ "target": "/",
143
+ "status": "200",
144
+ },
145
+ ],
146
+ )
147
+
148
+ def get_sqs_policy_template(
149
+ self,
150
+ queue_name: str,
151
+ queue_producers: Sequence[Mapping[str, str]],
152
+ queue_handler: Mapping[str, str],
153
+ ) -> str:
154
+ from velocity.aws.deploy.operations import build_sqs_queue_policy
155
+
156
+ return build_sqs_queue_policy(
157
+ self.get_account_id(),
158
+ self.get_region(),
159
+ queue_name,
160
+ queue_producers,
161
+ queue_handler,
162
+ )
163
+
164
+ def get_lambda_vpc_policy_template(self):
165
+ from velocity.aws.deploy.policies import baseline_lambda_policy_document
166
+
167
+ return baseline_lambda_policy_document(self.get_account_id())
168
+
169
+ def setup_sqs_queue_and_permissions(
170
+ self,
171
+ branch: str,
172
+ queue_name: str,
173
+ queue_producers: Sequence[Mapping[str, str]],
174
+ queue_handler: Mapping[str, str],
175
+ use_reserved_concurrency: bool = True,
176
+ ) -> None:
177
+ from velocity.aws.deploy.operations import setup_sqs_queue_and_permissions
178
+
179
+ setup_sqs_queue_and_permissions(
180
+ account_id=self.get_account_id(),
181
+ region=self.get_region(),
182
+ stage=branch,
183
+ queue_name=queue_name,
184
+ queue_producers=queue_producers,
185
+ queue_handler=queue_handler,
186
+ use_reserved_concurrency=use_reserved_concurrency,
187
+ sqs_client=self.sqs_client,
188
+ sqs_resource=self.sqs_resource,
189
+ lambda_client=self.lambda_client,
190
+ )
191
+
192
+ def check_policies(self, function):
193
+ # Attach a role policy
194
+ iam_client = boto3.client("iam")
195
+ response = iam_client.list_attached_role_policies(
196
+ RoleName=function["Role"].split("/")[1]
197
+ )
198
+ has_policy_attached = False
199
+ for policy in response["AttachedPolicies"]:
200
+ if policy["PolicyName"] == "lambda-vpc-execution":
201
+ has_policy_attached = True
202
+ if not has_policy_attached:
203
+ account_id = self.get_account_id()
204
+ iam_client.attach_role_policy(
205
+ PolicyArn=f"arn:aws:iam::{account_id}:policy/lambda-vpc-execution",
206
+ RoleName=function["Role"].split("/")[1],
207
+ )
208
+ time.sleep(15)
209
+ has_policy_attached = False
210
+ for policy in response["AttachedPolicies"]:
211
+ if policy["PolicyName"] == "AmazonSQSFullAccess":
212
+ has_policy_attached = True
213
+ if not has_policy_attached:
214
+ iam_client.attach_role_policy(
215
+ PolicyArn="arn:aws:iam::aws:policy/AmazonSQSFullAccess",
216
+ RoleName=function["Role"].split("/")[1],
217
+ )
218
+
219
+ def sync(self, branch):
220
+ raise RuntimeError(
221
+ "AmplifyProject.sync() is retired. Lambda environment variables are no "
222
+ "longer copied from Amplify configuration. Use SSM-backed runtime "
223
+ "configuration instead."
224
+ )
225
+
226
+
227
+ def main():
228
+ app_id = "d3c209q3ri53mk"
229
+ app = AmplifyProject(app_id)
230
+ print(app.list_backend_branches())
231
+
232
+
233
+ if __name__ == "__main__":
234
+ main()
@@ -0,0 +1,160 @@
1
+ """Backwards-compatibility shim over velocity.aws.deploy.
2
+
3
+ The deployment engine moved to the platform-neutral velocity.aws.deploy
4
+ package (config / targets / policies / operations / reconcile). This module
5
+ keeps every name and signature the existing project build.py files import,
6
+ with pre-refactor behavior:
7
+
8
+ - run_backend_deployment() runs in "legacy-union" policy mode (config extras
9
+ unioned into the shared lambda-vpc-execution policy). Projects migrated to
10
+ velocity.aws.deploy.run_deployment() get per-app reconciled policies.
11
+
12
+ New projects should import from velocity.aws.deploy directly.
13
+ """
14
+
15
+ import time
16
+ from pathlib import Path
17
+ from typing import Optional, Sequence, Union
18
+
19
+ import boto3
20
+
21
+ from velocity.aws.amplify import AmplifyProject
22
+ from velocity.aws.deploy.config import BackendDeploymentConfig, DeploymentConfig
23
+ from velocity.aws.deploy.policies import (
24
+ IAM_MANAGED_POLICY_MAX_CHARS,
25
+ ManagedPolicySizeError,
26
+ _canonical_statement,
27
+ _ensure_policy_document_size,
28
+ _merge_policy_statements,
29
+ _normalize_policy_document,
30
+ _policy_document_char_count,
31
+ _serialize_policy_document,
32
+ attach_role_policies,
33
+ baseline_lambda_policy_document,
34
+ sync_managed_policy_document,
35
+ )
36
+ from velocity.aws.deploy.operations import (
37
+ THROTTLE_ERROR_CODES,
38
+ ensure_cloudwatch_log_group,
39
+ resolve_latest_layer_arns,
40
+ retryable_call,
41
+ )
42
+ from velocity.aws.deploy.operations import (
43
+ set_cloudwatch_logging as _set_cloudwatch_logging_op,
44
+ )
45
+ from velocity.aws.deploy.reconcile import AWS_SQS_FULL_ACCESS_ARN, run_deployment
46
+ from velocity.aws.deploy.reconcile import (
47
+ update_lambda_layers_to_latest as _update_layers_new,
48
+ )
49
+ from velocity.aws.deploy.targets import (
50
+ ANSI_ESCAPE_RE,
51
+ get_amplify_app_id_and_branch,
52
+ initialize_build_environment,
53
+ )
54
+
55
+ # Legacy private alias kept for any direct importers.
56
+ _sync_managed_policy_document = sync_managed_policy_document
57
+
58
+
59
+ class _AmplifyProjectTarget:
60
+ """Adapts a legacy AmplifyProject (+ branch) to the DeployTarget shape."""
61
+
62
+ def __init__(self, app: AmplifyProject, branch: str):
63
+ self._app = app
64
+ self.app_name = app.app_name
65
+ self.stage = branch
66
+
67
+ def account_id(self) -> str:
68
+ return self._app.get_account_id()
69
+
70
+ def region(self) -> str:
71
+ return self._app.get_region()
72
+
73
+ def list_functions(self):
74
+ return self._app.list_lambda_functions_filtered(self.stage)
75
+
76
+
77
+ def ensure_lambda_policies_and_attach(
78
+ app: AmplifyProject,
79
+ function,
80
+ config: Optional[DeploymentConfig] = None,
81
+ iam_client=None,
82
+ ) -> None:
83
+ """Legacy per-function policy ensure: union document into the shared
84
+ lambda-vpc-execution policy, then attach it + AmazonSQSFullAccess."""
85
+ if iam_client is None:
86
+ iam_client = boto3.client("iam")
87
+
88
+ account_id = app.get_account_id()
89
+ policy_arn = f"arn:aws:iam::{account_id}:policy/lambda-vpc-execution"
90
+ policy_document = baseline_lambda_policy_document(account_id)
91
+ if config is not None:
92
+ policy_document = config.build_lambda_policy_document(policy_document)
93
+
94
+ try:
95
+ retryable_call(iam_client.get_policy, PolicyArn=policy_arn)
96
+ except iam_client.exceptions.NoSuchEntityException:
97
+ _ensure_policy_document_size("lambda-vpc-execution", policy_document)
98
+ print("Creating policy lambda-vpc-execution")
99
+ retryable_call(
100
+ iam_client.create_policy,
101
+ PolicyName="lambda-vpc-execution",
102
+ PolicyDocument=_serialize_policy_document(policy_document),
103
+ )
104
+ time.sleep(10)
105
+ else:
106
+ sync_managed_policy_document(iam_client, policy_arn, policy_document)
107
+
108
+ role_name = function["Role"].split("/")[-1]
109
+ attach_role_policies(iam_client, role_name, [policy_arn, AWS_SQS_FULL_ACCESS_ARN])
110
+
111
+
112
+ def set_cloudwatch_logging(
113
+ app: AmplifyProject,
114
+ function,
115
+ branch: str,
116
+ lambda_client=None,
117
+ logs_client=None,
118
+ ) -> bool:
119
+ return _set_cloudwatch_logging_op(
120
+ account_id=app.get_account_id(),
121
+ region=app.get_region(),
122
+ function=function,
123
+ stage=branch,
124
+ lambda_client=lambda_client,
125
+ logs_client=logs_client,
126
+ )
127
+
128
+
129
+ def run_backend_deployment(
130
+ app_id: str,
131
+ branch: str,
132
+ config: DeploymentConfig,
133
+ project_root: Union[str, Path] = ".",
134
+ app: Optional[AmplifyProject] = None,
135
+ lambda_client=None,
136
+ logs_client=None,
137
+ ) -> None:
138
+ if app is None:
139
+ app = AmplifyProject(app_id)
140
+ target = _AmplifyProjectTarget(app, branch)
141
+ run_deployment(
142
+ target,
143
+ config,
144
+ policy_mode="legacy-union",
145
+ lambda_client=lambda_client,
146
+ logs_client=logs_client,
147
+ )
148
+
149
+
150
+ def update_lambda_layers_to_latest(
151
+ app_id: str,
152
+ branch: str,
153
+ function_names: Optional[Sequence[str]] = None,
154
+ app: Optional[AmplifyProject] = None,
155
+ lambda_client=None,
156
+ ) -> None:
157
+ if app is None:
158
+ app = AmplifyProject(app_id)
159
+ target = _AmplifyProjectTarget(app, branch)
160
+ _update_layers_new(target, function_names=function_names, lambda_client=lambda_client)
@@ -0,0 +1,75 @@
1
+ """velocity.aws.deploy — platform-neutral backend deployment.
2
+
3
+ Public API:
4
+
5
+ from velocity.aws.deploy import (
6
+ DeploymentConfig, AmplifyTarget, PlainTarget,
7
+ run_deployment, update_lambda_layers_to_latest,
8
+ initialize_build_environment, get_amplify_app_id_and_branch,
9
+ )
10
+
11
+ target = AmplifyTarget(PROJECT_ROOT) # existing Amplify apps
12
+ target = PlainTarget("MyApp", stage="demo") # no Amplify anywhere
13
+ run_deployment(target, config)
14
+
15
+ See docs/deploy.md in the velocity-python repo.
16
+ """
17
+
18
+ from velocity.aws.deploy.config import BackendDeploymentConfig, DeploymentConfig
19
+ from velocity.aws.deploy.policies import (
20
+ IAM_MANAGED_POLICY_MAX_CHARS,
21
+ ManagedPolicySizeError,
22
+ app_policy_name,
23
+ baseline_lambda_policy_document,
24
+ ensure_app_policy,
25
+ sync_managed_policy_document,
26
+ )
27
+ from velocity.aws.deploy.operations import (
28
+ ensure_api_cors_header,
29
+ ensure_cloudwatch_log_group,
30
+ ensure_dlq,
31
+ ensure_identity_pool_developer_provider,
32
+ list_functions_by_tag,
33
+ resolve_latest_layer_arns,
34
+ retryable_call,
35
+ set_cloudwatch_logging,
36
+ setup_sqs_queue_and_permissions,
37
+ update_lambda_function_config,
38
+ )
39
+ from velocity.aws.deploy.targets import (
40
+ AmplifyTarget,
41
+ PlainTarget,
42
+ get_amplify_app_id_and_branch,
43
+ initialize_build_environment,
44
+ )
45
+ from velocity.aws.deploy.reconcile import (
46
+ run_deployment,
47
+ update_lambda_layers_to_latest,
48
+ )
49
+
50
+ __all__ = [
51
+ "AmplifyTarget",
52
+ "BackendDeploymentConfig",
53
+ "DeploymentConfig",
54
+ "IAM_MANAGED_POLICY_MAX_CHARS",
55
+ "ManagedPolicySizeError",
56
+ "PlainTarget",
57
+ "app_policy_name",
58
+ "baseline_lambda_policy_document",
59
+ "ensure_api_cors_header",
60
+ "ensure_app_policy",
61
+ "ensure_cloudwatch_log_group",
62
+ "ensure_dlq",
63
+ "ensure_identity_pool_developer_provider",
64
+ "get_amplify_app_id_and_branch",
65
+ "initialize_build_environment",
66
+ "list_functions_by_tag",
67
+ "resolve_latest_layer_arns",
68
+ "retryable_call",
69
+ "run_deployment",
70
+ "set_cloudwatch_logging",
71
+ "setup_sqs_queue_and_permissions",
72
+ "sync_managed_policy_document",
73
+ "update_lambda_function_config",
74
+ "update_lambda_layers_to_latest",
75
+ ]
@@ -0,0 +1,65 @@
1
+ """Declarative deployment configuration for velocity.aws.deploy.
2
+
3
+ DeploymentConfig describes everything a project's backend deployment needs:
4
+ queue naming, VPC placement, per-function timeout/memory overrides, and the
5
+ project's IAM policy statements. It is platform-neutral — nothing here assumes
6
+ Amplify.
7
+ """
8
+
9
+ from dataclasses import dataclass, field
10
+ from typing import Any, Dict, Mapping, Optional, Sequence, Tuple
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class DeploymentConfig:
15
+ queue_name_template: str
16
+ subnet_ids: Tuple[str, ...] = field(default_factory=tuple)
17
+ security_group_ids: Tuple[str, ...] = field(default_factory=tuple)
18
+ short_timeout_seconds: int = 60
19
+ default_timeout_seconds: int = 900
20
+ short_timeout_tokens: Tuple[str, ...] = (
21
+ "Events",
22
+ "Data",
23
+ "Public",
24
+ "WebHooks",
25
+ )
26
+ memory_size_by_token: Mapping[str, int] = field(default_factory=dict)
27
+ extra_lambda_policy_statements: Tuple[Mapping[str, Any], ...] = field(
28
+ default_factory=tuple
29
+ )
30
+ use_reserved_concurrency: bool = True
31
+
32
+ def resolve_queue_name(self, stage: str) -> str:
33
+ return self.queue_name_template.format(branch=stage.lower(), raw_branch=stage)
34
+
35
+ def resolve_timeout(self, function_name: str) -> int:
36
+ if any(token in function_name for token in self.short_timeout_tokens):
37
+ return self.short_timeout_seconds
38
+ return self.default_timeout_seconds
39
+
40
+ def resolve_memory_size(self, function_name: str) -> Optional[int]:
41
+ for token, memory_size in self.memory_size_by_token.items():
42
+ if token in function_name:
43
+ return memory_size
44
+ return None
45
+
46
+ def build_lambda_policy_document(
47
+ self, base_policy_document: Mapping[str, Any]
48
+ ) -> Dict[str, Any]:
49
+ """Legacy helper: base document + this config's extra statements.
50
+
51
+ Used only by the legacy shared-union policy mode (velocity.aws
52
+ amplify_build shim). The per-app policy mode reads
53
+ extra_lambda_policy_statements directly.
54
+ """
55
+ policy_document = dict(base_policy_document)
56
+ statements = list(policy_document.get("Statement", []))
57
+ statements.extend(
58
+ dict(statement) for statement in self.extra_lambda_policy_statements
59
+ )
60
+ policy_document["Statement"] = statements
61
+ return policy_document
62
+
63
+
64
+ # Backwards-compatible name used by existing build.py files.
65
+ BackendDeploymentConfig = DeploymentConfig