vgi-python 0.22.1__tar.gz → 0.23.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.github/workflows/integration.yml +7 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/PKG-INFO +1 -1
- {vgi_python-0.22.1 → vgi_python-0.23.0}/pyproject.toml +1 -1
- {vgi_python-0.22.1 → vgi_python-0.23.0}/uv.lock +1 -1
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/http_server.py +4 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/argument_spec.py +51 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/logging_config.py +68 -0
- vgi_python-0.23.0/vgi/profiling.py +93 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/serve.py +6 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.gitattributes +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.github/dependabot.yml +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.github/workflows/ci.yml +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.github/workflows/docs.yml +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.github/workflows/release.yml +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.gitignore +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.python-version +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/.vale.ini +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/CLAUDE.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/LICENSE +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/README.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/SECURITY.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/ci/README.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/ci/run-integration.sh +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/arguments.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/auth.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/catalogs.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/client.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/exceptions.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/filters.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/functions.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/http.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/index.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/metadata.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/observability.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/storage.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/transactor.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/api/worker.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/argument-serialization.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/logo.png +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/assets/social-card.png +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/authentication.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/catalog-interface.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/cli.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/column-statistics.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/concepts/index.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/contributing-docs.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/generator-api.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/how-to/index.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/how-to/state-storage.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/index.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/lifecycle.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/metadata.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/overrides/main.html +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/robots.txt +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/shared-storage.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/tutorial/index.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/tutorial/table.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/docs/vgi-logo.png +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/examples/calc_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/examples/filter_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/examples/row_count_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/examples/sum_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/mkdocs.yml +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/scripts/measure_startup.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/test-data/generate.sh +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_declarative.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_required_filters.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_scan_branches.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_serialization.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/client/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/client/test_cli.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_accumulate.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_const_param_enforcement.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_container.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_copy_from.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_copy_to.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_directory_parity.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_github.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_protocol_version.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_resumable_scan.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/conftest.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/landing/_checker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/landing/describe.expected.json +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/landing/describe.schema.json +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/test_blended_metadata.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_aggregate_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_argument_spec.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_auth.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_bind_request_at_clause.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_bound_storage_conformance.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_cache_control.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_copy_from_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_copy_to_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_docstrings.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_examples_workers.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_exceptions.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_filter_pushdown_extension.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_function_storage.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_function_storage_cf_do.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_function_storage_cf_do_integration.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_function_storage_conformance.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_cpp_schemas.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_cpp_secret.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_http_demo_storage.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_http_s3_offload_input.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_landing_conformance.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_metadata.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_nest_tensor.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_otel.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_projection_repro.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_protocol_classes.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_resolved_secrets.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_schema_scoped_functions.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_serve.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_setting_secret_annotations.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_table_buffering_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_tcp_transport.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_union_argument.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/test_worker_page.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_duckdb.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/attach_options.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/companion.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/copy_from.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/copy_to.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/_common.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/cache.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/filters.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/arguments.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/attach_header.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/auth.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/cache_control.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/_descriptor_spec.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/attach_option.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/catalog_interface.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/descriptors.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/catalog_mixin.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/cli.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/client/client.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/copy_from_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/copy_to_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/exceptions.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/function_storage.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/function_storage_cf_do.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/http/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/http/describe_json.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/http/landing.html +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/http/landing_page.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/invocation.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/meta_worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/metadata.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/otel.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/protocol.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/protocol_version.txt +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/py.typed +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/scalar_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/schema_utils.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/secret_service.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/table_filter_pushdown.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/table_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/transactor/client.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/transactor/server.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/vgi/worker.py +0 -0
- {vgi_python-0.22.1 → vgi_python-0.23.0}/wrangler.jsonc +0 -0
|
@@ -33,6 +33,13 @@ env:
|
|
|
33
33
|
# The Haybarn release providing the prebuilt haybarn-unittest binary. Must be
|
|
34
34
|
# ABI-compatible with the community-published vgi extension.
|
|
35
35
|
HAYBARN_RELEASE: haybarn-v1.5.4-rc3
|
|
36
|
+
# CI is not a user: its ATTACHes should not land in Query.Farm's adoption data.
|
|
37
|
+
# The vgi extension fires a telemetry event per successful ATTACH, and this
|
|
38
|
+
# suite performs several hundred of them per lane, so opting out keeps the
|
|
39
|
+
# numbers honest. It also removes telemetry as a variable in lane timings —
|
|
40
|
+
# the per-ATTACH event was added in Query-farm/vgi 71e2d51 (2026-07-12), and
|
|
41
|
+
# the stdio lane total stepped from ~690s to ~870s across that window.
|
|
42
|
+
QUERY_FARM_TELEMETRY_OPT_OUT: "1"
|
|
36
43
|
|
|
37
44
|
jobs:
|
|
38
45
|
integration:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vgi-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.0
|
|
4
4
|
Summary: Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow
|
|
5
5
|
Project-URL: Homepage, https://query.farm
|
|
6
6
|
Project-URL: Repository, https://github.com/Query-farm/vgi-python
|
|
@@ -27,6 +27,7 @@ from vgi._test_fixtures.schema_reconcile.worker import SchemaReconcileWorker
|
|
|
27
27
|
from vgi._test_fixtures.worker import ExampleWorker
|
|
28
28
|
from vgi.logging_config import LogFormat, LogLevel, configure_worker_logging
|
|
29
29
|
from vgi.meta_worker import MetaWorker
|
|
30
|
+
from vgi.profiling import maybe_start_profile
|
|
30
31
|
|
|
31
32
|
if TYPE_CHECKING:
|
|
32
33
|
from vgi_rpc.external import UploadUrl
|
|
@@ -209,12 +210,15 @@ def main() -> None:
|
|
|
209
210
|
|
|
210
211
|
env_debug = os.environ.get("VGI_WORKER_DEBUG", "").lower() in ("1", "true", "yes")
|
|
211
212
|
effective_debug = debug or env_debug
|
|
213
|
+
# VGI_WORKER_LOG_* overrides are applied inside configure_worker_logging,
|
|
214
|
+
# so this server and `vgi-serve` are configurable the same way.
|
|
212
215
|
effective_level = configure_worker_logging(
|
|
213
216
|
debug=effective_debug,
|
|
214
217
|
log_level=log_level,
|
|
215
218
|
log_loggers=log_logger,
|
|
216
219
|
log_format=log_format,
|
|
217
220
|
)
|
|
221
|
+
maybe_start_profile()
|
|
218
222
|
|
|
219
223
|
bucket = s3_bucket or os.environ.get("VGI_HTTP_S3_BUCKET")
|
|
220
224
|
external_location = None
|
|
@@ -18,6 +18,7 @@ import json
|
|
|
18
18
|
import warnings
|
|
19
19
|
from collections.abc import Sequence
|
|
20
20
|
from dataclasses import dataclass
|
|
21
|
+
from functools import cache
|
|
21
22
|
from typing import Annotated, Any, get_args, get_origin, get_type_hints
|
|
22
23
|
|
|
23
24
|
import pyarrow as pa
|
|
@@ -519,6 +520,10 @@ def extract_argument_specs(
|
|
|
519
520
|
2. Type annotation with `PYTHON_TO_ARROW` mapping
|
|
520
521
|
3. Default to pa.null() with warning for unknown types
|
|
521
522
|
|
|
523
|
+
Memoized per class — see :func:`_extract_argument_specs_cached`. A fresh
|
|
524
|
+
list is returned each call so a caller that mutates it cannot corrupt the
|
|
525
|
+
cache; the `ArgumentSpec`s inside are frozen dataclasses and safe to share.
|
|
526
|
+
|
|
522
527
|
Args:
|
|
523
528
|
cls: Function class with `Arg` descriptors.
|
|
524
529
|
|
|
@@ -527,6 +532,52 @@ def extract_argument_specs(
|
|
|
527
532
|
then named).
|
|
528
533
|
|
|
529
534
|
"""
|
|
535
|
+
return list(_extract_argument_specs_cached(cls))
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
@cache
|
|
539
|
+
def _extract_argument_specs_cached(cls: type) -> tuple[ArgumentSpec, ...]:
|
|
540
|
+
"""Memoized :func:`_extract_argument_specs`, keyed on the class.
|
|
541
|
+
|
|
542
|
+
A function class's argument specs are fixed once the class exists — they are
|
|
543
|
+
derived from its annotations, its ``FunctionArguments``, and the `Arg`
|
|
544
|
+
descriptors on its MRO, none of which change at runtime. Deriving them was
|
|
545
|
+
nonetheless repeated on **every** catalog listing and every overload match:
|
|
546
|
+
profiling one run of the upstream integration suite through the proxy showed
|
|
547
|
+
58,058 calls costing 15.8s, which drove 131,653 ``typing.get_type_hints``
|
|
548
|
+
calls, 2.4M ``_eval_type`` calls and 648k ``compile`` calls — roughly a
|
|
549
|
+
quarter of the worker's CPU. ``catalog_schema_contents_functions`` was 38ms
|
|
550
|
+
per call against 0.1-2ms for every other catalog method, entirely because of
|
|
551
|
+
this.
|
|
552
|
+
|
|
553
|
+
Unbounded (``functools.cache``) is the right size: the keys are function
|
|
554
|
+
classes, which the catalog already holds for the process's lifetime, so the
|
|
555
|
+
cache adds no retention that did not already exist. It is also thread safe,
|
|
556
|
+
which matters because workers serve requests on a pool.
|
|
557
|
+
|
|
558
|
+
Returns a tuple so the cached value cannot be mutated through a caller's
|
|
559
|
+
reference.
|
|
560
|
+
|
|
561
|
+
Args:
|
|
562
|
+
cls: Function class with `Arg` descriptors.
|
|
563
|
+
|
|
564
|
+
Returns:
|
|
565
|
+
The class's argument specs, sorted.
|
|
566
|
+
"""
|
|
567
|
+
return tuple(_extract_argument_specs(cls))
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
def _extract_argument_specs(
|
|
571
|
+
cls: type,
|
|
572
|
+
) -> list[ArgumentSpec]:
|
|
573
|
+
"""Derive a class's argument specs, without caching.
|
|
574
|
+
|
|
575
|
+
Args:
|
|
576
|
+
cls: Function class with `Arg` descriptors.
|
|
577
|
+
|
|
578
|
+
Returns:
|
|
579
|
+
List of `ArgumentSpec` objects, sorted by position.
|
|
580
|
+
"""
|
|
530
581
|
specs: list[ArgumentSpec] = []
|
|
531
582
|
seen_names: set[str] = set()
|
|
532
583
|
|
|
@@ -11,6 +11,7 @@ VGI workers.
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
13
|
import logging
|
|
14
|
+
import os
|
|
14
15
|
import sys
|
|
15
16
|
from enum import StrEnum
|
|
16
17
|
|
|
@@ -46,6 +47,68 @@ _KNOWN_LOGGERS: list[tuple[str, str, str]] = [
|
|
|
46
47
|
]
|
|
47
48
|
|
|
48
49
|
|
|
50
|
+
def _env_overrides(
|
|
51
|
+
log_level: LogLevel,
|
|
52
|
+
log_loggers: list[str] | None,
|
|
53
|
+
log_format: LogFormat,
|
|
54
|
+
) -> tuple[LogLevel, list[str] | None, LogFormat]:
|
|
55
|
+
"""Apply ``VGI_WORKER_LOG_*`` environment overrides to the CLI options.
|
|
56
|
+
|
|
57
|
+
The access log (``vgi_rpc.access``) already records ``duration_ms``,
|
|
58
|
+
``method`` and row/byte counts for every RPC, but reaching it required
|
|
59
|
+
passing ``--log-logger vgi_rpc.access --log-format json`` on the command
|
|
60
|
+
line. Anything that launches a worker without owning its argv — a container
|
|
61
|
+
image, a test harness spawning workers from a dozen call sites — could not
|
|
62
|
+
turn it on. These variables make the same configuration reachable the way
|
|
63
|
+
``VGI_SIGNING_KEY`` and ``VGI_ENABLE_DESCRIBE`` already are.
|
|
64
|
+
|
|
65
|
+
Applied here rather than in a single CLI so that *every* worker entry point
|
|
66
|
+
honours them identically — ``vgi-serve`` and the fixture servers had
|
|
67
|
+
byte-identical logging blocks, and an override wired into only one of them
|
|
68
|
+
would be a trap.
|
|
69
|
+
|
|
70
|
+
Each variable wins when set, matching ``VGI_ENABLE_DESCRIBE``: Typer cannot
|
|
71
|
+
distinguish "user passed the default" from "user passed nothing", so
|
|
72
|
+
deferring to an explicit environment setting is the only unambiguous rule.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
log_level: The ``--log-level`` value.
|
|
76
|
+
log_loggers: The ``--log-logger`` values, if any.
|
|
77
|
+
log_format: The ``--log-format`` value.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
The effective ``(level, loggers, format)``.
|
|
81
|
+
|
|
82
|
+
Raises:
|
|
83
|
+
SystemExit: If a variable names a level or format that does not exist.
|
|
84
|
+
A typo would otherwise silently leave logging as it was, which is
|
|
85
|
+
indistinguishable from the feature not working.
|
|
86
|
+
"""
|
|
87
|
+
raw_level = os.environ.get("VGI_WORKER_LOG_LEVEL")
|
|
88
|
+
if raw_level:
|
|
89
|
+
try:
|
|
90
|
+
log_level = LogLevel(raw_level.upper())
|
|
91
|
+
except ValueError:
|
|
92
|
+
valid = ", ".join(level.value for level in LogLevel)
|
|
93
|
+
sys.exit(f"VGI_WORKER_LOG_LEVEL={raw_level!r} is not a log level (expected one of: {valid})")
|
|
94
|
+
|
|
95
|
+
raw_format = os.environ.get("VGI_WORKER_LOG_FORMAT")
|
|
96
|
+
if raw_format:
|
|
97
|
+
try:
|
|
98
|
+
log_format = LogFormat(raw_format.lower())
|
|
99
|
+
except ValueError:
|
|
100
|
+
valid = ", ".join(fmt.value for fmt in LogFormat)
|
|
101
|
+
sys.exit(f"VGI_WORKER_LOG_FORMAT={raw_format!r} is not a log format (expected one of: {valid})")
|
|
102
|
+
|
|
103
|
+
raw_loggers = os.environ.get("VGI_WORKER_LOG_LOGGERS")
|
|
104
|
+
if raw_loggers:
|
|
105
|
+
names = [name.strip() for name in raw_loggers.split(",") if name.strip()]
|
|
106
|
+
if names:
|
|
107
|
+
log_loggers = names
|
|
108
|
+
|
|
109
|
+
return log_level, log_loggers, log_format
|
|
110
|
+
|
|
111
|
+
|
|
49
112
|
def configure_worker_logging(
|
|
50
113
|
*,
|
|
51
114
|
debug: bool = False,
|
|
@@ -55,6 +118,10 @@ def configure_worker_logging(
|
|
|
55
118
|
) -> int:
|
|
56
119
|
"""Configure stdlib logging for a VGI worker process.
|
|
57
120
|
|
|
121
|
+
``VGI_WORKER_LOG_LEVEL``, ``VGI_WORKER_LOG_FORMAT`` and
|
|
122
|
+
``VGI_WORKER_LOG_LOGGERS`` override the corresponding arguments when set —
|
|
123
|
+
see :func:`_env_overrides`.
|
|
124
|
+
|
|
58
125
|
Args:
|
|
59
126
|
debug: If True, force DEBUG on all default loggers (overrides *log_level*).
|
|
60
127
|
log_level: Logging level when *debug* is False.
|
|
@@ -65,6 +132,7 @@ def configure_worker_logging(
|
|
|
65
132
|
The effective numeric log level.
|
|
66
133
|
|
|
67
134
|
"""
|
|
135
|
+
log_level, log_loggers, log_format = _env_overrides(log_level, log_loggers, log_format)
|
|
68
136
|
effective_level = logging.DEBUG if debug else getattr(logging, log_level.value)
|
|
69
137
|
|
|
70
138
|
handler = logging.StreamHandler(sys.stderr)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Opt-in CPU profiling for VGI worker processes.
|
|
4
|
+
|
|
5
|
+
A worker is normally a subprocess someone else launched — a container, a test
|
|
6
|
+
harness, a DuckDB client spawning it over stdio — so the usual ways of profiling
|
|
7
|
+
Python (``python -m cProfile``, an interactive session) are not available to
|
|
8
|
+
whoever needs the answer. Setting one environment variable is.
|
|
9
|
+
|
|
10
|
+
Shared by every worker entry point rather than living in one CLI, so that
|
|
11
|
+
``vgi-serve`` and the fixture servers profile identically.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import pathlib
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
__all__ = ["maybe_start_profile"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def maybe_start_profile() -> None:
|
|
24
|
+
"""Start a ``cProfile`` profiler when ``VGI_WORKER_PROFILE`` names a path.
|
|
25
|
+
|
|
26
|
+
Set ``VGI_WORKER_PROFILE`` to a directory (or a file path) and the worker
|
|
27
|
+
writes ``pstats`` data on exit, readable with :mod:`pstats`, snakeviz, or
|
|
28
|
+
``python -m pstats``. A directory gets one file per process
|
|
29
|
+
(``worker-<pid>.prof``), which is what you want when the thing under
|
|
30
|
+
investigation spawns more than one worker.
|
|
31
|
+
|
|
32
|
+
**All threads are covered by the single profiler.** That matters because
|
|
33
|
+
under ``--http`` a worker runs on waitress, which serves every request on a
|
|
34
|
+
pool thread — a main-thread-only profile would faithfully report time spent
|
|
35
|
+
in ``select()`` and nothing about the work being measured. Since Python 3.12
|
|
36
|
+
``cProfile`` is built on :mod:`sys.monitoring`, whose tool registration is
|
|
37
|
+
process-global rather than per-thread, so one profiler observes the pool
|
|
38
|
+
threads too.
|
|
39
|
+
|
|
40
|
+
The corollary is that there can be only **one** active profiler in the
|
|
41
|
+
process: ``sys.monitoring`` allows a given tool id to be claimed once, so a
|
|
42
|
+
profiler-per-thread raises ``ValueError: Another profiling tool is already
|
|
43
|
+
active`` in every waitress thread — and because that happens as the thread
|
|
44
|
+
starts, the server never accepts a connection at all.
|
|
45
|
+
|
|
46
|
+
``atexit`` alone would not be enough: a worker is normally stopped with
|
|
47
|
+
``SIGTERM``, whose default action terminates without unwinding, so the
|
|
48
|
+
profile would be lost on every normal shutdown. A handler turns it into an
|
|
49
|
+
ordinary exit — but only if nothing else has claimed ``SIGTERM``, since
|
|
50
|
+
stealing another component's shutdown path would be a worse bug than a
|
|
51
|
+
missing profile.
|
|
52
|
+
"""
|
|
53
|
+
dest = os.environ.get("VGI_WORKER_PROFILE")
|
|
54
|
+
if not dest:
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
import atexit
|
|
58
|
+
import cProfile
|
|
59
|
+
import signal
|
|
60
|
+
|
|
61
|
+
path = pathlib.Path(dest)
|
|
62
|
+
if path.is_dir() or dest.endswith(os.sep):
|
|
63
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
64
|
+
path = path / f"worker-{os.getpid()}.prof"
|
|
65
|
+
else:
|
|
66
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
67
|
+
|
|
68
|
+
profiler = cProfile.Profile()
|
|
69
|
+
profiler.enable()
|
|
70
|
+
dumped = False
|
|
71
|
+
|
|
72
|
+
def _dump() -> None:
|
|
73
|
+
# atexit and the SIGTERM handler can both reach this; dumping twice
|
|
74
|
+
# would truncate the file the first call just wrote.
|
|
75
|
+
nonlocal dumped
|
|
76
|
+
if dumped:
|
|
77
|
+
return
|
|
78
|
+
dumped = True
|
|
79
|
+
try:
|
|
80
|
+
profiler.disable()
|
|
81
|
+
profiler.dump_stats(str(path))
|
|
82
|
+
except Exception as exc: # noqa: BLE001 — never fail a shutdown over telemetry
|
|
83
|
+
sys.stderr.write(f"vgi: could not write profile: {exc}\n")
|
|
84
|
+
return
|
|
85
|
+
sys.stderr.write(f"vgi: wrote profile to {path}\n")
|
|
86
|
+
|
|
87
|
+
atexit.register(_dump)
|
|
88
|
+
|
|
89
|
+
def _on_sigterm(signum: int, frame: object) -> None:
|
|
90
|
+
raise SystemExit(128 + signum)
|
|
91
|
+
|
|
92
|
+
if signal.getsignal(signal.SIGTERM) in (signal.SIG_DFL, None):
|
|
93
|
+
signal.signal(signal.SIGTERM, _on_sigterm)
|
|
@@ -35,6 +35,7 @@ from types import ModuleType
|
|
|
35
35
|
from typing import TYPE_CHECKING, Any, Literal
|
|
36
36
|
|
|
37
37
|
from vgi.logging_config import LogFormat, LogLevel
|
|
38
|
+
from vgi.profiling import maybe_start_profile
|
|
38
39
|
|
|
39
40
|
if TYPE_CHECKING:
|
|
40
41
|
import falcon
|
|
@@ -364,12 +365,17 @@ def main() -> None:
|
|
|
364
365
|
) -> None:
|
|
365
366
|
env_debug = os.environ.get("VGI_WORKER_DEBUG", "").lower() in ("1", "true", "yes")
|
|
366
367
|
effective_debug = debug or env_debug
|
|
368
|
+
# VGI_WORKER_LOG_* overrides are applied inside configure_worker_logging,
|
|
369
|
+
# so every worker entry point honours them identically.
|
|
367
370
|
effective_level = configure_worker_logging(
|
|
368
371
|
debug=effective_debug,
|
|
369
372
|
log_level=log_level,
|
|
370
373
|
log_loggers=log_logger,
|
|
371
374
|
log_format=log_format,
|
|
372
375
|
)
|
|
376
|
+
# Before the worker class is imported, so module-import cost lands in
|
|
377
|
+
# the profile too — for many workers that is the bulk of startup.
|
|
378
|
+
maybe_start_profile()
|
|
373
379
|
|
|
374
380
|
# Resolve env var overrides
|
|
375
381
|
describe = _resolve_describe(describe)
|
|
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
|
|
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
|
|
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
|
|
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
|