hypequery 0.0.1.dev0__tar.gz → 0.1.0b1__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 (460) hide show
  1. hypequery-0.1.0b1/.gitattributes +3 -0
  2. hypequery-0.1.0b1/.gitignore +23 -0
  3. hypequery-0.1.0b1/ARCHITECTURE.md +133 -0
  4. hypequery-0.1.0b1/CHANGELOG.md +451 -0
  5. hypequery-0.1.0b1/LICENSE +201 -0
  6. hypequery-0.1.0b1/PKG-INFO +2063 -0
  7. hypequery-0.1.0b1/README.md +1994 -0
  8. hypequery-0.1.0b1/RELEASING.md +272 -0
  9. hypequery-0.1.0b1/changelog.d/README.md +26 -0
  10. hypequery-0.1.0b1/changelog.d/template.md +12 -0
  11. hypequery-0.1.0b1/examples/README.md +106 -0
  12. hypequery-0.1.0b1/examples/__init__.py +1 -0
  13. hypequery-0.1.0b1/examples/client_dashboard/README.md +174 -0
  14. hypequery-0.1.0b1/examples/client_dashboard/__init__.py +1 -0
  15. hypequery-0.1.0b1/examples/client_dashboard/__main__.py +7 -0
  16. hypequery-0.1.0b1/examples/client_dashboard/api.py +52 -0
  17. hypequery-0.1.0b1/examples/client_dashboard/definitions.py +31 -0
  18. hypequery-0.1.0b1/examples/client_dashboard/frontend/.gitignore +6 -0
  19. hypequery-0.1.0b1/examples/client_dashboard/frontend/app.tsx +59 -0
  20. hypequery-0.1.0b1/examples/client_dashboard/frontend/mcp-check.mjs +46 -0
  21. hypequery-0.1.0b1/examples/client_dashboard/frontend/package.json +24 -0
  22. hypequery-0.1.0b1/examples/client_dashboard/frontend/public/index.html +3 -0
  23. hypequery-0.1.0b1/examples/client_dashboard/frontend/tsconfig.json +8 -0
  24. hypequery-0.1.0b1/examples/client_dashboard/seed.sql +17 -0
  25. hypequery-0.1.0b1/examples/dataframes.py +33 -0
  26. hypequery-0.1.0b1/examples/django_app.py +204 -0
  27. hypequery-0.1.0b1/examples/django_urls.py +30 -0
  28. hypequery-0.1.0b1/examples/embedded_analytics.py +71 -0
  29. hypequery-0.1.0b1/examples/flask_app.py +136 -0
  30. hypequery-0.1.0b1/examples/governed_agent.py +59 -0
  31. hypequery-0.1.0b1/examples/multitenant_saas.py +59 -0
  32. hypequery-0.1.0b1/examples/seed.sql +16 -0
  33. hypequery-0.1.0b1/examples/sqlalchemy_engine.py +49 -0
  34. hypequery-0.1.0b1/examples/utils/__init__.py +1 -0
  35. hypequery-0.1.0b1/examples/utils/analytics.py +85 -0
  36. hypequery-0.1.0b1/examples/utils/analytics_page.html +87 -0
  37. hypequery-0.1.0b1/examples/utils/config.py +16 -0
  38. hypequery-0.1.0b1/examples/utils/login.py +23 -0
  39. hypequery-0.1.0b1/examples/utils/orders.py +56 -0
  40. hypequery-0.1.0b1/examples/utils/server.py +90 -0
  41. hypequery-0.1.0b1/pyproject.toml +307 -0
  42. hypequery-0.1.0b1/scripts/audit_artifacts.py +165 -0
  43. hypequery-0.1.0b1/scripts/check_coverage.py +79 -0
  44. hypequery-0.1.0b1/scripts/check_release_artifacts.py +21 -0
  45. hypequery-0.1.0b1/scripts/check_sql_interpolation.py +194 -0
  46. hypequery-0.1.0b1/scripts/cli_smoke.py +29 -0
  47. hypequery-0.1.0b1/scripts/getting_started.py +223 -0
  48. hypequery-0.1.0b1/scripts/prepare_release.py +39 -0
  49. hypequery-0.1.0b1/scripts/prepare_release_pr.py +106 -0
  50. hypequery-0.1.0b1/scripts/utils/__init__.py +1 -0
  51. hypequery-0.1.0b1/scripts/utils/checks.py +6 -0
  52. hypequery-0.1.0b1/scripts/utils/installed_cli.py +470 -0
  53. hypequery-0.1.0b1/scripts/utils/release_artifacts.py +47 -0
  54. hypequery-0.1.0b1/scripts/utils/release_notes.py +28 -0
  55. hypequery-0.1.0b1/scripts/utils/release_versions.py +39 -0
  56. hypequery-0.1.0b1/src/hypequery/__init__.py +22 -0
  57. hypequery-0.1.0b1/src/hypequery/__main__.py +6 -0
  58. hypequery-0.1.0b1/src/hypequery/cli/__init__.py +33 -0
  59. hypequery-0.1.0b1/src/hypequery/cli/commands/__init__.py +1 -0
  60. hypequery-0.1.0b1/src/hypequery/cli/commands/dev.py +74 -0
  61. hypequery-0.1.0b1/src/hypequery/cli/commands/export.py +39 -0
  62. hypequery-0.1.0b1/src/hypequery/cli/commands/generate.py +94 -0
  63. hypequery-0.1.0b1/src/hypequery/cli/commands/init.py +58 -0
  64. hypequery-0.1.0b1/src/hypequery/cli/errors.py +5 -0
  65. hypequery-0.1.0b1/src/hypequery/cli/generators/__init__.py +1 -0
  66. hypequery-0.1.0b1/src/hypequery/cli/generators/count_measure.py +29 -0
  67. hypequery-0.1.0b1/src/hypequery/cli/generators/datasets.py +369 -0
  68. hypequery-0.1.0b1/src/hypequery/cli/generators/framework_apps.py +257 -0
  69. hypequery-0.1.0b1/src/hypequery/cli/generators/project.py +131 -0
  70. hypequery-0.1.0b1/src/hypequery/cli/generators/schema.py +170 -0
  71. hypequery-0.1.0b1/src/hypequery/cli/options.py +90 -0
  72. hypequery-0.1.0b1/src/hypequery/cli/parser.py +144 -0
  73. hypequery-0.1.0b1/src/hypequery/cli/scaffold.py +62 -0
  74. hypequery-0.1.0b1/src/hypequery/cli/templates/.env.example +12 -0
  75. hypequery-0.1.0b1/src/hypequery/cli/templates/.gitignore +6 -0
  76. hypequery-0.1.0b1/src/hypequery/cli/templates/README.md +103 -0
  77. hypequery-0.1.0b1/src/hypequery/cli/templates/app.py +50 -0
  78. hypequery-0.1.0b1/src/hypequery/cli/templates/datasets.py +21 -0
  79. hypequery-0.1.0b1/src/hypequery/cli/templates/django/analytics.py +106 -0
  80. hypequery-0.1.0b1/src/hypequery/cli/templates/django/manage.py +10 -0
  81. hypequery-0.1.0b1/src/hypequery/cli/templates/django/settings.py +58 -0
  82. hypequery-0.1.0b1/src/hypequery/cli/templates/django/urls.py +25 -0
  83. hypequery-0.1.0b1/src/hypequery/cli/templates/flask/app.py +134 -0
  84. hypequery-0.1.0b1/src/hypequery/cli/templates/pyproject.toml.template +12 -0
  85. hypequery-0.1.0b1/src/hypequery/cli/templates/seed.sql +17 -0
  86. hypequery-0.1.0b1/src/hypequery/cli/utils/__init__.py +1 -0
  87. hypequery-0.1.0b1/src/hypequery/cli/utils/catalog_comment.py +35 -0
  88. hypequery-0.1.0b1/src/hypequery/cli/utils/clickhouse_hints.py +38 -0
  89. hypequery-0.1.0b1/src/hypequery/cli/utils/client_contract_factory.py +92 -0
  90. hypequery-0.1.0b1/src/hypequery/cli/utils/connection_scaffold.py +68 -0
  91. hypequery-0.1.0b1/src/hypequery/cli/utils/display_path.py +11 -0
  92. hypequery-0.1.0b1/src/hypequery/cli/utils/generated_file.py +233 -0
  93. hypequery-0.1.0b1/src/hypequery/cli/utils/next_steps.py +23 -0
  94. hypequery-0.1.0b1/src/hypequery/cli/utils/recorded_selection.py +54 -0
  95. hypequery-0.1.0b1/src/hypequery/cli/utils/startup_errors.py +29 -0
  96. hypequery-0.1.0b1/src/hypequery/cli/utils/templates.py +26 -0
  97. hypequery-0.1.0b1/src/hypequery/cli/utils/tenant_settings.py +48 -0
  98. hypequery-0.1.0b1/src/hypequery/contrib/__init__.py +9 -0
  99. hypequery-0.1.0b1/src/hypequery/contrib/django/__init__.py +60 -0
  100. hypequery-0.1.0b1/src/hypequery/contrib/django/apps.py +37 -0
  101. hypequery-0.1.0b1/src/hypequery/contrib/django/auth.py +113 -0
  102. hypequery-0.1.0b1/src/hypequery/contrib/django/clients.py +120 -0
  103. hypequery-0.1.0b1/src/hypequery/contrib/django/conf.py +102 -0
  104. hypequery-0.1.0b1/src/hypequery/contrib/django/middleware.py +53 -0
  105. hypequery-0.1.0b1/src/hypequery/contrib/django/views.py +231 -0
  106. hypequery-0.1.0b1/src/hypequery/contrib/flask.py +390 -0
  107. hypequery-0.1.0b1/src/hypequery/contrib/sqlalchemy.py +126 -0
  108. hypequery-0.1.0b1/src/hypequery/contrib/utils/__init__.py +1 -0
  109. hypequery-0.1.0b1/src/hypequery/contrib/utils/lazy_executor.py +48 -0
  110. hypequery-0.1.0b1/src/hypequery/contrib/utils/mounted_path.py +36 -0
  111. hypequery-0.1.0b1/src/hypequery/contrib/utils/process_clients.py +151 -0
  112. hypequery-0.1.0b1/src/hypequery/contrib/utils/tenant_value.py +46 -0
  113. hypequery-0.1.0b1/src/hypequery/datasets/__init__.py +216 -0
  114. hypequery-0.1.0b1/src/hypequery/datasets/_base.py +34 -0
  115. hypequery-0.1.0b1/src/hypequery/datasets/adapter.py +71 -0
  116. hypequery-0.1.0b1/src/hypequery/datasets/aggregations.py +101 -0
  117. hypequery-0.1.0b1/src/hypequery/datasets/cache/__init__.py +15 -0
  118. hypequery-0.1.0b1/src/hypequery/datasets/cache/cached_rows_check.py +27 -0
  119. hypequery-0.1.0b1/src/hypequery/datasets/cache/preimage_inputs.py +106 -0
  120. hypequery-0.1.0b1/src/hypequery/datasets/cache/result_cache.py +191 -0
  121. hypequery-0.1.0b1/src/hypequery/datasets/cache/store.py +87 -0
  122. hypequery-0.1.0b1/src/hypequery/datasets/catalog.py +286 -0
  123. hypequery-0.1.0b1/src/hypequery/datasets/client/__init__.py +52 -0
  124. hypequery-0.1.0b1/src/hypequery/datasets/client/clients.py +436 -0
  125. hypequery-0.1.0b1/src/hypequery/datasets/client/dataframes.py +232 -0
  126. hypequery-0.1.0b1/src/hypequery/datasets/client/inputs.py +74 -0
  127. hypequery-0.1.0b1/src/hypequery/datasets/client/pagination.py +33 -0
  128. hypequery-0.1.0b1/src/hypequery/datasets/client/results.py +171 -0
  129. hypequery-0.1.0b1/src/hypequery/datasets/client/tenant_binding.py +37 -0
  130. hypequery-0.1.0b1/src/hypequery/datasets/client_contract/__init__.py +6 -0
  131. hypequery-0.1.0b1/src/hypequery/datasets/client_contract/annotations.py +84 -0
  132. hypequery-0.1.0b1/src/hypequery/datasets/client_contract/export.py +120 -0
  133. hypequery-0.1.0b1/src/hypequery/datasets/client_contract/fields.py +118 -0
  134. hypequery-0.1.0b1/src/hypequery/datasets/client_contract/models.py +88 -0
  135. hypequery-0.1.0b1/src/hypequery/datasets/constants.py +67 -0
  136. hypequery-0.1.0b1/src/hypequery/datasets/contract.py +195 -0
  137. hypequery-0.1.0b1/src/hypequery/datasets/dataset.py +185 -0
  138. hypequery-0.1.0b1/src/hypequery/datasets/deployment.py +212 -0
  139. hypequery-0.1.0b1/src/hypequery/datasets/deployment_bundle.py +104 -0
  140. hypequery-0.1.0b1/src/hypequery/datasets/deployment_values.py +57 -0
  141. hypequery-0.1.0b1/src/hypequery/datasets/derived_measures.py +22 -0
  142. hypequery-0.1.0b1/src/hypequery/datasets/dimensions.py +103 -0
  143. hypequery-0.1.0b1/src/hypequery/datasets/formulas.py +177 -0
  144. hypequery-0.1.0b1/src/hypequery/datasets/immutability.py +77 -0
  145. hypequery-0.1.0b1/src/hypequery/datasets/measures.py +149 -0
  146. hypequery-0.1.0b1/src/hypequery/datasets/planner/__init__.py +82 -0
  147. hypequery-0.1.0b1/src/hypequery/datasets/planner/admission.py +18 -0
  148. hypequery-0.1.0b1/src/hypequery/datasets/planner/aggregates.py +31 -0
  149. hypequery-0.1.0b1/src/hypequery/datasets/planner/aliases.py +6 -0
  150. hypequery-0.1.0b1/src/hypequery/datasets/planner/compiled_query.py +116 -0
  151. hypequery-0.1.0b1/src/hypequery/datasets/planner/compiler.py +110 -0
  152. hypequery-0.1.0b1/src/hypequery/datasets/planner/context.py +198 -0
  153. hypequery-0.1.0b1/src/hypequery/datasets/planner/dialects/__init__.py +8 -0
  154. hypequery-0.1.0b1/src/hypequery/datasets/planner/dialects/base.py +68 -0
  155. hypequery-0.1.0b1/src/hypequery/datasets/planner/dialects/clickhouse.py +154 -0
  156. hypequery-0.1.0b1/src/hypequery/datasets/planner/errors.py +119 -0
  157. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/__init__.py +6 -0
  158. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/base.py +17 -0
  159. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/dimensions.py +52 -0
  160. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/fields.py +86 -0
  161. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/filtering.py +144 -0
  162. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/having.py +75 -0
  163. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/joins.py +113 -0
  164. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/measures.py +157 -0
  165. hypequery-0.1.0b1/src/hypequery/datasets/planner/features/ordering.py +48 -0
  166. hypequery-0.1.0b1/src/hypequery/datasets/planner/filter_validation.py +84 -0
  167. hypequery-0.1.0b1/src/hypequery/datasets/planner/identifiers.py +71 -0
  168. hypequery-0.1.0b1/src/hypequery/datasets/planner/operators.py +17 -0
  169. hypequery-0.1.0b1/src/hypequery/datasets/planner/parameters.py +107 -0
  170. hypequery-0.1.0b1/src/hypequery/datasets/planner/planner.py +61 -0
  171. hypequery-0.1.0b1/src/hypequery/datasets/planner/predicates.py +16 -0
  172. hypequery-0.1.0b1/src/hypequery/datasets/planner/query.py +43 -0
  173. hypequery-0.1.0b1/src/hypequery/datasets/planner/query_node.py +39 -0
  174. hypequery-0.1.0b1/src/hypequery/datasets/planner/query_validation.py +96 -0
  175. hypequery-0.1.0b1/src/hypequery/datasets/planner/resolution.py +216 -0
  176. hypequery-0.1.0b1/src/hypequery/datasets/planner/settings.py +89 -0
  177. hypequery-0.1.0b1/src/hypequery/datasets/planner/sql_fragments.py +75 -0
  178. hypequery-0.1.0b1/src/hypequery/datasets/query_helpers.py +153 -0
  179. hypequery-0.1.0b1/src/hypequery/datasets/registry.py +66 -0
  180. hypequery-0.1.0b1/src/hypequery/datasets/relationship_check.py +96 -0
  181. hypequery-0.1.0b1/src/hypequery/datasets/relationship_check_plan.py +82 -0
  182. hypequery-0.1.0b1/src/hypequery/datasets/relationships.py +161 -0
  183. hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/__init__.py +23 -0
  184. hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/compiler.py +94 -0
  185. hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/errors.py +54 -0
  186. hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/limits.py +34 -0
  187. hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/parser.py +546 -0
  188. hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/tokenizer.py +306 -0
  189. hypequery-0.1.0b1/src/hypequery/datasets/utils/__init__.py +1 -0
  190. hypequery-0.1.0b1/src/hypequery/datasets/utils/canonical_json.py +30 -0
  191. hypequery-0.1.0b1/src/hypequery/datasets/utils/definition_projection.py +80 -0
  192. hypequery-0.1.0b1/src/hypequery/datasets/utils/deployable_formulas.py +96 -0
  193. hypequery-0.1.0b1/src/hypequery/datasets/utils/derived_measures.py +165 -0
  194. hypequery-0.1.0b1/src/hypequery/datasets/utils/measure_references.py +43 -0
  195. hypequery-0.1.0b1/src/hypequery/datasets/utils/output_column_types.py +104 -0
  196. hypequery-0.1.0b1/src/hypequery/datasets/utils/output_columns.py +14 -0
  197. hypequery-0.1.0b1/src/hypequery/datasets/utils/portable_grains.py +34 -0
  198. hypequery-0.1.0b1/src/hypequery/datasets/utils/portable_order.py +26 -0
  199. hypequery-0.1.0b1/src/hypequery/datasets/utils/query_timezone.py +43 -0
  200. hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_fields.py +54 -0
  201. hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_key_check.py +44 -0
  202. hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_measures.py +97 -0
  203. hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_names.py +27 -0
  204. hypequery-0.1.0b1/src/hypequery/datasets/utils/stable_json.py +47 -0
  205. hypequery-0.1.0b1/src/hypequery/datasets/utils/timestamp_text.py +35 -0
  206. hypequery-0.1.0b1/src/hypequery/datasets/validation.py +37 -0
  207. hypequery-0.1.0b1/src/hypequery/execution/__init__.py +29 -0
  208. hypequery-0.1.0b1/src/hypequery/execution/cancellation.py +242 -0
  209. hypequery-0.1.0b1/src/hypequery/execution/clickhouse.py +640 -0
  210. hypequery-0.1.0b1/src/hypequery/execution/errors.py +91 -0
  211. hypequery-0.1.0b1/src/hypequery/execution/parameters.py +72 -0
  212. hypequery-0.1.0b1/src/hypequery/execution/readonly_settings.py +117 -0
  213. hypequery-0.1.0b1/src/hypequery/execution/results.py +62 -0
  214. hypequery-0.1.0b1/src/hypequery/execution/sync_cancellation.py +51 -0
  215. hypequery-0.1.0b1/src/hypequery/execution/utils/__init__.py +1 -0
  216. hypequery-0.1.0b1/src/hypequery/execution/utils/close_cancellation.py +17 -0
  217. hypequery-0.1.0b1/src/hypequery/execution/utils/connection_env.py +105 -0
  218. hypequery-0.1.0b1/src/hypequery/execution/utils/connection_url.py +139 -0
  219. hypequery-0.1.0b1/src/hypequery/execution/utils/datetime_parameters.py +37 -0
  220. hypequery-0.1.0b1/src/hypequery/execution/utils/driver_loggers.py +31 -0
  221. hypequery-0.1.0b1/src/hypequery/execution/utils/refused_kill.py +37 -0
  222. hypequery-0.1.0b1/src/hypequery/protocol/__init__.py +408 -0
  223. hypequery-0.1.0b1/src/hypequery/protocol/_jcs.py +238 -0
  224. hypequery-0.1.0b1/src/hypequery/protocol/adapter.py +451 -0
  225. hypequery-0.1.0b1/src/hypequery/protocol/bundle_codec.py +85 -0
  226. hypequery-0.1.0b1/src/hypequery/protocol/bundles.py +365 -0
  227. hypequery-0.1.0b1/src/hypequery/protocol/cache_keys.py +170 -0
  228. hypequery-0.1.0b1/src/hypequery/protocol/cache_preimages.py +176 -0
  229. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/__init__.py +44 -0
  230. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/bounds.py +26 -0
  231. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/codec.py +12 -0
  232. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/conformance.py +90 -0
  233. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/decode.py +112 -0
  234. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/errors.py +47 -0
  235. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/models.py +92 -0
  236. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/nodes.py +150 -0
  237. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/primitives.py +138 -0
  238. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/query.py +220 -0
  239. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/safe_data.py +98 -0
  240. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/timezone_names.py +603 -0
  241. hypequery-0.1.0b1/src/hypequery/protocol/client_contract/validate.py +154 -0
  242. hypequery-0.1.0b1/src/hypequery/protocol/constructors.py +205 -0
  243. hypequery-0.1.0b1/src/hypequery/protocol/deployment_codec.py +102 -0
  244. hypequery-0.1.0b1/src/hypequery/protocol/deployment_fixtures.py +85 -0
  245. hypequery-0.1.0b1/src/hypequery/protocol/deployment_nodes.py +468 -0
  246. hypequery-0.1.0b1/src/hypequery/protocol/deployment_primitives.py +286 -0
  247. hypequery-0.1.0b1/src/hypequery/protocol/deployment_v3_nodes.py +168 -0
  248. hypequery-0.1.0b1/src/hypequery/protocol/deployments.py +599 -0
  249. hypequery-0.1.0b1/src/hypequery/protocol/errors.py +258 -0
  250. hypequery-0.1.0b1/src/hypequery/protocol/expression_fixtures.py +64 -0
  251. hypequery-0.1.0b1/src/hypequery/protocol/expression_models.py +277 -0
  252. hypequery-0.1.0b1/src/hypequery/protocol/expressions.py +571 -0
  253. hypequery-0.1.0b1/src/hypequery/protocol/fixture_primitives.py +41 -0
  254. hypequery-0.1.0b1/src/hypequery/protocol/identifiers.py +136 -0
  255. hypequery-0.1.0b1/src/hypequery/protocol/js_strings.py +31 -0
  256. hypequery-0.1.0b1/src/hypequery/protocol/limits.py +42 -0
  257. hypequery-0.1.0b1/src/hypequery/protocol/query_event_fixtures.py +107 -0
  258. hypequery-0.1.0b1/src/hypequery/protocol/query_events.py +358 -0
  259. hypequery-0.1.0b1/src/hypequery/protocol/query_implementation_fixtures.py +45 -0
  260. hypequery-0.1.0b1/src/hypequery/protocol/query_implementation_primitives.py +151 -0
  261. hypequery-0.1.0b1/src/hypequery/protocol/query_implementations.py +320 -0
  262. hypequery-0.1.0b1/src/hypequery/protocol/releases.py +196 -0
  263. hypequery-0.1.0b1/src/hypequery/protocol/row_resolution.py +29 -0
  264. hypequery-0.1.0b1/src/hypequery/protocol/schema_defaults.py +148 -0
  265. hypequery-0.1.0b1/src/hypequery/protocol/schema_fixtures.py +46 -0
  266. hypequery-0.1.0b1/src/hypequery/protocol/schema_models.py +255 -0
  267. hypequery-0.1.0b1/src/hypequery/protocol/schemas.py +398 -0
  268. hypequery-0.1.0b1/src/hypequery/protocol/sql_expressions.py +91 -0
  269. hypequery-0.1.0b1/src/hypequery/protocol/stdio_adapter.py +95 -0
  270. hypequery-0.1.0b1/src/hypequery/protocol/utf8.py +60 -0
  271. hypequery-0.1.0b1/src/hypequery/protocol/values.py +509 -0
  272. hypequery-0.1.0b1/src/hypequery/protocol/wire_numbers.py +23 -0
  273. hypequery-0.1.0b1/src/hypequery/py.typed +0 -0
  274. hypequery-0.1.0b1/src/hypequery/serve/__init__.py +127 -0
  275. hypequery-0.1.0b1/src/hypequery/serve/api.py +192 -0
  276. hypequery-0.1.0b1/src/hypequery/serve/asgi.py +157 -0
  277. hypequery-0.1.0b1/src/hypequery/serve/auth.py +59 -0
  278. hypequery-0.1.0b1/src/hypequery/serve/client_contract.py +63 -0
  279. hypequery-0.1.0b1/src/hypequery/serve/client_discovery.py +24 -0
  280. hypequery-0.1.0b1/src/hypequery/serve/core/__init__.py +14 -0
  281. hypequery-0.1.0b1/src/hypequery/serve/core/api.py +411 -0
  282. hypequery-0.1.0b1/src/hypequery/serve/core/auth.py +232 -0
  283. hypequery-0.1.0b1/src/hypequery/serve/core/authentication.py +155 -0
  284. hypequery-0.1.0b1/src/hypequery/serve/core/body.py +161 -0
  285. hypequery-0.1.0b1/src/hypequery/serve/core/client_contract.py +195 -0
  286. hypequery-0.1.0b1/src/hypequery/serve/core/client_discovery.py +78 -0
  287. hypequery-0.1.0b1/src/hypequery/serve/core/context_auth.py +73 -0
  288. hypequery-0.1.0b1/src/hypequery/serve/core/discovery.py +31 -0
  289. hypequery-0.1.0b1/src/hypequery/serve/core/endpoints.py +349 -0
  290. hypequery-0.1.0b1/src/hypequery/serve/core/errors.py +187 -0
  291. hypequery-0.1.0b1/src/hypequery/serve/core/jwks.py +233 -0
  292. hypequery-0.1.0b1/src/hypequery/serve/core/jwt_auth.py +373 -0
  293. hypequery-0.1.0b1/src/hypequery/serve/core/lifetime.py +71 -0
  294. hypequery-0.1.0b1/src/hypequery/serve/core/messages.py +160 -0
  295. hypequery-0.1.0b1/src/hypequery/serve/core/openapi.py +174 -0
  296. hypequery-0.1.0b1/src/hypequery/serve/core/openapi_info.py +21 -0
  297. hypequery-0.1.0b1/src/hypequery/serve/core/policy.py +51 -0
  298. hypequery-0.1.0b1/src/hypequery/serve/core/production.py +60 -0
  299. hypequery-0.1.0b1/src/hypequery/serve/core/production_limits.py +115 -0
  300. hypequery-0.1.0b1/src/hypequery/serve/core/rate_limit.py +160 -0
  301. hypequery-0.1.0b1/src/hypequery/serve/core/request_ids.py +56 -0
  302. hypequery-0.1.0b1/src/hypequery/serve/core/security.py +344 -0
  303. hypequery-0.1.0b1/src/hypequery/serve/core/state.py +32 -0
  304. hypequery-0.1.0b1/src/hypequery/serve/core/utils/docs_html.py +54 -0
  305. hypequery-0.1.0b1/src/hypequery/serve/core/utils/host_header.py +48 -0
  306. hypequery-0.1.0b1/src/hypequery/serve/core/utils/http_deadline.py +114 -0
  307. hypequery-0.1.0b1/src/hypequery/serve/core/utils/http_proxy.py +39 -0
  308. hypequery-0.1.0b1/src/hypequery/serve/core/utils/json_body.py +93 -0
  309. hypequery-0.1.0b1/src/hypequery/serve/core/utils/jwk_selection.py +70 -0
  310. hypequery-0.1.0b1/src/hypequery/serve/core/utils/jwt_claims.py +112 -0
  311. hypequery-0.1.0b1/src/hypequery/serve/core/utils/jwt_options.py +111 -0
  312. hypequery-0.1.0b1/src/hypequery/serve/core/utils/operation_ids.py +17 -0
  313. hypequery-0.1.0b1/src/hypequery/serve/core/utils/provider_call.py +62 -0
  314. hypequery-0.1.0b1/src/hypequery/serve/core/utils/same_origin.py +75 -0
  315. hypequery-0.1.0b1/src/hypequery/serve/core/utils/security_headers.py +31 -0
  316. hypequery-0.1.0b1/src/hypequery/serve/core/work.py +168 -0
  317. hypequery-0.1.0b1/src/hypequery/serve/dev/__init__.py +151 -0
  318. hypequery-0.1.0b1/src/hypequery/serve/dev/__main__.py +25 -0
  319. hypequery-0.1.0b1/src/hypequery/serve/discovery.py +23 -0
  320. hypequery-0.1.0b1/src/hypequery/serve/endpoints.py +154 -0
  321. hypequery-0.1.0b1/src/hypequery/serve/events.py +55 -0
  322. hypequery-0.1.0b1/src/hypequery/serve/models.py +90 -0
  323. hypequery-0.1.0b1/src/hypequery/serve/policy.py +7 -0
  324. hypequery-0.1.0b1/src/hypequery/serve/production.py +49 -0
  325. hypequery-0.1.0b1/src/hypequery/serve/utils/asgi_body.py +91 -0
  326. hypequery-0.1.0b1/src/hypequery/serve/utils/asgi_scope.py +57 -0
  327. hypequery-0.1.0b1/src/hypequery/serve/utils/bind_address.py +22 -0
  328. hypequery-0.1.0b1/src/hypequery/serve/utils/blocking.py +30 -0
  329. hypequery-0.1.0b1/src/hypequery/serve/utils/client_contract_view.py +24 -0
  330. hypequery-0.1.0b1/src/hypequery/serve/utils/discovery.py +74 -0
  331. hypequery-0.1.0b1/src/hypequery/serve/utils/fault.py +37 -0
  332. hypequery-0.1.0b1/src/hypequery/serve/utils/metric_alias.py +43 -0
  333. hypequery-0.1.0b1/src/hypequery/serve/utils/query_input.py +30 -0
  334. hypequery-0.1.0b1/src/hypequery/serve/utils/query_response.py +44 -0
  335. hypequery-0.1.0b1/src/hypequery/serve/utils/query_schema.py +29 -0
  336. hypequery-0.1.0b1/src/hypequery/serve/utils/related_fields.py +83 -0
  337. hypequery-0.1.0b1/src/hypequery/serve/utils/response_head.py +66 -0
  338. hypequery-0.1.0b1/src/hypequery/serve/utils/serving_loop.py +250 -0
  339. hypequery-0.1.0b1/src/hypequery/serve/utils/thread_body.py +42 -0
  340. hypequery-0.1.0b1/src/hypequery/serve/utils/uvicorn_server.py +20 -0
  341. hypequery-0.1.0b1/src/hypequery/serve/utils/wsgi_environ.py +139 -0
  342. hypequery-0.1.0b1/src/hypequery/serve/wsgi.py +106 -0
  343. hypequery-0.1.0b1/tests/asgi_client.py +155 -0
  344. hypequery-0.1.0b1/tests/client_dashboard_journey.py +63 -0
  345. hypequery-0.1.0b1/tests/contrib_doubles.py +96 -0
  346. hypequery-0.1.0b1/tests/core_transport.py +67 -0
  347. hypequery-0.1.0b1/tests/django_settings.py +65 -0
  348. hypequery-0.1.0b1/tests/golden_model.py +165 -0
  349. hypequery-0.1.0b1/tests/jwks_server.py +105 -0
  350. hypequery-0.1.0b1/tests/scaffold_driver.py +156 -0
  351. hypequery-0.1.0b1/tests/serve_transports.py +169 -0
  352. hypequery-0.1.0b1/tests/snapshots/cli_generated_datasets.json +39 -0
  353. hypequery-0.1.0b1/tests/snapshots/definition_projections.json +5310 -0
  354. hypequery-0.1.0b1/tests/snapshots/planner_golden_sql.json +707 -0
  355. hypequery-0.1.0b1/tests/test_artifact_audit.py +232 -0
  356. hypequery-0.1.0b1/tests/test_beta_tenant_http.py +207 -0
  357. hypequery-0.1.0b1/tests/test_check_coverage.py +105 -0
  358. hypequery-0.1.0b1/tests/test_cli.py +144 -0
  359. hypequery-0.1.0b1/tests/test_cli_dataset_generation.py +492 -0
  360. hypequery-0.1.0b1/tests/test_cli_dev.py +335 -0
  361. hypequery-0.1.0b1/tests/test_cli_generator_golden.py +66 -0
  362. hypequery-0.1.0b1/tests/test_cli_init_framework.py +310 -0
  363. hypequery-0.1.0b1/tests/test_cli_regeneration.py +524 -0
  364. hypequery-0.1.0b1/tests/test_cli_scaffold.py +102 -0
  365. hypequery-0.1.0b1/tests/test_cli_scaffold_fixes.py +277 -0
  366. hypequery-0.1.0b1/tests/test_clickhouse_execution.py +511 -0
  367. hypequery-0.1.0b1/tests/test_clickhouse_live.py +695 -0
  368. hypequery-0.1.0b1/tests/test_client_contract_discovery.py +257 -0
  369. hypequery-0.1.0b1/tests/test_client_contract_export.py +336 -0
  370. hypequery-0.1.0b1/tests/test_client_contract_export_cli.py +278 -0
  371. hypequery-0.1.0b1/tests/test_client_dashboard_example.py +71 -0
  372. hypequery-0.1.0b1/tests/test_client_endpoint_bindings.py +400 -0
  373. hypequery-0.1.0b1/tests/test_client_execution_core.py +169 -0
  374. hypequery-0.1.0b1/tests/test_composite_relationships.py +452 -0
  375. hypequery-0.1.0b1/tests/test_connection_env.py +164 -0
  376. hypequery-0.1.0b1/tests/test_connection_url.py +200 -0
  377. hypequery-0.1.0b1/tests/test_contract_surrogates.py +43 -0
  378. hypequery-0.1.0b1/tests/test_contrib_django.py +252 -0
  379. hypequery-0.1.0b1/tests/test_contrib_django_auth.py +277 -0
  380. hypequery-0.1.0b1/tests/test_contrib_django_serve.py +242 -0
  381. hypequery-0.1.0b1/tests/test_contrib_flask.py +179 -0
  382. hypequery-0.1.0b1/tests/test_contrib_flask_auth.py +115 -0
  383. hypequery-0.1.0b1/tests/test_contrib_flask_csrf.py +105 -0
  384. hypequery-0.1.0b1/tests/test_contrib_flask_serve.py +160 -0
  385. hypequery-0.1.0b1/tests/test_contrib_process_clients.py +200 -0
  386. hypequery-0.1.0b1/tests/test_dataset_cache.py +430 -0
  387. hypequery-0.1.0b1/tests/test_dataset_catalog.py +344 -0
  388. hypequery-0.1.0b1/tests/test_dataset_client.py +262 -0
  389. hypequery-0.1.0b1/tests/test_dataset_definitions.py +421 -0
  390. hypequery-0.1.0b1/tests/test_dataset_deployment.py +362 -0
  391. hypequery-0.1.0b1/tests/test_dataset_execution_capabilities.py +129 -0
  392. hypequery-0.1.0b1/tests/test_dataset_having.py +463 -0
  393. hypequery-0.1.0b1/tests/test_datasets_adapter.py +79 -0
  394. hypequery-0.1.0b1/tests/test_datetime_parameters.py +68 -0
  395. hypequery-0.1.0b1/tests/test_definition_projection_golden.py +63 -0
  396. hypequery-0.1.0b1/tests/test_derived_measures.py +545 -0
  397. hypequery-0.1.0b1/tests/test_examples.py +136 -0
  398. hypequery-0.1.0b1/tests/test_execution_cancellation.py +907 -0
  399. hypequery-0.1.0b1/tests/test_executor_server_faults.py +240 -0
  400. hypequery-0.1.0b1/tests/test_framework_examples.py +390 -0
  401. hypequery-0.1.0b1/tests/test_import_hygiene.py +230 -0
  402. hypequery-0.1.0b1/tests/test_installed_cli.py +67 -0
  403. hypequery-0.1.0b1/tests/test_planner.py +1085 -0
  404. hypequery-0.1.0b1/tests/test_planner_aggregates.py +25 -0
  405. hypequery-0.1.0b1/tests/test_planner_dialect.py +49 -0
  406. hypequery-0.1.0b1/tests/test_planner_golden_sql.py +270 -0
  407. hypequery-0.1.0b1/tests/test_prepare_release_pr.py +158 -0
  408. hypequery-0.1.0b1/tests/test_protocol_adapter.py +96 -0
  409. hypequery-0.1.0b1/tests/test_protocol_bundles.py +440 -0
  410. hypequery-0.1.0b1/tests/test_protocol_cache_keys.py +161 -0
  411. hypequery-0.1.0b1/tests/test_protocol_cache_preimages.py +87 -0
  412. hypequery-0.1.0b1/tests/test_protocol_client_contract.py +280 -0
  413. hypequery-0.1.0b1/tests/test_protocol_deployments.py +465 -0
  414. hypequery-0.1.0b1/tests/test_protocol_deployments_v3.py +74 -0
  415. hypequery-0.1.0b1/tests/test_protocol_expression_extension_2.py +104 -0
  416. hypequery-0.1.0b1/tests/test_protocol_expressions.py +228 -0
  417. hypequery-0.1.0b1/tests/test_protocol_identifiers.py +221 -0
  418. hypequery-0.1.0b1/tests/test_protocol_jcs.py +28 -0
  419. hypequery-0.1.0b1/tests/test_protocol_js_strings.py +104 -0
  420. hypequery-0.1.0b1/tests/test_protocol_query_events.py +191 -0
  421. hypequery-0.1.0b1/tests/test_protocol_query_implementations.py +284 -0
  422. hypequery-0.1.0b1/tests/test_protocol_schemas.py +279 -0
  423. hypequery-0.1.0b1/tests/test_protocol_sql_expressions.py +131 -0
  424. hypequery-0.1.0b1/tests/test_protocol_values.py +319 -0
  425. hypequery-0.1.0b1/tests/test_public_api_naming.py +216 -0
  426. hypequery-0.1.0b1/tests/test_python_release.py +123 -0
  427. hypequery-0.1.0b1/tests/test_query_timezone.py +392 -0
  428. hypequery-0.1.0b1/tests/test_relationship_check.py +316 -0
  429. hypequery-0.1.0b1/tests/test_relationship_measures.py +422 -0
  430. hypequery-0.1.0b1/tests/test_result_dataframes.py +408 -0
  431. hypequery-0.1.0b1/tests/test_serve_asgi.py +407 -0
  432. hypequery-0.1.0b1/tests/test_serve_auth.py +542 -0
  433. hypequery-0.1.0b1/tests/test_serve_context_auth.py +458 -0
  434. hypequery-0.1.0b1/tests/test_serve_core.py +522 -0
  435. hypequery-0.1.0b1/tests/test_serve_core_security.py +421 -0
  436. hypequery-0.1.0b1/tests/test_serve_create_api.py +343 -0
  437. hypequery-0.1.0b1/tests/test_serve_dev.py +273 -0
  438. hypequery-0.1.0b1/tests/test_serve_discovery.py +117 -0
  439. hypequery-0.1.0b1/tests/test_serve_endpoints.py +1034 -0
  440. hypequery-0.1.0b1/tests/test_serve_errors.py +481 -0
  441. hypequery-0.1.0b1/tests/test_serve_helpers.py +21 -0
  442. hypequery-0.1.0b1/tests/test_serve_http_fixtures.py +160 -0
  443. hypequery-0.1.0b1/tests/test_serve_jwt.py +928 -0
  444. hypequery-0.1.0b1/tests/test_serve_jwt_adapters.py +59 -0
  445. hypequery-0.1.0b1/tests/test_serve_jwt_fixtures.py +143 -0
  446. hypequery-0.1.0b1/tests/test_serve_native_adapters.py +187 -0
  447. hypequery-0.1.0b1/tests/test_serve_production.py +547 -0
  448. hypequery-0.1.0b1/tests/test_serve_security.py +511 -0
  449. hypequery-0.1.0b1/tests/test_serve_security_headers.py +142 -0
  450. hypequery-0.1.0b1/tests/test_serve_semantic_fixtures.py +187 -0
  451. hypequery-0.1.0b1/tests/test_serve_wsgi.py +766 -0
  452. hypequery-0.1.0b1/tests/test_sql_portability.py +238 -0
  453. hypequery-0.1.0b1/tests/test_tenant_capability.py +359 -0
  454. hypequery-0.1.0b1/tests/test_time_grains.py +168 -0
  455. hypequery-0.1.0b1/tests/wsgi_client.py +144 -0
  456. hypequery-0.1.0b1/uv.lock +2856 -0
  457. hypequery-0.0.1.dev0/.gitignore +0 -5
  458. hypequery-0.0.1.dev0/PKG-INFO +0 -24
  459. hypequery-0.0.1.dev0/README.md +0 -7
  460. hypequery-0.0.1.dev0/pyproject.toml +0 -28
