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.
- {velocity_python-0.1.129 → velocity_python-0.1.133}/PKG-INFO +73 -32
- {velocity_python-0.1.129 → velocity_python-0.1.133}/README.md +66 -27
- {velocity_python-0.1.129 → velocity_python-0.1.133}/pyproject.toml +15 -7
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/__init__.py +1 -1
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/__init__.py +11 -36
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/amplify.py +67 -36
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/__init__.py +6 -2
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/backfill.py +3 -16
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/indexing.py +40 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/service.py +30 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/dispatch.py +2 -2
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/provisioning.py +37 -4
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/security.py +2 -2
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/__init__.py +44 -3
- velocity_python-0.1.133/src/velocity/aws/deploy/ci_gate.py +660 -0
- velocity_python-0.1.133/src/velocity/aws/deploy/config.py +374 -0
- velocity_python-0.1.133/src/velocity/aws/deploy/frontend_checks.py +200 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/operations.py +205 -20
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/policies.py +74 -1
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/reconcile.py +249 -12
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/dirty_pipeline.py +6 -1
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/failures.py +258 -28
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/feature_flags.py +4 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/base_handler.py +22 -18
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/exceptions.py +17 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/lambda_handler.py +49 -1
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/__init__.py +10 -0
- velocity_python-0.1.133/src/velocity/aws/handlers/mixins/client_errors.py +425 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/client_input.py +51 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/data_service.py +242 -86
- velocity_python-0.1.133/src/velocity/aws/handlers/mixins/row_scoped.py +287 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/session_control.py +26 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/web_handler.py +84 -1
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/sqs_handler.py +7 -2
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/job_lifecycle.py +25 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/job_results.py +10 -0
- velocity_python-0.1.133/src/velocity/aws/queue_defaults.py +13 -0
- velocity_python-0.1.133/src/velocity/aws/s3.py +777 -0
- velocity_python-0.1.133/src/velocity/aws/schema.py +124 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/ssm_config.py +35 -0
- 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
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/table.py +203 -6
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/migrations.py +14 -8
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/initializer.py +26 -1
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/types.py +93 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/__init__.py +82 -7
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/types.py +93 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/types.py +90 -0
- velocity_python-0.1.133/src/velocity/db/servers/sqlserver/types.py +209 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tunnel.py +5 -2
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/conv/iconv.py +42 -17
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/dynamodb/__init__.py +4 -1
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/__init__.py +9 -2
- velocity_python-0.1.133/src/velocity/payment/_mirror_core.py +162 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/authorizenet_adapter.py +22 -22
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/authorizenet_mirror.py +10 -14
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/braintree_adapter.py +49 -29
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/braintree_mirror.py +11 -20
- velocity_python-0.1.133/src/velocity/payment/plaid_webhook.py +361 -0
- velocity_python-0.1.133/src/velocity/payment/schema.py +253 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/stripe_adapter.py +18 -23
- velocity_python-0.1.133/src/velocity/payment/stripe_mirror.py +303 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/PKG-INFO +73 -32
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/SOURCES.txt +34 -4
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/requires.txt +6 -1
- velocity_python-0.1.133/tests/test_amplify_redirects.py +84 -0
- velocity_python-0.1.133/tests/test_aws_package_hygiene.py +223 -0
- velocity_python-0.1.133/tests/test_ci_gate.py +772 -0
- velocity_python-0.1.133/tests/test_client_errors_mixin.py +588 -0
- velocity_python-0.1.133/tests/test_client_input_contract_export.py +109 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_connection_resilience.py +12 -3
- velocity_python-0.1.133/tests/test_data_service_row_number.py +435 -0
- velocity_python-0.1.133/tests/test_declared_column_types.py +481 -0
- velocity_python-0.1.133/tests/test_deploy_config_fields.py +650 -0
- velocity_python-0.1.129/tests/test_amplify_build.py → velocity_python-0.1.133/tests/test_deploy_engine.py +34 -37
- velocity_python-0.1.133/tests/test_deploy_frontend_checks.py +163 -0
- velocity_python-0.1.133/tests/test_deploy_operations_queue.py +217 -0
- velocity_python-0.1.133/tests/test_dlq_constant.py +35 -0
- velocity_python-0.1.133/tests/test_docs_snippets.py +175 -0
- velocity_python-0.1.133/tests/test_ensure_infrastructure.py +596 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_failures.py +168 -0
- velocity_python-0.1.133/tests/test_iconv_money_to_cents.py +113 -0
- velocity_python-0.1.133/tests/test_mirror_upsert_public.py +252 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_dynamodb.py +16 -0
- velocity_python-0.1.133/tests/test_on_action_default.py +96 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_authorizenet_adapter.py +36 -11
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_braintree_adapter.py +92 -11
- velocity_python-0.1.133/tests/test_payment_business_agnostic.py +225 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_stripe_adapter.py +61 -14
- velocity_python-0.1.133/tests/test_pgserver_ensure_infrastructure.py +122 -0
- velocity_python-0.1.133/tests/test_plaid_webhook.py +418 -0
- velocity_python-0.1.133/tests/test_postgres_initializer_config.py +197 -0
- velocity_python-0.1.133/tests/test_readme_imports.py +59 -0
- velocity_python-0.1.133/tests/test_row_scoped_data_service.py +679 -0
- velocity_python-0.1.133/tests/test_s3_upload.py +551 -0
- velocity_python-0.1.133/tests/test_ssm_config_require.py +96 -0
- velocity_python-0.1.133/tests/test_user_not_provisioned.py +257 -0
- velocity_python-0.1.129/src/velocity/aws/amplify_build.py +0 -144
- velocity_python-0.1.129/src/velocity/aws/deploy/config.py +0 -115
- velocity_python-0.1.129/src/velocity/aws/s3.py +0 -269
- velocity_python-0.1.129/src/velocity/aws/tests/test_amplify_build_shim.py +0 -74
- velocity_python-0.1.129/src/velocity/db/servers/sqlserver/types.py +0 -114
- velocity_python-0.1.129/src/velocity/payment/_mirror_core.py +0 -107
- velocity_python-0.1.129/src/velocity/payment/stripe_mirror.py +0 -307
- velocity_python-0.1.129/tests/test_iconv_money_to_cents.py +0 -20
- {velocity_python-0.1.129 → velocity_python-0.1.133}/LICENSE +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/setup.cfg +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/references.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/assets/usage_index.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/blobs.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/base.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/infra.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/jobs.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/retention.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/capabilities/single_session.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/deploy/targets.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/email.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/facets.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/context.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/context_factory.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/masquerade.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/mixins/job_handler.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/perf.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/handlers/response.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/mirror.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/ops.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/sms.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_deploy_least_privilege.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_deploy_policies.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_deploy_reconcile.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_email.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_response.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/aws/tests/test_sms.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/cache.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/async_support.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/column.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/database.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/decorators.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/engine.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/jsonproxy.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/lazy_engine.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/result.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/row.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/sequence.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/transaction.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/core/view.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/exceptions.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/fragments.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/maintenance.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/operators.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/sql.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/base/types.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/operators.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/reserved.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/mysql/sql.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/operators.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/reserved.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/postgres/sql.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/operators.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/reserved.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlite/sql.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/operators.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/sqlserver/sql.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/servers/tablehelper.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/common_db_test.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/common.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/conftest.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_column.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_connections.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_database.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_engine.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_imports.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_result.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_row.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_table.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/common.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_db_utils.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_postgres.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_result_caching.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_sql_builder.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_tablehelper.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/tests/test_view_helper.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/db/utils.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/logging.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/conv/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/conv/oconv.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/db.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/export.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/format.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/mail.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/merge.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/pdf.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_db.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_fix.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_format.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_iconv.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_mail_send.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_merge.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_oconv.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_original_error.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tests/test_timer.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/timer.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/misc/tools.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/capabilities.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/store.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/core/where.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/exceptions.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/base/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/cassandra/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/cassandra/translation.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/couchbase/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/couchbase/translation.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/dynamodb/translation.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/elasticsearch/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/elasticsearch/translation.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/memory/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/mongodb/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/mongodb/translation.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/nosql/servers/redis/__init__.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/base_adapter.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/charge_rules.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/money.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity/payment/redact.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/dependency_links.txt +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/entry_points.txt +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/src/velocity_python.egg-info/top_level.txt +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_access_error_403.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_activity_tracking_aborted_tx.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_asset_indexing.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_asset_references.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_assets_service.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_async_support.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_batch_operations.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_blob_store.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_capabilities.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_capability_catalog.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_client_sql_boundary.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_cognito_user_cache.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_column_tx_arg.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_concurrency_safety.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_connection_pool.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_context_flags_loader.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_context_job_descriptions.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_data_service_query_cap.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_data_service_renumber.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_data_service_save_as.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_db_credentials_ssm_cascade.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_db_maintenance.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_db_tunnel.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_decorators.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_delete_hook_fk_blocked.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_dirty_pipeline_fast_path.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_email_processing.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_enqueue_metric_namespace.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_enqueue_send_failures.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_facets.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_feature_flags.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_get_cognito_user_provider.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_http_handler_rollback.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_identifier_injection_guard.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_job_handler.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_job_lifecycle.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_job_results.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_json_columns.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_jsonb_dict_adapter.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler_auth.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler_masquerade.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lambda_handler_user_cache.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_lazy_engine.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_masquerade_grant.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_mirror.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_mixins_import.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_n_plus_one.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_memory.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_mongodb.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_redis.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_translation.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_nosql_where.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_observability.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_on_commit.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_ops.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_audit_fixes.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_braintree_mirror.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_mirror_empty_table.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_payment_profile_sorting.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pdf.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pgserver_bulk_cache.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pgserver_pointer_joins.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_pointer_join_sql.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_prepared_statements.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_psycopg3_upgrade.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_query_cache.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_query_missing_table_unlocked.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_raw_sql_prefix_policy.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_read_cache.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_response.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_restricted_direct_tables.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_result_returning.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_retry_side_effect_guard.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_return_default_safety.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_row_batch_update.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_row_cache_staleness.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_s3_bucket_config.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_s3_list_client_files.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_schema_migrations.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_security_capability.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_security_hardening.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_server_cursor.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_session_control.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_single_autocommit_safety.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_single_session_capability.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_spreadsheet_functions.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_sqlite_backend.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_sqs_per_record_transactions.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_ssm_config.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_store_user_data.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_sys_modified_count_postgres_demo.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_table_alter.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_table_find_cache.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_table_purge.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_transaction_class_wrapping.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_transaction_commit_and_ownership.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_transaction_edge_cases.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_tx_lifecycle_retry.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_tx_read_cache_and_bulk.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_where_clause_validation.py +0 -0
- {velocity_python-0.1.129 → velocity_python-0.1.133}/tests/test_write_hook_create_flow.py +0 -0
- {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.
|
|
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.
|
|
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` |
|
|
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
|
-
| `
|
|
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` |
|
|
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
|
|
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.
|
|
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
|
-
│ │ │ ├──
|
|
317
|
-
│ │ │ ├──
|
|
318
|
-
│ │ │ ├──
|
|
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,
|
|
324
|
-
│ │
|
|
325
|
-
│ │
|
|
326
|
-
│ │
|
|
327
|
-
│ │
|
|
328
|
-
│ │
|
|
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
|
-
│ │
|
|
331
|
-
│ │
|
|
332
|
-
│ │
|
|
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
|
|
336
|
-
│ │
|
|
337
|
-
│
|
|
338
|
-
├──
|
|
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
|
|
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` |
|
|
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
|
-
| `
|
|
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` |
|
|
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
|
|
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.
|
|
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
|
-
│ │ │ ├──
|
|
225
|
-
│ │ │ ├──
|
|
226
|
-
│ │ │ ├──
|
|
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,
|
|
232
|
-
│ │
|
|
233
|
-
│ │
|
|
234
|
-
│ │
|
|
235
|
-
│ │
|
|
236
|
-
│ │
|
|
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
|
-
│ │
|
|
239
|
-
│ │
|
|
240
|
-
│ │
|
|
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
|
|
244
|
-
│ │
|
|
245
|
-
│
|
|
246
|
-
├──
|
|
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
|
|
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.
|
|
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.
|
|
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 = ['
|
|
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.
|
|
174
|
+
python_version = "3.11"
|
|
167
175
|
mypy_path = "src"
|
|
168
176
|
explicit_package_bases = true
|
|
169
177
|
exclude = "(?x)(^src/velocity/.*/tests/)"
|
|
@@ -1,37 +1,18 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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,
|