Skip to content

Commit bb13933

Browse files
authored
Merge pull request #101 from PolicyEngine/add-variable-labels
Add label column to variables table with search support
2 parents 04dac7a + 1dfff30 commit bb13933

6 files changed

Lines changed: 421 additions & 4 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Add label column to variables table
2+
3+
Revision ID: add_variable_label
4+
Revises: 886921687770
5+
Create Date: 2026-03-05
6+
7+
Variables now carry a human-readable label sourced from OpenFisca's
8+
Variable.label class attribute (e.g. "Employment income"). Previously
9+
labels were auto-generated on the frontend from the snake_case name.
10+
"""
11+
12+
from typing import Sequence, Union
13+
14+
import sqlalchemy as sa
15+
import sqlmodel.sql.sqltypes
16+
17+
from alembic import op
18+
19+
# revision identifiers, used by Alembic.
20+
revision: str = "add_variable_label"
21+
down_revision: Union[str, Sequence[str], None] = "886921687770"
22+
branch_labels: Union[str, Sequence[str], None] = None
23+
depends_on: Union[str, Sequence[str], None] = None
24+
25+
26+
def upgrade() -> None:
27+
"""Add label column to variables table."""
28+
op.add_column(
29+
"variables",
30+
sa.Column("label", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
31+
)
32+
33+
34+
def downgrade() -> None:
35+
"""Remove label column from variables table."""
36+
op.drop_column("variables", "label")

scripts/seed_models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ def seed_model(
146146
{
147147
"id": uuid4(),
148148
"name": var.name,
149+
"label": getattr(var, "label", None) or "",
149150
"entity": var.entity,
150151
"description": var.description or "",
151152
"data_type": data_type,
@@ -163,6 +164,7 @@ def seed_model(
163164
[
164165
"id",
165166
"name",
167+
"label",
166168
"entity",
167169
"description",
168170
"data_type",

src/policyengine_api/api/variables.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ def list_variables(
5656

5757
if search:
5858
# Case-insensitive search using ILIKE
59-
# Note: Variables don't have a label field, only name and description
6059
search_pattern = f"%{search}%"
61-
search_filter = Variable.name.ilike(
62-
search_pattern
63-
) | Variable.description.ilike(search_pattern)
60+
search_filter = (
61+
Variable.name.ilike(search_pattern)
62+
| Variable.label.ilike(search_pattern)
63+
| Variable.description.ilike(search_pattern)
64+
)
6465
query = query.where(search_filter)
6566

6667
variables = session.exec(

src/policyengine_api/models/variable.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class VariableBase(SQLModel):
1212
"""Base variable fields."""
1313

1414
name: str
15+
label: str | None = None
1516
entity: str
1617
description: str | None = None
1718
data_type: str | None = None # Store as string representation
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"""Fixtures and helpers for variable-related tests."""
2+
3+
import pytest
4+
5+
from policyengine_api.models import (
6+
TaxBenefitModel,
7+
TaxBenefitModelVersion,
8+
Variable,
9+
)
10+
11+
# ---------------------------------------------------------------------------
12+
# Fixtures
13+
# ---------------------------------------------------------------------------
14+
15+
16+
@pytest.fixture
17+
def us_model_version(session):
18+
"""Create a policyengine-us model and version for testing."""
19+
model = TaxBenefitModel(name="policyengine-us", description="US model")
20+
session.add(model)
21+
session.commit()
22+
session.refresh(model)
23+
24+
version = TaxBenefitModelVersion(
25+
model_id=model.id,
26+
version="1.0.0",
27+
description="Test US version",
28+
)
29+
session.add(version)
30+
session.commit()
31+
session.refresh(version)
32+
return version
33+
34+
35+
@pytest.fixture
36+
def uk_model_version(session):
37+
"""Create a policyengine-uk model and version for testing."""
38+
model = TaxBenefitModel(name="policyengine-uk", description="UK model")
39+
session.add(model)
40+
session.commit()
41+
session.refresh(model)
42+
43+
version = TaxBenefitModelVersion(
44+
model_id=model.id,
45+
version="1.0.0",
46+
description="Test UK version",
47+
)
48+
session.add(version)
49+
session.commit()
50+
session.refresh(version)
51+
return version
52+
53+
54+
# ---------------------------------------------------------------------------
55+
# Factory Functions
56+
# ---------------------------------------------------------------------------
57+
58+
59+
def create_variable(
60+
session,
61+
model_version,
62+
name: str,
63+
label: str | None = None,
64+
entity: str = "person",
65+
description: str | None = None,
66+
data_type: str | None = "float",
67+
) -> Variable:
68+
"""Create and persist a Variable."""
69+
var = Variable(
70+
name=name,
71+
label=label,
72+
entity=entity,
73+
description=description,
74+
data_type=data_type,
75+
tax_benefit_model_version_id=model_version.id,
76+
)
77+
session.add(var)
78+
session.commit()
79+
session.refresh(var)
80+
return var

0 commit comments

Comments
 (0)