Metadata-Version: 2.5
Name: sweatmeter
Version: 0.4.0
Summary: CPU/RAM/GPU/VRAM/thermal/power telemetry and static machine profiling; degrades honestly to Unsupported rather than fabricating a value.
Project-URL: Homepage, https://github.com/JPKell/SweatMeter
Project-URL: Documentation, https://github.com/JPKell/SweatMeter/tree/main/docs
Project-URL: Changelog, https://github.com/JPKell/SweatMeter/blob/main/CHANGELOG.md
Author: Local AI Suite contributors
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: baseaicore<0.5,>=0.4
Provides-Extra: dev
Requires-Dist: import-linter<3,>=2.0; extra == 'dev'
Requires-Dist: mypy<2,>=1.11; extra == 'dev'
Requires-Dist: pynvml<12,>=11; extra == 'dev'
Requires-Dist: pytest-cov<6,>=5; extra == 'dev'
Requires-Dist: pytest-randomly<4,>=3; extra == 'dev'
Requires-Dist: pytest<10,>=9.0.3; extra == 'dev'
Requires-Dist: respx<1,>=0.21; extra == 'dev'
Requires-Dist: ruff<1,>=0.6; extra == 'dev'
Provides-Extra: psutil
Requires-Dist: psutil<7,>=6; extra == 'psutil'
Provides-Extra: pynvml
Requires-Dist: pynvml<12,>=11; extra == 'pynvml'
Description-Content-Type: text/markdown

# SweatMeter

CPU/RAM/GPU/VRAM/thermal/power telemetry and static machine profiling; degrades honestly to Unsupported rather than fabricating a value.

**Status:** Phases 1–4 implemented (`sweatmeter 0.4.0`). Linux host readers, NVIDIA telemetry,
non-raising snapshots, stable machine profiles, bounded background sampling, per-device window
statistics, telemetry-derived energy estimates, and explained throttling verdicts are available.

Part of the **Local AI Suite** — see [docs/architecture/executive-summary.md](docs/architecture/executive-summary.md)
for how SweatMeter fits with the suite's other applications and packages.

## Install

```bash
pip install sweatmeter

# Optional NVML backend: reads NVIDIA GPUs in-process instead of running `nvidia-smi` per sample.
pip install "sweatmeter[pynvml]"
```

## Quickstart

```python
from sweatmeter import TelemetryCollector

snapshot = TelemetryCollector().snapshot()
print("CPU:", snapshot.cpu_percent, "RAM:", snapshot.ram_used_bytes)
for gpu in snapshot.gpus:
    print(f"GPU {gpu.index}:", gpu.utilization_percent, "VRAM:", gpu.vram_used_bytes)
```

`snapshot()` and `machine_profile()` isolate ordinary sensor failures and do not raise. An absent
tool, unreadable source, malformed value, or unsupported sensor degrades honestly: collections
become empty and individual measurements become BaseAiCore's explicit `UNSUPPORTED` value, never
zero. Every degraded snapshot field has a reason in `snapshot.unavailable_reasons()`.

Background sampling and per-device derived metrics stay bounded and explicit:

```python
from sweatmeter import TelemetrySampler, TelemetryWindow

collector = TelemetryCollector()
with TelemetrySampler(collector, interval_seconds=1.0, buffer_size=60) as sampler:
    run_work()  # your workload

window = TelemetryWindow(sampler.buffered())
print("GPU 0 peak VRAM:", window.peak_vram_bytes(0))
print("GPU 0 energy estimate (J):", window.energy_joules(0))
print("Power samples used:", window.supported_sample_count("energy_joules", 0))
```

Two GPU backends read the same devices and return identical values: the always-available
`nvidia-smi` command, and NVML through the optional `pynvml` extra, which is selected automatically
when installed and removes the per-sample subprocess. One conformance suite runs against both.

Energy is always a telemetry-derived estimate, never hardware instrumentation. No derived method
aggregates devices: each GPU figure takes a `gpu_index` and describes only that device.

## Documentation

This repository carries its own copy of the relevant suite documentation under [`docs/`](docs/README.md),
so it can be read and implemented independently of the other eight suite repositories. Start with
[`docs/README.md`](docs/README.md).

| Read this | For |
|---|---|
| [docs/packages/sweatmeter/spec.md](docs/packages/sweatmeter/spec.md) | Purpose, scope, non-goals, public contracts, configuration, acceptance criteria |
| [docs/packages/sweatmeter/development-plan.md](docs/packages/sweatmeter/development-plan.md) | The phased build plan: goals, work, tests, acceptance criteria per phase |
| [docs/quickstart.md](docs/quickstart.md) | Snapshot, profile, sampler, deterministic-test, and derived-metric examples |
| [docs/platform-support.md](docs/platform-support.md) | Exact Linux, NVIDIA, Windows, and macOS support and degradation behaviour |
| [docs/performance-validation.md](docs/performance-validation.md) | Recorded Phase 4 overhead measurements and methodology |
| [docs/standards/](docs/standards/) | Coding, testing, security, API, database and packaging standards every phase follows |
| [docs/adr/](docs/adr/README.md) | The architectural decisions this design rests on |

## Development

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pre-commit install
pytest -m "not live and not performance"
```

See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full workflow and [`SECURITY.md`](SECURITY.md) for
how to report a vulnerability.

## License

Apache-2.0 — see [`LICENSE`](LICENSE).