@@ -0,0 +1,3 @@
1
+ # Golden snapshots are written by their tests (HYPEQUERY_UPDATE_SNAPSHOTS=1);
2
+ # collapse them in review diffs.
3
+ tests/snapshots/*.json linguist-generated=true
@@ -0,0 +1,23 @@
1
+ # Intentionally present. Hatchling bundles the nearest .gitignore into the
2
+ # sdist with no way to suppress it; without this file it walks up and ships the
3
+ # monorepo root's instead. See ../reservations/README.md.
4
+ dist/
5
+ .venv/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ .pytest_cache/
9
+ .import_linter_cache/
10
+ __pycache__/
11
+ reports/
12
+ coverage.json
13
+ .hypothesis/
14
+ # Local state that must never reach an sdist: coverage data holds absolute
15
+ # paths from the machine that ran the tests; .env files and databases hold
16
+ # credentials and user data.
17
+ .coverage
18
+ .coverage.*
19
+ htmlcov/
20
+ .env
21
+ .env.*
22
+ !.env.example
23
+ *.sqlite3
@@ -0,0 +1,133 @@
1
+ # Python datasets implementation guide
2
+
3
+ `create_dataset_client()` and `create_async_dataset_client()` are the canonical
4
+ entry points. Clients resolve targets and inputs, plan queries, manage cache
5
+ state, execute compiled queries and shape results. SQL compilation belongs to
6
+ the planner package and has no dependency on clients, caches or executors.
7
+
8
+ ## Where changes belong
9
+
10
+ | Responsibility | Module under `src/hypequery/datasets/` |
11
+ | --- | --- |
12
+ | Dataset authoring and definition validation | `dataset.py`, `dimensions.py`, `measures.py`, `validation.py` |
13
+ | Request query model | `planner/query.py` |
14
+ | Execution admission: cancellation and expired deadlines | `planner/admission.py` |
15
+ | Query limits, reserved names and tenant capability validation | `planner/query_validation.py` |
16
+ | Field and relationship name resolution | `planner/resolution.py` |
17
+ | Filter value validation | `planner/filter_validation.py` |
18
+ | Per-query compiler state and orchestration | `planner/compiler.py` |
19
+ | Field SQL, joins, dimensions, measures, filters, having, ordering | `planner/features/` (one module each) |
20
+ | Statement clauses and their rendering | `planner/query_node.py` |
21
+ | Aggregate calls, tenant predicates, operator spellings | `planner/aggregates.py`, `planner/predicates.py`, `planner/operators.py` |
22
+ | SQL fragment rendering, including grains and pagination | `planner/sql_fragments.py` |
23
+ | Identifier quoting and typed parameter binding | `planner/identifiers.py`, `planner/parameters.py` |
24
+ | Planning entry point and execution metadata | `planner/planner.py` |
25
+ | Client orchestration and tenant-bound clients | `client/clients.py`, `client/tenant_binding.py` |
26
+ | Target/input coercion and result shaping | `client/inputs.py`, `client/results.py` |
27
+ | Cache identity and storage | `cache/` |
28
+
29
+ `plan_dataset_query()` runs admission, limit and reserved-name checks before
30
+ creating a `DatasetQueryCompiler`. One compiler instance owns one query's mutable
31
+ state: a `DatasetSelectNode` of clauses, the parameter binder and the selected
32
+ aliases. Following `@hypequery/clickhouse`'s query builder, each concern is a
33
+ feature in `planner/features/` that holds the compiler and reaches the others
34
+ through it. `compile()` calls them in a fixed order — dimensions, measures,
35
+ filters, having, ordering — which is also the parameter allocation order, then
36
+ renders the node. `tests/test_planner_golden_sql.py` pins the SQL and parameter
37
+ order of every compiler path; structural changes must leave it unchanged. The planning entry point wraps that output in
38
+ `CompiledQuery`, attaching settings, deadlines, cancellation and correlation
39
+ metadata. Clients then execute or cache it.
40
+
41
+ Validation is split by responsibility, preserving the existing rejection order.
42
+ Pure admission and contract checks do not allocate parameters. Field-specific
43
+ checks still occur during compilation as each field is resolved. Client
44
+ `validate()` plans without executing; cancelled or expired requests still raise
45
+ rather than being reported as invalid query inputs. Every execution plans before
46
+ cache lookup, so the cache cannot bypass admission or tenant validation.
47
+
48
+ Keep helpers that do not depend on compiler state in focused domain modules or
49
+ the nearest `utils/` directory. Behavior that owns or changes selections, joins
50
+ or parameter state stays on the compiler. Preserve the existing planner entry
51
+ point, aliases and package exports when moving implementations.
52
+
53
+ ## Dialects
54
+
55
+ Compilation spells every ClickHouse-specific construct through a `SqlDialect`
56
+ (`planner/dialects/`): aggregate functions and the conditional (`-If`)
57
+ combinator, grain truncation and period text, time-zone conversion, the join
58
+ match marker, the single-match join keyword, and the relationship-check counts.
59
+ `ClickHouseDialect` is the only implementation and the default.
60
+
61
+ Identifier quoting (`SafeIdentifier`) and `{name:Type}` placeholders
62
+ (`TypedParameter`) are not yet dialect-owned; a dialect that needs different
63
+ ones should move them behind the same seam. A new dialect must reproduce the
64
+ semantics each ClickHouse spelling documents — single-match joins, tenant
65
+ predicates inside the join condition, the match marker's null behaviour and
66
+ parameter allocation order — and needs its own live semantic-equivalence tests.
67
+ Keep intentional SQL changes separate from structural extraction.
68
+
69
+ Python does not currently author TypeScript metric handles or named queries;
70
+ extend the existing Python dataset compilation path when adding Python features.
71
+
72
+ ## Serving
73
+
74
+ `hypequery.serve` mirrors TypeScript `packages/serve` (decision 0023).
75
+ `create_api()` returns the framework-neutral `Api` from `serve/core/`, whose
76
+ `handle(ServeRequest) -> ServeResponse` runs the whole pipeline: request ids,
77
+ the `HttpSecurity` profile, production budgets, routing, authentication before
78
+ the body, rate limits, the body policy, validation and the error envelope.
79
+ Adapters only translate a transport's request and response:
80
+
81
+ | Responsibility | Module under `src/hypequery/serve/` |
82
+ | --- | --- |
83
+ | The pipeline, routes and their order | `core/api.py` |
84
+ | Requests and responses | `core/messages.py` |
85
+ | Hosts, proxies and CORS; production budgets; rate limits | `core/security.py`, `core/production_limits.py`, `core/rate_limit.py` |
86
+ | Authentication: header credentials, JWT, the host's session (`from_context`) and its same-origin check | `core/auth.py`, `core/authentication.py`, `core/jwt_auth.py`, `core/context_auth.py`, `core/utils/same_origin.py` |
87
+ | Dataset, metric and discovery endpoints | `core/endpoints.py`, `core/discovery.py`, `core/client_discovery.py` |
88
+ | Development OpenAPI and docs | `core/openapi.py` |
89
+ | The public factory and its declared endpoints | `api.py` |
90
+ | The pure-ASGI adapter | `asgi.py`, `utils/asgi_body.py`, `utils/asgi_scope.py` |
91
+ | The WSGI adapter | `wsgi.py`, `utils/wsgi_environ.py` |
92
+ | Serving sync hosts on one loop per process | `utils/serving_loop.py`, `utils/blocking.py`, `utils/thread_body.py` |
93
+ | Writing a response; a fault in the core | `utils/response_head.py`, `utils/fault.py` |
94
+ | Native Django and Flask adapters | `../contrib/django/views.py`, `../contrib/flask.py`, `../contrib/utils/mounted_path.py` |
95
+ | Django and Flask login as `from_context` strategies | `../contrib/django/auth.py` (`django_user`), `../contrib/flask.py` (`flask_session`) |
96
+ | uvicorn runners | `production.py`, `dev/` |
97
+
98
+ The core imports no web framework (an import-linter contract), and neither does
99
+ the rest of `hypequery.serve` (another). The Django and Flask adapters live in
100
+ `hypequery.contrib`, beside each framework's other integrations, and map that
101
+ framework's request onto `ServeRequest`. Behaviour belongs in the core, so
102
+ every adapter, and `Api.handle` called directly, answers the same bytes; the
103
+ shared fixtures in `specs/serve-http` and the security matrix run against
104
+ `Api.handle` and every adapter (`tests/serve_transports.py`).
105
+
106
+ Sync hosts (a WSGI server, Django under WSGI, Flask) never run an event loop
107
+ per request. The first request starts one loop thread per process
108
+ (`serving_loop.py`); each request's coroutine runs there, in a copy of the
109
+ request thread's context, while that thread waits and performs the request's
110
+ blocking reads when the coroutine asks (`RequestThread.call`). Code that must
111
+ run on the request's own thread uses the same channel: a sync host sets
112
+ `ServeRequest.run_on_request_thread`, and a sync `from_context` extractor runs
113
+ there, so a Django user or a Flask-Login user is loaded on the thread whose
114
+ database connection the framework manages. Like worker-pool work, it is tracked
115
+ by the request's `RequestWork` (`core/work.py`), so a lookup still running
116
+ after a 504 keeps its production slot until it returns. The loop restarts in
117
+ each forked worker and stops at exit. Django under ASGI runs the core on the
118
+ server's loop instead: `urls(api)` resolves to an async view when Django
119
+ resolves the request on an event loop and to a sync view otherwise.
120
+
121
+ A framework router hands the core the path below its prefix, as sent, and the
122
+ prefix it routed through (`Api.handle(..., mounted_at=...)`); client contracts
123
+ and discovery name paths under that prefix unless the API's
124
+ `client_mount_path` says otherwise.
125
+
126
+ ## Verification
127
+
128
+ Run `uv run pytest`, `uv run mypy`, `uv run ruff check .`,
129
+ `uv run ruff format --check .`, `uv run lint-imports` and
130
+ `uv run python scripts/check_sql_interpolation.py`. The import contracts enforce
131
+ the compiler's independence from orchestration and execution. Planner and client
132
+ tests cover SQL, parameter binding, tenancy, admission and cache behavior.
133
+ Changes to SQL semantics also need the relevant live ClickHouse tests.