policyengine 3.0.0__py3-none-any.whl → 3.1.1__py3-none-any.whl

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.
Files changed (76) hide show
  1. policyengine/__pycache__/__init__.cpython-313.pyc +0 -0
  2. policyengine/core/__init__.py +22 -0
  3. policyengine/core/dataset.py +260 -0
  4. policyengine/core/dataset_version.py +16 -0
  5. policyengine/core/dynamic.py +43 -0
  6. policyengine/core/output.py +26 -0
  7. policyengine/{models → core}/parameter.py +4 -2
  8. policyengine/{models → core}/parameter_value.py +1 -1
  9. policyengine/core/policy.py +43 -0
  10. policyengine/{models → core}/simulation.py +10 -14
  11. policyengine/core/tax_benefit_model.py +11 -0
  12. policyengine/core/tax_benefit_model_version.py +34 -0
  13. policyengine/core/variable.py +15 -0
  14. policyengine/outputs/__init__.py +21 -0
  15. policyengine/outputs/aggregate.py +124 -0
  16. policyengine/outputs/change_aggregate.py +184 -0
  17. policyengine/outputs/decile_impact.py +140 -0
  18. policyengine/tax_benefit_models/uk/__init__.py +26 -0
  19. policyengine/tax_benefit_models/uk/analysis.py +97 -0
  20. policyengine/tax_benefit_models/uk/datasets.py +176 -0
  21. policyengine/tax_benefit_models/uk/model.py +268 -0
  22. policyengine/tax_benefit_models/uk/outputs.py +108 -0
  23. policyengine/tax_benefit_models/uk.py +33 -0
  24. policyengine/tax_benefit_models/us/__init__.py +36 -0
  25. policyengine/tax_benefit_models/us/analysis.py +99 -0
  26. policyengine/tax_benefit_models/us/datasets.py +307 -0
  27. policyengine/tax_benefit_models/us/model.py +447 -0
  28. policyengine/tax_benefit_models/us/outputs.py +108 -0
  29. policyengine/tax_benefit_models/us.py +32 -0
  30. policyengine/utils/__init__.py +3 -0
  31. policyengine/utils/dates.py +40 -0
  32. policyengine/utils/parametric_reforms.py +39 -0
  33. policyengine/utils/plotting.py +179 -0
  34. {policyengine-3.0.0.dist-info → policyengine-3.1.1.dist-info}/METADATA +185 -20
  35. policyengine-3.1.1.dist-info/RECORD +39 -0
  36. policyengine/database/__init__.py +0 -56
  37. policyengine/database/aggregate.py +0 -33
  38. policyengine/database/baseline_parameter_value_table.py +0 -66
  39. policyengine/database/baseline_variable_table.py +0 -40
  40. policyengine/database/database.py +0 -251
  41. policyengine/database/dataset_table.py +0 -41
  42. policyengine/database/dynamic_table.py +0 -34
  43. policyengine/database/link.py +0 -82
  44. policyengine/database/model_table.py +0 -27
  45. policyengine/database/model_version_table.py +0 -28
  46. policyengine/database/parameter_table.py +0 -31
  47. policyengine/database/parameter_value_table.py +0 -62
  48. policyengine/database/policy_table.py +0 -34
  49. policyengine/database/report_element_table.py +0 -48
  50. policyengine/database/report_table.py +0 -24
  51. policyengine/database/simulation_table.py +0 -50
  52. policyengine/database/user_table.py +0 -28
  53. policyengine/database/versioned_dataset_table.py +0 -28
  54. policyengine/models/__init__.py +0 -30
  55. policyengine/models/aggregate.py +0 -92
  56. policyengine/models/baseline_parameter_value.py +0 -14
  57. policyengine/models/baseline_variable.py +0 -12
  58. policyengine/models/dataset.py +0 -18
  59. policyengine/models/dynamic.py +0 -15
  60. policyengine/models/model.py +0 -124
  61. policyengine/models/model_version.py +0 -14
  62. policyengine/models/policy.py +0 -17
  63. policyengine/models/policyengine_uk.py +0 -114
  64. policyengine/models/policyengine_us.py +0 -115
  65. policyengine/models/report.py +0 -10
  66. policyengine/models/report_element.py +0 -36
  67. policyengine/models/user.py +0 -14
  68. policyengine/models/versioned_dataset.py +0 -12
  69. policyengine/utils/charts.py +0 -286
  70. policyengine/utils/compress.py +0 -20
  71. policyengine/utils/datasets.py +0 -71
  72. policyengine-3.0.0.dist-info/RECORD +0 -47
  73. policyengine-3.0.0.dist-info/entry_points.txt +0 -2
  74. {policyengine-3.0.0.dist-info → policyengine-3.1.1.dist-info}/WHEEL +0 -0
  75. {policyengine-3.0.0.dist-info → policyengine-3.1.1.dist-info}/licenses/LICENSE +0 -0
  76. {policyengine-3.0.0.dist-info → policyengine-3.1.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,179 @@
1
+ """Plotting utilities for PolicyEngine visualisations."""
2
+
3
+
4
+ import plotly.graph_objects as go
5
+
6
+ # PolicyEngine brand colours
7
+ COLORS = {
8
+ "primary": "#319795", # Teal
9
+ "primary_light": "#E6FFFA",
10
+ "primary_dark": "#1D4044",
11
+ "success": "#22C55E", # Green (positive changes)
12
+ "warning": "#FEC601", # Yellow (cautions)
13
+ "error": "#EF4444", # Red (negative changes)
14
+ "info": "#1890FF", # Blue (neutral info)
15
+ "gray_light": "#F2F4F7",
16
+ "gray": "#667085",
17
+ "gray_dark": "#101828",
18
+ "blue_secondary": "#026AA2",
19
+ }
20
+
21
+ # Typography
22
+ FONT_FAMILY = (
23
+ "Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
24
+ )
25
+ FONT_SIZE_LABEL = 12
26
+ FONT_SIZE_DEFAULT = 14
27
+ FONT_SIZE_TITLE = 16
28
+
29
+
30
+ def format_fig(
31
+ fig: go.Figure,
32
+ title: str | None = None,
33
+ xaxis_title: str | None = None,
34
+ yaxis_title: str | None = None,
35
+ show_legend: bool = True,
36
+ height: int | None = None,
37
+ width: int | None = None,
38
+ ) -> go.Figure:
39
+ """Apply PolicyEngine visual style to a plotly figure.
40
+
41
+ Applies professional, clean styling following PolicyEngine design principles:
42
+ - Data-driven clarity prioritising immediate understanding
43
+ - Professional brand colours (teal primary, semantic colours)
44
+ - Clean typography with Inter font family
45
+ - Minimal visual clutter
46
+ - Appropriate spacing and margins
47
+
48
+ Args:
49
+ fig: Plotly figure to format
50
+ title: Optional title to set/override
51
+ xaxis_title: Optional x-axis title to set/override
52
+ yaxis_title: Optional y-axis title to set/override
53
+ show_legend: Whether to show the legend (default: True)
54
+ height: Optional height in pixels
55
+ width: Optional width in pixels
56
+
57
+ Returns:
58
+ Formatted plotly figure (same object, modified in place)
59
+
60
+ Example:
61
+ >>> import plotly.graph_objects as go
62
+ >>> from policyengine.utils import format_fig
63
+ >>> fig = go.Figure(data=go.Scatter(x=[1, 2, 3], y=[4, 5, 6]))
64
+ >>> format_fig(fig, title="Example chart", xaxis_title="X", yaxis_title="Y")
65
+ """
66
+ # Build layout updates
67
+ layout_updates = {
68
+ "font": {
69
+ "family": FONT_FAMILY,
70
+ "size": FONT_SIZE_DEFAULT,
71
+ "color": COLORS["gray_dark"],
72
+ },
73
+ "plot_bgcolor": "#FAFAFA",
74
+ "paper_bgcolor": "white",
75
+ "margin": {"l": 100, "r": 60, "t": 100, "b": 80},
76
+ "showlegend": show_legend,
77
+ "xaxis": {
78
+ "title": {
79
+ "font": {
80
+ "size": FONT_SIZE_DEFAULT,
81
+ "family": FONT_FAMILY,
82
+ "color": COLORS["gray_dark"],
83
+ },
84
+ "standoff": 20,
85
+ },
86
+ "tickfont": {
87
+ "size": FONT_SIZE_LABEL,
88
+ "family": FONT_FAMILY,
89
+ "color": COLORS["gray"],
90
+ },
91
+ "showgrid": False,
92
+ "showline": True,
93
+ "linewidth": 2,
94
+ "linecolor": COLORS["gray_light"],
95
+ "zeroline": False,
96
+ "ticks": "outside",
97
+ "tickwidth": 1,
98
+ "tickcolor": COLORS["gray_light"],
99
+ },
100
+ "yaxis": {
101
+ "title": {
102
+ "font": {
103
+ "size": FONT_SIZE_DEFAULT,
104
+ "family": FONT_FAMILY,
105
+ "color": COLORS["gray_dark"],
106
+ },
107
+ "standoff": 20,
108
+ },
109
+ "tickfont": {
110
+ "size": FONT_SIZE_LABEL,
111
+ "family": FONT_FAMILY,
112
+ "color": COLORS["gray"],
113
+ },
114
+ "showgrid": True,
115
+ "gridwidth": 1,
116
+ "gridcolor": "#E5E7EB",
117
+ "showline": False,
118
+ "zeroline": False,
119
+ },
120
+ "legend": {
121
+ "bgcolor": "white",
122
+ "bordercolor": COLORS["gray_light"],
123
+ "borderwidth": 1,
124
+ "font": {"size": FONT_SIZE_LABEL, "family": FONT_FAMILY},
125
+ "orientation": "v",
126
+ "yanchor": "top",
127
+ "y": 0.99,
128
+ "xanchor": "right",
129
+ "x": 0.99,
130
+ },
131
+ }
132
+
133
+ # Add optional parameters
134
+ if title is not None:
135
+ layout_updates["title"] = {
136
+ "text": title,
137
+ "font": {
138
+ "size": 18,
139
+ "family": FONT_FAMILY,
140
+ "color": COLORS["gray_dark"],
141
+ "weight": 600,
142
+ },
143
+ "x": 0,
144
+ "xanchor": "left",
145
+ "y": 0.98,
146
+ "yanchor": "top",
147
+ }
148
+
149
+ if xaxis_title is not None:
150
+ layout_updates["xaxis"]["title"]["text"] = xaxis_title
151
+
152
+ if yaxis_title is not None:
153
+ layout_updates["yaxis"]["title"]["text"] = yaxis_title
154
+
155
+ if height is not None:
156
+ layout_updates["height"] = height
157
+
158
+ if width is not None:
159
+ layout_updates["width"] = width
160
+
161
+ # Apply layout
162
+ fig.update_layout(**layout_updates)
163
+
164
+ # Update all traces to have cleaner styling
165
+ fig.update_traces(
166
+ marker=dict(size=8, line=dict(width=0)),
167
+ line=dict(width=3),
168
+ selector=dict(mode="markers+lines"),
169
+ )
170
+ fig.update_traces(
171
+ marker=dict(size=8, line=dict(width=0)),
172
+ selector=dict(mode="markers"),
173
+ )
174
+ fig.update_traces(
175
+ line=dict(width=3),
176
+ selector=dict(mode="lines"),
177
+ )
178
+
179
+ return fig
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: policyengine
3
- Version: 3.0.0
3
+ Version: 3.1.1
4
4
  Summary: A package to conduct policy analysis using PolicyEngine tax-benefit models.
5
5
  Author-email: PolicyEngine <hello@policyengine.org>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -668,20 +668,11 @@ License: GNU AFFERO GENERAL PUBLIC LICENSE
668
668
  Requires-Python: >=3.13
669
669
  Description-Content-Type: text/markdown
670
670
  License-File: LICENSE
671
- Requires-Dist: sqlalchemy>=2.0.0
672
- Requires-Dist: sqlmodel>=0.0.21
673
- Requires-Dist: alembic>=1.13.0
674
- Requires-Dist: psycopg2-binary>=2.9.0
675
- Requires-Dist: pymysql>=1.1.0
676
- Requires-Dist: google-cloud-storage>=2.10.0
677
- Requires-Dist: getpass4
678
671
  Requires-Dist: pydantic>=2.0.0
679
672
  Requires-Dist: pandas>=2.0.0
680
- Requires-Dist: rich>=13.0.0
681
- Requires-Dist: ipywidgets>=8.0.0
682
673
  Requires-Dist: microdf_python
683
- Requires-Dist: tqdm>=4.67.1
684
- Requires-Dist: blosc>=1.11.3
674
+ Requires-Dist: plotly>=5.0.0
675
+ Requires-Dist: requests>=2.31.0
685
676
  Provides-Extra: uk
686
677
  Requires-Dist: policyengine_core>=3.10; extra == "uk"
687
678
  Requires-Dist: policyengine-uk>=2.51.0; extra == "uk"
@@ -706,13 +697,187 @@ Dynamic: license-file
706
697
 
707
698
  # PolicyEngine.py
708
699
 
709
- Documentation
700
+ A Python package for tax-benefit microsimulation analysis. Run policy simulations, analyse distributional impacts, and visualise results across the UK and US.
710
701
 
711
- - Parameters, variables, and values: `docs/01_parameters_variables.ipynb`
712
- - Policies and dynamic: `docs/02_policies_dynamic.ipynb`
713
- - Datasets: `docs/03_datasets.ipynb`
714
- - Simulations: `docs/04_simulations.ipynb`
715
- - Output data items: `docs/05_output_data_items.ipynb`
716
- - Reports and users: `docs/06_reports_users.ipynb`
702
+ ## Quick start
717
703
 
718
- Open these notebooks in Jupyter or your preferred IDE to run the examples.
704
+ ```python
705
+ from policyengine.core import Simulation
706
+ from policyengine.tax_benefit_models.uk import PolicyEngineUKDataset, uk_latest
707
+ from policyengine.outputs.aggregate import Aggregate, AggregateType
708
+
709
+ # Load representative microdata
710
+ dataset = PolicyEngineUKDataset(
711
+ name="FRS 2023-24",
712
+ filepath="./data/frs_2023_24_year_2026.h5",
713
+ year=2026,
714
+ )
715
+
716
+ # Run simulation
717
+ simulation = Simulation(
718
+ dataset=dataset,
719
+ tax_benefit_model_version=uk_latest,
720
+ )
721
+ simulation.run()
722
+
723
+ # Calculate total universal credit spending
724
+ agg = Aggregate(
725
+ simulation=simulation,
726
+ variable="universal_credit",
727
+ aggregate_type=AggregateType.SUM,
728
+ entity="benunit",
729
+ )
730
+ agg.run()
731
+ print(f"Total UC spending: £{agg.result / 1e9:.1f}bn")
732
+ ```
733
+
734
+ ## Documentation
735
+
736
+ **Core concepts:**
737
+ - [Core concepts](docs/core-concepts.md): Architecture, datasets, simulations, outputs
738
+ - [UK tax-benefit model](docs/country-models-uk.md): Entities, parameters, examples
739
+ - [US tax-benefit model](docs/country-models-us.md): Entities, parameters, examples
740
+
741
+ **Examples:**
742
+ - `examples/income_distribution_us.py`: Analyse benefit distribution by decile
743
+ - `examples/employment_income_variation_uk.py`: Model employment income phase-outs
744
+ - `examples/policy_change_uk.py`: Analyse policy reform impacts
745
+
746
+ ## Installation
747
+
748
+ ```bash
749
+ pip install policyengine
750
+ ```
751
+
752
+ ## Features
753
+
754
+ - **Multi-country support**: UK and US tax-benefit systems
755
+ - **Representative microdata**: Load FRS, CPS, or create custom scenarios
756
+ - **Policy reforms**: Parametric reforms with date-bound parameter values
757
+ - **Distributional analysis**: Aggregate statistics by income decile, demographics
758
+ - **Entity mapping**: Automatic mapping between person, household, tax unit levels
759
+ - **Visualisation**: PolicyEngine-branded charts with Plotly
760
+
761
+ ## Key concepts
762
+
763
+ ### Datasets
764
+
765
+ Datasets contain microdata at entity level (person, household, tax unit). Load representative data or create custom scenarios:
766
+
767
+ ```python
768
+ from policyengine.tax_benefit_models.uk import PolicyEngineUKDataset
769
+
770
+ dataset = PolicyEngineUKDataset(
771
+ name="Representative data",
772
+ filepath="./data/frs_2023_24_year_2026.h5",
773
+ year=2026,
774
+ )
775
+ dataset.load()
776
+ ```
777
+
778
+ ### Simulations
779
+
780
+ Simulations apply tax-benefit models to datasets:
781
+
782
+ ```python
783
+ from policyengine.core import Simulation
784
+ from policyengine.tax_benefit_models.uk import uk_latest
785
+
786
+ simulation = Simulation(
787
+ dataset=dataset,
788
+ tax_benefit_model_version=uk_latest,
789
+ )
790
+ simulation.run()
791
+
792
+ # Access calculated variables
793
+ output = simulation.output_dataset.data
794
+ print(output.household[["household_net_income", "household_benefits"]])
795
+ ```
796
+
797
+ ### Outputs
798
+
799
+ Extract insights with aggregate statistics:
800
+
801
+ ```python
802
+ from policyengine.outputs.aggregate import Aggregate, AggregateType
803
+
804
+ # Mean income in top decile
805
+ agg = Aggregate(
806
+ simulation=simulation,
807
+ variable="household_net_income",
808
+ aggregate_type=AggregateType.MEAN,
809
+ filter_variable="household_net_income",
810
+ quantile=10,
811
+ quantile_eq=10,
812
+ )
813
+ agg.run()
814
+ print(f"Top decile mean income: £{agg.result:,.0f}")
815
+ ```
816
+
817
+ ### Policy reforms
818
+
819
+ Apply parametric reforms:
820
+
821
+ ```python
822
+ from policyengine.core import Policy, Parameter, ParameterValue
823
+ import datetime
824
+
825
+ parameter = Parameter(
826
+ name="gov.hmrc.income_tax.allowances.personal_allowance.amount",
827
+ tax_benefit_model_version=uk_latest,
828
+ data_type=float,
829
+ )
830
+
831
+ policy = Policy(
832
+ name="Increase personal allowance",
833
+ parameter_values=[
834
+ ParameterValue(
835
+ parameter=parameter,
836
+ start_date=datetime.date(2026, 1, 1),
837
+ end_date=datetime.date(2026, 12, 31),
838
+ value=15000,
839
+ )
840
+ ],
841
+ )
842
+
843
+ # Run reform simulation
844
+ reform_sim = Simulation(
845
+ dataset=dataset,
846
+ tax_benefit_model_version=uk_latest,
847
+ policy=policy,
848
+ )
849
+ reform_sim.run()
850
+ ```
851
+
852
+ ## Country models
853
+
854
+ ### UK
855
+
856
+ Three entity levels:
857
+ - **Person**: Individual with income and demographics
858
+ - **Benunit**: Benefit unit (single person or couple with children)
859
+ - **Household**: Residence unit
860
+
861
+ Key benefits: Universal Credit, Child Benefit, Pension Credit
862
+ Key taxes: Income tax, National Insurance
863
+
864
+ ### US
865
+
866
+ Six entity levels:
867
+ - **Person**: Individual
868
+ - **Tax unit**: Federal tax filing unit
869
+ - **SPM unit**: Supplemental Poverty Measure unit
870
+ - **Family**: Census family definition
871
+ - **Marital unit**: Married couple or single person
872
+ - **Household**: Residence unit
873
+
874
+ Key benefits: SNAP, TANF, EITC, CTC, SSI, Social Security
875
+ Key taxes: Federal income tax, payroll tax
876
+
877
+ ## Contributing
878
+
879
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
880
+
881
+ ## License
882
+
883
+ AGPL-3.0
@@ -0,0 +1,39 @@
1
+ policyengine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ policyengine/__pycache__/__init__.cpython-313.pyc,sha256=dmkhqYKcUjDPvirOFgf1L-P-aV3l7JIWK6zZZ6J45LU,175
3
+ policyengine/core/__init__.py,sha256=3vabkWXYNNmQmN4Vy1yx2kKk6RKVSsdjtToQ8s8gzUg,870
4
+ policyengine/core/dataset.py,sha256=jGjnoyEQ6VcTiCs8Hr6PT22l59CRhK1oUT5RPaz7mC0,9256
5
+ policyengine/core/dataset_version.py,sha256=6KeFCRGQto_Yyl4QY4Vo2JFythjaXrNAOHQiwRGESyM,378
6
+ policyengine/core/dynamic.py,sha256=40RO3N6hmUT6-3tpJy0wSOC-9ITdFSS5LRiqPmi79f0,1605
7
+ policyengine/core/output.py,sha256=cCW4vbzkLdQaT_nJTyDJBl7Hubm7nZeRuR7aVG1dKvg,643
8
+ policyengine/core/parameter.py,sha256=PLDaepytqB7FVSfYQ541vnkVuMDLamFBeHtz2TmQrOE,378
9
+ policyengine/core/parameter_value.py,sha256=b0ts1kbWcwjPSYnZm2rlCylmTLPJRLxDL8z3RmxM5OI,377
10
+ policyengine/core/policy.py,sha256=xorVf03bcjB-3mBEmwj2YMqF1-6Xzps74SquzqtS0lo,1599
11
+ policyengine/core/simulation.py,sha256=x9dU_nKEIgCZa11cxB-VdRNt9DZjjSML7n7M8_3STv8,941
12
+ policyengine/core/tax_benefit_model.py,sha256=2Yc1RlQrUG7djDMZbJOQH4Ns86_lOnLeISCGR4-9zMo,176
13
+ policyengine/core/tax_benefit_model_version.py,sha256=AJHFRaSEzR2_0FVkBBb40ID3FAaFFrFLnhSXRYYbtWs,1291
14
+ policyengine/core/variable.py,sha256=AjSImORlRkh05xhYxyeT6GFMOfViRzYg0qRQAIj-mxo,350
15
+ policyengine/outputs/__init__.py,sha256=IJUmLP0Og41VrwiqhJF-a9-3fIb4nlXpS7uFuVCINIs,515
16
+ policyengine/outputs/aggregate.py,sha256=exI-U04OF5kVf2BBYV6sf8VldIWnT_IzxgkBs5wtnCw,4846
17
+ policyengine/outputs/change_aggregate.py,sha256=tK4K87YlByKikqFaB7OHyh1SqAuGtUnLL7cSF_EhrOs,7373
18
+ policyengine/outputs/decile_impact.py,sha256=jclhbj5U-xX8D-myy0SuWeJFVfQTqJDCh7qBXugak5U,4811
19
+ policyengine/tax_benefit_models/uk.py,sha256=MCeJGQCTwUzBYdz0ru7IgT8Mgv-vJMqqVwFrntGWWTE,734
20
+ policyengine/tax_benefit_models/us.py,sha256=d6rdhW2awoUvk5Ldp9mHAUiHqlnSfEQR318PkIXS_9c,794
21
+ policyengine/tax_benefit_models/uk/__init__.py,sha256=1L1HBbOTflRefjOcU5vgEYkn6wLWOt_uG9G_PF089S0,732
22
+ policyengine/tax_benefit_models/uk/analysis.py,sha256=O4eYJYF7tsgiuLuiWMU0OXq7ss6U8-vzlg6nC2U8sgU,3175
23
+ policyengine/tax_benefit_models/uk/datasets.py,sha256=LvbHemfhMU1kk9sZU5eAPrix8EmTl07p9fYkwbSasIE,6542
24
+ policyengine/tax_benefit_models/uk/model.py,sha256=5GGhscQEX1-YBgkUt4kd2RyFfVIBEd7IihaSP3ia7hg,9247
25
+ policyengine/tax_benefit_models/uk/outputs.py,sha256=2mYLwQW4QNvrOHtHfm_ACqE9gbmuLxvcCyldRU46s0o,3543
26
+ policyengine/tax_benefit_models/us/__init__.py,sha256=ClBkFwRa_nFQ3YU003uxBKiMG3pktaUb8jRvhzfR0vE,968
27
+ policyengine/tax_benefit_models/us/analysis.py,sha256=Xf-DT0QjVySs0QG_koCwgvOeWI_scLtv3S3SP8u8ZWc,3253
28
+ policyengine/tax_benefit_models/us/datasets.py,sha256=sQ0YsTsmqpaM-j7w6Cea1lKUzjMV3UPqH5Bc3hH71cI,12718
29
+ policyengine/tax_benefit_models/us/model.py,sha256=SNQ3_pVLJDF41gRzU4NZ1yZUq8nLMPSHWwb-qGaTae0,16021
30
+ policyengine/tax_benefit_models/us/outputs.py,sha256=GT8Eur8DfB9cPQRbSljEl9RpKSNHW80Fq_CBXCybvIU,3519
31
+ policyengine/utils/__init__.py,sha256=1X-VYAWLyB9A0YRHwsGWrqQHns1WfeZ7ISC6DMU5myM,140
32
+ policyengine/utils/dates.py,sha256=HnAqyl8S8EOYp8ibsnMTmECYoDWCSqwL-7A2_qKgxSc,1510
33
+ policyengine/utils/parametric_reforms.py,sha256=4P3U39-4pYTU4BN6JjgmVLUkCkBhRfZJ6UIWTlsjyQE,1155
34
+ policyengine/utils/plotting.py,sha256=JbMPwD7SCQqp_qbjYrXixT5zS0eG734n0Sg4JkD9nDc,5336
35
+ policyengine-3.1.1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
36
+ policyengine-3.1.1.dist-info/METADATA,sha256=JuCAmXnSyBcTeeqyBm54GYmsYrrOPg8zGhWHdYoleT4,45889
37
+ policyengine-3.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
+ policyengine-3.1.1.dist-info/top_level.txt,sha256=_23UPobfkneHQkpJ0e0OmDJfhCUfoXj_F2sTckCGOH4,13
39
+ policyengine-3.1.1.dist-info/RECORD,,
@@ -1,56 +0,0 @@
1
- from .baseline_parameter_value_table import (
2
- BaselineParameterValueTable,
3
- baseline_parameter_value_table_link,
4
- )
5
- from .baseline_variable_table import (
6
- BaselineVariableTable,
7
- baseline_variable_table_link,
8
- )
9
- from .database import Database
10
- from .dataset_table import DatasetTable, dataset_table_link
11
- from .dynamic_table import DynamicTable, dynamic_table_link
12
- from .link import TableLink
13
-
14
- # Import all table classes and links
15
- from .model_table import ModelTable, model_table_link
16
- from .model_version_table import ModelVersionTable, model_version_table_link
17
- from .parameter_table import ParameterTable, parameter_table_link
18
- from .parameter_value_table import (
19
- ParameterValueTable,
20
- parameter_value_table_link,
21
- )
22
- from .policy_table import PolicyTable, policy_table_link
23
- from .simulation_table import SimulationTable, simulation_table_link
24
- from .versioned_dataset_table import (
25
- VersionedDatasetTable,
26
- versioned_dataset_table_link,
27
- )
28
-
29
- __all__ = [
30
- "Database",
31
- "TableLink",
32
- # Tables
33
- "ModelTable",
34
- "ModelVersionTable",
35
- "DatasetTable",
36
- "VersionedDatasetTable",
37
- "PolicyTable",
38
- "DynamicTable",
39
- "ParameterTable",
40
- "ParameterValueTable",
41
- "BaselineParameterValueTable",
42
- "BaselineVariableTable",
43
- "SimulationTable",
44
- # Links
45
- "model_table_link",
46
- "model_version_table_link",
47
- "dataset_table_link",
48
- "versioned_dataset_table_link",
49
- "policy_table_link",
50
- "dynamic_table_link",
51
- "parameter_table_link",
52
- "parameter_value_table_link",
53
- "baseline_parameter_value_table_link",
54
- "baseline_variable_table_link",
55
- "simulation_table_link",
56
- ]
@@ -1,33 +0,0 @@
1
- from uuid import uuid4
2
-
3
- from sqlmodel import Field, SQLModel
4
-
5
- from policyengine.database.link import TableLink
6
- from policyengine.models.aggregate import Aggregate
7
-
8
-
9
- class AggregateTable(SQLModel, table=True):
10
- __tablename__ = "aggregates"
11
-
12
- id: str = Field(default_factory=lambda: str(uuid4()), primary_key=True)
13
- simulation_id: str = Field(
14
- foreign_key="simulations.id", ondelete="CASCADE"
15
- )
16
- entity: str
17
- variable_name: str
18
- year: int | None = None
19
- filter_variable_name: str | None = None
20
- filter_variable_value: str | None = None
21
- filter_variable_leq: float | None = None
22
- filter_variable_geq: float | None = None
23
- aggregate_function: str
24
- value: float | None = None
25
-
26
-
27
- aggregate_table_link = TableLink(
28
- model_cls=Aggregate,
29
- table_cls=AggregateTable,
30
- model_to_table_custom_transforms=dict(
31
- simulation_id=lambda a: a.simulation.id,
32
- ),
33
- )
@@ -1,66 +0,0 @@
1
- from datetime import datetime
2
- from typing import Any
3
- from uuid import uuid4
4
-
5
- from sqlmodel import JSON, Column, Field, SQLModel
6
-
7
- from policyengine.models import BaselineParameterValue
8
-
9
- from .link import TableLink
10
-
11
-
12
- class BaselineParameterValueTable(SQLModel, table=True):
13
- __tablename__ = "baseline_parameter_values"
14
- __table_args__ = ({"extend_existing": True},)
15
-
16
- id: str = Field(default_factory=lambda: str(uuid4()), primary_key=True)
17
- parameter_id: str = Field(nullable=False) # Part of composite foreign key
18
- model_id: str = Field(nullable=False) # Part of composite foreign key
19
- model_version_id: str = Field(
20
- foreign_key="model_versions.id", ondelete="CASCADE"
21
- )
22
- value: Any | None = Field(
23
- default=None, sa_column=Column(JSON)
24
- ) # JSON field for any type
25
- start_date: datetime = Field(nullable=False)
26
- end_date: datetime | None = Field(default=None)
27
-
28
-
29
- def transform_value_to_table(bpv):
30
- """Transform value for storage, handling special float values."""
31
- import math
32
-
33
- value = bpv.value
34
- if isinstance(value, float):
35
- if math.isinf(value):
36
- return "Infinity" if value > 0 else "-Infinity"
37
- elif math.isnan(value):
38
- return "NaN"
39
- return value
40
-
41
-
42
- def transform_value_from_table(table_row):
43
- """Transform value from storage, converting special strings back to floats."""
44
- value = table_row.value
45
- if value == "Infinity":
46
- return float("inf")
47
- elif value == "-Infinity":
48
- return float("-inf")
49
- elif value == "NaN":
50
- return float("nan")
51
- return value
52
-
53
-
54
- baseline_parameter_value_table_link = TableLink(
55
- model_cls=BaselineParameterValue,
56
- table_cls=BaselineParameterValueTable,
57
- model_to_table_custom_transforms=dict(
58
- parameter_id=lambda bpv: bpv.parameter.id,
59
- model_id=lambda bpv: bpv.parameter.model.id, # Add model_id from parameter
60
- model_version_id=lambda bpv: bpv.model_version.id,
61
- value=transform_value_to_table,
62
- ),
63
- table_to_model_custom_transforms=dict(
64
- value=transform_value_from_table,
65
- ),
66
- )
@@ -1,40 +0,0 @@
1
- from sqlmodel import Field, SQLModel
2
-
3
- from policyengine.models import BaselineVariable
4
- from policyengine.utils.compress import compress_data, decompress_data
5
-
6
- from .link import TableLink
7
-
8
-
9
- class BaselineVariableTable(SQLModel, table=True):
10
- __tablename__ = "baseline_variables"
11
- __table_args__ = ({"extend_existing": True},)
12
-
13
- id: str = Field(primary_key=True) # Variable name
14
- model_id: str = Field(
15
- primary_key=True, foreign_key="models.id"
16
- ) # Part of composite key
17
- model_version_id: str = Field(
18
- foreign_key="model_versions.id", ondelete="CASCADE"
19
- )
20
- entity: str = Field(nullable=False)
21
- label: str | None = Field(default=None)
22
- description: str | None = Field(default=None)
23
- data_type: bytes | None = Field(default=None) # Pickled type
24
-
25
-
26
- baseline_variable_table_link = TableLink(
27
- model_cls=BaselineVariable,
28
- table_cls=BaselineVariableTable,
29
- primary_key=("id", "model_id"), # Composite primary key
30
- model_to_table_custom_transforms=dict(
31
- model_id=lambda bv: bv.model_version.model.id, # Add model_id from model_version
32
- model_version_id=lambda bv: bv.model_version.id,
33
- data_type=lambda bv: compress_data(bv.data_type)
34
- if bv.data_type
35
- else None,
36
- ),
37
- table_to_model_custom_transforms=dict(
38
- data_type=lambda dt: decompress_data(dt) if dt else None,
39
- ),
40
- )