Skip to main content

cleanshift

Delay batch ML/AI jobs to the cleanest grid window.

cleanshift wraps your long-running job — fine-tuning, batch inference, embedding generation — and schedules it during the lowest-carbon hour within a time window you specify. After execution it prints a savings receipt showing estimated CO₂ avoided vs. running immediately.

Install

pip install cleanshift

Quick start — no API key needed

import time
from cleanshift import carbon_window, MockProvider

provider = MockProvider()

with carbon_window(provider=provider, max_delay_hours=6) as window:
    time.sleep(1)  # your job here

print(window.receipt.model_dump_json(indent=2))

MockProvider generates a synthetic sinusoidal intensity curve (peak at 3 PM UTC, trough at 3 AM UTC) so you can develop and test without signing up for anything.

Real API example

import os, time
from cleanshift import carbon_window, ElectricityMapProvider

provider = ElectricityMapProvider(
    api_key=os.environ["ELECTRICITY_MAP_API_KEY"],
    zone="US-CAL-CISO",
)

with carbon_window(provider=provider, max_delay_hours=6) as window:
    run_fine_tuning()

print(window.receipt.model_dump_json(indent=2))

Decorator form

from cleanshift import carbon_window, ElectricityMapProvider, Policy

@carbon_window(
    provider=provider,
    max_delay_hours=12,
    policy=Policy.THRESHOLD,
    max_intensity_gco2_per_kwh=150,
)
def nightly_finetune():
    ...

nightly_finetune()
print(nightly_finetune.last_receipt.model_dump_json(indent=2))

Pure scheduling query

from cleanshift import find_cleanest_window, MockProvider

best = find_cleanest_window(
    MockProvider(),
    duration_hours=2,
    max_delay_hours=24,
)
print(f"Recommended start: {best.isoformat()}")

Policies

Policy Behaviour
min_carbon (default) Sleep until the lowest-intensity hour in the allowable window
threshold Run as soon as intensity drops below max_intensity_gco2_per_kwh; falls back to the cleanest available slot if the threshold is never met
now_or_never Run immediately if intensity is clean; raise JobSkipped otherwise
halt_if_dirty Start immediately; pause execution if intensity spikes above max_intensity_gco2_per_kwh mid-run; resume automatically when it drops back (Unix only)

halt_if_dirty notes

halt_if_dirty requires max_intensity_gco2_per_kwh and uses SIGSTOP/SIGCONT to pause the process, so it is not supported on Windows. The intensity is re-checked every poll_interval_seconds (default 5 minutes).

Receipt schema

class CarbonReceipt(BaseModel):
    scheduled_at: AwareDatetime        # when carbon_window was entered
    ran_at: AwareDatetime              # when execution actually started
    delay_seconds: int
    duration_seconds: int
    avg_intensity_gco2_per_kwh: float  # mean of readings at start + end of run
    counterfactual_avg_intensity: float  # intensity at scheduling time
    estimated_savings_pct: float       # computed field (positive = savings)
    region: str
    provider: str

avg_intensity_gco2_per_kwh is the arithmetic mean of readings taken at the start and end of the run — a point estimate, not a true integral. If your job is long enough that accuracy matters, prefer a provider with dense historical data.

Providers

Class Source Sign-up
MockProvider Synthetic curve None
ElectricityMapProvider electricitymaps.com Free tier available
WattTimeProvider watttime.org Free tier available

Adding a provider

Implement GridIntensityProvider:

from cleanshift.providers.base import GridIntensityProvider, IntensityPoint

class MyProvider(GridIntensityProvider):
    @property
    def provider_name(self) -> str: return "myprovider"

    @property
    def region(self) -> str: return "MY-REGION"

    async def current(self) -> IntensityPoint: ...

    async def forecast(self, from_dt, to_dt) -> list[IntensityPoint]: ...

CLI

# Dry-run with mock data (no API key)
cleanshift schedule --duration 2h --max-delay 24h --region US-CAL-CISO --dry-run

# With ElectricityMap
cleanshift schedule --duration 2h --max-delay 24h \
    --provider electricitymap --api-key $KEY --zone US-CAL-CISO --dry-run

Development

pip install -e ".[dev]"
pytest
python examples/synthetic_demo.py

License

MIT

Metadata

Release files for cleanshift 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cleanshift 0.1.0
File Size Uploaded Provenance
cleanshift-0.1.0.tar.gz 14.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for cleanshift 0.1.0
File Interpreter ABI Platform
cleanshift-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.2 kB

Release files / cleanshift-0.1.0.tar.gz

Download URL cleanshift-0.1.0.tar.gz
Size 14.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c35d02ff81ff5e03150f83a176cf9517db2452d8f2eeda070a3359927745ed40
BLAKE2b-256 checksum
How to use checksums
806d9f64140a02312c3ce6a011914fec89aecd4ce419ba1e4a97e8a997d29771
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 18, 2026.

Transparency log

Release files / cleanshift-0.1.0-py3-none-any.whl

Download URL cleanshift-0.1.0-py3-none-any.whl
Size 15.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cad3f528cb297bd01d714c6cfae5624bdaf31cf522ce038da8e84a7276d161c5
BLAKE2b-256 checksum
How to use checksums
5c9dcc2ce47e8ea6a042475432ca675fa1308b51897c443c500227461b14c7ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 18, 2026.

Transparency log

Security for cleanshift 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cleanshift-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page