AGENTS.md · git:20260823.0b2b664 · 2026-08-23 · sha256 68c453708c8c00e5
AGENTS.md git:20260823.0b2b664A
Immutable. This exact content is served forever at /api/v1/blob/68c453708c8c00e5.
# Sidemantic Universal SQL-first semantic layer in Python. Imports from Cube/LookML/dbt/Hex/Rill/Malloy, queries against DuckDB/Postgres/BigQuery/Snowflake/etc. ## Usage Preference (Important) - Sidemantic usage is overwhelmingly CLI-first in practice (roughly 95% CLI usage). - Default to `sidemantic` CLI workflows (`validate`, `info`, `query`, `migrator`, etc.). - Treat Python API examples as secondary, advanced automation paths, not the default onboarding path. ## Codebase Structure **Main Python package:** `sidemantic/` - `core/` - SemanticLayer, Model, Dimension, Metric, SemanticGraph - `adapters/` - Format parsers (Cube, LookML, MetricFlow, Hex, Rill, Malloy, etc.) - `db/` - Database adapters - `sql/` - SQL generation and query rewriting - `widget/`, `server/`, `workbench/`, `mcp_server.py` - Optional features with lazy imports **Separate experimental implementations (not the main codebase):** - `sidemantic-rs/` - Rust rewrite (WIP) - `sidemantic-duckdb/` - DuckDB extension wrapping sidemantic-rs These don't share code with Python. CI runs them only when their dirs change. ## Version Management Update BOTH when releasing: - `pyproject.toml`: `version = "X.Y.Z"` - `sidemantic/__init__.py`: `__version__ = "X.Y.Z"` ## Validation Before Commits Match validation scope to the change instead of running the entire suite automatically. - For small, localized changes, run ruff on the changed Python files and the narrowest relevant tests. This is the default. - Expand to the affected package or subsystem when shared code, planners, adapters, or fixtures may have broader impact. - Run the full CI-equivalent sequence only when explicitly requested, preparing a release, changing dependencies/CI/tooling, making a broad cross-cutting refactor, or when targeted checks cannot bound the blast radius. - Do not rerun the full suite for a small follow-up on a branch that already had a green full run when targeted tests cover the follow-up. - Before handoff, report exactly what ran and what was left to CI. When full CI parity is warranted, run these commands in order: ```bash # Run these in order: uv sync --extra dev uv run python - <<'PY' import sys from sidemantic import Dimension, Metric, Model assert Model.__name__ == "Model" assert Dimension.__name__ == "Dimension" assert Metric.__name__ == "Metric" assert "sidemantic_dax" not in sys.modules PY uv sync --extra dev --extra dax uv run ruff check . --exclude docs/_extensions --exclude sidemantic-duckdb/extension-ci-tools --exclude sidemantic-duckdb/scripts --exclude sidemantic-duckdb/duckdb --exclude sidemantic/adapters/malloy_grammar --exclude sidemantic/adapters/holistics_grammar uv run ruff format --check . --exclude docs/_extensions --exclude sidemantic-duckdb/extension-ci-tools --exclude sidemantic-duckdb/scripts --exclude sidemantic-duckdb/duckdb --exclude sidemantic/adapters/malloy_grammar --exclude sidemantic/adapters/holistics_grammar uv run python -m playwright install --with-deps chromium uv run pytest -v ``` If any fail, fix them: ```bash # Fix ruff issues uv run ruff check --fix . --exclude docs/_extensions --exclude sidemantic-duckdb/extension-ci-tools --exclude sidemantic-duckdb/scripts --exclude sidemantic-duckdb/duckdb --exclude sidemantic/adapters/malloy_grammar --exclude sidemantic/adapters/holistics_grammar uv run ruff format . --exclude docs/_extensions --exclude sidemantic-duckdb/extension-ci-tools --exclude sidemantic-duckdb/scripts --exclude sidemantic-duckdb/duckdb --exclude sidemantic/adapters/malloy_grammar --exclude sidemantic/adapters/holistics_grammar ``` **PRs:** Do not include test commands in PR bodies unless explicitly requested. **Why this matters:** - Targeted checks keep small changes fast while still covering the affected behavior - CI runs the full matrix and remains the final integration gate - Ruff must be in `[project.optional-dependencies] dev` for CI - NOT in `[dependency-groups]` (that's uv-specific, CI uses optional-dependencies) ## Dependency Management - Use `uv` for all Python package management - Ruff should be in dev dependencies (`[dependency-groups] dev`) - DO NOT add dev tools to main dependencies unless explicitly requested - Optional features use `[project.optional-dependencies]`: - `workbench` - textual, plotext, textual-plotext (for TUI, NOT Pyodide compatible) - `serve` - mcp[cli], riffq, pyarrow (for PostgreSQL server, NOT Pyodide compatible) - `dev` - pytest, ruff, pandas, numpy (for development) **CRITICAL: Pyodide Compatibility Rules** - **Core dependencies** (in main `dependencies` list) MUST work in Pyodide/WASM - **Optional dependencies** can use packages incompatible with Pyodide (textual, riffq, pyarrow, mcp) - **ALL imports** of optional deps MUST be lazy (inside functions, NOT at module level) - **Test**: `from sidemantic import Model, Dimension, Metric` must work without any optional deps ## Pyodide Compatibility **Import Structure:** - `sidemantic/__init__.py` - Only imports core classes (Model, Dimension, etc.) - `sidemantic/cli.py` - Imports typer (core dep) at top, workbench/server imports inside command functions - `sidemantic/workbench/__init__.py` - Lazy imports textual inside `run_workbench()` function - `sidemantic/server/` - Never imported unless `sidemantic serve` command is run **Pyodide typing-extensions issue:** - Pyodide has typing-extensions==4.11.0 - Some deps (pydantic>=2.10, inflect>=7.2) require typing-extensions>=4.12+ - Dashboard handles this by installing pydantic<2.10 with deps=False - inflect<7.2 constraint in core deps marked with `# PYODIDE:` comment **Version constraints with "PYODIDE:" comments are REQUIRED:** - Heavy deps (textual, riffq, mcp) are optional to avoid Pyodide conflicts - Pyodide CI builds local wheel and installs it with `deps=False` - This ensures code changes are tested in Pyodide before publish - If adding new core deps, check they work in Pyodide or make them optional **If Pyodide CI fails:** - Check if a dep version changed that requires newer typing-extensions - Either downgrade that dep OR add workaround in dashboard.qmd install - CI installs local wheel to test current code, not PyPI version ## Testing Use the validation scope above. Prefer focused test paths or test names for localized changes; reserve `uv run pytest -v` for cases that warrant full CI parity. ## Publishing to PyPI ```bash gh workflow run publish.yml ``` ## Common Mistakes to Avoid 1. **Breaking ruff** - Always ensure ruff is installed in dev dependencies 2. **Pyodide compatibility** - Keep heavy deps (textual, pygments) optional 3. **Not linting** - Format and lint EVERY TIME before commit