Metadata-Version: 2.4
Name: infraredshift
Version: 0.1.0
Summary: Amazon Redshift workload triage: captures SYS/SVV telemetry from producer and consumer clusters into local DuckDB, groups repeat query patterns, and ranks physical-design fixes by total time cost.
Author-email: "Louis N. Capece, Jr." <lcapece@optonline.net>
License: MIT
Project-URL: Homepage, https://github.com/lcapece/redshift#readme
Project-URL: Repository, https://github.com/lcapece/redshift
Project-URL: Issues, https://github.com/lcapece/redshift/issues
Keywords: amazon-redshift,redshift,duckdb,query-analysis,workload-triage,distkey,sortkey,spectrum,query-optimization,database-tuning
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT 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: Topic :: Database
Classifier: Topic :: Database :: Database Engines/Servers
Classifier: Topic :: System :: Monitoring
Classifier: Environment :: X11 Applications :: Qt
Classifier: Environment :: Win32 (MS Windows)
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PySide6<7,>=6.7.0
Requires-Dist: pandas<3,>=2.2.0
Requires-Dist: numpy<3,>=1.26.0
Requires-Dist: duckdb<2,>=1.1.0
Requires-Dist: sqlglot==26.33.0
Requires-Dist: rapidfuzz<4,>=3.5.0
Requires-Dist: redshift-query-decomposer>=0.2.3
Provides-Extra: redshift
Requires-Dist: redshift-connector<3,>=2.1.0; extra == "redshift"
Provides-Extra: jdbc
Requires-Dist: JayDeBeApi>=1.2.3; extra == "jdbc"
Requires-Dist: JPype1>=1.5.0; extra == "jdbc"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Provides-Extra: all
Requires-Dist: redshift-connector<3,>=2.1.0; extra == "all"
Requires-Dist: JayDeBeApi>=1.2.3; extra == "all"
Requires-Dist: JPype1>=1.5.0; extra == "all"
Dynamic: license-file

# Infraredshift

Amazon Redshift workload triage. It captures SYS/SVV telemetry from your
producer and consumer clusters into a local DuckDB file, groups queries that
repeat with different literals into one pattern, and ranks physical-design
fixes by the total time they actually cost you.

The point is triage. A cluster running fifteen thousand slow queries does not
have fifteen thousand problems — it usually has a few dozen query *shapes* run
over and over. Infraredshift finds the shapes, totals their real cost, and
tells you which ones are worth fixing first.

Everything runs locally. Your SQL, your telemetry, and your credentials never
leave the machine.

---

## Install

```bash
pip install infraredshift
```

To capture live from Redshift, add the connector:

```bash
pip install "infraredshift[redshift]"
```

On Windows/ARM, where the native connector has no wheel, use the JDBC path:

```bash
pip install "infraredshift[jdbc]"
```

Python 3.10+.

---

## First run

```bash
infraredshift
```

The app opens on a local sign-in screen. **This is not a Redshift login** — it
creates an access code and PIN that encrypt your Redshift credentials at rest
on this machine, using Windows DPAPI scoped to your Windows user. Nobody else
signing in to this machine can decrypt them, and they are never written to a
`.env` file or exported into environment variables.

There is nothing to configure before this step. If you have no data yet, the
app opens with empty screens and tells you what to load.

### Getting data in

You need three things: a cluster profile, credentials, and a load.

**1. Describe your clusters.** Create `redshift_cluster_profiles.json` next to
the app, or point at one with `REDSHIFT_ANALYZER_PROFILE_PATH`:

```json
{
  "format": "redshift-query-anatomy-cluster-profiles",
  "version": 1,
  "profiles": [
    {
      "profile": "REDSHIFT_PRODUCER",
      "display_name": "Producer",
      "namespace_id": "your-producer-namespace-uuid",
      "port": "5439",
      "primary_database": "dev",
      "floor_seconds": "300"
    },
    {
      "profile": "REDSHIFT_CONSUMER_1",
      "display_name": "Reporting",
      "namespace_id": "your-consumer-namespace-uuid",
      "port": "5439",
      "primary_database": "dev",
      "floor_seconds": "30"
    }
  ]
}
```

`floor_seconds` is the capture threshold for that cluster — queries faster than
this are not captured. A busy producer earns a high floor (300s); a quieter
consumer can afford 30s. This file holds **no credentials**, so it is safe to
share with teammates.

**2. Enter credentials** in the app under Local Credentials. They are encrypted
immediately.

**3. Load.** Use the Data Loader tab, or:

```bash
infraredshift-loader refresh --days 7
```

The first load is the slow one. After that, loads are incremental.

**No cluster handy?** The app ships a mock warehouse, so you can open every
screen and see real-shaped data before connecting anything.

---

## What you get

**Workload Triage** — one bubble per repeat pattern. Horizontal axis is how
often it runs, vertical is what you choose (runtime, rows, spill). Big bubble
in the upper right is where your time is going. Each pattern carries a verdict:
fix the query, fix the tables, or leave it alone.

**Table Heat Map** — every table as a square, coloured by distribution and sort
health. Missing DISTKEY, unsorted, stale statistics. Spectrum tables get their
own view coloured by whether a partition key exists.

**Query Decomposer** — takes one slow query and splits it into the stages it
actually runs, so you can see which join or scan is the expensive one.

**Behind Views** — the base tables a query really touches once views are
expanded, which is usually more than the SQL suggests.

---

## Commands

| Command | Does |
|---|---|
| `infraredshift` | Open the desktop app |
| `infraredshift-loader refresh --days 7` | Incremental capture |
| `infraredshift-capture --external-tables` | Spectrum/external metadata (opt-in) |

### Large Spectrum catalogs

`SVV_EXTERNAL_COLUMNS` returns **one row per column**, so a catalog with
millions of external tables is tens of millions of rows. If yours is large,
restrict the capture in the producer profile:

```json
"external_schemas": "curated, analytics",
"external_table_patterns": "fact_*, dim_*"
```

The filter runs on Redshift, so the rows never cross the wire. `*` and `?` are
the wildcards; a literal `_` in a table name means itself.

---

## Privacy

Analysis is local. The app makes no outbound calls except to your own Redshift
clusters. Captured SQL, telemetry, and credentials stay in your DuckDB file and
your DPAPI-encrypted secrets file on this machine.

---

## License

MIT. See [LICENSE](https://github.com/lcapece/redshift/blob/main/LICENSE).
