Metadata-Version: 2.4
Name: grid-view-spec
Version: 2.0.0
Summary: Declarative GridViewSpec pages: tables, filters, KPI, charts, PDF/XLSX export; optional Django backend
Author-email: Oleksii Pylypchuk <alpi@keemail.me>
License-Expression: MIT
Project-URL: Homepage, https://github.com/alpiua/grid-view-spec
Project-URL: Repository, https://github.com/alpiua/grid-view-spec
Project-URL: Documentation, https://alpiua.github.io/grid-view-spec/
Project-URL: Issues, https://github.com/alpiua/grid-view-spec/issues
Project-URL: Changelog, https://github.com/alpiua/grid-view-spec/blob/main/CHANGELOG.md
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: jinja2>=3.1
Provides-Extra: django
Requires-Dist: django<6.0,>=4.2; extra == "django"
Provides-Extra: mcp
Requires-Dist: fastmcp>=2.0.0; extra == "mcp"
Provides-Extra: starlette
Requires-Dist: starlette>=0.40; extra == "starlette"
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.115; extra == "fastapi"
Requires-Dist: starlette>=0.40; extra == "fastapi"
Provides-Extra: static-charts
Requires-Dist: matplotlib>=3.8; extra == "static-charts"
Provides-Extra: pdf
Requires-Dist: weasyprint>=62; extra == "pdf"
Requires-Dist: jinja2>=3.1; extra == "pdf"
Provides-Extra: xlsx
Requires-Dist: xlsxwriter>=3.2.0; extra == "xlsx"
Provides-Extra: xlsx-all
Requires-Dist: xlsxwriter>=3.2.0; extra == "xlsx-all"
Requires-Dist: openpyxl>=3.1; extra == "xlsx-all"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.6; extra == "docs"
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Provides-Extra: dev
Requires-Dist: basedpyright>=1.28.0; extra == "dev"
Requires-Dist: build>=1.2.0; extra == "dev"
Requires-Dist: django<6.0,>=4.2; extra == "dev"
Requires-Dist: django-stubs>=5.1.0; extra == "dev"
Requires-Dist: jinja2>=3.1; extra == "dev"
Requires-Dist: matplotlib>=3.8; extra == "dev"
Requires-Dist: matplotlib-stubs>=0.3.11; extra == "dev"
Requires-Dist: mkdocs>=1.6; extra == "dev"
Requires-Dist: mkdocs-material>=9.5; extra == "dev"
Requires-Dist: openpyxl>=3.1; extra == "dev"
Requires-Dist: pre-commit>=4.0.0; extra == "dev"
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-django>=4.8.0; extra == "dev"
Requires-Dist: jsonschema>=4.23.0; extra == "dev"
Requires-Dist: ruff>=0.8.0; extra == "dev"
Requires-Dist: twine>=5.0.0; extra == "dev"
Requires-Dist: typing_extensions>=4.12.0; extra == "dev"
Requires-Dist: weasyprint>=62; extra == "dev"
Requires-Dist: xlsxwriter>=3.2.0; extra == "dev"
Dynamic: license-file

# Grid View Spec

[![PyPI](https://img.shields.io/pypi/v/grid-view-spec.svg?label=PyPI)](https://pypi.org/project/grid-view-spec/)
[![Python](https://img.shields.io/pypi/pyversions/grid-view-spec.svg)](https://pypi.org/project/grid-view-spec/)
[![Docs](https://img.shields.io/badge/docs-GitHub%20Pages-2563eb)](https://alpiua.github.io/grid-view-spec/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

**Declarative dashboard pages for Django and other hosts** — tables, filters, KPI strips, charts, and export from one typed **`GridViewSpec`** contract. You own SQL/ORM rows; the package owns layout, templates, browser runtime, and PDF/XLSX pipelines.

**[Documentation](https://alpiua.github.io/grid-view-spec/)** · **[MCP server](docs/tools/mcp-server.md)** · **[PyPI](https://pypi.org/project/grid-view-spec/)**

---

## Core idea

| Layer | Owner |
|-------|--------|
| **Data** | Host — querysets, aggregates, authorization |
| **Spec** | `GridViewSpec` — blocks (`GridViewTable`, `GridViewFilters`, …) + layout |
| **Render** | Package — Jinja/Django HTML, `gridviewspec.min.js`, export |

```python
from grid_view_spec import GridViewSpec, validate_spec
from grid_view_spec.types.layout import GridViewArea, GridViewLayout
from grid_view_spec.types.table_v2 import GridViewColumn, GridViewTable

spec = GridViewSpec(
    id="orders",
    blocks=(
        GridViewTable(
            id="orders_table",
            backend="simple",
            columns=(
                GridViewColumn(id="name", label="Customer", field="name"),
                GridViewColumn(id="amount", label="Amount", field="amount", type="currency"),
            ),
        ),
    ),
    layout=GridViewLayout(root=GridViewArea(id="root", blocks=("orders_table",))),
)
validate_spec(spec)
```

```django
{% load grid_view_spec %}
{% grid_view_spec_assets part='css' %}
{% render_grid_view_spec spec rows %}
{% grid_view_spec_assets part='js' force_core=True %}
```

---

## Install

```bash
pip install "grid-view-spec[django]"
# optional:
pip install "grid-view-spec[django,pdf,xlsx,mcp]"
```

**Django**

```python
INSTALLED_APPS = ["grid_view_spec.backends.django"]
```

```bash
python manage.py migrate grid_view_spec_django
```

```python
urlpatterns = [
    path("", include("grid_view_spec.backends.django.urls")),
]
```

See [Getting started](docs/getting-started.md) and [Django integration](docs/integration/django.md).

---

## Export

Register builders that return **`GridViewExportJob(spec, rows, table_id=…)`**:

```python
from grid_view_spec.export.registry import register_pdf_export, register_xlsx_export
from grid_view_spec.export.registry import GridViewExportJob

def register_exports():
    def builder(host, ctx):
        page = load_orders_page(ctx)  # same loader as HTML view
        return GridViewExportJob(spec=page.spec, rows=page.rows, table_id="orders_table")

    register_pdf_export("orders", builder)
    register_xlsx_export("orders", builder)
```

Browser links use `?builder=orders` plus current filter query params. Details: [Export page pattern](docs/export/page-pattern.md).

---

## AG-Grid, charts, MCP

- **AG-Grid** — `GridViewTable(backend="ag_grid")` + host JSON API; helpers in `grid_view_spec.backends.django.ag_grid`
- **Charts / KPI** — spec blocks + ECharts; values always from host `rows`
- **MCP** — `gridviewspec-mcp` for validation, catalog, migration hints ([tools/mcp-server.md](docs/tools/mcp-server.md))

---

## Development

```bash
uv sync
uv run pytest -q
uv run basedpyright --warnings src/grid_view_spec tests
cd frontend && npm run build && npm run typecheck
```

Pre-commit hooks: ruff, basedpyright, frontend typecheck/eslint, pytest.

---

## License

MIT — see [LICENSE](LICENSE).
