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.
- hypequery-0.1.0b1/.gitattributes +3 -0
- hypequery-0.1.0b1/.gitignore +23 -0
- hypequery-0.1.0b1/ARCHITECTURE.md +133 -0
- hypequery-0.1.0b1/CHANGELOG.md +451 -0
- hypequery-0.1.0b1/LICENSE +201 -0
- hypequery-0.1.0b1/PKG-INFO +2063 -0
- hypequery-0.1.0b1/README.md +1994 -0
- hypequery-0.1.0b1/RELEASING.md +272 -0
- hypequery-0.1.0b1/changelog.d/README.md +26 -0
- hypequery-0.1.0b1/changelog.d/template.md +12 -0
- hypequery-0.1.0b1/examples/README.md +106 -0
- hypequery-0.1.0b1/examples/__init__.py +1 -0
- hypequery-0.1.0b1/examples/client_dashboard/README.md +174 -0
- hypequery-0.1.0b1/examples/client_dashboard/__init__.py +1 -0
- hypequery-0.1.0b1/examples/client_dashboard/__main__.py +7 -0
- hypequery-0.1.0b1/examples/client_dashboard/api.py +52 -0
- hypequery-0.1.0b1/examples/client_dashboard/definitions.py +31 -0
- hypequery-0.1.0b1/examples/client_dashboard/frontend/.gitignore +6 -0
- hypequery-0.1.0b1/examples/client_dashboard/frontend/app.tsx +59 -0
- hypequery-0.1.0b1/examples/client_dashboard/frontend/mcp-check.mjs +46 -0
- hypequery-0.1.0b1/examples/client_dashboard/frontend/package.json +24 -0
- hypequery-0.1.0b1/examples/client_dashboard/frontend/public/index.html +3 -0
- hypequery-0.1.0b1/examples/client_dashboard/frontend/tsconfig.json +8 -0
- hypequery-0.1.0b1/examples/client_dashboard/seed.sql +17 -0
- hypequery-0.1.0b1/examples/dataframes.py +33 -0
- hypequery-0.1.0b1/examples/django_app.py +204 -0
- hypequery-0.1.0b1/examples/django_urls.py +30 -0
- hypequery-0.1.0b1/examples/embedded_analytics.py +71 -0
- hypequery-0.1.0b1/examples/flask_app.py +136 -0
- hypequery-0.1.0b1/examples/governed_agent.py +59 -0
- hypequery-0.1.0b1/examples/multitenant_saas.py +59 -0
- hypequery-0.1.0b1/examples/seed.sql +16 -0
- hypequery-0.1.0b1/examples/sqlalchemy_engine.py +49 -0
- hypequery-0.1.0b1/examples/utils/__init__.py +1 -0
- hypequery-0.1.0b1/examples/utils/analytics.py +85 -0
- hypequery-0.1.0b1/examples/utils/analytics_page.html +87 -0
- hypequery-0.1.0b1/examples/utils/config.py +16 -0
- hypequery-0.1.0b1/examples/utils/login.py +23 -0
- hypequery-0.1.0b1/examples/utils/orders.py +56 -0
- hypequery-0.1.0b1/examples/utils/server.py +90 -0
- hypequery-0.1.0b1/pyproject.toml +307 -0
- hypequery-0.1.0b1/scripts/audit_artifacts.py +165 -0
- hypequery-0.1.0b1/scripts/check_coverage.py +79 -0
- hypequery-0.1.0b1/scripts/check_release_artifacts.py +21 -0
- hypequery-0.1.0b1/scripts/check_sql_interpolation.py +194 -0
- hypequery-0.1.0b1/scripts/cli_smoke.py +29 -0
- hypequery-0.1.0b1/scripts/getting_started.py +223 -0
- hypequery-0.1.0b1/scripts/prepare_release.py +39 -0
- hypequery-0.1.0b1/scripts/prepare_release_pr.py +106 -0
- hypequery-0.1.0b1/scripts/utils/__init__.py +1 -0
- hypequery-0.1.0b1/scripts/utils/checks.py +6 -0
- hypequery-0.1.0b1/scripts/utils/installed_cli.py +470 -0
- hypequery-0.1.0b1/scripts/utils/release_artifacts.py +47 -0
- hypequery-0.1.0b1/scripts/utils/release_notes.py +28 -0
- hypequery-0.1.0b1/scripts/utils/release_versions.py +39 -0
- hypequery-0.1.0b1/src/hypequery/__init__.py +22 -0
- hypequery-0.1.0b1/src/hypequery/__main__.py +6 -0
- hypequery-0.1.0b1/src/hypequery/cli/__init__.py +33 -0
- hypequery-0.1.0b1/src/hypequery/cli/commands/__init__.py +1 -0
- hypequery-0.1.0b1/src/hypequery/cli/commands/dev.py +74 -0
- hypequery-0.1.0b1/src/hypequery/cli/commands/export.py +39 -0
- hypequery-0.1.0b1/src/hypequery/cli/commands/generate.py +94 -0
- hypequery-0.1.0b1/src/hypequery/cli/commands/init.py +58 -0
- hypequery-0.1.0b1/src/hypequery/cli/errors.py +5 -0
- hypequery-0.1.0b1/src/hypequery/cli/generators/__init__.py +1 -0
- hypequery-0.1.0b1/src/hypequery/cli/generators/count_measure.py +29 -0
- hypequery-0.1.0b1/src/hypequery/cli/generators/datasets.py +369 -0
- hypequery-0.1.0b1/src/hypequery/cli/generators/framework_apps.py +257 -0
- hypequery-0.1.0b1/src/hypequery/cli/generators/project.py +131 -0
- hypequery-0.1.0b1/src/hypequery/cli/generators/schema.py +170 -0
- hypequery-0.1.0b1/src/hypequery/cli/options.py +90 -0
- hypequery-0.1.0b1/src/hypequery/cli/parser.py +144 -0
- hypequery-0.1.0b1/src/hypequery/cli/scaffold.py +62 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/.env.example +12 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/.gitignore +6 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/README.md +103 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/app.py +50 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/datasets.py +21 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/django/analytics.py +106 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/django/manage.py +10 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/django/settings.py +58 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/django/urls.py +25 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/flask/app.py +134 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/pyproject.toml.template +12 -0
- hypequery-0.1.0b1/src/hypequery/cli/templates/seed.sql +17 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/__init__.py +1 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/catalog_comment.py +35 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/clickhouse_hints.py +38 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/client_contract_factory.py +92 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/connection_scaffold.py +68 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/display_path.py +11 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/generated_file.py +233 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/next_steps.py +23 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/recorded_selection.py +54 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/startup_errors.py +29 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/templates.py +26 -0
- hypequery-0.1.0b1/src/hypequery/cli/utils/tenant_settings.py +48 -0
- hypequery-0.1.0b1/src/hypequery/contrib/__init__.py +9 -0
- hypequery-0.1.0b1/src/hypequery/contrib/django/__init__.py +60 -0
- hypequery-0.1.0b1/src/hypequery/contrib/django/apps.py +37 -0
- hypequery-0.1.0b1/src/hypequery/contrib/django/auth.py +113 -0
- hypequery-0.1.0b1/src/hypequery/contrib/django/clients.py +120 -0
- hypequery-0.1.0b1/src/hypequery/contrib/django/conf.py +102 -0
- hypequery-0.1.0b1/src/hypequery/contrib/django/middleware.py +53 -0
- hypequery-0.1.0b1/src/hypequery/contrib/django/views.py +231 -0
- hypequery-0.1.0b1/src/hypequery/contrib/flask.py +390 -0
- hypequery-0.1.0b1/src/hypequery/contrib/sqlalchemy.py +126 -0
- hypequery-0.1.0b1/src/hypequery/contrib/utils/__init__.py +1 -0
- hypequery-0.1.0b1/src/hypequery/contrib/utils/lazy_executor.py +48 -0
- hypequery-0.1.0b1/src/hypequery/contrib/utils/mounted_path.py +36 -0
- hypequery-0.1.0b1/src/hypequery/contrib/utils/process_clients.py +151 -0
- hypequery-0.1.0b1/src/hypequery/contrib/utils/tenant_value.py +46 -0
- hypequery-0.1.0b1/src/hypequery/datasets/__init__.py +216 -0
- hypequery-0.1.0b1/src/hypequery/datasets/_base.py +34 -0
- hypequery-0.1.0b1/src/hypequery/datasets/adapter.py +71 -0
- hypequery-0.1.0b1/src/hypequery/datasets/aggregations.py +101 -0
- hypequery-0.1.0b1/src/hypequery/datasets/cache/__init__.py +15 -0
- hypequery-0.1.0b1/src/hypequery/datasets/cache/cached_rows_check.py +27 -0
- hypequery-0.1.0b1/src/hypequery/datasets/cache/preimage_inputs.py +106 -0
- hypequery-0.1.0b1/src/hypequery/datasets/cache/result_cache.py +191 -0
- hypequery-0.1.0b1/src/hypequery/datasets/cache/store.py +87 -0
- hypequery-0.1.0b1/src/hypequery/datasets/catalog.py +286 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client/__init__.py +52 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client/clients.py +436 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client/dataframes.py +232 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client/inputs.py +74 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client/pagination.py +33 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client/results.py +171 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client/tenant_binding.py +37 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client_contract/__init__.py +6 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client_contract/annotations.py +84 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client_contract/export.py +120 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client_contract/fields.py +118 -0
- hypequery-0.1.0b1/src/hypequery/datasets/client_contract/models.py +88 -0
- hypequery-0.1.0b1/src/hypequery/datasets/constants.py +67 -0
- hypequery-0.1.0b1/src/hypequery/datasets/contract.py +195 -0
- hypequery-0.1.0b1/src/hypequery/datasets/dataset.py +185 -0
- hypequery-0.1.0b1/src/hypequery/datasets/deployment.py +212 -0
- hypequery-0.1.0b1/src/hypequery/datasets/deployment_bundle.py +104 -0
- hypequery-0.1.0b1/src/hypequery/datasets/deployment_values.py +57 -0
- hypequery-0.1.0b1/src/hypequery/datasets/derived_measures.py +22 -0
- hypequery-0.1.0b1/src/hypequery/datasets/dimensions.py +103 -0
- hypequery-0.1.0b1/src/hypequery/datasets/formulas.py +177 -0
- hypequery-0.1.0b1/src/hypequery/datasets/immutability.py +77 -0
- hypequery-0.1.0b1/src/hypequery/datasets/measures.py +149 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/__init__.py +82 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/admission.py +18 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/aggregates.py +31 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/aliases.py +6 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/compiled_query.py +116 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/compiler.py +110 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/context.py +198 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/dialects/__init__.py +8 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/dialects/base.py +68 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/dialects/clickhouse.py +154 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/errors.py +119 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/__init__.py +6 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/base.py +17 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/dimensions.py +52 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/fields.py +86 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/filtering.py +144 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/having.py +75 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/joins.py +113 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/measures.py +157 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/features/ordering.py +48 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/filter_validation.py +84 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/identifiers.py +71 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/operators.py +17 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/parameters.py +107 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/planner.py +61 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/predicates.py +16 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/query.py +43 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/query_node.py +39 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/query_validation.py +96 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/resolution.py +216 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/settings.py +89 -0
- hypequery-0.1.0b1/src/hypequery/datasets/planner/sql_fragments.py +75 -0
- hypequery-0.1.0b1/src/hypequery/datasets/query_helpers.py +153 -0
- hypequery-0.1.0b1/src/hypequery/datasets/registry.py +66 -0
- hypequery-0.1.0b1/src/hypequery/datasets/relationship_check.py +96 -0
- hypequery-0.1.0b1/src/hypequery/datasets/relationship_check_plan.py +82 -0
- hypequery-0.1.0b1/src/hypequery/datasets/relationships.py +161 -0
- hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/__init__.py +23 -0
- hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/compiler.py +94 -0
- hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/errors.py +54 -0
- hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/limits.py +34 -0
- hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/parser.py +546 -0
- hypequery-0.1.0b1/src/hypequery/datasets/sql_portability/tokenizer.py +306 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/__init__.py +1 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/canonical_json.py +30 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/definition_projection.py +80 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/deployable_formulas.py +96 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/derived_measures.py +165 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/measure_references.py +43 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/output_column_types.py +104 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/output_columns.py +14 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/portable_grains.py +34 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/portable_order.py +26 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/query_timezone.py +43 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_fields.py +54 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_key_check.py +44 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_measures.py +97 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/relationship_names.py +27 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/stable_json.py +47 -0
- hypequery-0.1.0b1/src/hypequery/datasets/utils/timestamp_text.py +35 -0
- hypequery-0.1.0b1/src/hypequery/datasets/validation.py +37 -0
- hypequery-0.1.0b1/src/hypequery/execution/__init__.py +29 -0
- hypequery-0.1.0b1/src/hypequery/execution/cancellation.py +242 -0
- hypequery-0.1.0b1/src/hypequery/execution/clickhouse.py +640 -0
- hypequery-0.1.0b1/src/hypequery/execution/errors.py +91 -0
- hypequery-0.1.0b1/src/hypequery/execution/parameters.py +72 -0
- hypequery-0.1.0b1/src/hypequery/execution/readonly_settings.py +117 -0
- hypequery-0.1.0b1/src/hypequery/execution/results.py +62 -0
- hypequery-0.1.0b1/src/hypequery/execution/sync_cancellation.py +51 -0
- hypequery-0.1.0b1/src/hypequery/execution/utils/__init__.py +1 -0
- hypequery-0.1.0b1/src/hypequery/execution/utils/close_cancellation.py +17 -0
- hypequery-0.1.0b1/src/hypequery/execution/utils/connection_env.py +105 -0
- hypequery-0.1.0b1/src/hypequery/execution/utils/connection_url.py +139 -0
- hypequery-0.1.0b1/src/hypequery/execution/utils/datetime_parameters.py +37 -0
- hypequery-0.1.0b1/src/hypequery/execution/utils/driver_loggers.py +31 -0
- hypequery-0.1.0b1/src/hypequery/execution/utils/refused_kill.py +37 -0
- hypequery-0.1.0b1/src/hypequery/protocol/__init__.py +408 -0
- hypequery-0.1.0b1/src/hypequery/protocol/_jcs.py +238 -0
- hypequery-0.1.0b1/src/hypequery/protocol/adapter.py +451 -0
- hypequery-0.1.0b1/src/hypequery/protocol/bundle_codec.py +85 -0
- hypequery-0.1.0b1/src/hypequery/protocol/bundles.py +365 -0
- hypequery-0.1.0b1/src/hypequery/protocol/cache_keys.py +170 -0
- hypequery-0.1.0b1/src/hypequery/protocol/cache_preimages.py +176 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/__init__.py +44 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/bounds.py +26 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/codec.py +12 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/conformance.py +90 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/decode.py +112 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/errors.py +47 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/models.py +92 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/nodes.py +150 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/primitives.py +138 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/query.py +220 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/safe_data.py +98 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/timezone_names.py +603 -0
- hypequery-0.1.0b1/src/hypequery/protocol/client_contract/validate.py +154 -0
- hypequery-0.1.0b1/src/hypequery/protocol/constructors.py +205 -0
- hypequery-0.1.0b1/src/hypequery/protocol/deployment_codec.py +102 -0
- hypequery-0.1.0b1/src/hypequery/protocol/deployment_fixtures.py +85 -0
- hypequery-0.1.0b1/src/hypequery/protocol/deployment_nodes.py +468 -0
- hypequery-0.1.0b1/src/hypequery/protocol/deployment_primitives.py +286 -0
- hypequery-0.1.0b1/src/hypequery/protocol/deployment_v3_nodes.py +168 -0
- hypequery-0.1.0b1/src/hypequery/protocol/deployments.py +599 -0
- hypequery-0.1.0b1/src/hypequery/protocol/errors.py +258 -0
- hypequery-0.1.0b1/src/hypequery/protocol/expression_fixtures.py +64 -0
- hypequery-0.1.0b1/src/hypequery/protocol/expression_models.py +277 -0
- hypequery-0.1.0b1/src/hypequery/protocol/expressions.py +571 -0
- hypequery-0.1.0b1/src/hypequery/protocol/fixture_primitives.py +41 -0
- hypequery-0.1.0b1/src/hypequery/protocol/identifiers.py +136 -0
- hypequery-0.1.0b1/src/hypequery/protocol/js_strings.py +31 -0
- hypequery-0.1.0b1/src/hypequery/protocol/limits.py +42 -0
- hypequery-0.1.0b1/src/hypequery/protocol/query_event_fixtures.py +107 -0
- hypequery-0.1.0b1/src/hypequery/protocol/query_events.py +358 -0
- hypequery-0.1.0b1/src/hypequery/protocol/query_implementation_fixtures.py +45 -0
- hypequery-0.1.0b1/src/hypequery/protocol/query_implementation_primitives.py +151 -0
- hypequery-0.1.0b1/src/hypequery/protocol/query_implementations.py +320 -0
- hypequery-0.1.0b1/src/hypequery/protocol/releases.py +196 -0
- hypequery-0.1.0b1/src/hypequery/protocol/row_resolution.py +29 -0
- hypequery-0.1.0b1/src/hypequery/protocol/schema_defaults.py +148 -0
- hypequery-0.1.0b1/src/hypequery/protocol/schema_fixtures.py +46 -0
- hypequery-0.1.0b1/src/hypequery/protocol/schema_models.py +255 -0
- hypequery-0.1.0b1/src/hypequery/protocol/schemas.py +398 -0
- hypequery-0.1.0b1/src/hypequery/protocol/sql_expressions.py +91 -0
- hypequery-0.1.0b1/src/hypequery/protocol/stdio_adapter.py +95 -0
- hypequery-0.1.0b1/src/hypequery/protocol/utf8.py +60 -0
- hypequery-0.1.0b1/src/hypequery/protocol/values.py +509 -0
- hypequery-0.1.0b1/src/hypequery/protocol/wire_numbers.py +23 -0
- hypequery-0.1.0b1/src/hypequery/py.typed +0 -0
- hypequery-0.1.0b1/src/hypequery/serve/__init__.py +127 -0
- hypequery-0.1.0b1/src/hypequery/serve/api.py +192 -0
- hypequery-0.1.0b1/src/hypequery/serve/asgi.py +157 -0
- hypequery-0.1.0b1/src/hypequery/serve/auth.py +59 -0
- hypequery-0.1.0b1/src/hypequery/serve/client_contract.py +63 -0
- hypequery-0.1.0b1/src/hypequery/serve/client_discovery.py +24 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/__init__.py +14 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/api.py +411 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/auth.py +232 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/authentication.py +155 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/body.py +161 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/client_contract.py +195 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/client_discovery.py +78 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/context_auth.py +73 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/discovery.py +31 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/endpoints.py +349 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/errors.py +187 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/jwks.py +233 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/jwt_auth.py +373 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/lifetime.py +71 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/messages.py +160 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/openapi.py +174 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/openapi_info.py +21 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/policy.py +51 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/production.py +60 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/production_limits.py +115 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/rate_limit.py +160 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/request_ids.py +56 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/security.py +344 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/state.py +32 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/docs_html.py +54 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/host_header.py +48 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/http_deadline.py +114 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/http_proxy.py +39 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/json_body.py +93 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/jwk_selection.py +70 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/jwt_claims.py +112 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/jwt_options.py +111 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/operation_ids.py +17 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/provider_call.py +62 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/same_origin.py +75 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/utils/security_headers.py +31 -0
- hypequery-0.1.0b1/src/hypequery/serve/core/work.py +168 -0
- hypequery-0.1.0b1/src/hypequery/serve/dev/__init__.py +151 -0
- hypequery-0.1.0b1/src/hypequery/serve/dev/__main__.py +25 -0
- hypequery-0.1.0b1/src/hypequery/serve/discovery.py +23 -0
- hypequery-0.1.0b1/src/hypequery/serve/endpoints.py +154 -0
- hypequery-0.1.0b1/src/hypequery/serve/events.py +55 -0
- hypequery-0.1.0b1/src/hypequery/serve/models.py +90 -0
- hypequery-0.1.0b1/src/hypequery/serve/policy.py +7 -0
- hypequery-0.1.0b1/src/hypequery/serve/production.py +49 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/asgi_body.py +91 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/asgi_scope.py +57 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/bind_address.py +22 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/blocking.py +30 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/client_contract_view.py +24 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/discovery.py +74 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/fault.py +37 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/metric_alias.py +43 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/query_input.py +30 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/query_response.py +44 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/query_schema.py +29 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/related_fields.py +83 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/response_head.py +66 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/serving_loop.py +250 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/thread_body.py +42 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/uvicorn_server.py +20 -0
- hypequery-0.1.0b1/src/hypequery/serve/utils/wsgi_environ.py +139 -0
- hypequery-0.1.0b1/src/hypequery/serve/wsgi.py +106 -0
- hypequery-0.1.0b1/tests/asgi_client.py +155 -0
- hypequery-0.1.0b1/tests/client_dashboard_journey.py +63 -0
- hypequery-0.1.0b1/tests/contrib_doubles.py +96 -0
- hypequery-0.1.0b1/tests/core_transport.py +67 -0
- hypequery-0.1.0b1/tests/django_settings.py +65 -0
- hypequery-0.1.0b1/tests/golden_model.py +165 -0
- hypequery-0.1.0b1/tests/jwks_server.py +105 -0
- hypequery-0.1.0b1/tests/scaffold_driver.py +156 -0
- hypequery-0.1.0b1/tests/serve_transports.py +169 -0
- hypequery-0.1.0b1/tests/snapshots/cli_generated_datasets.json +39 -0
- hypequery-0.1.0b1/tests/snapshots/definition_projections.json +5310 -0
- hypequery-0.1.0b1/tests/snapshots/planner_golden_sql.json +707 -0
- hypequery-0.1.0b1/tests/test_artifact_audit.py +232 -0
- hypequery-0.1.0b1/tests/test_beta_tenant_http.py +207 -0
- hypequery-0.1.0b1/tests/test_check_coverage.py +105 -0
- hypequery-0.1.0b1/tests/test_cli.py +144 -0
- hypequery-0.1.0b1/tests/test_cli_dataset_generation.py +492 -0
- hypequery-0.1.0b1/tests/test_cli_dev.py +335 -0
- hypequery-0.1.0b1/tests/test_cli_generator_golden.py +66 -0
- hypequery-0.1.0b1/tests/test_cli_init_framework.py +310 -0
- hypequery-0.1.0b1/tests/test_cli_regeneration.py +524 -0
- hypequery-0.1.0b1/tests/test_cli_scaffold.py +102 -0
- hypequery-0.1.0b1/tests/test_cli_scaffold_fixes.py +277 -0
- hypequery-0.1.0b1/tests/test_clickhouse_execution.py +511 -0
- hypequery-0.1.0b1/tests/test_clickhouse_live.py +695 -0
- hypequery-0.1.0b1/tests/test_client_contract_discovery.py +257 -0
- hypequery-0.1.0b1/tests/test_client_contract_export.py +336 -0
- hypequery-0.1.0b1/tests/test_client_contract_export_cli.py +278 -0
- hypequery-0.1.0b1/tests/test_client_dashboard_example.py +71 -0
- hypequery-0.1.0b1/tests/test_client_endpoint_bindings.py +400 -0
- hypequery-0.1.0b1/tests/test_client_execution_core.py +169 -0
- hypequery-0.1.0b1/tests/test_composite_relationships.py +452 -0
- hypequery-0.1.0b1/tests/test_connection_env.py +164 -0
- hypequery-0.1.0b1/tests/test_connection_url.py +200 -0
- hypequery-0.1.0b1/tests/test_contract_surrogates.py +43 -0
- hypequery-0.1.0b1/tests/test_contrib_django.py +252 -0
- hypequery-0.1.0b1/tests/test_contrib_django_auth.py +277 -0
- hypequery-0.1.0b1/tests/test_contrib_django_serve.py +242 -0
- hypequery-0.1.0b1/tests/test_contrib_flask.py +179 -0
- hypequery-0.1.0b1/tests/test_contrib_flask_auth.py +115 -0
- hypequery-0.1.0b1/tests/test_contrib_flask_csrf.py +105 -0
- hypequery-0.1.0b1/tests/test_contrib_flask_serve.py +160 -0
- hypequery-0.1.0b1/tests/test_contrib_process_clients.py +200 -0
- hypequery-0.1.0b1/tests/test_dataset_cache.py +430 -0
- hypequery-0.1.0b1/tests/test_dataset_catalog.py +344 -0
- hypequery-0.1.0b1/tests/test_dataset_client.py +262 -0
- hypequery-0.1.0b1/tests/test_dataset_definitions.py +421 -0
- hypequery-0.1.0b1/tests/test_dataset_deployment.py +362 -0
- hypequery-0.1.0b1/tests/test_dataset_execution_capabilities.py +129 -0
- hypequery-0.1.0b1/tests/test_dataset_having.py +463 -0
- hypequery-0.1.0b1/tests/test_datasets_adapter.py +79 -0
- hypequery-0.1.0b1/tests/test_datetime_parameters.py +68 -0
- hypequery-0.1.0b1/tests/test_definition_projection_golden.py +63 -0
- hypequery-0.1.0b1/tests/test_derived_measures.py +545 -0
- hypequery-0.1.0b1/tests/test_examples.py +136 -0
- hypequery-0.1.0b1/tests/test_execution_cancellation.py +907 -0
- hypequery-0.1.0b1/tests/test_executor_server_faults.py +240 -0
- hypequery-0.1.0b1/tests/test_framework_examples.py +390 -0
- hypequery-0.1.0b1/tests/test_import_hygiene.py +230 -0
- hypequery-0.1.0b1/tests/test_installed_cli.py +67 -0
- hypequery-0.1.0b1/tests/test_planner.py +1085 -0
- hypequery-0.1.0b1/tests/test_planner_aggregates.py +25 -0
- hypequery-0.1.0b1/tests/test_planner_dialect.py +49 -0
- hypequery-0.1.0b1/tests/test_planner_golden_sql.py +270 -0
- hypequery-0.1.0b1/tests/test_prepare_release_pr.py +158 -0
- hypequery-0.1.0b1/tests/test_protocol_adapter.py +96 -0
- hypequery-0.1.0b1/tests/test_protocol_bundles.py +440 -0
- hypequery-0.1.0b1/tests/test_protocol_cache_keys.py +161 -0
- hypequery-0.1.0b1/tests/test_protocol_cache_preimages.py +87 -0
- hypequery-0.1.0b1/tests/test_protocol_client_contract.py +280 -0
- hypequery-0.1.0b1/tests/test_protocol_deployments.py +465 -0
- hypequery-0.1.0b1/tests/test_protocol_deployments_v3.py +74 -0
- hypequery-0.1.0b1/tests/test_protocol_expression_extension_2.py +104 -0
- hypequery-0.1.0b1/tests/test_protocol_expressions.py +228 -0
- hypequery-0.1.0b1/tests/test_protocol_identifiers.py +221 -0
- hypequery-0.1.0b1/tests/test_protocol_jcs.py +28 -0
- hypequery-0.1.0b1/tests/test_protocol_js_strings.py +104 -0
- hypequery-0.1.0b1/tests/test_protocol_query_events.py +191 -0
- hypequery-0.1.0b1/tests/test_protocol_query_implementations.py +284 -0
- hypequery-0.1.0b1/tests/test_protocol_schemas.py +279 -0
- hypequery-0.1.0b1/tests/test_protocol_sql_expressions.py +131 -0
- hypequery-0.1.0b1/tests/test_protocol_values.py +319 -0
- hypequery-0.1.0b1/tests/test_public_api_naming.py +216 -0
- hypequery-0.1.0b1/tests/test_python_release.py +123 -0
- hypequery-0.1.0b1/tests/test_query_timezone.py +392 -0
- hypequery-0.1.0b1/tests/test_relationship_check.py +316 -0
- hypequery-0.1.0b1/tests/test_relationship_measures.py +422 -0
- hypequery-0.1.0b1/tests/test_result_dataframes.py +408 -0
- hypequery-0.1.0b1/tests/test_serve_asgi.py +407 -0
- hypequery-0.1.0b1/tests/test_serve_auth.py +542 -0
- hypequery-0.1.0b1/tests/test_serve_context_auth.py +458 -0
- hypequery-0.1.0b1/tests/test_serve_core.py +522 -0
- hypequery-0.1.0b1/tests/test_serve_core_security.py +421 -0
- hypequery-0.1.0b1/tests/test_serve_create_api.py +343 -0
- hypequery-0.1.0b1/tests/test_serve_dev.py +273 -0
- hypequery-0.1.0b1/tests/test_serve_discovery.py +117 -0
- hypequery-0.1.0b1/tests/test_serve_endpoints.py +1034 -0
- hypequery-0.1.0b1/tests/test_serve_errors.py +481 -0
- hypequery-0.1.0b1/tests/test_serve_helpers.py +21 -0
- hypequery-0.1.0b1/tests/test_serve_http_fixtures.py +160 -0
- hypequery-0.1.0b1/tests/test_serve_jwt.py +928 -0
- hypequery-0.1.0b1/tests/test_serve_jwt_adapters.py +59 -0
- hypequery-0.1.0b1/tests/test_serve_jwt_fixtures.py +143 -0
- hypequery-0.1.0b1/tests/test_serve_native_adapters.py +187 -0
- hypequery-0.1.0b1/tests/test_serve_production.py +547 -0
- hypequery-0.1.0b1/tests/test_serve_security.py +511 -0
- hypequery-0.1.0b1/tests/test_serve_security_headers.py +142 -0
- hypequery-0.1.0b1/tests/test_serve_semantic_fixtures.py +187 -0
- hypequery-0.1.0b1/tests/test_serve_wsgi.py +766 -0
- hypequery-0.1.0b1/tests/test_sql_portability.py +238 -0
- hypequery-0.1.0b1/tests/test_tenant_capability.py +359 -0
- hypequery-0.1.0b1/tests/test_time_grains.py +168 -0
- hypequery-0.1.0b1/tests/wsgi_client.py +144 -0
- hypequery-0.1.0b1/uv.lock +2856 -0
- hypequery-0.0.1.dev0/.gitignore +0 -5
- hypequery-0.0.1.dev0/PKG-INFO +0 -24
- hypequery-0.0.1.dev0/README.md +0 -7
- hypequery-0.0.1.dev0/pyproject.toml +0 -28
|
@@ -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.
|