Skip to content

Commit 721d23b

Browse files
authored
Merge pull request #216 from PolicyEngine/fix/split-api-v2-version-registries
Split api-v2 version registries from the legacy simulation registry
2 parents 0bc27a0 + d9abd1a commit 721d23b

6 files changed

Lines changed: 25 additions & 20 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ See [docs/DESIGN.md](docs/DESIGN.md) for the full design including future endpoi
2323

2424
## Versioned Modal deployments
2525

26-
Each deploy creates a versioned Modal app named `policyengine-v2-us{X}-uk{Y}` (e.g., `policyengine-v2-us1-592-4-uk2-75-1`). Old versions remain deployed and accessible. Cloud Run routes to the correct version via Modal Dict registries (`simulation-api-us-versions`, `simulation-api-uk-versions`).
26+
Each deploy creates a versioned Modal app named `policyengine-v2-us{X}-uk{Y}` (e.g., `policyengine-v2-us1-592-4-uk2-75-1`). Old versions remain deployed and accessible. Cloud Run routes to the correct version via v2-specific Modal Dict registries (`api-v2-us-versions`, `api-v2-uk-versions`).
2727

2828
**Key files:**
2929
- `src/policyengine_api/modal/app.py` — Versioned app definition (dynamic name from env vars)

changelog.d/215.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Moved api-v2 version routing to dedicated Modal registries so api-v2-alpha deployments no longer overwrite the legacy simulation API registry.

