greenpick 0.4.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {greenpick-0.4.0/src/greenpick.egg-info → greenpick-0.4.1}/PKG-INFO +9 -8
- {greenpick-0.4.0 → greenpick-0.4.1}/README.md +8 -7
- {greenpick-0.4.0 → greenpick-0.4.1}/pyproject.toml +1 -1
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/__init__.py +1 -1
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/annual.json +3 -1
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/regions.json +1 -1
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/server.py +1 -1
- {greenpick-0.4.0 → greenpick-0.4.1/src/greenpick.egg-info}/PKG-INFO +9 -8
- {greenpick-0.4.0 → greenpick-0.4.1}/tests/test_services.py +16 -4
- {greenpick-0.4.0 → greenpick-0.4.1}/LICENSE +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/setup.cfg +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/__main__.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/config.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/__init__.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/_net.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/auto_repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/canada_repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/eia_repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/electricitymaps_repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/emission_factors.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/entsoe_repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/gpu_power.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/inference_energy.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/instance_families.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/mock_repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/network.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/power.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/pricing.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/static_data.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/typical.json +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/data/typical_repository.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/models.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/__init__.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/carbon_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/cost_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/data_hint.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/forecast_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/inference_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/instance_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/latency_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/locality_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/metric_scaffold_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/recommender.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/residency_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/rightsizing_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/scheduling_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/serving_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick/services/training_service.py +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick.egg-info/SOURCES.txt +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick.egg-info/dependency_links.txt +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick.egg-info/entry_points.txt +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick.egg-info/requires.txt +0 -0
- {greenpick-0.4.0 → greenpick-0.4.1}/src/greenpick.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: greenpick
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Design-time sustainability co-pilot (MCP server): greener, cheaper cloud infrastructure decisions with carbon + cost + latency tradeoffs.
|
|
5
5
|
Author-email: "Data Science Advisers, LLC" <info@datascienceadvisers.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,11 +60,12 @@ seconds. (It responds when you ask; auto-nudging on infra-code changes is on the
|
|
|
60
60
|
> this month's average for each grid, from a year of real data.
|
|
61
61
|
|
|
62
62
|
<p align="center">
|
|
63
|
-
<img src="https://raw.githubusercontent.com/bithug01/greenpick/master/docs/img/region-carbon-30x.svg" alt="Same H100 training run, ~
|
|
63
|
+
<img src="https://raw.githubusercontent.com/bithug01/greenpick/master/docs/img/region-carbon-30x.svg" alt="Same H100 training run, ~28× the carbon depending only on region (Stockholm vs Sydney)" width="560" />
|
|
64
64
|
</p>
|
|
65
65
|
|
|
66
|
-
*The same 40-GPU-hour training run emits ~0.
|
|
67
|
-
difference from region choice alone
|
|
66
|
+
*The same 40-GPU-hour training run emits ~0.6 kg CO₂ in Stockholm vs ~17.5 kg in Sydney — a ~28×
|
|
67
|
+
difference from region choice alone (typical October grids; Sydney on Ember's 2025 national figure,
|
|
68
|
+
a lower bound for its coal-heavier state grid). Ask GreenPick and it surfaces that (with the cost and latency
|
|
68
69
|
tradeoff) while you're still in the editor, before you commit.*
|
|
69
70
|
|
|
70
71
|
**▶ [See the 5-minute demo](docs/demo.md)** — three scenarios with real tool output (training placement, the egress backfire, the forecast).
|
|
@@ -195,12 +196,12 @@ See `docs/user-questions-backlog.md`.
|
|
|
195
196
|
intensity and average hour-of-day profile (UTC), computed from 12 months of real hourly EIA-930 /
|
|
196
197
|
ENTSO-E data (`data/typical.json`, refreshed by `scripts/refresh_typical.py`). Labelled
|
|
197
198
|
`quality: "typical"` — a realistic norm, never presented as a current reading.
|
|
198
|
-
- **Annual** — for Singapore, Tokyo
|
|
199
|
+
- **Annual** — for Singapore, Tokyo, Mumbai/Pune and Sydney, where no free hourly data exists: the country's
|
|
199
200
|
yearly lifecycle grid intensity from [Ember](https://ember-energy.org/) (via Our World in Data,
|
|
200
201
|
CC BY 4.0), with source and year (`data/annual.json`). Labelled `quality: "annual_average"`; fine for
|
|
201
202
|
comparing regions, but carries no timing signal.
|
|
202
|
-
- **Mock** — a hand-set illustrative value, labelled `quality: "mock"`,
|
|
203
|
-
|
|
203
|
+
- **Mock** — a hand-set illustrative value, labelled `quality: "mock"`, kept only as a last resort if
|
|
204
|
+
every other source is missing. No catalog region relies on it.
|
|
204
205
|
- Cost: a **dated static pricing table** (`data/pricing.json`), refreshed from live Vantage
|
|
205
206
|
pricing via `scripts/refresh_pricing.py` using one matched method across all three clouds.
|
|
206
207
|
- Instance-family efficiency: directional perf-per-watt multipliers (`data/instance_families.json`).
|
|
@@ -318,7 +319,7 @@ carbon, set two free keys (`EIA_API_KEY` for US, `ENTSOE_TOKEN` for EU) and
|
|
|
318
319
|
`GREENPICK_CARBON_SOURCE=auto` — see [Turn on live data](#turn-on-live-data).
|
|
319
320
|
|
|
320
321
|
**Why "directional" and not audited numbers?** Because it's for a *design-time decision*, not a
|
|
321
|
-
compliance report. "Stockholm is ~
|
|
322
|
+
compliance report. "Stockholm is ~28× cleaner than Sydney" is what you need to pick a region in
|
|
322
323
|
seconds — a certified figure is a different job for a different tool (Electricity Maps, WattTime).
|
|
323
324
|
GreenPick is for *decisions*, not *disclosures*, and says so in every tool's limitations.
|
|
324
325
|
|
|
@@ -30,11 +30,12 @@ seconds. (It responds when you ask; auto-nudging on infra-code changes is on the
|
|
|
30
30
|
> this month's average for each grid, from a year of real data.
|
|
31
31
|
|
|
32
32
|
<p align="center">
|
|
33
|
-
<img src="https://raw.githubusercontent.com/bithug01/greenpick/master/docs/img/region-carbon-30x.svg" alt="Same H100 training run, ~
|
|
33
|
+
<img src="https://raw.githubusercontent.com/bithug01/greenpick/master/docs/img/region-carbon-30x.svg" alt="Same H100 training run, ~28× the carbon depending only on region (Stockholm vs Sydney)" width="560" />
|
|
34
34
|
</p>
|
|
35
35
|
|
|
36
|
-
*The same 40-GPU-hour training run emits ~0.
|
|
37
|
-
difference from region choice alone
|
|
36
|
+
*The same 40-GPU-hour training run emits ~0.6 kg CO₂ in Stockholm vs ~17.5 kg in Sydney — a ~28×
|
|
37
|
+
difference from region choice alone (typical October grids; Sydney on Ember's 2025 national figure,
|
|
38
|
+
a lower bound for its coal-heavier state grid). Ask GreenPick and it surfaces that (with the cost and latency
|
|
38
39
|
tradeoff) while you're still in the editor, before you commit.*
|
|
39
40
|
|
|
40
41
|
**▶ [See the 5-minute demo](docs/demo.md)** — three scenarios with real tool output (training placement, the egress backfire, the forecast).
|
|
@@ -165,12 +166,12 @@ See `docs/user-questions-backlog.md`.
|
|
|
165
166
|
intensity and average hour-of-day profile (UTC), computed from 12 months of real hourly EIA-930 /
|
|
166
167
|
ENTSO-E data (`data/typical.json`, refreshed by `scripts/refresh_typical.py`). Labelled
|
|
167
168
|
`quality: "typical"` — a realistic norm, never presented as a current reading.
|
|
168
|
-
- **Annual** — for Singapore, Tokyo
|
|
169
|
+
- **Annual** — for Singapore, Tokyo, Mumbai/Pune and Sydney, where no free hourly data exists: the country's
|
|
169
170
|
yearly lifecycle grid intensity from [Ember](https://ember-energy.org/) (via Our World in Data,
|
|
170
171
|
CC BY 4.0), with source and year (`data/annual.json`). Labelled `quality: "annual_average"`; fine for
|
|
171
172
|
comparing regions, but carries no timing signal.
|
|
172
|
-
- **Mock** — a hand-set illustrative value, labelled `quality: "mock"`,
|
|
173
|
-
|
|
173
|
+
- **Mock** — a hand-set illustrative value, labelled `quality: "mock"`, kept only as a last resort if
|
|
174
|
+
every other source is missing. No catalog region relies on it.
|
|
174
175
|
- Cost: a **dated static pricing table** (`data/pricing.json`), refreshed from live Vantage
|
|
175
176
|
pricing via `scripts/refresh_pricing.py` using one matched method across all three clouds.
|
|
176
177
|
- Instance-family efficiency: directional perf-per-watt multipliers (`data/instance_families.json`).
|
|
@@ -288,7 +289,7 @@ carbon, set two free keys (`EIA_API_KEY` for US, `ENTSOE_TOKEN` for EU) and
|
|
|
288
289
|
`GREENPICK_CARBON_SOURCE=auto` — see [Turn on live data](#turn-on-live-data).
|
|
289
290
|
|
|
290
291
|
**Why "directional" and not audited numbers?** Because it's for a *design-time decision*, not a
|
|
291
|
-
compliance report. "Stockholm is ~
|
|
292
|
+
compliance report. "Stockholm is ~28× cleaner than Sydney" is what you need to pick a region in
|
|
292
293
|
seconds — a certified figure is a different job for a different tool (Electricity Maps, WattTime).
|
|
293
294
|
GreenPick is for *decisions*, not *disclosures*, and says so in every tool's limitations.
|
|
294
295
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "greenpick"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
description = "Design-time sustainability co-pilot (MCP server): greener, cheaper cloud infrastructure decisions with carbon + cost + latency tradeoffs."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -4,7 +4,7 @@ Greener cloud-region choices with honest carbon + cost + latency tradeoffs,
|
|
|
4
4
|
delivered inside the vibe-coding loop. Directional guidance, not audited accounting.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
__version__ = "0.4.
|
|
7
|
+
__version__ = "0.4.1"
|
|
8
8
|
|
|
9
9
|
# httpx logs every request URL at INFO, and our live sources pass their API key / token as a URL
|
|
10
10
|
# query parameter — so at the default log level the secret would land in the MCP client's logs.
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
"JP": { "country": "Japan", "g_co2_per_kwh": 477.3, "year": 2025,
|
|
9
9
|
"note": "National average; the Tokyo (TEPCO) area mix differs somewhat and varies by hour." },
|
|
10
10
|
"IN": { "country": "India", "g_co2_per_kwh": 670.1, "year": 2025,
|
|
11
|
-
"note": "National average; Maharashtra (Mumbai, Pune) runs about 6% above it on Ember's state-level data." }
|
|
11
|
+
"note": "National average; Maharashtra (Mumbai, Pune) runs about 6% above it on Ember's state-level data." },
|
|
12
|
+
"AU": { "country": "Australia", "g_co2_per_kwh": 525.2, "year": 2025,
|
|
13
|
+
"note": "National average; New South Wales (Sydney) is more coal-heavy and runs higher, so treat this as a lower bound for Sydney." }
|
|
12
14
|
}
|
|
13
15
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"us-west-2": { "name": "Oregon", "lat": 45.87, "lon": -119.69, "zone": "US-NW-PACW", "eia_ba": "BPAT", "jurisdiction": "US" },
|
|
7
7
|
"eu-west-1": { "name": "Ireland", "lat": 53.41, "lon": -8.24, "zone": "IE", "entsoe_eic": "10Y1001A1001A59C", "jurisdiction": "EEA" },
|
|
8
8
|
"eu-north-1": { "name": "Stockholm", "lat": 59.33, "lon": 18.07, "zone": "SE", "entsoe_eic": "10YSE-1--------K", "jurisdiction": "EEA" },
|
|
9
|
-
"ap-southeast-2": { "name": "Sydney", "lat": -33.87, "lon": 151.21, "zone": "AU-NSW", "jurisdiction": "AU" },
|
|
9
|
+
"ap-southeast-2": { "name": "Sydney", "lat": -33.87, "lon": 151.21, "zone": "AU-NSW", "annual_zone": "AU", "jurisdiction": "AU" },
|
|
10
10
|
"ca-central-1": { "name": "Montreal", "lat": 45.50, "lon": -73.57, "zone": "CA-QC", "ca_source": "hq", "jurisdiction": "CA" },
|
|
11
11
|
"ap-southeast-1": { "name": "Singapore", "lat": 1.29, "lon": 103.85, "zone": "SG", "annual_zone": "SG", "jurisdiction": "SG" },
|
|
12
12
|
"ap-northeast-1": { "name": "Tokyo", "lat": 35.68, "lon": 139.69, "zone": "JP-TK", "annual_zone": "JP", "jurisdiction": "JP" },
|
|
@@ -381,6 +381,6 @@ def explain_methodology_and_limits() -> dict:
|
|
|
381
381
|
"forecast": "Day-ahead forecast is RELATIVE: upcoming hours ranked by forecast wind+solar output (ENTSO-E A69), not an absolute gCO2/kWh forecast. EU only; US/uncovered zones degrade to the recent historical pattern (labelled 'historical').",
|
|
382
382
|
"data_residency": "GreenPick flags when a recommended move CROSSES a jurisdiction (esp. leaving the EEA) as a geographic heads-up only. It does NOT assess legal/GDPR compliance, does not encode adequacy decisions, and is not legal advice — confirm with your own data governance.",
|
|
383
383
|
"ignored": "Embodied/hardware carbon and provider renewable-energy certificates.",
|
|
384
|
-
"fallback_data": "Used when live data isn't available (no key, the source didn't respond, or GreenPick isn't set to live). 'typical' = this calendar month's average intensity and average hour-of-day profile (UTC) for the region, computed from 12 months of real hourly EIA-930 / ENTSO-E data with GreenPick's own emission factors (bundled typical.json, refreshed by scripts/refresh_typical.py) — a realistic norm, not a current reading. 'annual_average' = the country's yearly lifecycle grid intensity from Ember (via Our World in Data; bundled annual.json with source and year), for regions with no free hourly data (Singapore, Tokyo, Mumbai/Pune) — sound for comparing regions, no timing signal (no hourly profile). 'mock' = a hand-set illustrative value with a synthetic hourly pattern,
|
|
384
|
+
"fallback_data": "Used when live data isn't available (no key, the source didn't respond, or GreenPick isn't set to live). 'typical' = this calendar month's average intensity and average hour-of-day profile (UTC) for the region, computed from 12 months of real hourly EIA-930 / ENTSO-E data with GreenPick's own emission factors (bundled typical.json, refreshed by scripts/refresh_typical.py) — a realistic norm, not a current reading. 'annual_average' = the country's yearly lifecycle grid intensity from Ember (via Our World in Data; bundled annual.json with source and year), for regions with no free hourly data (Singapore, Tokyo, Mumbai/Pune, Sydney — national figures, so Sydney's is a lower bound for its coal-heavier state) — sound for comparing regions, no timing signal (no hourly profile). 'mock' = a hand-set illustrative value with a synthetic hourly pattern, a last resort no catalog region relies on; timing advice on mock isn't meaningful. Both carry a live_data_hint saying why the result isn't live and how to turn live data on.",
|
|
385
385
|
"data_sources": "GREENPICK_CARBON_SOURCE=auto routes US regions to EIA-930 and EU regions to ENTSO-E (both free, key needed), and Canadian regions to Hydro-Québec (Québec) and IESO (Ontario) open data (free, no key). All mixes are weighted with the same per-fuel factors. Without live data a region uses its clearly-labelled typical value (or mock where no free source exists). Electricity Maps is available when selected explicitly (GREENPICK_CARBON_SOURCE=electricitymaps).",
|
|
386
386
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: greenpick
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Design-time sustainability co-pilot (MCP server): greener, cheaper cloud infrastructure decisions with carbon + cost + latency tradeoffs.
|
|
5
5
|
Author-email: "Data Science Advisers, LLC" <info@datascienceadvisers.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,11 +60,12 @@ seconds. (It responds when you ask; auto-nudging on infra-code changes is on the
|
|
|
60
60
|
> this month's average for each grid, from a year of real data.
|
|
61
61
|
|
|
62
62
|
<p align="center">
|
|
63
|
-
<img src="https://raw.githubusercontent.com/bithug01/greenpick/master/docs/img/region-carbon-30x.svg" alt="Same H100 training run, ~
|
|
63
|
+
<img src="https://raw.githubusercontent.com/bithug01/greenpick/master/docs/img/region-carbon-30x.svg" alt="Same H100 training run, ~28× the carbon depending only on region (Stockholm vs Sydney)" width="560" />
|
|
64
64
|
</p>
|
|
65
65
|
|
|
66
|
-
*The same 40-GPU-hour training run emits ~0.
|
|
67
|
-
difference from region choice alone
|
|
66
|
+
*The same 40-GPU-hour training run emits ~0.6 kg CO₂ in Stockholm vs ~17.5 kg in Sydney — a ~28×
|
|
67
|
+
difference from region choice alone (typical October grids; Sydney on Ember's 2025 national figure,
|
|
68
|
+
a lower bound for its coal-heavier state grid). Ask GreenPick and it surfaces that (with the cost and latency
|
|
68
69
|
tradeoff) while you're still in the editor, before you commit.*
|
|
69
70
|
|
|
70
71
|
**▶ [See the 5-minute demo](docs/demo.md)** — three scenarios with real tool output (training placement, the egress backfire, the forecast).
|
|
@@ -195,12 +196,12 @@ See `docs/user-questions-backlog.md`.
|
|
|
195
196
|
intensity and average hour-of-day profile (UTC), computed from 12 months of real hourly EIA-930 /
|
|
196
197
|
ENTSO-E data (`data/typical.json`, refreshed by `scripts/refresh_typical.py`). Labelled
|
|
197
198
|
`quality: "typical"` — a realistic norm, never presented as a current reading.
|
|
198
|
-
- **Annual** — for Singapore, Tokyo
|
|
199
|
+
- **Annual** — for Singapore, Tokyo, Mumbai/Pune and Sydney, where no free hourly data exists: the country's
|
|
199
200
|
yearly lifecycle grid intensity from [Ember](https://ember-energy.org/) (via Our World in Data,
|
|
200
201
|
CC BY 4.0), with source and year (`data/annual.json`). Labelled `quality: "annual_average"`; fine for
|
|
201
202
|
comparing regions, but carries no timing signal.
|
|
202
|
-
- **Mock** — a hand-set illustrative value, labelled `quality: "mock"`,
|
|
203
|
-
|
|
203
|
+
- **Mock** — a hand-set illustrative value, labelled `quality: "mock"`, kept only as a last resort if
|
|
204
|
+
every other source is missing. No catalog region relies on it.
|
|
204
205
|
- Cost: a **dated static pricing table** (`data/pricing.json`), refreshed from live Vantage
|
|
205
206
|
pricing via `scripts/refresh_pricing.py` using one matched method across all three clouds.
|
|
206
207
|
- Instance-family efficiency: directional perf-per-watt multipliers (`data/instance_families.json`).
|
|
@@ -318,7 +319,7 @@ carbon, set two free keys (`EIA_API_KEY` for US, `ENTSOE_TOKEN` for EU) and
|
|
|
318
319
|
`GREENPICK_CARBON_SOURCE=auto` — see [Turn on live data](#turn-on-live-data).
|
|
319
320
|
|
|
320
321
|
**Why "directional" and not audited numbers?** Because it's for a *design-time decision*, not a
|
|
321
|
-
compliance report. "Stockholm is ~
|
|
322
|
+
compliance report. "Stockholm is ~28× cleaner than Sydney" is what you need to pick a region in
|
|
322
323
|
seconds — a certified figure is a different job for a different tool (Electricity Maps, WattTime).
|
|
323
324
|
GreenPick is for *decisions*, not *disclosures*, and says so in every tool's limitations.
|
|
324
325
|
|
|
@@ -348,10 +348,10 @@ async def test_auto_router_picks_source_by_region(monkeypatch):
|
|
|
348
348
|
repo = AutoRepository(eia_key="k", entsoe_token="t")
|
|
349
349
|
us = await repo.carbon_now("aws", "us-east-1") # -> EIA
|
|
350
350
|
eu = await repo.carbon_now("aws", "eu-north-1") # -> ENTSO-E
|
|
351
|
-
syd = await repo.carbon_now("aws", "ap-southeast-2") # ->
|
|
351
|
+
syd = await repo.carbon_now("aws", "ap-southeast-2") # -> no live source: sourced yearly figure
|
|
352
352
|
assert us.source == "eia"
|
|
353
353
|
assert eu.source == "entsoe"
|
|
354
|
-
assert syd.quality == "
|
|
354
|
+
assert syd.quality == "annual_average"
|
|
355
355
|
|
|
356
356
|
|
|
357
357
|
@pytest.mark.asyncio
|
|
@@ -1494,14 +1494,26 @@ async def test_typical_reading_is_this_months_real_average():
|
|
|
1494
1494
|
|
|
1495
1495
|
|
|
1496
1496
|
@pytest.mark.asyncio
|
|
1497
|
-
async def
|
|
1497
|
+
async def test_mock_is_only_the_last_resort(monkeypatch):
|
|
1498
|
+
from greenpick.data import typical_repository as tr
|
|
1498
1499
|
repo = TypicalCarbonRepository()
|
|
1500
|
+
# Sydney has no typical data but a sourced yearly figure -> annual, not mock.
|
|
1499
1501
|
r = await repo.carbon_now("aws", "ap-southeast-2")
|
|
1500
|
-
assert r.quality == "
|
|
1502
|
+
assert r.quality == "annual_average" and r.g_co2_per_kwh == 525.2
|
|
1503
|
+
# With no yearly figure either, mock still answers (labelled) rather than failing.
|
|
1504
|
+
monkeypatch.setattr(tr, "annual_entry", lambda p, reg: None)
|
|
1505
|
+
m = await repo.carbon_now("aws", "ap-southeast-2")
|
|
1506
|
+
assert m.quality == "mock"
|
|
1501
1507
|
hist = await repo.carbon_history("aws", "ap-southeast-2")
|
|
1502
1508
|
assert hist and hist[0].period.startswith("H") and not hist[0].period.endswith("Z")
|
|
1503
1509
|
|
|
1504
1510
|
|
|
1511
|
+
def test_no_catalog_region_relies_on_mock():
|
|
1512
|
+
from greenpick.data.static_data import iter_regions
|
|
1513
|
+
for prov, reg, meta in iter_regions():
|
|
1514
|
+
assert typical_entry(prov, reg) or annual_entry(prov, reg), f"{prov}/{reg} would be mock"
|
|
1515
|
+
|
|
1516
|
+
|
|
1505
1517
|
@pytest.mark.asyncio
|
|
1506
1518
|
async def test_typical_history_is_the_months_real_profile_in_utc():
|
|
1507
1519
|
from greenpick.services import scheduling_service as ss
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|