vgi-python 0.41.0__tar.gz → 0.42.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.
Files changed (685) hide show
  1. {vgi_python-0.41.0 → vgi_python-0.42.0}/CLAUDE.md +19 -0
  2. {vgi_python-0.41.0 → vgi_python-0.42.0}/PKG-INFO +2 -2
  3. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/index.md +1 -1
  4. vgi_python-0.42.0/docs/api/transactor.md +32 -0
  5. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/authentication.md +43 -1
  6. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/catalog-interface.md +28 -3
  7. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/cli.md +1 -1
  8. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/function-patterns.md +9 -6
  9. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/state-storage.md +5 -3
  10. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/shared-storage.md +2 -2
  11. {vgi_python-0.41.0 → vgi_python-0.42.0}/pyproject.toml +2 -2
  12. vgi_python-0.42.0/tests/test_grant_auth.py +290 -0
  13. {vgi_python-0.41.0 → vgi_python-0.42.0}/uv.lock +5 -5
  14. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_duckdb.py +3 -3
  15. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/http_server.py +2 -1
  16. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/identity_fixture.py +7 -1
  17. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/rpc_server.py +56 -3
  18. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/serve.py +73 -2
  19. vgi_python-0.41.0/docs/api/transactor.md +0 -12
  20. {vgi_python-0.41.0 → vgi_python-0.42.0}/.dockerignore +0 -0
  21. {vgi_python-0.41.0 → vgi_python-0.42.0}/.gitattributes +0 -0
  22. {vgi_python-0.41.0 → vgi_python-0.42.0}/.github/dependabot.yml +0 -0
  23. {vgi_python-0.41.0 → vgi_python-0.42.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
  24. {vgi_python-0.41.0 → vgi_python-0.42.0}/.github/workflows/ci.yml +0 -0
  25. {vgi_python-0.41.0 → vgi_python-0.42.0}/.github/workflows/docs.yml +0 -0
  26. {vgi_python-0.41.0 → vgi_python-0.42.0}/.github/workflows/integration.yml +0 -0
  27. {vgi_python-0.41.0 → vgi_python-0.42.0}/.github/workflows/release.yml +0 -0
  28. {vgi_python-0.41.0 → vgi_python-0.42.0}/.github/workflows/tailnet-integration.yml +0 -0
  29. {vgi_python-0.41.0 → vgi_python-0.42.0}/.gitignore +0 -0
  30. {vgi_python-0.41.0 → vgi_python-0.42.0}/.python-version +0 -0
  31. {vgi_python-0.41.0 → vgi_python-0.42.0}/.vale.ini +0 -0
  32. {vgi_python-0.41.0 → vgi_python-0.42.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
  33. {vgi_python-0.41.0 → vgi_python-0.42.0}/DOCS_REVIEW_RUBRIC.md +0 -0
  34. {vgi_python-0.41.0 → vgi_python-0.42.0}/DOCS_USABILITY_TEST.md +0 -0
  35. {vgi_python-0.41.0 → vgi_python-0.42.0}/LICENSE +0 -0
  36. {vgi_python-0.41.0 → vgi_python-0.42.0}/PROTOCOL.md +0 -0
  37. {vgi_python-0.41.0 → vgi_python-0.42.0}/README.md +0 -0
  38. {vgi_python-0.41.0 → vgi_python-0.42.0}/RELEASE-RUNBOOK.md +0 -0
  39. {vgi_python-0.41.0 → vgi_python-0.42.0}/SECURITY.md +0 -0
  40. {vgi_python-0.41.0 → vgi_python-0.42.0}/ci/README.md +0 -0
  41. {vgi_python-0.41.0 → vgi_python-0.42.0}/ci/preprocess-require.awk +0 -0
  42. {vgi_python-0.41.0 → vgi_python-0.42.0}/ci/run-integration.sh +0 -0
  43. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/README.md +0 -0
  44. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/and-too-few-children.json +0 -0
  45. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/delta-required-upsert.json +0 -0
  46. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/nested-runtime-filter.json +0 -0
  47. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/remove-with-expression.json +0 -0
  48. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/required-runtime-filter.json +0 -0
  49. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/snapshot-nonzero-revision.json +0 -0
  50. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/unknown-document-property.json +0 -0
  51. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/negative/unknown-node.json +0 -0
  52. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/positive/advisory-upsert-delta.json +0 -0
  53. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/positive/boolean-column-predicate.json +0 -0
  54. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/positive/empty-snapshot.json +0 -0
  55. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/positive/nested-required-snapshot.json +0 -0
  56. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/positive/remove-delta.json +0 -0
  57. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/cases/positive/runtime-filter-snapshot.json +0 -0
  58. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/filter-v2.schema.json +0 -0
  59. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/generate_runtime.py +0 -0
  60. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/manifest.json +0 -0
  61. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/run_worker.py +0 -0
  62. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-add/expected.arrow +0 -0
  63. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-add/filter.arrow +0 -0
  64. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-add/input.arrow +0 -0
  65. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-multiply/expected.arrow +0 -0
  66. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-multiply/filter.arrow +0 -0
  67. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-multiply/input.arrow +0 -0
  68. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-negate/expected.arrow +0 -0
  69. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-negate/filter.arrow +0 -0
  70. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-negate/input.arrow +0 -0
  71. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-subtract/expected.arrow +0 -0
  72. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-subtract/filter.arrow +0 -0
  73. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/arithmetic-subtract/input.arrow +0 -0
  74. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/cast-integer-to-double/expected.arrow +0 -0
  75. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/cast-integer-to-double/filter.arrow +0 -0
  76. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/cast-integer-to-double/input.arrow +0 -0
  77. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-distinct_from/expected.arrow +0 -0
  78. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-distinct_from/filter.arrow +0 -0
  79. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-distinct_from/input.arrow +0 -0
  80. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-distinct_from/worker-expected.arrow +0 -0
  81. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-eq/expected.arrow +0 -0
  82. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-eq/filter.arrow +0 -0
  83. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-eq/input.arrow +0 -0
  84. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-eq/worker-expected.arrow +0 -0
  85. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ge/expected.arrow +0 -0
  86. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ge/filter.arrow +0 -0
  87. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ge/input.arrow +0 -0
  88. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ge/worker-expected.arrow +0 -0
  89. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-gt/expected.arrow +0 -0
  90. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-gt/filter.arrow +0 -0
  91. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-gt/input.arrow +0 -0
  92. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-gt/worker-expected.arrow +0 -0
  93. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-le/expected.arrow +0 -0
  94. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-le/filter.arrow +0 -0
  95. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-le/input.arrow +0 -0
  96. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-le/worker-expected.arrow +0 -0
  97. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-lt/expected.arrow +0 -0
  98. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-lt/filter.arrow +0 -0
  99. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-lt/input.arrow +0 -0
  100. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-lt/worker-expected.arrow +0 -0
  101. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ne/expected.arrow +0 -0
  102. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ne/filter.arrow +0 -0
  103. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ne/input.arrow +0 -0
  104. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-ne/worker-expected.arrow +0 -0
  105. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/expected.arrow +0 -0
  106. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/filter.arrow +0 -0
  107. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/input.arrow +0 -0
  108. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/worker-expected.arrow +0 -0
  109. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/delta-0.arrow +0 -0
  110. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/expected.arrow +0 -0
  111. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/filter.arrow +0 -0
  112. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/input.arrow +0 -0
  113. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-empty-noop/delta-0.arrow +0 -0
  114. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-empty-noop/expected.arrow +0 -0
  115. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-empty-noop/filter.arrow +0 -0
  116. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-empty-noop/input.arrow +0 -0
  117. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-0.arrow +0 -0
  118. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-1.arrow +0 -0
  119. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-2.arrow +0 -0
  120. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/expected.arrow +0 -0
  121. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/filter.arrow +0 -0
  122. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/input.arrow +0 -0
  123. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/empty-snapshot/expected.arrow +0 -0
  124. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/empty-snapshot/filter.arrow +0 -0
  125. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/empty-snapshot/input.arrow +0 -0
  126. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/empty-snapshot/worker-expected.arrow +0 -0
  127. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-cast-type-not-null/filter.arrow +0 -0
  128. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-cast-type-not-null/input.arrow +0 -0
  129. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-column-index/filter.arrow +0 -0
  130. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-column-index/input.arrow +0 -0
  131. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-column-name/filter.arrow +0 -0
  132. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-column-name/input.arrow +0 -0
  133. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-contextual-cast-without-session/filter.arrow +0 -0
  134. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-contextual-cast-without-session/input.arrow +0 -0
  135. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-duplicate-predicate-id/filter.arrow +0 -0
  136. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-duplicate-predicate-id/input.arrow +0 -0
  137. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-external-column-index/filter.arrow +0 -0
  138. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-external-column-index/input.arrow +0 -0
  139. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-external-column-index/join-keys-0.arrow +0 -0
  140. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-external-column-name/filter.arrow +0 -0
  141. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-external-column-name/input.arrow +0 -0
  142. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-external-column-name/join-keys-0.arrow +0 -0
  143. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-field-non-struct/filter.arrow +0 -0
  144. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-field-non-struct/input.arrow +0 -0
  145. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-in-payload-not-list/filter.arrow +0 -0
  146. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-in-payload-not-list/input.arrow +0 -0
  147. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-in-payload-null-list/filter.arrow +0 -0
  148. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-in-payload-null-list/input.arrow +0 -0
  149. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-invalid-overload/filter.arrow +0 -0
  150. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-invalid-overload/input.arrow +0 -0
  151. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-missing-literal/filter.arrow +0 -0
  152. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-missing-literal/input.arrow +0 -0
  153. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-non-boolean-root/filter.arrow +0 -0
  154. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-non-boolean-root/input.arrow +0 -0
  155. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-unknown-standard-function/filter.arrow +0 -0
  156. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/error-unknown-standard-function/input.arrow +0 -0
  157. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/external-in-nonzero-column/expected.arrow +0 -0
  158. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/external-in-nonzero-column/filter.arrow +0 -0
  159. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/external-in-nonzero-column/input.arrow +0 -0
  160. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/external-in-nonzero-column/join-keys-0.arrow +0 -0
  161. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/external-in-nonzero-column/worker-expected.arrow +0 -0
  162. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-contains/expected.arrow +0 -0
  163. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-contains/filter.arrow +0 -0
  164. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-contains/input.arrow +0 -0
  165. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-ends-with/expected.arrow +0 -0
  166. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-ends-with/filter.arrow +0 -0
  167. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-ends-with/input.arrow +0 -0
  168. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-list-contains/expected.arrow +0 -0
  169. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-list-contains/filter.arrow +0 -0
  170. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-list-contains/input.arrow +0 -0
  171. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-starts-with/expected.arrow +0 -0
  172. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-starts-with/filter.arrow +0 -0
  173. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/function-starts-with/input.arrow +0 -0
  174. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-empty/expected.arrow +0 -0
  175. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-empty/filter.arrow +0 -0
  176. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-empty/input.arrow +0 -0
  177. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-empty/worker-expected.arrow +0 -0
  178. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-with-null/expected.arrow +0 -0
  179. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-with-null/filter.arrow +0 -0
  180. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-with-null/input.arrow +0 -0
  181. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/in-with-null/worker-expected.arrow +0 -0
  182. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-not-null/expected.arrow +0 -0
  183. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-not-null/filter.arrow +0 -0
  184. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-not-null/input.arrow +0 -0
  185. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-not-null/worker-expected.arrow +0 -0
  186. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-null/expected.arrow +0 -0
  187. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-null/filter.arrow +0 -0
  188. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-null/input.arrow +0 -0
  189. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/is-null/worker-expected.arrow +0 -0
  190. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-and/expected.arrow +0 -0
  191. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-and/filter.arrow +0 -0
  192. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-and/input.arrow +0 -0
  193. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-not/expected.arrow +0 -0
  194. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-not/filter.arrow +0 -0
  195. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-not/input.arrow +0 -0
  196. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-or/expected.arrow +0 -0
  197. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-or/filter.arrow +0 -0
  198. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/kleene-or/input.arrow +0 -0
  199. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/nan-comparison/expected.arrow +0 -0
  200. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/nan-comparison/filter.arrow +0 -0
  201. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/nan-comparison/input.arrow +0 -0
  202. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/negative-zero-membership/expected.arrow +0 -0
  203. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/negative-zero-membership/filter.arrow +0 -0
  204. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/negative-zero-membership/input.arrow +0 -0
  205. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/nested-null-propagation/expected.arrow +0 -0
  206. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/nested-null-propagation/filter.arrow +0 -0
  207. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/nested-null-propagation/input.arrow +0 -0
  208. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-empty/expected.arrow +0 -0
  209. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-empty/filter.arrow +0 -0
  210. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-empty/input.arrow +0 -0
  211. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-empty/worker-expected.arrow +0 -0
  212. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-with-null/expected.arrow +0 -0
  213. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-with-null/filter.arrow +0 -0
  214. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-with-null/input.arrow +0 -0
  215. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/not-in-with-null/worker-expected.arrow +0 -0
  216. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/session-integer-division/expected.arrow +0 -0
  217. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/session-integer-division/filter.arrow +0 -0
  218. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime/session-integer-division/input.arrow +0 -0
  219. {vgi_python-0.41.0 → vgi_python-0.42.0}/conformance/filter-v2/runtime-manifest.json +0 -0
  220. {vgi_python-0.41.0 → vgi_python-0.42.0}/dist-vgi/.gitignore +0 -0
  221. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/aggregate-functions.md +0 -0
  222. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/arguments.md +0 -0
  223. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/auth.md +0 -0
  224. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/catalogs.md +0 -0
  225. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/client.md +0 -0
  226. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/exceptions.md +0 -0
  227. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/filters.md +0 -0
  228. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/functions.md +0 -0
  229. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/http.md +0 -0
  230. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/metadata.md +0 -0
  231. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/observability.md +0 -0
  232. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/storage.md +0 -0
  233. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/api/worker.md +0 -0
  234. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/argument-serialization.md +0 -0
  235. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/apple-touch-icon.png +0 -0
  236. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/favicon-16x16.png +0 -0
  237. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/favicon-32x32.png +0 -0
  238. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/favicon.ico +0 -0
  239. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/kinds/aggregate.svg +0 -0
  240. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/kinds/buffering.svg +0 -0
  241. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/kinds/scalar.svg +0 -0
  242. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/kinds/table-in-out.svg +0 -0
  243. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/kinds/table.svg +0 -0
  244. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/logo.png +0 -0
  245. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/social-card.png +0 -0
  246. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/assets/video-thumbnail.jpg +0 -0
  247. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/column-statistics.md +0 -0
  248. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/concepts/index.md +0 -0
  249. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/contributing-docs.md +0 -0
  250. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/filter-pushdown.md +0 -0
  251. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/generator-api.md +0 -0
  252. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/global-functions.md +0 -0
  253. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/catalogs.md +0 -0
  254. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/http-auth.md +0 -0
  255. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/index.md +0 -0
  256. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/iroh.md +0 -0
  257. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/pushdown-and-statistics.md +0 -0
  258. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/how-to/tailnet.md +0 -0
  259. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/index.md +0 -0
  260. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/lifecycle.md +0 -0
  261. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/metadata.md +0 -0
  262. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/overrides/main.html +0 -0
  263. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/protocol/index.md +0 -0
  264. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/protocol/vgi-catalog-query-pushdown-design.md +0 -0
  265. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/protocol/vgi-duckdb-filter-adapter.md +0 -0
  266. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/protocol/vgi-filter-encoding-v2-spec.md +0 -0
  267. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/protocol/vgi-protocol-proposed-changes.md +0 -0
  268. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/protocol/vgi-runtime-filter-artifacts.md +0 -0
  269. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/robots.txt +0 -0
  270. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/stylesheets/extra.css +0 -0
  271. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/tutorial/index.md +0 -0
  272. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/tutorial/scalar.md +0 -0
  273. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/tutorial/table.md +0 -0
  274. {vgi_python-0.41.0 → vgi_python-0.42.0}/docs/vgi-logo.png +0 -0
  275. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/batch_index_worker.py +0 -0
  276. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/cache_worker.py +0 -0
  277. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/calc_scalar_worker.py +0 -0
  278. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/calc_worker.py +0 -0
  279. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/copy_format_worker.py +0 -0
  280. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/filter_worker.py +0 -0
  281. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/greeting_scalar_worker.py +0 -0
  282. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/row_count_worker.py +0 -0
  283. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/series_streaming_worker.py +0 -0
  284. {vgi_python-0.41.0 → vgi_python-0.42.0}/examples/sum_worker.py +0 -0
  285. {vgi_python-0.41.0 → vgi_python-0.42.0}/identity.png +0 -0
  286. {vgi_python-0.41.0 → vgi_python-0.42.0}/mkdocs.yml +0 -0
  287. {vgi_python-0.41.0 → vgi_python-0.42.0}/packages/vgi-fixtures/LICENSE +0 -0
  288. {vgi_python-0.41.0 → vgi_python-0.42.0}/packages/vgi-fixtures/README.md +0 -0
  289. {vgi_python-0.41.0 → vgi_python-0.42.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
  290. {vgi_python-0.41.0 → vgi_python-0.42.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
  291. {vgi_python-0.41.0 → vgi_python-0.42.0}/packages/vgi-fixtures/pyproject.toml +0 -0
  292. {vgi_python-0.41.0 → vgi_python-0.42.0}/scripts/hosted_protocols_conformance.sh +0 -0
  293. {vgi_python-0.41.0 → vgi_python-0.42.0}/scripts/measure_startup.py +0 -0
  294. {vgi_python-0.41.0 → vgi_python-0.42.0}/scripts/regen_generated.py +0 -0
  295. {vgi_python-0.41.0 → vgi_python-0.42.0}/scripts/run_all_tests.sh +0 -0
  296. {vgi_python-0.41.0 → vgi_python-0.42.0}/test-data/generate.sh +0 -0
  297. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/__init__.py +0 -0
  298. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/_hosted_protocols_worker.py +0 -0
  299. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/_http_fixtures.py +0 -0
  300. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/__init__.py +0 -0
  301. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_attach_option.py +0 -0
  302. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_catalog_contents.py +0 -0
  303. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_catalog_interface.py +0 -0
  304. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_client_catalog.py +0 -0
  305. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_client_load_catalog.py +0 -0
  306. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_column_statistics.py +0 -0
  307. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_declarative.py +0 -0
  308. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_example_worker_catalog.py +0 -0
  309. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_integration.py +0 -0
  310. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_required_filters.py +0 -0
  311. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_scan_branches.py +0 -0
  312. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_serialization.py +0 -0
  313. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_setting.py +0 -0
  314. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_storage.py +0 -0
  315. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_time_travel.py +0 -0
  316. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/catalog/test_writable_table.py +0 -0
  317. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/__init__.py +0 -0
  318. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_aggregate_client.py +0 -0
  319. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_batch_metadata_callback.py +0 -0
  320. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_bind_and_join_keys.py +0 -0
  321. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_broken_pipe.py +0 -0
  322. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_cli.py +0 -0
  323. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_cli_catalog_functions.py +0 -0
  324. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_copy_client.py +0 -0
  325. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_http_response_budget.py +0 -0
  326. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_iroh_client.py +0 -0
  327. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_scan_branches_client.py +0 -0
  328. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_split_client.py +0 -0
  329. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_stop_force.py +0 -0
  330. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_table_column_statistics.py +0 -0
  331. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_time_travel_client.py +0 -0
  332. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/client/test_worker_debug.py +0 -0
  333. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/__init__.py +0 -0
  334. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/_stub.py +0 -0
  335. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/conftest.py +0 -0
  336. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_accumulate.py +0 -0
  337. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_aggregate.py +0 -0
  338. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_attach.py +0 -0
  339. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_bearer_auth.py +0 -0
  340. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_const_param_enforcement.py +0 -0
  341. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_container.py +0 -0
  342. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_copy_from.py +0 -0
  343. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_copy_to.py +0 -0
  344. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_directory_parity.py +0 -0
  345. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_function_inventory.py +0 -0
  346. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_github.py +0 -0
  347. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_http_client.py +0 -0
  348. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_http_external_location.py +0 -0
  349. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_http_upload_url.py +0 -0
  350. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_macro.py +0 -0
  351. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_overload.py +0 -0
  352. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_protocol_inventory.py +0 -0
  353. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_protocol_version.py +0 -0
  354. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_resumable_scan.py +0 -0
  355. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_scalar.py +0 -0
  356. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
  357. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_secret.py +0 -0
  358. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_settings.py +0 -0
  359. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_splits.py +0 -0
  360. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_table.py +0 -0
  361. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_table_in_out.py +0 -0
  362. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_view.py +0 -0
  363. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conformance/test_writable.py +0 -0
  364. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/conftest.py +0 -0
  365. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/anchor_len_overrun.bin +0 -0
  366. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/bad_fingerprint.bin +0 -0
  367. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/bad_flags_unsealed_but_key_present.bin +0 -0
  368. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/bad_version.bin +0 -0
  369. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/generate.py +0 -0
  370. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/manifest.json +0 -0
  371. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/reserved_flag_bit.bin +0 -0
  372. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/stale_anchor.bin +0 -0
  373. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/truncated.bin +0 -0
  374. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/valid_sealed.bin +0 -0
  375. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/data/split_tokens/valid_unsealed.bin +0 -0
  376. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/__init__.py +0 -0
  377. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_bernoulli_function.py +0 -0
  378. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_binary_packet_function.py +0 -0
  379. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_client.py +0 -0
  380. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_conditional_message_function.py +0 -0
  381. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_hash_seed_function.py +0 -0
  382. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
  383. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_multiply_function.py +0 -0
  384. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_random_bytes_function.py +0 -0
  385. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/scalar/test_return_secret_value_function.py +0 -0
  386. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/__init__.py +0 -0
  387. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/__init__.py +0 -0
  388. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_constant_columns_function.py +0 -0
  389. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_double_sequence_function.py +0 -0
  390. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_exception_function.py +0 -0
  391. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_filter_echo_function.py +0 -0
  392. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_logging_function.py +0 -0
  393. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
  394. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_partitioned_function.py +0 -0
  395. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_projected_data_function.py +0 -0
  396. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_sequence_function.py +0 -0
  397. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_settings_function.py +0 -0
  398. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_struct_settings_function.py +0 -0
  399. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
  400. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table/test_wide_columns.py +0 -0
  401. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/__init__.py +0 -0
  402. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/__init__.py +0 -0
  403. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
  404. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
  405. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
  406. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
  407. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
  408. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
  409. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
  410. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/test_blended_exchange.py +0 -0
  411. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/test_blended_metadata.py +0 -0
  412. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/test_client.py +0 -0
  413. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/table_in_out/test_table_buffering_empty_input.py +0 -0
  414. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/tailnet/Dockerfile +0 -0
  415. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/tailnet/__init__.py +0 -0
  416. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/tailnet/compose.yaml +0 -0
  417. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/tailnet/probe.py +0 -0
  418. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/tailnet/run.sh +0 -0
  419. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/tailnet/test_worker.py +0 -0
  420. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/tailnet/worker.py +0 -0
  421. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_access_log_audit.py +0 -0
  422. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_aggregate_function.py +0 -0
  423. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_argument_spec.py +0 -0
  424. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_auth.py +0 -0
  425. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_bind_exceptions.py +0 -0
  426. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_bind_request_at_clause.py +0 -0
  427. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_bound_storage_conformance.py +0 -0
  428. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_cache_control.py +0 -0
  429. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_call_state_attach.py +0 -0
  430. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_catalog_auth_binding.py +0 -0
  431. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_client_oauth.py +0 -0
  432. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_codegen_request_inventory.py +0 -0
  433. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_copy_from_function.py +0 -0
  434. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_copy_to_function.py +0 -0
  435. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_docstrings.py +0 -0
  436. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_documentation_examples.py +0 -0
  437. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_dynamic_filter_http_turns.py +0 -0
  438. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_example_function_arg_types.py +0 -0
  439. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_examples_workers.py +0 -0
  440. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_exception_handling.py +0 -0
  441. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_exceptions.py +0 -0
  442. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_filter_pushdown.py +0 -0
  443. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_filter_pushdown_extension.py +0 -0
  444. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_filter_v2.py +0 -0
  445. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_filter_v2_builder.py +0 -0
  446. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_filter_v2_runtime_corpus.py +0 -0
  447. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_filter_v2_spec_schema.py +0 -0
  448. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_fixture_catalog_parity.py +0 -0
  449. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_function_shape_mismatch.py +0 -0
  450. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_function_storage.py +0 -0
  451. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_function_storage_azure_sql.py +0 -0
  452. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_function_storage_cf_do.py +0 -0
  453. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_function_storage_cf_do_integration.py +0 -0
  454. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_function_storage_conformance.py +0 -0
  455. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_cpp_constants.py +0 -0
  456. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_cpp_protocol_name.py +0 -0
  457. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_cpp_protocol_version.py +0 -0
  458. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_cpp_request_builders.py +0 -0
  459. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_cpp_schemas.py +0 -0
  460. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_cpp_secret.py +0 -0
  461. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_csharp.py +0 -0
  462. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_go_schemas.py +0 -0
  463. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_go_types.py +0 -0
  464. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_java_schemas.py +0 -0
  465. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_java_types.py +0 -0
  466. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_protocol_version.py +0 -0
  467. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_rust_request_builders.py +0 -0
  468. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_rust_schemas.py +0 -0
  469. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_rust_types.py +0 -0
  470. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_schemas_cross_lang.py +0 -0
  471. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_ts_client.py +0 -0
  472. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_ts_schemas.py +0 -0
  473. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_generated_ts_types.py +0 -0
  474. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_hosted_protocols.py +0 -0
  475. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_http_demo_storage.py +0 -0
  476. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_http_s3_offload_input.py +0 -0
  477. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_http_s3_offload_output.py +0 -0
  478. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_import_side_effects.py +0 -0
  479. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_landing_discovery.py +0 -0
  480. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_launch_transport.py +0 -0
  481. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_metadata.py +0 -0
  482. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_mypy_consolidated.py +0 -0
  483. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_nest_tensor.py +0 -0
  484. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_otel.py +0 -0
  485. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_projection_enforcement.py +0 -0
  486. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_projection_repro.py +0 -0
  487. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_protocol_classes.py +0 -0
  488. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_resolved_secrets.py +0 -0
  489. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_schema_paths_v2.py +0 -0
  490. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_schema_scoped_functions.py +0 -0
  491. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_schema_utils.py +0 -0
  492. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_serve.py +0 -0
  493. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_setting_secret_annotations.py +0 -0
  494. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_signing_key.py +0 -0
  495. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_split_token.py +0 -0
  496. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_subprocess_transport.py +0 -0
  497. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_table_buffering_function.py +0 -0
  498. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_table_function_dynamic_to_string.py +0 -0
  499. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_tcp_transport.py +0 -0
  500. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_type_bounds.py +0 -0
  501. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_union_argument.py +0 -0
  502. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_wire_record_schema_parity.py +0 -0
  503. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_worker.py +0 -0
  504. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_worker_cli.py +0 -0
  505. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_worker_page.py +0 -0
  506. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/test_write_results.py +0 -0
  507. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/transactor/__init__.py +0 -0
  508. {vgi_python-0.41.0 → vgi_python-0.42.0}/tests/transactor/test_transactor.py +0 -0
  509. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/__init__.py +0 -0
  510. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_storage_profile.py +0 -0
  511. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/__init__.py +0 -0
  512. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
  513. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
  514. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
  515. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
  516. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
  517. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
  518. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
  519. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
  520. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
  521. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
  522. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
  523. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
  524. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
  525. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
  526. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/attach_options.py +0 -0
  527. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/bad_enum.py +0 -0
  528. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
  529. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/cancellable.py +0 -0
  530. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/catalog.py +0 -0
  531. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/catalog_contents.py +0 -0
  532. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/companion.py +0 -0
  533. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/copy_from.py +0 -0
  534. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/copy_to.py +0 -0
  535. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/global_functions.py +0 -0
  536. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
  537. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
  538. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
  539. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
  540. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
  541. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
  542. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
  543. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
  544. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
  545. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
  546. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
  547. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
  548. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
  549. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
  550. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
  551. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
  552. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
  553. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
  554. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
  555. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
  556. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/secret_cache.py +0 -0
  557. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/simple_writable.py +0 -0
  558. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/__init__.py +0 -0
  559. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/_common.py +0 -0
  560. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
  561. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
  562. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/cache.py +0 -0
  563. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
  564. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/filters.py +0 -0
  565. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
  566. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/make_series.py +0 -0
  567. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/misc.py +0 -0
  568. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
  569. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/pairs.py +0 -0
  570. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
  571. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
  572. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
  573. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
  574. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
  575. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/same_name_schemas.py +0 -0
  576. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/sequence.py +0 -0
  577. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/settings.py +0 -0
  578. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/splits.py +0 -0
  579. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
  580. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
  581. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
  582. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/versioned.py +0 -0
  583. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table/wide.py +0 -0
  584. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table_in_out.py +0 -0
  585. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
  586. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
  587. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/versioned.py +0 -0
  588. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
  589. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/worker.py +0 -0
  590. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
  591. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/writable/generic.py +0 -0
  592. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/writable/table.py +0 -0
  593. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/_test_fixtures/writable/worker.py +0 -0
  594. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/aggregate_function.py +0 -0
  595. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/argument_spec.py +0 -0
  596. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/arguments.py +0 -0
  597. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/attach_header.py +0 -0
  598. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/auth.py +0 -0
  599. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/cache_control.py +0 -0
  600. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/__init__.py +0 -0
  601. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/_descriptor_spec.py +0 -0
  602. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/attach_option.py +0 -0
  603. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/catalog_interface.py +0 -0
  604. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/descriptors.py +0 -0
  605. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/duckdb_statistics.py +0 -0
  606. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/secret_type.py +0 -0
  607. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/setting.py +0 -0
  608. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/catalog/storage.py +0 -0
  609. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/__init__.py +0 -0
  610. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/aggregate.py +0 -0
  611. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/catalog_mixin.py +0 -0
  612. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/cli.py +0 -0
  613. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/cli_catalog.py +0 -0
  614. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/cli_schema.py +0 -0
  615. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/cli_table.py +0 -0
  616. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/cli_transaction.py +0 -0
  617. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/cli_utils.py +0 -0
  618. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/cli_view.py +0 -0
  619. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/client.py +0 -0
  620. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/client/errors.py +0 -0
  621. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/__init__.py +0 -0
  622. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/_common.py +0 -0
  623. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_constants.py +0 -0
  624. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_protocol_name.py +0 -0
  625. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_protocol_version.py +0 -0
  626. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_request_builders.py +0 -0
  627. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_schemas.py +0 -0
  628. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
  629. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
  630. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
  631. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/csharp_schemas.py +0 -0
  632. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/csharp_types.py +0 -0
  633. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/go_schemas.py +0 -0
  634. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/go_types.py +0 -0
  635. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/java_schemas.py +0 -0
  636. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/java_types.py +0 -0
  637. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/protocol_version.py +0 -0
  638. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/rust_request_builders.py +0 -0
  639. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/rust_schemas.py +0 -0
  640. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/rust_types.py +0 -0
  641. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/ts_client.py +0 -0
  642. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/ts_schemas.py +0 -0
  643. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/codegen/ts_types.py +0 -0
  644. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/copy_from_function.py +0 -0
  645. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/copy_to_function.py +0 -0
  646. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/exceptions.py +0 -0
  647. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/filter_v2.py +0 -0
  648. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/filter_v2_builder.py +0 -0
  649. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/function.py +0 -0
  650. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/function_storage.py +0 -0
  651. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/function_storage_azure_sql.py +0 -0
  652. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/function_storage_cf_do.py +0 -0
  653. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/http/__init__.py +0 -0
  654. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/http/demo_storage.py +0 -0
  655. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/http/landing.html +0 -0
  656. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/http/landing_page.py +0 -0
  657. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/http/vgi-client.js +0 -0
  658. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/http/worker_page.py +0 -0
  659. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/invocation.py +0 -0
  660. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/logging_config.py +0 -0
  661. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/meta_worker.py +0 -0
  662. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/metadata.py +0 -0
  663. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/otel.py +0 -0
  664. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/profiling.py +0 -0
  665. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/protocol.py +0 -0
  666. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/protocol_version.txt +0 -0
  667. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/py.typed +0 -0
  668. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/scalar_function.py +0 -0
  669. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/schema_path.py +0 -0
  670. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/schema_utils.py +0 -0
  671. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/secret_protocol.py +0 -0
  672. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/secret_service.py +0 -0
  673. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/split_token.py +0 -0
  674. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/table_buffering_function.py +0 -0
  675. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/table_filter_pushdown.py +0 -0
  676. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/table_function.py +0 -0
  677. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/table_in_out_function.py +0 -0
  678. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/transactor/__init__.py +0 -0
  679. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/transactor/_duckdb_compat.py +0 -0
  680. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/transactor/client.py +0 -0
  681. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/transactor/protocol.py +0 -0
  682. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/transactor/server.py +0 -0
  683. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/worker.py +0 -0
  684. {vgi_python-0.41.0 → vgi_python-0.42.0}/vgi/write_results.py +0 -0
  685. {vgi_python-0.41.0 → vgi_python-0.42.0}/wrangler.jsonc +0 -0
@@ -297,6 +297,7 @@ vgi-client --input data.parquet --function sum_all_columns --worker vgi-fixture-
297
297
  | `VGI_OAUTH_DEVICE_CODE_CLIENT_ID` | Client ID for device-code flow (optional, URL-safe chars only) |
298
298
  | `VGI_OAUTH_DEVICE_CODE_CLIENT_SECRET` | Client secret for device-code flow (optional, URL-safe chars only) |
299
299
  | `VGI_OAUTH_USE_ID_TOKEN` | When `1`/`true`/`yes`, clients use OIDC `id_token` as Bearer instead of `access_token` |
300
+ | `VGI_RPC_GRANT_KEYS` | Comma-separated base64 32-byte sealed-grant keys (first mints, all verify); enables grants as HTTP bearers. Also `VGI_RPC_GRANT_AUDIENCE`, `VGI_RPC_GRANT_MAX_TTL_SECONDS` |
300
301
  | `VGI_INTROSPECT_PRINCIPALS` | Comma-separated principals permitted to call `vgi_rpc.Identity.v1`'s `introspect_token`. Required — no permissive default — whenever the worker implements `resolve_token()` (see below) |
301
302
  | `VGI_WORKER_ACCESS_LOG_SAMPLE` | Fraction of *successful* calls to keep in the access log, `0.0`–`1.0`. Errors are always kept; the decision is per call, so every record of one stream shares a fate |
302
303
  | `VGI_WORKER_ACCESS_LOG_ASYNC` | When `1`/`true`/`yes`, emit access-log records from a listener thread. Bounded queue; full means drop, and a crash loses whatever is queued |
@@ -484,6 +485,24 @@ sidecar outage raised as one is read as "not my credential, try the next" and
484
485
  ends up a 401 from the end of the chain, restarting every session in the fleet
485
486
  over a thirty-second blip.
486
487
 
488
+ ### Grants and `resolve_token` as HTTP Bearers
489
+
490
+ With `VGI_RPC_GRANT_KEYS` (or `vgi-serve --grant-key`) set, the HTTP worker
491
+ hosts Identity even without hooks. It mints sealed `vgig1.` grants through
492
+ `issue_grant`, unless the worker overrides `mint_grant`, and accepts them back
493
+ as `Authorization: Bearer` credentials, authenticated as the grant's owner. A
494
+ worker that overrides `resolve_token` also has it consulted for bearers. The
495
+ order is the deployment's authenticator, then grants, then `resolve_token`. A
496
+ bad `vgig1.` token is a 401 and never reaches `resolve_token`. vgi-rpc composes
497
+ this in `make_wsgi_app`. vgi-python resolves the keys in
498
+ `vgi.rpc_server.resolve_grant_keys` and passes them explicitly to `RpcServer`
499
+ (`None` off HTTP, never vgi-rpc's `"env"` default), so grants stay HTTP-only. It
500
+ also puts the bearers *inside* VGI's proxy-proof gate
501
+ (`serve._compose_identity_bearer`), because vgi-rpc refuses to OR them beside
502
+ one. Allowlist rules are unchanged. See `docs/authentication.md` and
503
+ `tests/test_grant_auth.py`, which also runs the shared
504
+ `grant_token_vectors.json` through `create_app`.
505
+
487
506
  ### Hosting Additional Protocols (`hosted_protocols`)
488
507
 
489
508
  Every transport (stdio, unix/named pipe, TCP, Iroh, HTTP) builds its `RpcServer`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vgi-python
3
- Version: 0.41.0
3
+ Version: 0.42.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
@@ -162,7 +162,7 @@ Requires-Dist: httpx2>=2.12.0
162
162
  Requires-Dist: platformdirs
163
163
  Requires-Dist: pyarrow
164
164
  Requires-Dist: typer>=0.9
165
- Requires-Dist: vgi-rpc>=0.48.0
165
+ Requires-Dist: vgi-rpc>=0.49.0
166
166
  Provides-Extra: azure
167
167
  Requires-Dist: azure-identity>=1.16.0; extra == 'azure'
168
168
  Requires-Dist: pymssql>=2.3.0; extra == 'azure'
@@ -32,7 +32,7 @@ added incrementally.
32
32
  | [Auth & Secrets](auth.md) | `AuthContext`, `CallContext`, bearer/JWT authenticators, secret protocol | HTTP: `[http]`; JWT: `[oauth]` |
33
33
  | [Observability](observability.md) | OpenTelemetry tracing, worker logging configuration | `[otel]` for tracing |
34
34
  | [HTTP](http.md) | Worker page, blob storage, request-size middleware | `pip install vgi-python[http]` |
35
- | [Transactor](transactor.md) | `TransactorClient`, `TransactorProtocol` | `pip install vgi-python[transactor]` |
35
+ | [Transactor](transactor.md) | `TransactorClient`, `TransactorProtocol` | `[transactor]` extra and a [compatible engine build](transactor.md#runtime-requirements) |
36
36
  | [Exceptions](exceptions.md) | VGI exception types | — |
37
37
 
38
38
  ## Import Convention
@@ -0,0 +1,32 @@
1
+ # Transactor
2
+
3
+ !!! note "Advanced — reference only"
4
+ The transactor is an advanced feature without a dedicated how-to guide yet. This page is the
5
+ API reference; start from the [tutorial](../tutorial/index.md) and
6
+ [function patterns](../how-to/function-patterns.md) if you're new to VGI.
7
+
8
+ The transactor is a long-lived subprocess that gives worker functions transactional access to a
9
+ database, mediated by `TransactorClient` over the `TransactorProtocol`.
10
+
11
+ ## Runtime requirements
12
+
13
+ The bundled transactor requires both:
14
+
15
+ - `pip install 'vgi-python[transactor]'` for its Python dependencies.
16
+ - A VGI fork build of `duckdb-python` providing `DuckDBPyConnection.subcursor()`,
17
+ which lets reads share an open write transaction. This extension has not yet
18
+ been merged into Haybarn or upstream DuckDB; installing the extra alone is
19
+ insufficient.
20
+
21
+ Engine resolution prefers `haybarn` when installed, then falls back to `duckdb`.
22
+ Use an environment where the selected engine provides `subcursor()`; installing
23
+ a compatible `duckdb` build alongside an incompatible `haybarn` installation
24
+ does not override that preference.
25
+
26
+ These requirements apply to the bundled transactor. Workers can implement
27
+ [table writes](../catalog-interface.md#table-writes-and-indexes) against their own
28
+ backing data sources without using it.
29
+
30
+ ## API
31
+
32
+ ::: vgi.transactor
@@ -24,7 +24,7 @@ the principal in the `AuthContext` available to functions.
24
24
  | Variable | Description |
25
25
  |----------|-------------|
26
26
  | `VGI_BEARER_TOKENS` | Comma-separated `token=principal` pairs for static bearer auth |
27
- | `VGI_JWT_ISSUER` | JWT issuer URL (requires `vgi[oauth]` extra) |
27
+ | `VGI_JWT_ISSUER` | JWT issuer URL (requires `vgi-python[oauth]` extra) |
28
28
  | `VGI_JWT_AUDIENCE` | JWT audience string, comma-separated for multiple audiences (required when `VGI_JWT_ISSUER` is set) |
29
29
  | `VGI_JWT_JWKS_URI` | JWKS endpoint URL (auto-discovered from issuer if omitted) |
30
30
  | `VGI_OAUTH_RESOURCE` | OAuth resource URL for RFC 9728 metadata |
@@ -39,6 +39,48 @@ When both `VGI_BEARER_TOKENS` and `VGI_JWT_ISSUER` are set, they are
39
39
  chained — JWT validation is attempted first, falling back to bearer token
40
40
  lookup.
41
41
 
42
+ ## Grants and resolved tokens as bearer credentials
43
+
44
+ `vgi_rpc.Identity.v1`'s `issue_grant` mints a standing credential that
45
+ unattended automation later presents as an ordinary bearer. Over HTTP the
46
+ worker accepts two kinds of identity credential after the deployment's own
47
+ authenticator:
48
+
49
+ 1. **Sealed grants** (opt-in). Set `VGI_RPC_GRANT_KEYS` (or
50
+ `vgi-serve --http --grant-key KEY`, repeatable). `issue_grant` then mints a
51
+ `vgig1.` grant sealed with the first key, unless the worker overrides
52
+ `mint_grant`. Every key verifies, so to rotate you add the new key first and
53
+ drop the old one once its grants have expired. A request carrying
54
+ `Authorization: Bearer vgig1.…` is authenticated as the grant's owner, with
55
+ `domain="grant"` and claims `grant_id`, `scopes` and `purpose`. The claims
56
+ carry no `auth_time`, so a grant cannot mint another grant.
57
+ 2. **`resolve_token`**. A worker that overrides
58
+ [`Worker.resolve_token`][vgi.worker.Worker.resolve_token] has it consulted
59
+ for any other bearer, with `domain="token"`. `None` means the credential is
60
+ unknown, which is a 401 unless something else accepts it.
61
+ `AuthUnavailableError` is a 503 with the hook's `Retry-After`.
62
+
63
+ The order is the deployment's authenticator (JWT, static bearer), then sealed
64
+ grants, then `resolve_token`. A `vgig1.` token that does not verify is a 401
65
+ that stops the chain: it never reaches `resolve_token`. A JWS-shaped token or
66
+ one over 4096 bytes never reaches the hook either. Your own `authenticate`
67
+ callback must raise `ValueError` for a credential it does not recognise, so the
68
+ chain moves on. One that answers anonymous for every request ends the chain
69
+ before grants are checked. With no authenticator configured, a request with no
70
+ `Authorization` header stays anonymous as before.
71
+
72
+ | Variable | Description |
73
+ |----------|-------------|
74
+ | `VGI_RPC_GRANT_KEYS` | Comma-separated standard-base64 keys, 32 bytes each. The first mints and all verify. Unset means grants are off. A malformed key stops startup |
75
+ | `VGI_RPC_GRANT_AUDIENCE` | Bound into every grant, so two deployments that share a key still reject each other's grants |
76
+ | `VGI_RPC_GRANT_MAX_TTL_SECONDS` | Ceiling on a grant's lifetime (default 7 days) |
77
+
78
+ The startup rules are unchanged. Overriding `resolve_token` still requires
79
+ `VGI_INTROSPECT_PRINCIPALS`. Grant keys alone need no allowlist, because
80
+ minting answers only for the caller. Grants and `resolve_token` bearers are
81
+ HTTP-only, like the rest of Identity. When `VGI_PROXY_PROOF_MODE` is on, both
82
+ are accepted only *inside* the proxy-proof gate, never as an alternative to it.
83
+
42
84
  ## Programmatic API
43
85
 
44
86
  ```python test="skip"
@@ -944,7 +944,7 @@ if __name__ == "__main__":
944
944
 
945
945
  ---
946
946
 
947
- ## API Limitations
947
+ ## Catalog capabilities and limitations { #api-limitations }
948
948
 
949
949
  The current CatalogInterface has the following limitations:
950
950
 
@@ -952,8 +952,33 @@ The current CatalogInterface has the following limitations:
952
952
  - **Tags**: Cannot be updated after object creation
953
953
  - **Schema metadata**: Comments and tags cannot be updated on schemas
954
954
  - **Constraints**: Only NOT NULL can be added/dropped (no ALTER for UNIQUE/CHECK)
955
- - **Indexes**: Not supported
956
- - **INSERT/UPDATE/DELETE**: Not yet implemented (metadata only)
955
+
956
+ ### Table writes and indexes
957
+
958
+ `INSERT`, `UPDATE`, and `DELETE` are supported when the catalog supplies a write
959
+ function for the operation. For declarative catalogs, configure the
960
+ [`Table`][vgi.catalog.descriptors.Table] descriptor:
961
+
962
+ | Operation | Descriptor field | Requirement |
963
+ |-----------|------------------|-------------|
964
+ | `INSERT` | `insert_function` | A `TableInOutGenerator` that accepts rows to insert |
965
+ | `UPDATE` | `update_function` | A write function and a scan `function` that provides row IDs |
966
+ | `DELETE` | `delete_function` | A write function and a scan `function` that provides row IDs |
967
+
968
+ Each field defaults to `None`, which leaves that operation unsupported. Custom
969
+ catalogs implement `table_insert_function_get()`, `table_update_function_get()`,
970
+ or `table_delete_function_get()` to return the corresponding `ScanFunctionResult`.
971
+ The worker's write functions implement the changes to the backing data source;
972
+ declaring a table alone does not make it writable.
973
+
974
+ `ReadOnlyCatalogInterface` rejects catalog DDL, but can expose these write functions
975
+ on declarative tables. Table writes do not require the bundled
976
+ [transactor](api/transactor.md); that is an optional database-access service with
977
+ additional engine requirements.
978
+
979
+ Index metadata can be declared with [`Index`][vgi.catalog.descriptors.Index]. Custom
980
+ catalogs can implement `index_get()`, `index_create()`, and `index_drop()`; support
981
+ depends on the catalog implementation and backing data source.
957
982
 
958
983
  ---
959
984
 
@@ -545,7 +545,7 @@ vgi-fixture-worker --log-format json
545
545
  | `VGI_QUIET=1` | Suppress the interactive-terminal startup warning (same as `--quiet`) |
546
546
  | `VGI_FILTER_DEBUG=1` | Enable filter pushdown debug logging |
547
547
  | `VGI_BEARER_TOKENS` | Comma-separated `token=principal` pairs for static bearer auth (HTTP only) |
548
- | `VGI_JWT_ISSUER` | JWT issuer URL for JWT/JWKS auth (requires `vgi[oauth]` extra) |
548
+ | `VGI_JWT_ISSUER` | JWT issuer URL for JWT/JWKS auth (requires `vgi-python[oauth]` extra) |
549
549
  | `VGI_JWT_AUDIENCE` | JWT audience string, comma-separated for multiple audiences (required when `VGI_JWT_ISSUER` is set) |
550
550
  | `VGI_JWT_JWKS_URI` | JWKS endpoint URL (auto-discovered if omitted) |
551
551
  | `VGI_OAUTH_RESOURCE` | OAuth resource URL for RFC 9728 metadata |
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "How to write each of the four VGI function patterns: scalar, table, table-in-out, and aggregate — with a complete runnable worker for each."
2
+ description: "How to write each of the five VGI function patterns: scalar, table, table-in-out, aggregate, and buffering — with a complete runnable worker for each."
3
3
  ---
4
4
 
5
5
  # Function patterns
@@ -178,11 +178,14 @@ ATTACH 'aggregates' (TYPE vgi, LOCATION 'uv run sum_worker.py');
178
178
  SELECT category, aggregates.vgi_sum(value) FROM t GROUP BY category;
179
179
  ```
180
180
 
181
- ??? info "State must be an `ArrowSerializableDataclass`"
182
- Table generators and aggregates keep state between calls. Because that state is serialized
183
- across parallel workers (aggregates) and HTTP round-trips, the framework requires it to extend
184
- `ArrowSerializableDataclass`. Annotate fields with `ArrowType(...)` so the wire type is
185
- explicit.
181
+ ??? info "State must be serializable"
182
+ Table generators and aggregates keep state between calls. A state type must provide
183
+ `serialize_to_bytes()` and `deserialize_from_bytes()` so the framework can carry it across
184
+ HTTP round-trips or persist it between aggregate calls. `ArrowSerializableDataclass`
185
+ implements these methods for you and is the usual starting point. Custom state types can
186
+ implement the same [`StreamStateCodec`][vgi.function.StreamStateCodec] contract without
187
+ inheriting from `ArrowSerializableDataclass`. See
188
+ [State Class](../aggregate-functions.md#state-class) for both approaches.
186
189
 
187
190
  ## Buffering
188
191
 
@@ -22,9 +22,11 @@ function that coordinates partial results across workers.
22
22
 
23
23
  ## Two kinds of "state" — don't confuse them
24
24
 
25
- - **Generator cursor state** — the small `ArrowSerializableDataclass` a table generator keeps
26
- *within one scan* (see [streaming with state](function-patterns.md#streaming-with-state)). It
27
- lives in the worker for the duration of the call.
25
+ - **Generator cursor state** — the small serializable object a table generator keeps
26
+ *within one scan* (see [streaming with state](function-patterns.md#streaming-with-state)).
27
+ Over HTTP, the framework serializes it between requests. `ArrowSerializableDataclass`
28
+ supplies the serialization methods; custom types can implement
29
+ [`StreamStateCodec`][vgi.function.StreamStateCodec] instead.
28
30
  - **Shared storage** (this page) — state that must outlive a single call or be shared across
29
31
  **separate worker processes**, e.g. combining partial aggregate results. This is backed by a
30
32
  pluggable store.
@@ -10,7 +10,7 @@ variable.
10
10
  | Backend | Value | Use Case | Dependencies |
11
11
  |---------|-------|----------|-------------|
12
12
  | SQLite | `sqlite` (default) | Local / subprocess transport | None (stdlib) |
13
- | Azure SQL | `azure-sql` | Azure cloud deployments | `vgi[azure]` |
13
+ | Azure SQL | `azure-sql` | Azure cloud deployments | `vgi-python[azure]` |
14
14
  | Cloudflare DO | `cloudflare-do` | Edge / multi-cloud deployments | None (stdlib) |
15
15
 
16
16
  ## SQLite (Default)
@@ -36,7 +36,7 @@ workers run on separate hosts.
36
36
  1. Install the Azure extra:
37
37
 
38
38
  ```bash
39
- pip install vgi[azure]
39
+ pip install 'vgi-python[azure]'
40
40
  ```
41
41
 
42
42
  2. Create an Azure SQL Database (Serverless recommended for cost):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vgi-python"
3
- version = "0.41.0"
3
+ version = "0.42.0"
4
4
  description = "Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow"
5
5
  readme = "README.md"
6
6
  keywords = [
@@ -40,7 +40,7 @@ dependencies = [
40
40
  "pyarrow",
41
41
  "typer>=0.9",
42
42
  "platformdirs",
43
- "vgi-rpc>=0.48.0",
43
+ "vgi-rpc>=0.49.0",
44
44
  "httpx2>=2.12.0",
45
45
  ]
46
46
 
@@ -0,0 +1,290 @@
1
+ # Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+
3
+ """Identity credentials accepted as HTTP bearers: sealed grants and ``resolve_token``.
4
+
5
+ vgi-rpc's ``Identity.v1`` mints grants "presented later by unattended
6
+ automation as an ordinary bearer". These tests close that loop through
7
+ vgi-python's own HTTP surface (``create_app``), not vgi-rpc in isolation:
8
+
9
+ - with ``VGI_RPC_GRANT_KEYS`` set, ``issue_grant`` mints a sealed grant and a
10
+ ``vgi.v2`` call presenting it is authenticated as the grant's owner;
11
+ - a worker that overrides ``resolve_token`` has it consulted for bearers;
12
+ - the shared vectors (``vgi_rpc/conformance/grant_token_vectors.json``) are
13
+ accepted and rejected through the full chain;
14
+ - VGI's proxy-proof gate still guards every request when grants are on.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import base64
20
+ import json
21
+ import time
22
+ import types
23
+ from collections.abc import Iterator
24
+ from importlib.resources import files
25
+ from typing import Any
26
+
27
+ import pyarrow as pa
28
+ import pytest
29
+ from vgi_rpc.grants import GRANT_KEYS_ENV, GrantKeys, mint_grant_token
30
+ from vgi_rpc.http import http_connect
31
+ from vgi_rpc.http._testing import _SyncTestClient
32
+ from vgi_rpc.rpc import AuthContext
33
+ from vgi_rpc.rpc._token_identity import Identity
34
+
35
+ from tests.test_serve import _PeerAuthWorker
36
+ from vgi.arguments import Arguments
37
+ from vgi.auth import TokenIdentity
38
+ from vgi.client import Client, ClientError
39
+ from vgi.rpc_server import build_rpc_server, resolve_grant_keys
40
+ from vgi.serve import create_app
41
+
42
+ _KEY_B64 = base64.b64encode(bytes(range(32))).decode()
43
+ _OTHER_KEY_B64 = base64.b64encode(bytes(range(32, 64))).decode()
44
+ _SIGNING_KEY = b"grant-auth-test-signing-key-0001"
45
+ _IDENTITY = "vgi_rpc.Identity.v1"
46
+ _GRANT_ENV = (GRANT_KEYS_ENV, "VGI_RPC_GRANT_AUDIENCE", "VGI_RPC_GRANT_MAX_TTL_SECONDS")
47
+
48
+ _VECTORS = json.loads(files("vgi_rpc.conformance").joinpath("grant_token_vectors.json").read_text(encoding="utf-8"))
49
+
50
+
51
+ @pytest.fixture(autouse=True)
52
+ def _clean_env(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
53
+ """No ambient grant, auth or allowlist configuration leaks into a test."""
54
+ for key in (*_GRANT_ENV, "VGI_INTROSPECT_PRINCIPALS", "VGI_BEARER_TOKENS", "VGI_JWT_ISSUER"):
55
+ monkeypatch.delenv(key, raising=False)
56
+ for key in ("VGI_PROXY_PROOF_MODE", "VGI_PROXY_PROOF_ORIGIN_ID", "VGI_PROXY_PROOF_SECRETS"):
57
+ monkeypatch.delenv(key, raising=False)
58
+ yield
59
+
60
+
61
+ def _header_authenticate(req: Any) -> AuthContext:
62
+ """Deployment authenticator: ``X-Test-Principal`` with a fresh ``auth_time``.
63
+
64
+ Raises ``ValueError`` for a bare bearer, as the chain contract requires, so
65
+ grants and ``resolve_token`` get to answer it.
66
+ """
67
+ principal = req.get_header("X-Test-Principal")
68
+ if principal:
69
+ return AuthContext(domain="test", authenticated=True, principal=principal, claims={"auth_time": time.time()})
70
+ if req.get_header("Authorization"):
71
+ raise ValueError("not a test-principal request")
72
+ return AuthContext.anonymous()
73
+
74
+
75
+ def _whoami(app: Any, *, bearer: str) -> str:
76
+ """Call ``peer_auth_echo`` (a vgi.v2 scalar function) and return its principal."""
77
+ client = _SyncTestClient(app, default_headers={"Authorization": f"Bearer {bearer}"})
78
+ with Client.from_http("http://vgi.test", httpx_client=client) as vgi:
79
+ out = list(
80
+ vgi.scalar_function(
81
+ function_name="peer_auth_echo",
82
+ schema_path=["main"],
83
+ arguments=Arguments(positional=(pa.scalar("value"),)),
84
+ input=iter((pa.record_batch({"value": pa.array([1], type=pa.int64())}),)),
85
+ )
86
+ )
87
+ return str(out[0].column("result")[0].as_py())
88
+
89
+
90
+ def _app(worker: type = _PeerAuthWorker, **kwargs: Any) -> Any:
91
+ return create_app(worker, describe=False, signing_key=_SIGNING_KEY, **kwargs)
92
+
93
+
94
+ class TestGrantKeyConfiguration:
95
+ """Opt-in, from the environment or ``--grant-key``; malformed keys stop startup."""
96
+
97
+ def test_no_key_means_grants_off(self) -> None:
98
+ """No key means grants off."""
99
+ assert resolve_grant_keys() is None
100
+ assert _IDENTITY not in build_rpc_server(_PeerAuthWorker(quiet=True), transport="http").bindings
101
+
102
+ def test_env_keys_parse(self, monkeypatch: pytest.MonkeyPatch) -> None:
103
+ """Env keys parse."""
104
+ monkeypatch.setenv(GRANT_KEYS_ENV, f"{_KEY_B64},{_OTHER_KEY_B64}")
105
+ monkeypatch.setenv("VGI_RPC_GRANT_AUDIENCE", "aud")
106
+ keys = resolve_grant_keys()
107
+ assert keys is not None
108
+ assert keys.keys == (bytes(range(32)), bytes(range(32, 64)))
109
+ assert keys.audience == "aud"
110
+
111
+ def test_explicit_keys_win_over_env(self, monkeypatch: pytest.MonkeyPatch) -> None:
112
+ """Explicit keys win over env."""
113
+ monkeypatch.setenv(GRANT_KEYS_ENV, _OTHER_KEY_B64)
114
+ keys = resolve_grant_keys([_KEY_B64])
115
+ assert keys is not None
116
+ assert keys.keys == (bytes(range(32)),)
117
+
118
+ @pytest.mark.parametrize("bad", ["not-base64!", base64.b64encode(b"short").decode()])
119
+ def test_malformed_key_refuses_to_start(self, monkeypatch: pytest.MonkeyPatch, bad: str) -> None:
120
+ """Malformed key refuses to start."""
121
+ monkeypatch.setenv(GRANT_KEYS_ENV, bad)
122
+ with pytest.raises(SystemExit):
123
+ _app()
124
+
125
+ def test_keys_alone_host_issue_grant_without_an_allowlist(self, monkeypatch: pytest.MonkeyPatch) -> None:
126
+ """Minting is not an oracle, so the introspection allowlist rule does not apply."""
127
+ monkeypatch.setenv(GRANT_KEYS_ENV, _KEY_B64)
128
+ server = build_rpc_server(_PeerAuthWorker(quiet=True), transport="http", grant_keys=resolve_grant_keys())
129
+ assert server.bindings[_IDENTITY].methods.keys() == {"issue_grant"}
130
+
131
+ def test_keys_are_http_only(self, monkeypatch: pytest.MonkeyPatch) -> None:
132
+ """Keys are http only."""
133
+ monkeypatch.setenv(GRANT_KEYS_ENV, _KEY_B64)
134
+ server = build_rpc_server(_PeerAuthWorker(quiet=True), transport="unix", grant_keys=resolve_grant_keys())
135
+ assert _IDENTITY not in server.bindings
136
+
137
+
138
+ class TestSealedGrantEndToEnd:
139
+ """issue_grant with fresh auth, then a vgi.v2 call with ``Bearer <grant>``, as the owner."""
140
+
141
+ def test_minted_grant_authenticates_as_its_owner(self, monkeypatch: pytest.MonkeyPatch) -> None:
142
+ """Minted grant authenticates as its owner."""
143
+ monkeypatch.setenv(GRANT_KEYS_ENV, _KEY_B64)
144
+ app = _app(authenticate=_header_authenticate)
145
+
146
+ minter = _SyncTestClient(app, default_headers={"X-Test-Principal": "alice@example.com"})
147
+ with http_connect(Identity, client=minter) as identity: # type: ignore[type-abstract]
148
+ grant = identity.issue_grant(purpose="nightly-report", scopes=["read"], ttl_seconds=600)
149
+ assert grant.token.startswith("vgig1.")
150
+
151
+ assert _whoami(app, bearer=grant.token) == "alice@example.com"
152
+
153
+ def test_tampered_grant_is_refused(self, monkeypatch: pytest.MonkeyPatch) -> None:
154
+ """Tampered grant is refused."""
155
+ monkeypatch.setenv(GRANT_KEYS_ENV, _KEY_B64)
156
+ keys = GrantKeys.parse([_KEY_B64])
157
+ token, _ = mint_grant_token(keys, principal="alice", scopes=[], purpose="p", ttl_seconds=60)
158
+ tampered = token[:-2] + ("A" if token[-2] != "A" else "B") + token[-1]
159
+ with pytest.raises(ClientError):
160
+ _whoami(_app(authenticate=_header_authenticate), bearer=tampered)
161
+
162
+ def test_unknown_bearer_without_grants_configured_stays_unaccepted(self) -> None:
163
+ """No keys, no hook: nothing changes -- the deployment authenticator decides."""
164
+ app = _app(authenticate=_header_authenticate)
165
+ with pytest.raises(ClientError):
166
+ _whoami(app, bearer="vgig1.AAAA")
167
+
168
+
169
+ class _ResolvingWorker(_PeerAuthWorker):
170
+ """Resolves one opaque credential; counts calls so routing is observable."""
171
+
172
+ calls: list[str] = []
173
+
174
+ @classmethod
175
+ def resolve_token(cls, token: str) -> TokenIdentity | None:
176
+ """Resolve token."""
177
+ cls.calls.append(token)
178
+ return TokenIdentity(principal="svc-reporting") if token == "opaque-api-key" else None
179
+
180
+
181
+ class TestResolveTokenBearer:
182
+ """A worker's resolve_token is consulted for bearers it did not mint."""
183
+
184
+ @pytest.fixture
185
+ def app(self, monkeypatch: pytest.MonkeyPatch) -> Any:
186
+ """App."""
187
+ monkeypatch.setenv("VGI_INTROSPECT_PRINCIPALS", "proxy-a")
188
+ monkeypatch.setenv(GRANT_KEYS_ENV, _KEY_B64)
189
+ _ResolvingWorker.calls = []
190
+ return _app(_ResolvingWorker, authenticate=_header_authenticate)
191
+
192
+ def test_resolved_bearer_authenticates(self, app: Any) -> None:
193
+ """Resolved bearer authenticates."""
194
+ assert _whoami(app, bearer="opaque-api-key") == "svc-reporting"
195
+
196
+ def test_unresolved_bearer_is_refused(self, app: Any) -> None:
197
+ """Unresolved bearer is refused."""
198
+ with pytest.raises(ClientError):
199
+ _whoami(app, bearer="unknown-key")
200
+
201
+ def test_a_bad_grant_never_reaches_the_resolver(self, app: Any) -> None:
202
+ """A bad grant never reaches the resolver."""
203
+ with pytest.raises(ClientError):
204
+ _whoami(app, bearer="vgig1.AAAA")
205
+ assert "vgig1.AAAA" not in _ResolvingWorker.calls
206
+
207
+ def test_allowlist_rule_unchanged(self, monkeypatch: pytest.MonkeyPatch) -> None:
208
+ """Allowlist rule unchanged."""
209
+ monkeypatch.delenv("VGI_INTROSPECT_PRINCIPALS", raising=False)
210
+ with pytest.raises(SystemExit):
211
+ _app(_ResolvingWorker)
212
+
213
+
214
+ def _vector_env(monkeypatch: pytest.MonkeyPatch, verify_keys: list[str], audience: str, max_ttl: int) -> None:
215
+ monkeypatch.setenv(GRANT_KEYS_ENV, ",".join(verify_keys))
216
+ monkeypatch.setenv("VGI_RPC_GRANT_AUDIENCE", audience)
217
+ monkeypatch.setenv("VGI_RPC_GRANT_MAX_TTL_SECONDS", str(max_ttl))
218
+
219
+
220
+ def _at(monkeypatch: pytest.MonkeyPatch, now: float) -> None:
221
+ """Pin the grant verifier's clock without touching the process clock."""
222
+ import vgi_rpc.grants
223
+
224
+ monkeypatch.setattr(vgi_rpc.grants, "time", types.SimpleNamespace(time=lambda: now))
225
+
226
+
227
+ class TestSharedVectors:
228
+ """The shared vectors, accepted and rejected through create_app's whole chain."""
229
+
230
+ @pytest.mark.parametrize("case", _VECTORS["mint"], ids=lambda c: c["name"])
231
+ def test_minted_vector_authenticates(self, monkeypatch: pytest.MonkeyPatch, case: dict[str, Any]) -> None:
232
+ """Minted vector authenticates."""
233
+ verify = [case["minting_key_b64"], *_VECTORS["defaults"]["verify_keys_b64"]]
234
+ _vector_env(monkeypatch, list(dict.fromkeys(verify)), case["audience"], case["max_ttl_seconds"])
235
+ _at(monkeypatch, case["now"] + 1)
236
+ assert _whoami(_app(), bearer=case["token"]) == case["claims"]["principal"]
237
+
238
+ @pytest.mark.parametrize("case", _VECTORS["accept"], ids=lambda c: c["name"])
239
+ def test_accept_case(self, monkeypatch: pytest.MonkeyPatch, case: dict[str, Any]) -> None:
240
+ """Accept case."""
241
+ d = _VECTORS["defaults"]
242
+ _vector_env(
243
+ monkeypatch,
244
+ case.get("verify_keys_b64", d["verify_keys_b64"]),
245
+ case.get("audience", d["audience"]),
246
+ case.get("max_ttl_seconds", d["max_ttl_seconds"]),
247
+ )
248
+ _at(monkeypatch, case.get("now", d["now"]))
249
+ assert _whoami(_app(), bearer=case["token"]) != "anonymous"
250
+
251
+ @pytest.mark.parametrize("case", _VECTORS["reject"], ids=lambda c: c["name"])
252
+ def test_reject_case(self, monkeypatch: pytest.MonkeyPatch, case: dict[str, Any]) -> None:
253
+ """Reject case."""
254
+ d = _VECTORS["defaults"]
255
+ _vector_env(
256
+ monkeypatch,
257
+ case.get("verify_keys_b64", d["verify_keys_b64"]),
258
+ case.get("audience", d["audience"]),
259
+ case.get("max_ttl_seconds", d["max_ttl_seconds"]),
260
+ )
261
+ _at(monkeypatch, case.get("now", d["now"]))
262
+ with pytest.raises(ClientError):
263
+ _whoami(_app(), bearer=case["token"])
264
+
265
+
266
+ class TestProxyProofGateStillGuards:
267
+ """Grants go inside VGI's proxy-proof gate, never beside it."""
268
+
269
+ @pytest.fixture
270
+ def gated(self, monkeypatch: pytest.MonkeyPatch) -> None:
271
+ """Gated."""
272
+ monkeypatch.setenv("VGI_PROXY_PROOF_MODE", "require")
273
+ monkeypatch.setenv("VGI_PROXY_PROOF_ORIGIN_ID", "worker-a")
274
+ monkeypatch.setenv("VGI_PROXY_PROOF_SECRETS", "k:" + "11" * 32)
275
+ monkeypatch.setenv(GRANT_KEYS_ENV, _KEY_B64)
276
+
277
+ def test_gated_worker_with_grants_starts(self, gated: None) -> None:
278
+ """vgi-rpc refuses to OR grants beside a proxy gate; create_app composes inside it."""
279
+ from vgi.serve import _resolve_authenticate
280
+
281
+ _app(authenticate=_resolve_authenticate())
282
+
283
+ def test_valid_grant_without_proof_is_refused(self, gated: None) -> None:
284
+ """Valid grant without proof is refused."""
285
+ from vgi.serve import _resolve_authenticate
286
+
287
+ keys = GrantKeys.parse([_KEY_B64])
288
+ token, _ = mint_grant_token(keys, principal="alice", scopes=[], purpose="p", ttl_seconds=60)
289
+ with pytest.raises(ClientError):
290
+ _whoami(_app(authenticate=_resolve_authenticate()), bearer=token)
@@ -2670,7 +2670,7 @@ requires-dist = [
2670
2670
 
2671
2671
  [[package]]
2672
2672
  name = "vgi-python"
2673
- version = "0.41.0"
2673
+ version = "0.42.0"
2674
2674
  source = { editable = "." }
2675
2675
  dependencies = [
2676
2676
  { name = "click" },
@@ -2790,7 +2790,7 @@ requires-dist = [
2790
2790
  { name = "vgi-python", extras = ["test-fixtures"], marker = "extra == 'test-fixtures-writable'" },
2791
2791
  { name = "vgi-python", extras = ["test-fixtures", "test-fixtures-writable", "http", "launch", "oauth", "otel", "sentry", "azure"], marker = "extra == 'dev'" },
2792
2792
  { name = "vgi-python", extras = ["transactor"], marker = "extra == 'test-fixtures-writable'" },
2793
- { name = "vgi-rpc", specifier = ">=0.48.0" },
2793
+ { name = "vgi-rpc", specifier = ">=0.49.0" },
2794
2794
  { name = "vgi-rpc", extras = ["cli"], marker = "extra == 'launch'" },
2795
2795
  { name = "vgi-rpc", extras = ["cli", "conformance", "external", "http", "oauth", "otel", "sentry"], marker = "extra == 'dev'" },
2796
2796
  { name = "vgi-rpc", extras = ["http"], marker = "extra == 'granian'" },
@@ -2821,7 +2821,7 @@ docs = [
2821
2821
 
2822
2822
  [[package]]
2823
2823
  name = "vgi-rpc"
2824
- version = "0.48.0"
2824
+ version = "0.49.0"
2825
2825
  source = { registry = "https://pypi.org/simple" }
2826
2826
  dependencies = [
2827
2827
  { name = "docstring-parser" },
@@ -2829,9 +2829,9 @@ dependencies = [
2829
2829
  { name = "pywin32", marker = "sys_platform == 'win32'" },
2830
2830
  { name = "tzdata", marker = "sys_platform == 'win32'" },
2831
2831
  ]
2832
- sdist = { url = "https://files.pythonhosted.org/packages/e9/b5/e3eded035fd7d947496ef2a923e83babe38da44420e943365ff8b456164d/vgi_rpc-0.48.0.tar.gz", hash = "sha256:862170c57d8a9708ee8bc6185c34a531adf569199a66a86fe35671364ee2732c", size = 1577079, upload-time = "2026-10-06T01:42:23.713Z" }
2832
+ sdist = { url = "https://files.pythonhosted.org/packages/d5/1c/29d313c20c578d711eadcff65680f7ebf4c574f157dbf45a6689d78f3fb8/vgi_rpc-0.49.0.tar.gz", hash = "sha256:84a1ea49cb24805bdad8ebe2006f63fb69a82fb5a8746b10b3f0a7345f4bb0a9", size = 1610726, upload-time = "2026-10-06T17:29:24.272Z" }
2833
2833
  wheels = [
2834
- { url = "https://files.pythonhosted.org/packages/c4/14/b23c4d1ed73330c11de59136634468d82fcdcd0f4c35f0eaec3eea9c2c63/vgi_rpc-0.48.0-py3-none-any.whl", hash = "sha256:4c41726e0ddbea1bd1e47feed77eb192d94da49111bf8bfecb7329d2be5747dd", size = 734936, upload-time = "2026-10-06T01:42:21.946Z" },
2834
+ { url = "https://files.pythonhosted.org/packages/bf/8d/c444dc959722506d3fa5c4fd623a790c3f140cccae2341d97c55d7df403a/vgi_rpc-0.49.0-py3-none-any.whl", hash = "sha256:faae05f9a3d08202c031d0b783c5ff93c6770833fd22fb1479a556267ad4ef63", size = 756201, upload-time = "2026-10-06T17:29:21.983Z" },
2835
2835
  ]
2836
2836
 
2837
2837
  [package.optional-dependencies]
@@ -7,8 +7,8 @@ engine (expression-filter evaluation, the transactor, the statistics
7
7
  fixtures) resolves it through this module, which prefers Query Farm's
8
8
  ``haybarn`` distribution when installed and falls back to stock ``duckdb``.
9
9
 
10
- Install one via the extras: ``pip install vgi[haybarn]`` (preferred) or
11
- ``pip install vgi[duckdb]``.
10
+ Install one via the extras: ``pip install 'vgi-python[haybarn]'`` (preferred) or
11
+ ``pip install 'vgi-python[duckdb]'``.
12
12
  """
13
13
 
14
14
  from __future__ import annotations
@@ -50,7 +50,7 @@ def engine_module() -> ModuleType:
50
50
  else:
51
51
  raise ImportError(
52
52
  "No DuckDB-compatible engine is installed. Install 'haybarn' (preferred) "
53
- "or 'duckdb', e.g. `pip install vgi[haybarn]` or `pip install vgi[duckdb]`."
53
+ "or 'duckdb', e.g. `pip install 'vgi-python[haybarn]'` or `pip install 'vgi-python[duckdb]'`."
54
54
  )
55
55
  return _engine
56
56