scripts/update_version_registry.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
Update Modal version registries after deployment.
33
44
Each deployment creates a versioned app (e.g., policyengine-v2-us1-592-4-uk2-75-1).
5-
This script updates the version dicts to map package versions to app names.
5+
This script updates the v2-specific version dicts to map package versions to
6+
app names.
67
78
The dicts allow Cloud Run to route requests for specific versions to the
89
correct versioned Modal app. Multiple versions coexist — old deployments
@@ -58,7 +59,7 @@ def update_version_dict(
5859
"""Update a version dict: set version → app_name and latest → version.
5960
6061
Args:
61-
dict_name: Name of the Modal Dict (e.g., "simulation-api-us-versions")
62+
dict_name: Name of the Modal Dict (e.g., "api-v2-us-versions")
6263
environment: Modal environment (staging or main)
6364
version: Package version (e.g., "1.592.4")
6465
app_name: App name to map this version to
@@ -107,7 +108,7 @@ def main():
107108

108109
print("US version registry:")
109110
update_version_dict(
110-
"simulation-api-us-versions",
111+
"api-v2-us-versions",
111112
args.environment,
112113
args.us_version,
113114
args.app_name,
@@ -116,7 +117,7 @@ def main():
116117

117118
print("UK version registry:")
118119
update_version_dict(
119-
"simulation-api-uk-versions",
120+
"api-v2-uk-versions",
120121
args.environment,
121122
args.uk_version,
122123
args.app_name,

src/policyengine_api/version_resolver.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
Resolve policyengine package versions to versioned Modal app names.
33
44
Uses Modal Dicts as a version registry:
5-
- simulation-api-us-versions: maps US version strings -> app names
6-
- simulation-api-uk-versions: maps UK version strings -> app names
5+
- api-v2-us-versions: maps US version strings -> app names
6+
- api-v2-uk-versions: maps UK version strings -> app names
77
88
Each dict also has a "latest" key pointing to the current default version.
99
@@ -22,6 +22,11 @@
2222
logger = logging.getLogger(__name__)
2323

2424

25+
def _registry_name(country: str) -> str:
26+
"""Return the v2-specific Modal Dict name for a country."""
27+
return f"api-v2-{country.lower()}-versions"
28+
29+
2530
@functools.lru_cache(maxsize=32)
2631
def _resolve_app_name(country: str, version: str | None, environment: str) -> str:
2732
"""Look up the Modal app name for a given country+version from Modal Dicts.
@@ -37,7 +42,7 @@ def _resolve_app_name(country: str, version: str | None, environment: str) -> st
3742
Raises:
3843
KeyError: If version not found in registry
3944
"""
40-
dict_name = f"simulation-api-{country.lower()}-versions"
45+
dict_name = _registry_name(country)
4146
version_dict = modal.Dict.from_name(dict_name, environment_name=environment)
4247

4348
if version is None:

tests/test_update_version_registry.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def test_creates_new_entry(self):
1616

1717
with patch("modal.Dict.from_name", return_value=mock_dict):
1818
update_version_dict(
19-
"simulation-api-us-versions",
19+
"api-v2-us-versions",
2020
"staging",
2121
"1.592.4",
2222
"policyengine-v2-us1-592-4-uk2-75-1",
@@ -35,7 +35,7 @@ def test_updates_existing_entry(self):
3535

3636
with patch("modal.Dict.from_name", return_value=mock_dict):
3737
update_version_dict(
38-
"simulation-api-us-versions",
38+
"api-v2-us-versions",
3939
"main",
4040
"1.592.4",
4141
"new-app-name",
@@ -51,7 +51,7 @@ def test_sets_latest_to_new_version(self):
5151

5252
with patch("modal.Dict.from_name", return_value=mock_dict):
5353
update_version_dict(
54-
"simulation-api-uk-versions",
54+
"api-v2-uk-versions",
5555
"staging",
5656
"2.0.0",
5757
"app-v2",
@@ -67,14 +67,14 @@ def test_passes_environment_to_modal(self):
6767

6868
with patch("modal.Dict.from_name", return_value=mock_dict) as from_name:
6969
update_version_dict(
70-
"simulation-api-us-versions",
70+
"api-v2-us-versions",
7171
"staging",
7272
"1.0.0",
7373
"app",
7474
)
7575

7676
from_name.assert_called_once_with(
77-
"simulation-api-us-versions",
77+
"api-v2-us-versions",
7878
environment_name="staging",
7979
create_if_missing=True,
8080
)
@@ -87,7 +87,7 @@ def test_create_if_missing_flag(self):
8787

8888
with patch("modal.Dict.from_name", return_value=mock_dict) as from_name:
8989
update_version_dict(
90-
"simulation-api-uk-versions",
90+
"api-v2-uk-versions",
9191
"main",
9292
"2.75.1",
9393
"app-uk",

tests/test_version_resolver.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,25 @@ def test_resolves_specific_version(self):
5050
mock_dict.__getitem__.assert_called_once_with("1.459.0")
5151

5252
def test_routes_to_correct_dict_for_us(self):
53-
"""Country 'us' reads from simulation-api-us-versions."""
53+
"""Country 'us' reads from api-v2-us-versions."""
5454
mock_dict = MagicMock()
5555
mock_dict.__getitem__ = MagicMock(return_value="app-name")
5656

5757
with patch("modal.Dict.from_name", return_value=mock_dict) as from_name:
5858
_resolve_app_name("us", "1.0.0", "main")
5959

60-
from_name.assert_called_once_with(
61-
"simulation-api-us-versions", environment_name="main"
62-
)
60+
from_name.assert_called_once_with("api-v2-us-versions", environment_name="main")
6361

6462
def test_routes_to_correct_dict_for_uk(self):
65-
"""Country 'uk' reads from simulation-api-uk-versions."""
63+
"""Country 'uk' reads from api-v2-uk-versions."""
6664
mock_dict = MagicMock()
6765
mock_dict.__getitem__ = MagicMock(return_value="app-name")
6866

6967
with patch("modal.Dict.from_name", return_value=mock_dict) as from_name:
7068
_resolve_app_name("uk", "2.0.0", "staging")
7169

7270
from_name.assert_called_once_with(
73-
"simulation-api-uk-versions", environment_name="staging"
71+
"api-v2-uk-versions", environment_name="staging"
7472
)
7573

7674
def test_lru_cache_returns_same_result(self):

0 commit comments

Comments
 (0)