Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/execution-receipt-api.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add engine-neutral execution receipts to household and economy calculation responses.
59 changes: 30 additions & 29 deletions docs/engineering/migration-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Generated from `policyengine_api/migration_registry.py` and `tests/contract/regi
| --- | ---: |
| route group count | 10 |
| workflow count | 7 |
| request count | 14 |
| request count | 15 |
| db entity count | 6 |
| sim flow count | 3 |

Expand All @@ -34,67 +34,68 @@ Generated from `policyengine_api/migration_registry.py` and `tests/contract/regi
- Current contract: `api_v1_compatible`
- Future owner: PR 10: Policy Migration

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/policy` | 201 | `policy` | `status`, `message`, `result.policy_id` |
| `GET` | `/us/policy/{policy_id}` | 200 | `policy` | `status`, `message`, `result` |
| `GET` | `/us/policies` | 200 | `policy` | `result` |
| Method | Path | Status | Route group | Stable response fields | Optional stable response fields |
| --- | --- | ---: | --- | --- | --- |
| `POST` | `/us/policy` | 201 | `policy` | `status`, `message`, `result.policy_id` | |
| `GET` | `/us/policy/{policy_id}` | 200 | `policy` | `status`, `message`, `result` | |
| `GET` | `/us/policies` | 200 | `policy` | `result` | |

### `household_save_edit_read`

- Current contract: `api_v1_compatible`
- Future owner: PR 11: Household Migration

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/household` | 201 | `household` | `status`, `message`, `result.household_id` |
| `PUT` | `/us/household/{household_id}` | 200 | `household` | `status`, `message`, `result.household_id` |
| `GET` | `/us/household/{household_id}` | 200 | `household` | `status`, `message`, `result` |
| Method | Path | Status | Route group | Stable response fields | Optional stable response fields |
| --- | --- | ---: | --- | --- | --- |
| `POST` | `/us/household` | 201 | `household` | `status`, `message`, `result.household_id` | |
| `PUT` | `/us/household/{household_id}` | 200 | `household` | `status`, `message`, `result.household_id` | |
| `GET` | `/us/household/{household_id}` | 200 | `household` | `status`, `message`, `result` | |

### `household_calculate`

- Current contract: `api_v1_compatible`
- Future owner: PR 13: Household Calculation Compute Cutover

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/calculate` | 200 | `household` | `status`, `message`, `result` |
| Method | Path | Status | Route group | Stable response fields | Optional stable response fields |
| --- | --- | ---: | --- | --- | --- |
| `POST` | `/us/calculate` | 200 | `household` | `status`, `message`, `result` | `execution_receipt.schema_version`, `execution_receipt.resolved.runtime.name`, `execution_receipt.resolved.numeric_mode`, `execution_receipt.resolved.model.actual.version`, `execution_receipt.resolved.model.certified.version`, `execution_receipt.request_sha256`, `execution_receipt.result_sha256` |
| `GET` | `/us/household/{household_id}/policy/{policy_id}` | 200 | `household` | `status`, `message`, `result` | `execution_receipt.schema_version`, `execution_receipt.resolved.runtime.name`, `execution_receipt.resolved.numeric_mode`, `execution_receipt.resolved.model.actual.version`, `execution_receipt.resolved.model.certified.version`, `execution_receipt.request_sha256`, `execution_receipt.result_sha256` |

### `region_selection`

- Current contract: `api_v1_compatible`
- Future owner: PR 9: v2 Metadata, Regions, Datasets, Parameters, and Variables

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `GET` | `/us/metadata` | 200 | `metadata` | `status`, `result.current_law_id`, `result.economy_options.region`, `result.economy_options.time_period` |
| `GET` | `/uk/metadata` | 200 | `metadata` | `status`, `result.current_law_id`, `result.economy_options.region`, `result.economy_options.time_period` |
| Method | Path | Status | Route group | Stable response fields | Optional stable response fields |
| --- | --- | ---: | --- | --- | --- |
| `GET` | `/us/metadata` | 200 | `metadata` | `status`, `result.current_law_id`, `result.economy_options.region`, `result.economy_options.time_period` | |
| `GET` | `/uk/metadata` | 200 | `metadata` | `status`, `result.current_law_id`, `result.economy_options.region`, `result.economy_options.time_period` | |

### `simulation_submit_poll`

- Current contract: `api_v1_compatible`
- Future owner: PR 13: Household Calculation Compute Cutover

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/simulation` | 201 | `simulation` | `status`, `message`, `result.id`, `result.status` |
| `GET` | `/us/simulation/{simulation_id}` | 200 | `simulation` | `status`, `message`, `result` |
| Method | Path | Status | Route group | Stable response fields | Optional stable response fields |
| --- | --- | ---: | --- | --- | --- |
| `POST` | `/us/simulation` | 201 | `simulation` | `status`, `message`, `result.id`, `result.status` | |
| `GET` | `/us/simulation/{simulation_id}` | 200 | `simulation` | `status`, `message`, `result` | |

### `report_create_poll`

