Metadata-Version: 2.4
Name: dwe-hub-superset-plugin
Version: 0.1.0a1
Summary: DWE Hub plugin for Apache Superset — browse the Hub gallery, validate datasets and import dashboards into any environment
License: Apache-2.0
Author: Hipposys
Requires-Python: >=3.10,<4.0
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: GitPython (>=3.1.40)
Requires-Dist: Pillow (>=10.0.0)
Requires-Dist: PyYAML (>=6.0)
Requires-Dist: SQLAlchemy (>=2.0.0)
Requires-Dist: flask (>=2.0.0)
Requires-Dist: flask-appbuilder (>=3.0.0)
Requires-Dist: httpx (>=0.25.0)
Requires-Dist: psycopg[binary] (>=3.1.0)
Project-URL: homepage, https://github.com/hipposys/dwe_hub_superset_plugin
Description-Content-Type: text/markdown

# DWE Hub — Superset Plugin

Apache Superset plugin that connects to a [DWE Hub](https://github.com/hipposys/dwe-hub) instance, letting users browse the asset gallery, validate dataset compatibility and import dashboards — all from within Superset.

---

## How it works

The plugin adds a **DWE Hub** entry under **Custom Tools** in the Superset nav. From there users can:

- Browse published Hub assets (dashboards, models)
- Preview thumbnails and version history
- Validate that all required datasets exist in the local Superset before importing
- Import a specific version of a dashboard with one click
- See which version was last imported into the current environment

---

## How Superset knows its environment name

> **Every import is tagged with the environment label. This is how "Already imported to prod" appears in the plugin.**

The environment name is controlled by a **single environment variable**:

```
SUPERSET_ENV=prod   # or "dev", "staging", etc.
```

This value is read at startup in `superset/superset_config.py`:

```python
SUPERSET_ENV = os.environ.get("SUPERSET_ENV", "dev")
```

It flows through the plugin in two ways:

1. **Display** — the asset detail page shows:
   ```
   Already imported to prod
   Version 3 imported on 2024-11-15 by alice
   ```

2. **Hub record** — on every successful import, the plugin calls the Hub API with
   `environment_name=SUPERSET_ENV`, so the Hub tracks import history **per environment**.
   This is what drives the "Imported" badge on versions in the Hub gallery.

**To deploy to production**, set `SUPERSET_ENV=prod` in your `.env` or deployment config.
The same Docker image works for every environment — no code changes needed.

---

## Quick start

```bash
cp template.env .env
# Edit .env — set SUPERSET_ENV, DWE_HUB_URL, DWE_HUB_USER, DWE_HUB_PASSWORD
just run
```

Superset will be available at `http://localhost:8088` (default admin / admin).

---

## Configuration

All configuration is via environment variables. Copy `template.env` to `.env`:

| Variable | Default | Description |
|---|---|---|
| `SUPERSET_ENV` | `dev` | **Environment label** recorded on every import and shown as "Already imported to `<value>`" in the plugin UI. |
| `DWE_HUB_URL` | `http://dwe-hub:5000` | URL of the DWE Hub instance |
| `DWE_HUB_USER` | `admin` | Hub login username |
| `DWE_HUB_PASSWORD` | `admin` | Hub login password |
| `SUPERSET_SECRET_KEY` | *(change this)* | Flask secret key — must match across restarts |
| `SUPERSET_BASE_URL` | `http://localhost:8088` | Superset's own URL, used for self-API calls during dataset validation |
| `SUPERSET_ADMIN_USER` | `admin` | Superset admin username for first-run init |
| `SUPERSET_ADMIN_PASSWORD` | `admin` | Superset admin password for first-run init |

### Pre-registering database connections

Dashboards reference datasets by UUID. For imports to work correctly across environments the same connection UUID **must exist in every Superset instance**. Register connections via `CONNECTION_*` env vars:

```
# Format: CONNECTION_<NAME>=<display_name>:<fixed_uuid>:<sqlalchemy_uri>
CONNECTION_WAREHOUSE=Data Warehouse:a2dc77af-e654-49bb-b321-40f6b559a1ee:postgresql+psycopg2://user:pass@host/db
```

The UUID must be identical in dev, staging, and prod.

---

## Project structure

```
dwe_hub_superset_plugin/
├── superset/
│   ├── Dockerfile              # Superset image with plugin pre-installed
│   ├── superset_config.py      # Single config for all environments (SUPERSET_ENV-driven)
│   └── superset-init.sh        # DB init, admin user creation, connection pre-registration
│
├── dwe_hub_superset_plugin/   # The plugin package
│   ├── views/
│   │   └── hub_view.py         # Flask-AppBuilder view (gallery, import, diff)
│   ├── services/
│   │   ├── hub_client.py       # DWE Hub REST API client
│   │   ├── superset_api.py     # Superset REST API wrapper
│   │   └── validation_service.py
│   └── setup/
│       └── connections.py      # CONNECTION_* env var handler
│
├── docker-compose.yaml
├── pyproject.toml
├── template.env
└── justfile
```

---

## Deploying to an existing Superset

Install the plugin and add the config hook to your `superset_config.py`:

```bash
pip install superset-dashboard-migration
```

```python
# superset_config.py
import os

SUPERSET_ENV = os.environ.get("SUPERSET_ENV", "dev")
DWE_HUB_URL = os.environ.get("DWE_HUB_URL")
DWE_HUB_USER = os.environ.get("DWE_HUB_USER")
DWE_HUB_PASSWORD = os.environ.get("DWE_HUB_PASSWORD")
SUPERSET_BASE_URL = os.environ.get("SUPERSET_BASE_URL", "http://localhost:8088")
SUPERSET_ADMIN_USER = os.environ.get("SUPERSET_ADMIN_USER")
SUPERSET_ADMIN_PASSWORD = os.environ.get("SUPERSET_ADMIN_PASSWORD")

FLASK_APP_MUTATOR = lambda app: init_custom_views(app)

def init_custom_views(app):
    from dwe_hub_superset_plugin.views.hub_view import HubView
    app.appbuilder.add_view(HubView, "DWE Hub", icon="fa-cloud", category="Custom Tools")
```

