velocity-python 0.1.28__tar.gz → 0.1.30__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.28/src/velocity_python.egg-info → velocity_python-0.1.30}/PKG-INFO +5 -1
- {velocity_python-0.1.28 → velocity_python-0.1.30}/pyproject.toml +7 -1
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/__init__.py +1 -1
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/mixins/data_service.py +164 -6
- {velocity_python-0.1.28 → velocity_python-0.1.30/src/velocity_python.egg-info}/PKG-INFO +5 -1
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/requires.txt +6 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/LICENSE +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/README.md +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/setup.cfg +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/amplify.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/amplify_build.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/assets/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/assets/backfill.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/assets/indexing.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/assets/references.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/assets/service.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/assets/usage_index.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/dirty_pipeline.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/base_handler.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/context.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/context_factory.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/exceptions.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/lambda_handler.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/mixins/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/mixins/web_handler.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/perf.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/response.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/sqs_handler.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/s3.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/ssm_config.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/tests/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/tests/test_response.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/async_support.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/column.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/database.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/decorators.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/engine.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/result.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/row.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/sequence.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/table.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/transaction.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/core/view.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/exceptions.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/migrations.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/base/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/base/initializer.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/base/operators.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/base/sql.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/base/types.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/mysql/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/mysql/operators.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/mysql/reserved.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/mysql/sql.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/mysql/types.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/operators.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/reserved.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/sql.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/types.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/operators.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/reserved.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/sql.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/types.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/operators.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/sql.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/types.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/tablehelper.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/common_db_test.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/common.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_column.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_connections.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_database.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_engine.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_imports.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_result.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_row.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_table.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/sql/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/sql/common.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_db_utils.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_postgres.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_result_caching.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_sql_builder.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_tablehelper.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_view_helper.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/utils.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/logging.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/conv/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/conv/iconv.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/conv/oconv.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/db.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/export.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/format.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/mail.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/merge.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/pdf.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_db.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_fix.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_format.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_iconv.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_merge.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_oconv.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_original_error.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_timer.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/timer.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tools.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/__init__.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/authorizenet_adapter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/authorizenet_mirror.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/base_adapter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/braintree_adapter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/braintree_mirror.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/charge_rules.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/stripe_adapter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/stripe_mirror.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/SOURCES.txt +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/dependency_links.txt +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/entry_points.txt +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/top_level.txt +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_amplify_build.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_asset_indexing.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_asset_references.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_assets_service.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_async_support.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_batch_operations.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_concurrency_safety.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_connection_pool.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_connection_resilience.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_decorators.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_dirty_pipeline_fast_path.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_email_processing.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_iconv_money_to_cents.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_lambda_handler.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_lambda_handler_auth.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_mixins_import.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_n_plus_one.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_observability.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_payment_authorizenet_adapter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_payment_braintree_adapter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_payment_profile_sorting.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_payment_stripe_adapter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_pdf.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_prepared_statements.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_psycopg3_upgrade.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_query_cache.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_row_batch_update.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_row_cache_staleness.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_row_dirty_tracking.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_schema_migrations.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_security_hardening.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_spreadsheet_functions.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_sqs_per_record_transactions.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_sys_modified_count_postgres_demo.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_table_alter.py +0 -0
- {velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_where_clause_validation.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.30
|
|
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
|
|
@@ -27,6 +27,10 @@ Requires-Dist: boto3>=1.35.0; extra == "aws"
|
|
|
27
27
|
Requires-Dist: requests>=2.32.0; extra == "aws"
|
|
28
28
|
Provides-Extra: excel
|
|
29
29
|
Requires-Dist: openpyxl>=3.1.0; extra == "excel"
|
|
30
|
+
Provides-Extra: parquet
|
|
31
|
+
Requires-Dist: pyarrow>=15.0.0; extra == "parquet"
|
|
32
|
+
Provides-Extra: ods
|
|
33
|
+
Requires-Dist: odfpy>=1.4.0; extra == "ods"
|
|
30
34
|
Provides-Extra: templates
|
|
31
35
|
Requires-Dist: jinja2>=3.1.0; extra == "templates"
|
|
32
36
|
Provides-Extra: pdf
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "velocity-python"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.30"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Velocity Team", email="info@codeclubs.org" },
|
|
10
10
|
]
|
|
@@ -45,6 +45,12 @@ aws = [
|
|
|
45
45
|
excel = [
|
|
46
46
|
"openpyxl>=3.1.0",
|
|
47
47
|
]
|
|
48
|
+
parquet = [
|
|
49
|
+
"pyarrow>=15.0.0",
|
|
50
|
+
]
|
|
51
|
+
ods = [
|
|
52
|
+
"odfpy>=1.4.0",
|
|
53
|
+
]
|
|
48
54
|
templates = [
|
|
49
55
|
"jinja2>=3.1.0",
|
|
50
56
|
]
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/mixins/data_service.py
RENAMED
|
@@ -6,11 +6,14 @@ that uses velocity.db for database access.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import base64
|
|
9
|
+
import csv
|
|
9
10
|
import datetime
|
|
10
11
|
import importlib
|
|
12
|
+
import json
|
|
11
13
|
import logging
|
|
12
14
|
import re
|
|
13
|
-
|
|
15
|
+
import xml.etree.ElementTree as ET
|
|
16
|
+
from io import BytesIO, StringIO
|
|
14
17
|
|
|
15
18
|
from velocity.aws import dirty_pipeline
|
|
16
19
|
from velocity.misc import export
|
|
@@ -333,7 +336,8 @@ class DataServiceMixin:
|
|
|
333
336
|
"message": message,
|
|
334
337
|
"missing": missing,
|
|
335
338
|
}
|
|
336
|
-
|
|
339
|
+
_file_export_formats_early = {"excel", "csv", "tsv", "json", "jsonl", "xml", "html", "markdown", "xlsx", "parquet", "ods"}
|
|
340
|
+
if result_format in _file_export_formats_early:
|
|
337
341
|
return {
|
|
338
342
|
"headers": payload.get("headers", []),
|
|
339
343
|
"rows": [],
|
|
@@ -354,7 +358,10 @@ class DataServiceMixin:
|
|
|
354
358
|
swallowed_error = getattr(tx, "_last_return_default_error", None)
|
|
355
359
|
if swallowed_error:
|
|
356
360
|
tx._last_return_default_error = None
|
|
357
|
-
|
|
361
|
+
|
|
362
|
+
_file_export_formats = {"excel", "csv", "tsv", "json", "jsonl", "xml", "html", "markdown", "xlsx", "parquet", "ods"}
|
|
363
|
+
|
|
364
|
+
if result_format in _file_export_formats:
|
|
358
365
|
data = {
|
|
359
366
|
"headers": payload.get(
|
|
360
367
|
"headers", [x.replace("_", " ").title() for x in result.headers]
|
|
@@ -373,7 +380,7 @@ class DataServiceMixin:
|
|
|
373
380
|
|
|
374
381
|
# If the DB call failed but was swallowed (return_default), surface a reason.
|
|
375
382
|
# Common symptoms are empty rows + null SQL.
|
|
376
|
-
if swallowed_error and result_format
|
|
383
|
+
if swallowed_error and result_format in _file_export_formats:
|
|
377
384
|
error_message = swallowed_error.get("message") or "Unknown database error"
|
|
378
385
|
context.response().toast(
|
|
379
386
|
f"Query failed for '{obj}': {error_message.splitlines()[0]}",
|
|
@@ -575,6 +582,142 @@ class DataServiceMixin:
|
|
|
575
582
|
#
|
|
576
583
|
# Payload parameters
|
|
577
584
|
|
|
585
|
+
# ---------------------------------------------------------------------------
|
|
586
|
+
# Export format helpers
|
|
587
|
+
# ---------------------------------------------------------------------------
|
|
588
|
+
|
|
589
|
+
@staticmethod
|
|
590
|
+
def _safe_xml_tag(name):
|
|
591
|
+
"""Sanitise a column name so it is a valid XML element name."""
|
|
592
|
+
tag = re.sub(r"[^a-zA-Z0-9_.-]", "_", str(name))
|
|
593
|
+
if tag and tag[0].isdigit():
|
|
594
|
+
tag = "_" + tag
|
|
595
|
+
return tag or "_col"
|
|
596
|
+
|
|
597
|
+
def _build_export_buffer(self, result_format, headers, rows, filename_base):
|
|
598
|
+
"""
|
|
599
|
+
Build a (bytes_buffer, filename, mime_type) tuple for the given
|
|
600
|
+
result_format. Returns None if the format is not handled here.
|
|
601
|
+
"""
|
|
602
|
+
if result_format == "csv":
|
|
603
|
+
buf = StringIO()
|
|
604
|
+
writer = csv.writer(buf)
|
|
605
|
+
writer.writerow(headers)
|
|
606
|
+
writer.writerows(rows)
|
|
607
|
+
return buf.getvalue().encode("utf-8"), f"{filename_base}.csv", "text/csv"
|
|
608
|
+
|
|
609
|
+
if result_format == "tsv":
|
|
610
|
+
buf = StringIO()
|
|
611
|
+
writer = csv.writer(buf, delimiter="\t")
|
|
612
|
+
writer.writerow(headers)
|
|
613
|
+
writer.writerows(rows)
|
|
614
|
+
return buf.getvalue().encode("utf-8"), f"{filename_base}.tsv", "text/tab-separated-values"
|
|
615
|
+
|
|
616
|
+
if result_format == "json":
|
|
617
|
+
data = [dict(zip(headers, row)) for row in rows]
|
|
618
|
+
return json.dumps(data, default=str).encode("utf-8"), f"{filename_base}.json", "application/json"
|
|
619
|
+
|
|
620
|
+
if result_format == "jsonl":
|
|
621
|
+
lines = [json.dumps(dict(zip(headers, row)), default=str) for row in rows]
|
|
622
|
+
return "\n".join(lines).encode("utf-8"), f"{filename_base}.jsonl", "application/x-ndjson"
|
|
623
|
+
|
|
624
|
+
if result_format == "xml":
|
|
625
|
+
root = ET.Element("rows")
|
|
626
|
+
for row in rows:
|
|
627
|
+
row_el = ET.SubElement(root, "row")
|
|
628
|
+
for header, value in zip(headers, row):
|
|
629
|
+
col_el = ET.SubElement(row_el, self._safe_xml_tag(header))
|
|
630
|
+
col_el.text = "" if value is None else str(value)
|
|
631
|
+
xml_bytes = ET.tostring(root, encoding="unicode").encode("utf-8")
|
|
632
|
+
return xml_bytes, f"{filename_base}.xml", "application/xml"
|
|
633
|
+
|
|
634
|
+
if result_format == "html":
|
|
635
|
+
th_cells = "".join(f"<th>{h}</th>" for h in headers)
|
|
636
|
+
tr_rows = "".join(
|
|
637
|
+
"<tr>" + "".join(f"<td>{'' if v is None else str(v)}</td>" for v in row) + "</tr>"
|
|
638
|
+
for row in rows
|
|
639
|
+
)
|
|
640
|
+
html = (
|
|
641
|
+
f"<!DOCTYPE html><html><head><meta charset='utf-8'></head>"
|
|
642
|
+
f"<body><table border='1'><thead><tr>{th_cells}</tr></thead>"
|
|
643
|
+
f"<tbody>{tr_rows}</tbody></table></body></html>"
|
|
644
|
+
)
|
|
645
|
+
return html.encode("utf-8"), f"{filename_base}.html", "text/html"
|
|
646
|
+
|
|
647
|
+
if result_format == "markdown":
|
|
648
|
+
header_row = "| " + " | ".join(str(h) for h in headers) + " |"
|
|
649
|
+
separator = "| " + " | ".join("---" for _ in headers) + " |"
|
|
650
|
+
data_rows = [
|
|
651
|
+
"| " + " | ".join("" if v is None else str(v) for v in row) + " |"
|
|
652
|
+
for row in rows
|
|
653
|
+
]
|
|
654
|
+
md = "\n".join([header_row, separator] + data_rows)
|
|
655
|
+
return md.encode("utf-8"), f"{filename_base}.md", "text/markdown"
|
|
656
|
+
|
|
657
|
+
if result_format == "xlsx":
|
|
658
|
+
try:
|
|
659
|
+
from openpyxl import Workbook
|
|
660
|
+
except ImportError:
|
|
661
|
+
raise ImportError("openpyxl is required for xlsx export (install velocity-python[excel])")
|
|
662
|
+
wb = Workbook()
|
|
663
|
+
ws = wb.active
|
|
664
|
+
ws.append(list(headers))
|
|
665
|
+
for row in rows:
|
|
666
|
+
ws.append(list(row))
|
|
667
|
+
buf = BytesIO()
|
|
668
|
+
wb.save(buf)
|
|
669
|
+
return (
|
|
670
|
+
buf.getvalue(),
|
|
671
|
+
f"{filename_base}.xlsx",
|
|
672
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
if result_format == "parquet":
|
|
676
|
+
try:
|
|
677
|
+
import pyarrow as pa
|
|
678
|
+
import pyarrow.parquet as pq
|
|
679
|
+
except ImportError:
|
|
680
|
+
raise ImportError("pyarrow is required for parquet export (install velocity-python[parquet])")
|
|
681
|
+
table = pa.table({h: [row[i] for row in rows] for i, h in enumerate(headers)})
|
|
682
|
+
buf = BytesIO()
|
|
683
|
+
pq.write_table(table, buf)
|
|
684
|
+
return buf.getvalue(), f"{filename_base}.parquet", "application/octet-stream"
|
|
685
|
+
|
|
686
|
+
if result_format == "ods":
|
|
687
|
+
try:
|
|
688
|
+
from odf.opendocument import OpenDocumentSpreadsheet
|
|
689
|
+
from odf.table import Table, TableRow, TableCell
|
|
690
|
+
from odf.text import P
|
|
691
|
+
except ImportError:
|
|
692
|
+
raise ImportError("odfpy is required for ods export (install velocity-python[ods])")
|
|
693
|
+
doc = OpenDocumentSpreadsheet()
|
|
694
|
+
sheet = Table(name="Sheet1")
|
|
695
|
+
doc.spreadsheet.addElement(sheet)
|
|
696
|
+
header_row_el = TableRow()
|
|
697
|
+
for h in headers:
|
|
698
|
+
cell = TableCell()
|
|
699
|
+
cell.addElement(P(text=str(h)))
|
|
700
|
+
header_row_el.addElement(cell)
|
|
701
|
+
sheet.addElement(header_row_el)
|
|
702
|
+
for row in rows:
|
|
703
|
+
tr = TableRow()
|
|
704
|
+
for v in row:
|
|
705
|
+
cell = TableCell()
|
|
706
|
+
cell.addElement(P(text="" if v is None else str(v)))
|
|
707
|
+
tr.addElement(cell)
|
|
708
|
+
sheet.addElement(tr)
|
|
709
|
+
buf = BytesIO()
|
|
710
|
+
doc.save(buf)
|
|
711
|
+
return (
|
|
712
|
+
buf.getvalue(),
|
|
713
|
+
f"{filename_base}.ods",
|
|
714
|
+
"application/vnd.oasis.opendocument.spreadsheet",
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
return None
|
|
718
|
+
|
|
719
|
+
# ---------------------------------------------------------------------------
|
|
720
|
+
|
|
578
721
|
def OnActionQuery(self, tx, context):
|
|
579
722
|
payload = context.payload()
|
|
580
723
|
|
|
@@ -586,8 +729,10 @@ class DataServiceMixin:
|
|
|
586
729
|
if not table:
|
|
587
730
|
raise ValueError("Parameter 'obj' cannot be empty")
|
|
588
731
|
|
|
732
|
+
result_format = payload.get("result_format")
|
|
589
733
|
data = self.query_hook(tx, table, payload, context)
|
|
590
|
-
|
|
734
|
+
|
|
735
|
+
if result_format == "excel":
|
|
591
736
|
filebuffer = BytesIO()
|
|
592
737
|
export.create_spreadsheet(data["headers"], data["rows"], filebuffer)
|
|
593
738
|
context.response().file_download(
|
|
@@ -598,7 +743,20 @@ class DataServiceMixin:
|
|
|
598
743
|
)
|
|
599
744
|
return
|
|
600
745
|
|
|
601
|
-
if
|
|
746
|
+
if result_format in ("csv", "tsv", "json", "jsonl", "xml", "html", "markdown", "xlsx", "parquet", "ods"):
|
|
747
|
+
filename_base = payload.get("filename_base") or table
|
|
748
|
+
built = self._build_export_buffer(result_format, data.get("headers", []), data.get("rows", []), filename_base)
|
|
749
|
+
if built is not None:
|
|
750
|
+
file_bytes, filename, _mime = built
|
|
751
|
+
context.response().file_download(
|
|
752
|
+
{
|
|
753
|
+
"filename": filename,
|
|
754
|
+
"data": base64.b64encode(file_bytes).decode(),
|
|
755
|
+
}
|
|
756
|
+
)
|
|
757
|
+
return
|
|
758
|
+
|
|
759
|
+
if result_format == "raw":
|
|
602
760
|
context.response().set_body(data)
|
|
603
761
|
else:
|
|
604
762
|
context.response().set_table(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: velocity-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.30
|
|
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
|
|
@@ -27,6 +27,10 @@ Requires-Dist: boto3>=1.35.0; extra == "aws"
|
|
|
27
27
|
Requires-Dist: requests>=2.32.0; extra == "aws"
|
|
28
28
|
Provides-Extra: excel
|
|
29
29
|
Requires-Dist: openpyxl>=3.1.0; extra == "excel"
|
|
30
|
+
Provides-Extra: parquet
|
|
31
|
+
Requires-Dist: pyarrow>=15.0.0; extra == "parquet"
|
|
32
|
+
Provides-Extra: ods
|
|
33
|
+
Requires-Dist: odfpy>=1.4.0; extra == "ods"
|
|
30
34
|
Provides-Extra: templates
|
|
31
35
|
Requires-Dist: jinja2>=3.1.0; extra == "templates"
|
|
32
36
|
Provides-Extra: pdf
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/context_factory.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/lambda_handler.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/mixins/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/aws/handlers/mixins/web_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/base/initializer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/mysql/operators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/operators.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/postgres/reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/operators.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlite/reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/operators.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/servers/sqlserver/types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_column.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_connections.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_database.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_engine.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_imports.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_result.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_row.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_sequence.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_table.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/postgres/test_transaction.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_cursor_rowcount_fix.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_postgres_unchanged.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_result_caching.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/db/tests/test_result_sql_aware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/misc/tests/test_original_error.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/authorizenet_adapter.py
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity/payment/authorizenet_mirror.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/src/velocity_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_payment_authorizenet_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.28 → velocity_python-0.1.30}/tests/test_sys_modified_count_postgres_demo.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|