- Current contract: `api_v1_compatible`
- Future owner: PR 14: Economy Simulation and Economic Impact Compute Cutover

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/report` | 201 | `report` | `status`, `message`, `result.id`, `result.status` |
| `GET` | `/us/report/{report_id}` | 200 | `report` | `status`, `message`, `result` |
| Method | Path | Status | Route group | Stable response fields | Optional stable response fields |
| --- | --- | ---: | --- | --- | --- |
| `POST` | `/us/report` | 201 | `report` | `status`, `message`, `result.id`, `result.status` | |
| `GET` | `/us/report/{report_id}` | 200 | `report` | `status`, `message`, `result` | |

### `budget_window_submit_poll`

- Current contract: `api_v1_compatible`
- Future owner: PR 15: Budget-Window and Remaining Simulation API Migration

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `GET` | `/us/economy/{policy_id}/over/{baseline_policy_id}/budget-window?region=us&start_year=2026&window_size=1` | 200 | `economy` | `status`, `result.kind`, `progress`, `completed_years`, `computing_years`, `queued_years`, `error` |
| Method | Path | Status | Route group | Stable response fields | Optional stable response fields |
| --- | --- | ---: | --- | --- | --- |
| `GET` | `/us/economy/{policy_id}/over/{baseline_policy_id}/budget-window?region=us&start_year=2026&window_size=1` | 200 | `economy` | `status`, `result.kind`, `progress`, `completed_years`, `computing_years`, `queued_years`, `error` | |
44 changes: 43 additions & 1 deletion docs/generated/migration_contracts.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"metadata": {
"db_entity_count": 6,
"request_count": 14,
"request_count": 15,
"route_group_count": 10,
"sim_flow_count": 3,
"workflow_count": 7
Expand Down Expand Up @@ -103,6 +103,7 @@
{
"expected_status": 201,
"method": "POST",
"optional_stable_response_fields": [],
"path": "/us/policy",
"route_group": "policy",
"stable_response_fields": [
Expand All @@ -114,6 +115,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/us/policy/{policy_id}",
"route_group": "policy",
"stable_response_fields": [
Expand All @@ -125,6 +127,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/us/policies",
"route_group": "policy",
"stable_response_fields": [
Expand All @@ -141,6 +144,7 @@
{
"expected_status": 201,
"method": "POST",
"optional_stable_response_fields": [],
"path": "/us/household",
"route_group": "household",
"stable_response_fields": [
Expand All @@ -152,6 +156,7 @@
{
"expected_status": 200,
"method": "PUT",
"optional_stable_response_fields": [],
"path": "/us/household/{household_id}",
"route_group": "household",
"stable_response_fields": [
Expand All @@ -163,6 +168,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/us/household/{household_id}",
"route_group": "household",
"stable_response_fields": [
Expand All @@ -181,13 +187,42 @@
{
"expected_status": 200,
"method": "POST",
"optional_stable_response_fields": [
"execution_receipt.schema_version",
"execution_receipt.resolved.runtime.name",
"execution_receipt.resolved.numeric_mode",
"execution_receipt.resolved.model.actual.version",
"execution_receipt.resolved.model.certified.version",
"execution_receipt.request_sha256",
"execution_receipt.result_sha256"
],
"path": "/us/calculate",
"route_group": "household",
"stable_response_fields": [
"status",
"message",
"result"
]
},
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [
"execution_receipt.schema_version",
"execution_receipt.resolved.runtime.name",
"execution_receipt.resolved.numeric_mode",
"execution_receipt.resolved.model.actual.version",
"execution_receipt.resolved.model.certified.version",
"execution_receipt.request_sha256",
"execution_receipt.result_sha256"
],
"path": "/us/household/{household_id}/policy/{policy_id}",
"route_group": "household",
"stable_response_fields": [
"status",
"message",
"result"
]
}
]
},
Expand All @@ -199,6 +234,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/us/metadata",
"route_group": "metadata",
"stable_response_fields": [
Expand All @@ -211,6 +247,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/uk/metadata",
"route_group": "metadata",
"stable_response_fields": [
Expand All @@ -230,6 +267,7 @@
{
"expected_status": 201,
"method": "POST",
"optional_stable_response_fields": [],
"path": "/us/simulation",
"route_group": "simulation",
"stable_response_fields": [
Expand All @@ -242,6 +280,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/us/simulation/{simulation_id}",
"route_group": "simulation",
"stable_response_fields": [
Expand All @@ -260,6 +299,7 @@
{
"expected_status": 201,
"method": "POST",
"optional_stable_response_fields": [],
"path": "/us/report",
"route_group": "report",
"stable_response_fields": [
Expand All @@ -272,6 +312,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/us/report/{report_id}",
"route_group": "report",
"stable_response_fields": [
Expand All @@ -290,6 +331,7 @@
{
"expected_status": 200,
"method": "GET",
"optional_stable_response_fields": [],
"path": "/us/economy/{policy_id}/over/{baseline_policy_id}/budget-window?region=us&start_year=2026&window_size=1",
"route_group": "economy",
"stable_response_fields": [
Expand Down
8 changes: 8 additions & 0 deletions policyengine_api/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import hashlib
import json
from copy import deepcopy
from datetime import datetime
from importlib.metadata import distribution, distributions
from pathlib import Path
Expand Down Expand Up @@ -100,6 +101,13 @@ def get_bundle_data_release(country_id: str) -> dict:
return release


def get_policyengine_bundle_manifest() -> dict | None:
"""Return a defensive copy of the installed PolicyEngine bundle manifest."""
if not isinstance(_policyengine_bundle, dict):
return None
return deepcopy(_policyengine_bundle)


def get_bundle_default_dataset(country_id: str) -> str | None:
release = get_bundle_data_release(country_id)
default_dataset = release.get("default_dataset")
Expand Down
Loading
Loading