greenpick 0.5.0__tar.gz → 0.5.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.5.0/src/greenpick.egg-info → greenpick-0.5.1}/PKG-INFO +1 -1
- {greenpick-0.5.0 → greenpick-0.5.1}/pyproject.toml +1 -1
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/__init__.py +1 -1
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/models.py +1 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/server.py +3 -1
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/locality_service.py +7 -4
- {greenpick-0.5.0 → greenpick-0.5.1/src/greenpick.egg-info}/PKG-INFO +1 -1
- {greenpick-0.5.0 → greenpick-0.5.1}/tests/test_services.py +13 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/LICENSE +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/README.md +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/setup.cfg +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/__main__.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/config.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/__init__.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/_net.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/annual.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/auto_repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/canada_repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/eia_repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/electricitymaps_repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/emission_factors.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/entsoe_repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/gpu_power.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/inference_energy.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/instance_families.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/mock_repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/network.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/power.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/pricing.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/regions.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/static_data.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/typical.json +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/data/typical_repository.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/__init__.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/carbon_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/cost_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/data_hint.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/forecast_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/inference_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/instance_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/latency_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/metric_scaffold_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/offhours_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/recommender.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/residency_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/rightsizing_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/scheduling_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/serving_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/training_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick/services/typical_ranking_service.py +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick.egg-info/SOURCES.txt +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick.egg-info/dependency_links.txt +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick.egg-info/entry_points.txt +0 -0
- {greenpick-0.5.0 → greenpick-0.5.1}/src/greenpick.egg-info/requires.txt +0 -0
- {greenpick-0.5.0 → greenpick-0.5.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.5.
|
|
3
|
+
Version: 0.5.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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "greenpick"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.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.5.
|
|
7
|
+
__version__ = "0.5.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.
|
|
@@ -317,6 +317,7 @@ class DataLocalityWarning(BaseModel):
|
|
|
317
317
|
transfer_carbon_quality: Optional[str] = None
|
|
318
318
|
carbon_saving_kg_co2_from_move: Optional[float] = None # echoed back if provided
|
|
319
319
|
net_carbon_verdict: Optional[str] = None # set only when a saving was supplied
|
|
320
|
+
verdict_status: str = "not_evaluated" # 'evaluated' only when a saving was supplied
|
|
320
321
|
residency_note: Optional[str] = None # neutral cross-jurisdiction heads-up, if any
|
|
321
322
|
warning: str = ""
|
|
322
323
|
recommendation: str = ""
|
|
@@ -358,7 +358,9 @@ async def data_locality_egress_check(
|
|
|
358
358
|
compute runs, where the data lives (provider+region), and monthly GB crossing between them.
|
|
359
359
|
Returns a directional egress-COST ballpark, a coarse transfer-carbon figure, and — if you
|
|
360
360
|
pass the carbon saving the greener-region move buys — whether it's still a net win. Use this
|
|
361
|
-
before accepting a greener-region suggestion when your data stays put.
|
|
361
|
+
before accepting a greener-region suggestion when your data stays put. Use the user's real GB and
|
|
362
|
+
data location; if unknown, ask rather than assume. If verdict_status is 'not_evaluated' there is NO
|
|
363
|
+
answer yet to 'does it backfire?': say so, and get carbon_saving_kg_co2_from_move first."""
|
|
362
364
|
advice = await locality_service.data_locality_check(
|
|
363
365
|
_repo, compute_provider, compute_region, data_provider, data_region, # type: ignore[arg-type]
|
|
364
366
|
monthly_cross_boundary_gb=monthly_cross_boundary_gb,
|
|
@@ -109,7 +109,9 @@ async def data_locality_check(
|
|
|
109
109
|
|
|
110
110
|
# Net verdict only if the caller told us what the move saves.
|
|
111
111
|
verdict = None
|
|
112
|
+
verdict_status = "not_evaluated"
|
|
112
113
|
if carbon_saving_kg_co2_from_move is not None:
|
|
114
|
+
verdict_status = "evaluated"
|
|
113
115
|
net = carbon_saving_kg_co2_from_move - transfer_kg
|
|
114
116
|
if net > 0:
|
|
115
117
|
verdict = (f"Still a net win: the move saves ~{carbon_saving_kg_co2_from_move:.1f} kg "
|
|
@@ -130,9 +132,10 @@ async def data_locality_check(
|
|
|
130
132
|
f"cross the boundary, costing {cost_txt}, plus ~{transfer_kg:.1f} kg CO2/mo of extra "
|
|
131
133
|
f"transfer. A greener-region move can be undone by this.")
|
|
132
134
|
if verdict is None:
|
|
133
|
-
#
|
|
134
|
-
warning
|
|
135
|
-
|
|
135
|
+
# Say up front that the question 'does it backfire?' is NOT answered yet, and what is missing.
|
|
136
|
+
warning = ("NO NET VERDICT: you did not pass carbon_saving_kg_co2_from_move, so this does NOT say "
|
|
137
|
+
"whether the move backfires on carbon. Ask the user for it, or compute it as the difference "
|
|
138
|
+
"between estimate_workload_carbon in the two regions, and call again. " + warning)
|
|
136
139
|
|
|
137
140
|
if severity == "high":
|
|
138
141
|
rec = ("High exposure. Co-locate compute with the data, or move the data to the greener "
|
|
@@ -160,6 +163,6 @@ async def data_locality_check(
|
|
|
160
163
|
est_monthly_transfer_kg_co2=transfer_kg,
|
|
161
164
|
transfer_carbon_source=reading.source, transfer_carbon_quality=reading.quality,
|
|
162
165
|
carbon_saving_kg_co2_from_move=carbon_saving_kg_co2_from_move,
|
|
163
|
-
net_carbon_verdict=verdict, residency_note=residency_note,
|
|
166
|
+
net_carbon_verdict=verdict, verdict_status=verdict_status, residency_note=residency_note,
|
|
164
167
|
warning=warning, recommendation=rec, limitations=LIMITATIONS,
|
|
165
168
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: greenpick
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.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
|
|
@@ -1882,3 +1882,16 @@ def test_tool_greenest_regions_filters_and_errors():
|
|
|
1882
1882
|
assert r["ranking"] and all(x["provider"] == "aws" for x in r["ranking"])
|
|
1883
1883
|
assert any(x["quality"] == "annual_average" for x in _tool("greenest_regions_on_average")(month=1)["ranking"])
|
|
1884
1884
|
assert "error" in _tool("greenest_regions_on_average")(month=13)
|
|
1885
|
+
|
|
1886
|
+
|
|
1887
|
+
# --- 0.5.1: a missing carbon saving is called out, not silently skipped ---
|
|
1888
|
+
@pytest.mark.asyncio
|
|
1889
|
+
async def test_locality_without_saving_says_no_verdict():
|
|
1890
|
+
from greenpick.services import locality_service as ls
|
|
1891
|
+
base = dict(compute_provider="aws", compute_region="eu-north-1",
|
|
1892
|
+
data_provider="aws", data_region="us-east-1", monthly_cross_boundary_gb=100)
|
|
1893
|
+
no = await ls.data_locality_check(MockCarbonRepository(), **base)
|
|
1894
|
+
assert no.net_carbon_verdict is None and no.verdict_status == "not_evaluated"
|
|
1895
|
+
assert no.warning.startswith("NO NET VERDICT") and "carbon_saving_kg_co2_from_move" in no.warning
|
|
1896
|
+
yes = await ls.data_locality_check(MockCarbonRepository(), carbon_saving_kg_co2_from_move=40.0, **base)
|
|
1897
|
+
assert yes.verdict_status == "evaluated" and not yes.warning.startswith("NO NET VERDICT")
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|