Skip to content

Commit

Permalink
Add RAC images.
Browse files Browse the repository at this point in the history
  • Loading branch information
steveworley committed Jan 11, 2024
0 parents commit ece51de
Show file tree
Hide file tree
Showing 49 changed files with 1,527 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Deploy images
on:
- push
jobs:
delploy:
runs-on: ubuntu-latest
15 changes: 15 additions & 0 deletions .github/workflows/rules-as-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Rules As Code build
on:
- workflow_call
jobs:
test:
name: Test the docker images
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

deploy:
name: Build the docker images
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Test images
on:
- push
jobs:
test:
runs-on: ubuntu-latest
Empty file added README.md
Empty file.
26 changes: 26 additions & 0 deletions images/rules-as-code/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM uselagoon/python-3.9:latest as build

WORKDIR /app/

RUN apk add gcc libc-dev g++ linux-headers yaml-dev
RUN pip wheel --wheel-dir=/app/wheel numpy==1.20.* numexpr==2.8.* psutil PyYAML


FROM uselagoon/python-3.9:latest

EXPOSE 3000

ARG PROJECT_NAME=rule
COPY openfisca_$PROJECT_NAME /app/openfisca_$PROJECT_NAME
COPY README.md setup.cfg setup.py /app/

WORKDIR /app/

COPY --from=build /app/ /app/
COPY README.md /app/openfisca_$PROJECT_NAME
RUN apk add gcc libc-dev g++ linux-headers yaml-dev libffi-dev
RUN pip install --no-index --find-links=/app/wheel numpy numexpr psutil PyYAML
RUN pip install -e /app


ENTRYPOINT ["openfisca", "serve", "--bind", "0.0.0.0:3000"]
7 changes: 7 additions & 0 deletions images/rules-as-code/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Rules As Code (Openfisca)

This provides a standardised version of [OpenFisca](https://openfisca.org/en/) which is compatible with Lagoon hosting environments.

## Attribution

- [OpenFisca template](https://github.com/openfisca/country-template)
41 changes: 41 additions & 0 deletions images/rules-as-code/openfisca_rules/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
This file defines our country's tax and benefit system.
A tax and benefit system is the higher-level instance in OpenFisca.
Its goal is to model the legislation of a country.
Basically a tax and benefit system contains simulation variables (source code) and legislation parameters (data).
See https://openfisca.org/doc/key-concepts/tax_and_benefit_system.html
"""

import os

from openfisca_core.taxbenefitsystems import TaxBenefitSystem

from openfisca_country_template import entities
from openfisca_country_template.situation_examples import couple


COUNTRY_DIR = os.path.dirname(os.path.abspath(__file__))


# Our country tax and benefit class inherits from the general TaxBenefitSystem class.
# The name CountryTaxBenefitSystem must not be changed, as all tools of the OpenFisca ecosystem expect a CountryTaxBenefitSystem class to be exposed in the __init__ module of a country package.
class CountryTaxBenefitSystem(TaxBenefitSystem):
def __init__(self):
# We initialize our tax and benefit system with the general constructor
super().__init__(entities.entities)

# We add to our tax and benefit system all the variables
self.add_variables_from_directory(os.path.join(COUNTRY_DIR, "variables"))

# We add to our tax and benefit system all the legislation parameters defined in the parameters files
param_path = os.path.join(COUNTRY_DIR, "parameters")
self.load_parameters(param_path)

# We define which variable, parameter and simulation example will be used in the OpenAPI specification
self.open_api_config = {
"variable_example": "disposable_income",
"parameter_example": "taxes.income_tax_rate",
"simulation_example": couple,
}
64 changes: 64 additions & 0 deletions images/rules-as-code/openfisca_rules/entities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
This file defines the entities needed by our legislation.
Taxes and benefits can be calculated for different entities: persons, household, companies, etc.
See https://openfisca.org/doc/key-concepts/person,_entities,_role.html
"""

from openfisca_core.entities import build_entity

Household = build_entity(
key = "household",
plural = "households",
label = "All the people in a family or group who live together in the same place.",
doc = """
Household is an example of a group entity.
A group entity contains one or more individual·s.
Each individual in a group entity has a role (e.g. parent or children). Some roles can only be held by a limited number of individuals (e.g. a 'first_parent' can only be held by one individual), while others can have an unlimited number of individuals (e.g. 'children').
Example:
Housing variables (e.g. housing_tax') are usually defined for a group entity such as 'Household'.
Usage:
Check the number of individuals of a specific role (e.g. check if there is a 'second_parent' with household.nb_persons(Household.SECOND_PARENT)).
Calculate a variable applied to each individual of the group entity (e.g. calculate the 'salary' of each member of the 'Household' with salaries = household.members("salary", period = MONTH); sum_salaries = household.sum(salaries)).
For more information, see: https://openfisca.org/doc/coding-the-legislation/50_entities.html
""",
roles = [
{
"key": "parent",
"plural": "parents",
"label": "Parents",
"max": 2,
"subroles": ["first_parent", "second_parent"],
"doc": "The one or two adults in charge of the household.",
},
{
"key": "child",
"plural": "children",
"label": "Child",
"doc": "Other individuals living in the household.",
},
],
)

Person = build_entity(
key = "person",
plural = "persons",
label = "An individual. The minimal legal entity on which a legislation might be applied.",
doc = """
Variables like 'salary' and 'income_tax' are usually defined for the entity 'Person'.
Usage:
Calculate a variable applied to a 'Person' (e.g. access the 'salary' of a specific month with person("salary", "2017-05")).
Check the role of a 'Person' in a group entity (e.g. check if a the 'Person' is a 'first_parent' in a 'Household' entity with person.has_role(Household.FIRST_PARENT)).
For more information, see: https://openfisca.org/doc/coding-the-legislation/50_entities.html
""",
is_person = True,
)

entities = [Household, Person]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: Amount of the basic income
metadata:
reference: https://law.gov.example/basic-income/amount
unit: currency-EUR
values:
# This parameter is only defined since the 1st of Dec 2015.
2015-12-01:
value: 600.0
metadata:
reference: https://law.gov.example/basic-income/amount/2015-12
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: Housing allowance amount (as a fraction of the rent)
metadata:
unit: /1
reference: https://law.gov.example/housing-allowance-rate
documentation: |
A fraction of the rent.
From the 1st of Dec 2016, the housing allowance no longer exists.
values:
# This parameter is only defined from the 1st of Jan 2010 to the 3Oth of Nov 2016.
2010-01-01:
value: 0.25
2016-12-01:
value: null
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# This (optional) file defines metadata for the node parameters.benefits in the parameter tree.

description: Social benefits
documentation: |
Government support for the citizens and residents of society.
They may be provided to people of any income level, as with social security,
but usually it is intended to ensure that everyone can meet their basic human needs
such as food and shelter.
(See https://en.wikipedia.org/wiki/Welfare)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: Parenting allowance amount
metadata:
reference: https://law.gov.example/parenting_allowance/amount
unit: currency-EUR
values:
# This parameter is only defined since the 1st of Dec 2015.
2015-12-01:
value: 600.0
metadata:
reference: https://law.gov.example/parenting-allowance/amount/2015-12
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: Parenting allowance income threshold
metadata:
reference: https://law.gov.example/parenting_allowance/income_threshold
unit: currency-EUR
values:
# This parameter is only defined since the 1st of Dec 2015.
2015-12-01:
value: 500.0
metadata:
reference: https://law.gov.example/parenting-allowance/income-threshold/2015-12
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
description: Age of majority (in years)
metadata:
unit: year
values:
# This parameter has last changed on the 1st of Jan 1971.
1945-01-01:
value: 21.0
1971-01-01:
value: 18.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# A parameter can contain utf-8 characters.
description: Age of retirement (in years). In French âge de la retraite (en années).
metadata:
reference: https://fr.wikipedia.org/wiki/Retraite_(économie)
unit: year
values:
2017-01-01:
value: 62.0
1951-07-01:
value: 60.33
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# One Yaml file can contain nested parameters
description: Housing tax
rate:
description: Housing tax due per square meter.
metadata:
unit: currency-EUR/m2
values:
2010-01-01: 10
minimal_amount:
description: Minimal amount due for the housing tax
metadata:
unit: currency-EUR
values:
2010-01-01: 200
documentation: The housing tax, introduced in 2010, is proportional to the surface area of the habitation, with a minimal amount.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
description: Income tax rate
metadata:
unit: /1
values:
2012-01-01:
value: 0.16
2013-01-01:
value: 0.13
2014-01-01:
value: 0.14
2015-01-01:
value: 0.15
# We expect this parameter to change on the 1st of Jan 2016
# Placeholders have no impact on calculations. They are just metadata to indicate that we expect a parameter to change at a certain date.
2016-01-01: expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# The social_security_contribution is calculated with a marginal scale. Marginal scales are represented with a specific structure.
description: Social security contribution tax scale
metadata:
threshold_unit: currency-EUR
rate_unit: /1
brackets:
- rate:
2013-01-01:
value: 0.03
2015-01-01:
value: 0.04
2017-01-01:
value: 0.02
threshold:
2013-01-01:
value: 0.0
- rate:
2013-01-01:
value: 0.1
2015-01-01:
value: 0.12
2017-01-01:
value: 0.06
threshold:
2013-01-01:
value: 12000.0
2014-01-01:
value: 12100.0
2015-01-01:
value: 12200.0
2016-01-01:
value: 12300.0
2017-01-01:
value: 6000.0
- rate:
2017-01-01:
value: 0.12
threshold:
2017-01-01:
value: 12400.0
7 changes: 7 additions & 0 deletions images/rules-as-code/openfisca_rules/reforms/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
This sub-package is used to define reforms.
A reform is a set of modifications to be applied to a reference tax and benefit system to carry out experiments.
See https://openfisca.org/doc/key-concepts/reforms.html
"""
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
This file defines a reform to add a dynamic variable, based on input data.
A reform is a set of modifications to be applied to a reference tax and benefit system to carry out experiments.
See https://openfisca.org/doc/key-concepts/reforms.html
"""

# Import from openfisca-core the Python objects used to code the legislation in OpenFisca
from openfisca_core.periods import MONTH
from openfisca_core.reforms import Reform
from openfisca_core.variables import Variable

# Import the Entities specifically defined for this tax and benefit system
from openfisca_country_template.entities import Person


def create_dynamic_variable(name, **variable):
"""Create new variable dynamically."""
NewVariable = type(name, (Variable,), {
"value_type": variable["value_type"],
"entity": variable["entity"],
"default_value": variable["default_value"],
"definition_period": variable["definition_period"],
"label": variable["label"],
"reference": variable["reference"],
})

return NewVariable


class add_dynamic_variable(Reform):
def apply(self):
"""
Apply reform.
A reform always defines an `apply` method that builds the reformed tax
and benefit system from the reference one.
See https://openfisca.org/doc/coding-the-legislation/reforms.html#writing-a-reform
"""
NewVariable = create_dynamic_variable(
name = "goes_to_school",
value_type = bool,
entity = Person,
default_value = True,
definition_period = MONTH,
label = "The person goes to school (only relevant for children)",
reference = "https://law.gov.example/goes_to_school",
)

self.add_variable(NewVariable)
Loading

0 comments on commit ece51de

Please sign in to comment.