def formula(famille, period, parameters):
        annee = periods.instant(period).year
        annee_n = periods.instant(annee).period('year')
        annee_n1 = annee_n.offset(-1, 'year')

        base_ressource_annuelle_membres_famille = famille.sum(famille.members('base_ressource_annuelle_individu', annee_n1))
        # base_ressource_mensuelle_famille_n1 = famille.sum(
        #     famille('base_ressource_mensuelle_famille', annee_n1, options = [ADD])
        #     )

        return (
             # famille('base_ressource_mensuelle_famille', period.offset(-1, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-2, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-3, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-4, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-5, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-6, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-7, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-8, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-9, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-10, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-11, 'month'))
             + famille('base_ressource_mensuelle_famille', period.offset(-12, 'month'))
            + famille('base_ressource_mensuelle_famille', period.offset(-13, 'month'))
            # base_ressource_mensuelle_famille_n1
            + base_ressource_annuelle_membres_famille
        )
def inflate_parameter_leaf(sub_parameter, base_year, inflator, unit_type = 'unit'):
    """
    Inflate a Parameter leaf according to unit type

    Basic unit type are supposed by default
    Other admissible unit types are threshold_unit and rate_unit
    """

    if isinstance(sub_parameter, Scale):
        if unit_type == 'threshold_unit':
            for bracket in sub_parameter.brackets:
                threshold = bracket.children['threshold']
                inflate_parameter_leaf(threshold, base_year, inflator)
            return
    else:
        # Remove new values for year > base_year
        kept_instants_str = [
            parameter_at_instant.instant_str
            for parameter_at_instant in sub_parameter.values_list
            if periods.instant(parameter_at_instant.instant_str).year <= base_year
            ]
        if not kept_instants_str:
            return

        last_admissible_instant_str = max(kept_instants_str)
        sub_parameter.update(
            start = last_admissible_instant_str,
            value = sub_parameter(last_admissible_instant_str)
            )
        restricted_to_base_year_value_list = [
            parameter_at_instant for parameter_at_instant in sub_parameter.values_list
            if periods.instant(parameter_at_instant.instant_str).year == base_year
            ]
        # When value is changed in the base year
        if restricted_to_base_year_value_list:
            for parameter_at_instant in reversed(restricted_to_base_year_value_list):
                if parameter_at_instant.instant_str.startswith(str(base_year)):
                    value = (
                        parameter_at_instant.value * (1 + inflator)
                        if parameter_at_instant.value is not None
                        else None
                        )
                    sub_parameter.update(
                        start = parameter_at_instant.instant_str.replace(
                            str(base_year), str(base_year + 1)
                            ),
                        value = value,
                        )
        # Or use the value at that instant even when it is defined earlier tahn the base year
        else:
            value = (
                sub_parameter("{}-12-31".format(base_year)) * (1 + inflator)
                if sub_parameter("{}-12-31".format(base_year)) is not None
                else None
                )
            sub_parameter.update(
                start = "{}-01-01".format(base_year + 1),
                value = value
                )
示例#3
0
def inflate_parameter_leaf(sub_parameter,
                           base_year,
                           inflator,
                           unit_type='unit'):
    """
    Inflate a Parameter leaf according to unit type

    Basic unit type are supposed by default
    Other admissible unit types are threshold_unit and rate_unit
    """

    if isinstance(sub_parameter, Scale):
        if unit_type == 'threshold_unit':
            for bracket in sub_parameter.brackets:
                threshold = bracket.children['threshold']
                inflate_parameter_leaf(threshold, base_year, inflator)
            return
    else:
        # Remove new values for year > base_year
        kept_instants_str = [
            parameter_at_instant.instant_str
            for parameter_at_instant in sub_parameter.values_list if
            periods.instant(parameter_at_instant.instant_str).year <= base_year
        ]
        if not kept_instants_str:
            return

        last_admissible_instant_str = max(kept_instants_str)
        sub_parameter.update(start=last_admissible_instant_str,
                             value=sub_parameter(last_admissible_instant_str))
        restricted_to_base_year_value_list = [
            parameter_at_instant
            for parameter_at_instant in sub_parameter.values_list if
            periods.instant(parameter_at_instant.instant_str).year == base_year
        ]
        # When value is changed in the base year
        if restricted_to_base_year_value_list:
            for parameter_at_instant in reversed(
                    restricted_to_base_year_value_list):
                if parameter_at_instant.instant_str.startswith(str(base_year)):
                    value = (parameter_at_instant.value * (1 + inflator) if
                             parameter_at_instant.value is not None else None)
                    sub_parameter.update(
                        start=parameter_at_instant.instant_str.replace(
                            str(base_year), str(base_year + 1)),
                        value=value,
                    )
        # Or use the value at that instant even when it is defined earlier tahn the base year
        else:
            value = (sub_parameter("{}-12-31".format(base_year)) *
                     (1 + inflator) if sub_parameter(
                         "{}-12-31".format(base_year)) is not None else None)
            sub_parameter.update(start="{}-01-01".format(base_year + 1),
                                 value=value)
示例#4
0
    def get_formula(self, period=None):
        """
        Returns the formula used to compute the variable at the given period.

        If no period is given and the variable has several formula, return the oldest formula.

        :returns: Formula used to compute the variable
        :rtype: function
        """

        if not self.formulas:
            return None

        if period is None:
            return self.formulas.peekitem(
                index=0
            )[1]  # peekitem gets the 1st key-value tuple (the oldest start_date and formula). Return the formula.

        if isinstance(period, periods.Period):
            instant = period.start
        else:
            try:
                instant = periods.period(period).start
            except ValueError:
                instant = periods.instant(period)

        if self.end and instant.date > self.end:
            return None

        instant = str(instant)
        for start_date in reversed(self.formulas):
            if start_date <= instant:
                return self.formulas[start_date]

        return None
示例#5
0
def variables_asof(tax_benefit_system, instant, variables_list=[]):
    if isinstance(instant, str):
        instant = periods.instant(instant)
    assert isinstance(instant, periods.Instant)

    if variables_list == []:
        variables_list = tax_benefit_system.variables.keys()

    for variable_name, variable in tax_benefit_system.variables.items():
        if variable_name in variables_list:
            formulas = variable.formulas
            for instant_str in list(formulas.keys()):
                if periods.instant(instant_str) > instant:
                    del formulas[instant_str]

            if variable.end is not None:
                if periods.instant(variable.end) >= instant:
                    variable.end = None
def variables_asof(tax_benefit_system, instant, variables_list = []):
    if isinstance(instant, str):
        instant = periods.instant(instant)
    assert isinstance(instant, periods.Instant)

    if variables_list == []:
        variables_list = tax_benefit_system.variables.keys()

    for variable_name, variable in tax_benefit_system.variables.items():
        if variable_name in variables_list:
            formulas = variable.formulas
            for instant_str in list(formulas.keys()):
                if periods.instant(instant_str) > instant:
                    del formulas[instant_str]

            if variable.end is not None:
                if periods.instant(variable.end) >= instant:
                    variable.end = None
示例#7
0
    def formula(famille, period, parameters):
        annee = periods.instant(period).year
        annee_n = periods.instant(annee).period('year')
        annee_n1 = annee_n.offset(-1, 'year')

        base_ressource_annuelle_membres_famille = famille.sum(
            famille.members('base_ressource_annuelle_individu', annee_n1))
        # base_ressource_mensuelle_famille_n1 = famille.sum(
        #     famille('base_ressource_mensuelle_famille', annee_n1, options = [ADD])
        #     )

        return (
            # famille('base_ressource_mensuelle_famille', period.offset(-1, 'month'))
            +famille('base_ressource_mensuelle_famille',
                     period.offset(-2, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-3, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-4, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-5, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-6, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-7, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-8, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-9, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-10, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-11, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-12, 'month')) +
            famille('base_ressource_mensuelle_famille',
                    period.offset(-13, 'month'))
            # base_ressource_mensuelle_famille_n1
            + base_ressource_annuelle_membres_famille)
示例#8
0
def leaf_asof(sub_parameter, instant):
    kept_instants_str = [
        parameter_at_instant.instant_str
        for parameter_at_instant in sub_parameter.values_list
        if periods.instant(parameter_at_instant.instant_str) <= instant
    ]
    if not kept_instants_str:
        sub_parameter.values_list = []
        return

    last_admissible_instant_str = max(kept_instants_str)
    sub_parameter.update(start=last_admissible_instant_str,
                         value=sub_parameter(last_admissible_instant_str))
    return
def leaf_asof(sub_parameter, instant):
    kept_instants_str = [
        parameter_at_instant.instant_str
        for parameter_at_instant in sub_parameter.values_list
        if periods.instant(parameter_at_instant.instant_str) <= instant
        ]
    if not kept_instants_str:
        sub_parameter.values_list = []
        return

    last_admissible_instant_str = max(kept_instants_str)
    sub_parameter.update(
        start = last_admissible_instant_str,
        value = sub_parameter(last_admissible_instant_str)
        )
    return
示例#10
0
def parameters_asof(parameters, instant):
    if isinstance(instant, str):
        instant = periods.instant(instant)
    assert isinstance(instant, periods.Instant)

    for name, sub_parameter in parameters.children.items():
        if isinstance(sub_parameter, ParameterNode):
            parameters_asof(sub_parameter, instant)
        else:
            if isinstance(sub_parameter, Scale):
                for bracket in sub_parameter.brackets:
                    threshold = bracket.children['threshold']
                    rate = bracket.children['rate']
                    leaf_asof(threshold, instant)
                    leaf_asof(rate, instant)
            else:
                leaf_asof(sub_parameter, instant)
示例#11
0
def test_inflate_scale_with_changing_number_of_brackets():
    """
        Test parameters inflator on a scale parameter when the number of brackets changes

        Use parameters_asof to use the present legislation the future pre-inflated legislation
        Test on the social security contributions tax_scale
    """
    tax_benefit_system = CountryTaxBenefitSystem()
    parameters = tax_benefit_system.parameters
    parameters_asof(
        parameters,
        instant=periods.instant(2016))  # Remove post 2016 legislation changes
    inflate_parameters(parameters, inflator=.3, base_year=2016, last_year=2017)
    for (threshold_2017, threshold_2016) in zip(
            parameters.taxes.social_security_contribution(2017).thresholds,
            parameters.taxes.social_security_contribution(2016).thresholds):
        assert threshold_2017 == threshold_2016 * 1.3, "{} != {}".format(
            threshold_2017, threshold_2016 * 1.3)
def test_inflate_scale_with_changing_number_of_brackets():
    """
        Test parameters inflator on a scale parameter when the number of brackets changes

        Use parameters_asof to use the present legislation the future pre-inflated legislation
        Test on the social security contributions tax_scale
    """
    tax_benefit_system = CountryTaxBenefitSystem()
    parameters = tax_benefit_system.parameters
    parameters_asof(parameters, instant = periods.instant(2016))  # Remove post 2016 legislation changes
    inflate_parameters(parameters, inflator = .3, base_year = 2016, last_year = 2017)
    for (threshold_2017, threshold_2016) in zip(
            parameters.taxes.social_security_contribution(2017).thresholds,
            parameters.taxes.social_security_contribution(2016).thresholds
            ):
        assert threshold_2017 == threshold_2016 * 1.3, "{} != {}".format(
            threshold_2017, threshold_2016 * 1.3
            )
    def get_parameters_at_instant(self, instant):
        """
        Get the parameters of the legislation at a given instant

        :param instant: string of the format 'YYYY-MM-DD' or `openfisca_core.periods.Instant` instance.
        :returns: The parameters of the legislation at a given instant.
        :rtype: :any:`ParameterNodeAtInstant`
        """
        if isinstance(instant, periods.Period):
            instant = instant.start
        elif isinstance(instant, (str, int)):
            instant = periods.instant(instant)
        else:
            assert isinstance(instant, periods.Instant), "Expected an Instant (e.g. Instant((2017, 1, 1)) ). Got: {}.".format(instant)

        parameters_at_instant = self._parameters_at_instant_cache.get(instant)
        if parameters_at_instant is None and self.parameters is not None:
            parameters_at_instant = self.parameters.get_at_instant(str(instant))
            self._parameters_at_instant_cache[instant] = parameters_at_instant
        return parameters_at_instant
示例#14
0
def parameters_asof(parameters, instant):
    if isinstance(instant, str):
        instant = periods.instant(instant)
    assert isinstance(instant, periods.Instant)

    for sub_parameter in parameters.children.values():
        if isinstance(sub_parameter, ParameterNode):
            parameters_asof(sub_parameter, instant)
        else:
            if isinstance(sub_parameter, Scale):
                for bracket in sub_parameter.brackets:
                    threshold = bracket.children['threshold']
                    rate = bracket.children.get('rate')
                    amount = bracket.children.get('amount')
                    leaf_asof(threshold, instant)
                    if rate:
                        leaf_asof(rate, instant)
                    if amount:
                        leaf_asof(amount, instant)
            else:
                leaf_asof(sub_parameter, instant)
示例#15
0
    def get_parameters_at_instant(self, instant):
        """
        Get the parameters of the legislation at a given instant

        :param instant: string of the format 'YYYY-MM-DD' or `openfisca_core.periods.Instant` instance.
        :returns: The parameters of the legislation at a given instant.
        """
        if isinstance(instant, periods.Period):
            instant = instant.start
        elif isinstance(instant, (basestring_type, int)):
            instant = periods.instant(instant)
        else:
            assert isinstance(
                instant, periods.Instant
            ), "Expected an Instant (e.g. Instant((2017, 1, 1)) ). Got: {}.".format(
                instant)

        parameters_at_instant = self._parameters_at_instant_cache.get(instant)
        if parameters_at_instant is None and self.parameters is not None:
            parameters_at_instant = self.parameters.get_at_instant(
                str(instant))
            self._parameters_at_instant_cache[instant] = parameters_at_instant
        return parameters_at_instant
    def get_parameters_at_instant(self, instant):
        """
        Get the parameters of the legislation at a given instant

        :param instant: :obj:`str` of the format 'YYYY-MM-DD' or :class:`.Instant` instance.
        :returns: The parameters of the legislation at a given instant.
        :rtype: :class:`.ParameterNodeAtInstant`
        """
        if isinstance(instant, Period):
            instant = instant.start
        elif isinstance(instant, (str, int)):
            instant = periods.instant(instant)
        else:
            assert isinstance(
                instant, Instant
            ), "Expected an Instant (e.g. Instant((2017, 1, 1)) ). Got: {}.".format(
                instant)

        parameters_at_instant = self._parameters_at_instant_cache.get(instant)
        if parameters_at_instant is None and self.parameters is not None:
            parameters_at_instant = self.parameters.get_at_instant(
                str(instant))
            self._parameters_at_instant_cache[instant] = parameters_at_instant
        return parameters_at_instant
示例#17
0
def instant():
    return periods.instant("2018")
示例#18
0
def generateSituation(file):
    parser = etree.XMLParser(remove_blank_text=True)
    tree = etree.parse(file, parser)

    dateDemande = periods.instant(
        tree.find('//ns1:dateCreationDemande', namespaces=namespaces).text)
    moisDemande = dateDemande.period('month')
    moisDemandeKey = str(moisDemande)

    last4Years = [
        moisDemande.offset(offset, 'month')
        for offset in range(-12 * 4 + 1, 1)
    ]

    def duplicateMonthly(value):
        return {str(m): value for m in last4Years}

    def expand(entity, additions={}):
        result = {field: duplicateMonthly(entity[field]) for field in entity}

        for k in additions:
            result[k] = additions[k]

        return result

    details = tree.find('//ns1:personnePhysique', namespaces=namespaces)
    famille = {
        'aide_logement': 0,  # Met à zéro l'aide au logement perçu par défaut
    }
    sourceDemandeur = details.find('ns1:demandeur', namespaces=namespaces)
    demandeur = processIndividu(sourceDemandeur, famille)

    rfr = getRFR(
        sourceDemandeur.find('ns1:revenuFiscal', namespaces=namespaces))

    situation = {
        'individus': {
            'demandeur': expand(demandeur)
        },
        'familles': {
            '_': expand(famille, {'parents': ['demandeur']})
        },
        'foyers_fiscaux': {
            '_': {
                'declarants': ['demandeur'],
                'rfr': rfr,
            }
        },
        'menages': {
            '_': {
                'personne_de_reference': ['demandeur'],
                'depcom': duplicateMonthly('75113'),
                'loyer': duplicateMonthly(800),
                'statut_occupation_logement':
                duplicateMonthly('locataire_hlm'),
            }
        }
    }

    situation['familles']['_']['aide_logement'][moisDemandeKey] = None
    print(json.dumps(situation, indent=2))
    return situation
def check_max_instant_leaf(sub_parameter, instant):
    for parameter_at_instant in sub_parameter.values_list:
        assert periods.instant(parameter_at_instant.instant_str) <= instant, "Error for {}: \n {}".format(
            sub_parameter.name, sub_parameter.values_list)
def test_variables_as_of():
    tax_benefit_system = CountryTaxBenefitSystem()
    instant = periods.instant("2015-12-31")
    variables_asof(tax_benefit_system, instant)
def test_parameters_as_of():
    tax_benefit_system = CountryTaxBenefitSystem()
    parameters = tax_benefit_system.parameters
    instant = periods.instant("2012-12-31")
    parameters_asof(parameters, instant)
    check_max_instant(parameters, instant)
示例#22
0
def api1_parameters(req):
    ctx = contexts.Ctx(req)
    headers = wsgihelpers.handle_cross_origin_resource_sharing(ctx)

    assert req.method == 'GET', req.method
    params = req.GET
    inputs = dict(
        instant = params.get('instant'),
        names = params.getall('name'),
        )

    parameters_name = [
        parameter_json['name']
        for parameter_json in model.parameters_json_cache
        ]

    data, errors = conv.pipe(
        conv.struct(
            dict(
                instant = conv.pipe(
                    conv.empty_to_none,
                    conv.test_isinstance(basestring),
                    conv.function(lambda str: periods.instant(str)),
                    ),
                names = conv.pipe(
                    conv.uniform_sequence(
                        conv.pipe(
                            conv.empty_to_none,
                            conv.test_in(parameters_name, error = u'Parameter does not exist'),
                            ),
                        drop_none_items = True,
                        ),
                    conv.empty_to_none,
                    ),
                ),
            default = 'drop',
            ),
        )(inputs, state = ctx)

    if errors is not None:
        return wsgihelpers.respond_json(ctx,
            collections.OrderedDict(sorted(dict(
                apiVersion = 1,
                error = collections.OrderedDict(sorted(dict(
                    code = 400,  # Bad Request
                    errors = [conv.jsonify_value(errors)],
                    message = ctx._(u'Bad parameters in request'),
                    ).iteritems())),
                method = req.script_name,
                params = inputs,
                url = req.url.decode('utf-8'),
                ).iteritems())),
            headers = headers,
            )

    tax_benefit_system = model.tax_benefit_system

    if data['instant'] is None:
        if data['names'] is None:
            parameters_json = model.parameters_json_cache
        else:
            parameters_json = [
                parameter_json
                for parameter_json in model.parameters_json_cache
                if parameter_json['name'] in data['names']
                ]
    else:
        instant = data['instant']
        parameters_json = []
        dated_legislation_json = legislations.generate_dated_legislation_json(
            tax_benefit_system.legislation_json,
            instant,
            )
        for name in data['names']:
            name_fragments = name.split('.')
            parameter_json = dated_legislation_json
            for name_fragment in name_fragments:
                parameter_json = parameter_json['children'][name_fragment]
            parameter_json['name'] = name
            parameter_json_in_cache = [
                parameter_json1
                for parameter_json1 in model.parameters_json_cache
                if parameter_json1['name'] == name
                ][0]
            parameter_json['description'] = parameter_json_in_cache['description']
            parameters_json.append(parameter_json)

    return wsgihelpers.respond_json(ctx,
        collections.OrderedDict(sorted(dict(
            apiVersion = 1,
            country_package_git_head_sha = environment.country_package_git_head_sha,
            currency = tax_benefit_system.CURRENCY,
            method = req.script_name,
            parameters = parameters_json,
            parameters_file_path = model.parameters_file_path,
            url = req.url.decode('utf-8'),
            ).iteritems())),
        headers = headers,
        )
示例#23
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(
        conv.check(
            conv.struct(
                {
                    'app_conf':
                    conv.set_value(app_conf),
                    'app_dir':
                    conv.set_value(app_dir),
                    'country_package':
                    conv.pipe(
                        conv.make_input_to_slug(separator=u'_'),
                        conv.test_in((
                            u'openfisca_france',
                            u'openfisca_tunisia',
                            u'openfisca_tunisia_pension',
                        )),
                        conv.not_none,
                    ),
                    'debug':
                    conv.pipe(conv.guess_bool, conv.default(False)),
                    'global_conf':
                    conv.set_value(global_conf),
                    'i18n_dir':
                    conv.default(os.path.join(app_dir, 'i18n')),
                    'load_alert':
                    conv.pipe(conv.guess_bool, conv.default(False)),
                    'log_level':
                    conv.pipe(
                        conv.default('WARNING'),
                        conv.function(lambda log_level: getattr(
                            logging, log_level.upper())),
                    ),
                    'package_name':
                    conv.default('openfisca-web-api'),
                    'realm':
                    conv.default(u'OpenFisca Web API'),
                    'reforms':
                    conv.ini_str_to_list,  # Another validation is done below.
                },
                default='drop',
            ))(conf))

    # Configure logging.
    logging.basicConfig(level=conf['log_level'], stream=sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get(
            'error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get(
            'error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Initialize tax-benefit system.

    country_package = importlib.import_module(conf['country_package'])
    CountryTaxBenefitSystem = country_package.init_country()

    class Scenario(CountryTaxBenefitSystem.Scenario):
        instance_and_error_couple_cache = {} if conf[
            'debug'] else weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def make_json_to_cached_or_new_instance(cls, ctx, repair,
                                                tax_benefit_system):
            def json_to_cached_or_new_instance(value, state=None):
                key = (unicode(ctx.lang), unicode(value), repair,
                       tax_benefit_system)
                instance_and_error_couple = cls.instance_and_error_couple_cache.get(
                    key)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(
                        repair, tax_benefit_system)(value,
                                                    state=state
                                                    or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_cache[key] = ValueAndError(
                        instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    class TaxBenefitSystem(CountryTaxBenefitSystem):
        pass

    TaxBenefitSystem.Scenario = Scenario

    model.TaxBenefitSystem = TaxBenefitSystem
    model.tax_benefit_system = tax_benefit_system = TaxBenefitSystem()

    tax_benefit_system.prefill_cache()

    # Initialize reforms
    build_reform_functions = conv.check(
        conv.uniform_sequence(conv.module_and_function_str_to_function, ))(
            conf['reforms'])
    if build_reform_functions is not None:
        api_reforms = [
            build_reform(tax_benefit_system)
            for build_reform in build_reform_functions
        ]
        api_reforms = conv.check(
            conv.uniform_sequence(conv.test_isinstance(
                reforms.AbstractReform)))(api_reforms)
        model.build_reform_function_by_key = {
            reform.key: build_reform
            for build_reform, reform in zip(build_reform_functions,
                                            api_reforms)
        }
        model.reform_by_full_key = {
            reform.full_key: reform
            for reform in api_reforms
        }

    # Cache default decomposition.
    if hasattr(tax_benefit_system, 'DEFAULT_DECOMP_FILE'):
        model.get_cached_or_new_decomposition_json(tax_benefit_system)

    # Compute and cache compact legislation for each first day of month since at least 2 legal years.
    today = periods.instant(datetime.date.today())
    first_day_of_year = today.offset('first-of', 'year')
    instant = first_day_of_year.offset(-2, 'year')
    two_years_later = first_day_of_year.offset(2, 'year')
    while instant < two_years_later:
        tax_benefit_system.get_compact_legislation(instant)
        instant = instant.offset(1, 'month')

    # Initialize lib2to3-based input variables extractor.
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(
            tax_benefit_system)

    global country_package_dir_path
    country_package_dir_path = pkg_resources.get_distribution(
        conf['country_package']).location

    # Store Git last commit SHA
    global git_head_sha
    git_head_sha = get_git_head_sha()
    global country_package_git_head_sha
    country_package_git_head_sha = get_git_head_sha(
        cwd=country_package.__path__[0])

    # Cache legislation JSON with references to original XML
    legislation_json_with_references_to_xml = tax_benefit_system.get_legislation_json(
        with_source_file_infos=True)
    parameters_json = []
    walk_legislation_json(
        legislation_json_with_references_to_xml,
        descriptions=[],
        parameters_json=parameters_json,
        path_fragments=[],
    )
    model.parameters_json_cache = parameters_json

    # Initialize multiprocessing and load_alert
    if conf['load_alert']:
        global cpu_count
        cpu_count = multiprocessing.cpu_count()
示例#24
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            'app_conf': conv.set_value(app_conf),
            'app_dir': conv.set_value(app_dir),
            'country_package': conv.pipe(
                conv.make_input_to_slug(separator = u'_'),
                conv.test_in((
                    u'openfisca_france',
                    u'openfisca_tunisia',
                    u'openfisca_tunisia_pension',
                    )),
                conv.not_none,
                ),
            'debug': conv.pipe(conv.guess_bool, conv.default(False)),
            'global_conf': conv.set_value(global_conf),
            'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            'load_alert': conv.pipe(conv.guess_bool, conv.default(False)),
            'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            'package_name': conv.default('openfisca-web-api'),
            'realm': conv.default(u'OpenFisca Web API'),
            'reforms': conv.ini_str_to_list,  # Another validation is done below.
            'extensions': conv.ini_str_to_list,
            },
        default = 'drop',
        ))(conf))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')
        errorware['show_exceptions_in_wsgi_errors'] = conf.get('show_exceptions_in_wsgi_errors', True)

    # Initialize tax-benefit system.
    country_package = importlib.import_module(conf['country_package'])
    tax_benefit_system = country_package.CountryTaxBenefitSystem()

    extensions = conf['extensions']
    if extensions is not None:
        for extension in extensions:
            tax_benefit_system.load_extension(extension)

    class Scenario(tax_benefit_system.Scenario):
        instance_and_error_couple_cache = {} if conf['debug'] else weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def make_json_to_cached_or_new_instance(cls, ctx, repair, tax_benefit_system):
            def json_to_cached_or_new_instance(value, state = None):
                key = (unicode(ctx.lang), unicode(value), repair, tax_benefit_system)
                instance_and_error_couple = cls.instance_and_error_couple_cache.get(key)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(repair, tax_benefit_system)(
                        value, state = state or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_cache[key] = ValueAndError(instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    tax_benefit_system.Scenario = Scenario

    model.tax_benefit_system = tax_benefit_system

    log.debug(u'Pre-fill tax and benefit system cache.')
    tax_benefit_system.prefill_cache()

    log.debug(u'Initialize reforms.')
    reforms = conv.check(
        conv.uniform_sequence(
            conv.module_and_function_str_to_function,
            )
        )(conf['reforms'])
    model.reforms = {}
    model.reformed_tbs = {}
    if reforms is not None:
        for reform in reforms:
            reformed_tbs = reform(tax_benefit_system)
            key = reformed_tbs.key
            full_key = reformed_tbs.full_key
            model.reforms[key] = reform
            model.reformed_tbs[full_key] = reformed_tbs

    log.debug(u'Cache default decomposition.')
    if tax_benefit_system.decomposition_file_path is not None:
        # Ignore the returned value, because we just want to pre-compute the cache.
        model.get_cached_or_new_decomposition_json(tax_benefit_system)

    log.debug(u'Initialize lib2to3-based input variables extractor.')
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(tax_benefit_system)

    global country_package_dir_path
    # Using pkg_resources.get_distribution(conf["country_package"]).location
    # returns a wrong path in virtualenvs (<venv>/lib versus <venv>/local/lib).
    country_package_dir_path = country_package.__path__[0]

    global api_package_version
    api_package_version = pkg_resources.get_distribution('openfisca_web_api').version

    global country_package_version
    country_package_version = pkg_resources.get_distribution(conf["country_package"]).version

    log.debug(u'Cache legislation JSON with references to original XML.')
    legislation_json = tax_benefit_system.get_legislation(with_source_file_infos=True)
    parameters_json = []
    walk_legislation_json(
        legislation_json,
        descriptions = [],
        parameters_json = parameters_json,
        path_fragments = [],
        )
    model.parameters_json_cache = parameters_json

    if not conf['debug']:
        # Do this after tax_benefit_system.get_legislation(with_source_file_infos=True).
        log.debug(u'Compute and cache compact legislation for each first day of month since at least 2 legal years.')
        today = periods.instant(datetime.date.today())
        first_day_of_year = today.offset('first-of', 'year')
        instant = first_day_of_year.offset(-2, 'year')
        two_years_later = first_day_of_year.offset(2, 'year')
        while instant < two_years_later:
            tax_benefit_system.get_compact_legislation(instant)
            instant = instant.offset(1, 'month')

    # Initialize multiprocessing and load_alert
    if conf['load_alert']:
        global cpu_count
        cpu_count = multiprocessing.cpu_count()
示例#25
0
def test_parameters_as_of():
    tax_benefit_system = CountryTaxBenefitSystem()
    parameters = tax_benefit_system.parameters
    instant = periods.instant("2012-12-31")
    parameters_asof(parameters, instant)
    check_max_instant(parameters, instant)
示例#26
0
 def __init__(self, tbs: FranceTaxBenefitSystem, payload: dict,
              period: str) -> None:
     self.payload = payload.get("impot_revenu", {})
     self.instant = periods.instant(period)
     self.period = periods.period("year:1900:200")
     super().__init__(tbs)
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf = openfisca_web_api.conf  # Empty dictionary
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            'app_conf': conv.set_value(app_conf),
            'app_dir': conv.set_value(app_dir),
            'country_package': conv.pipe(
                conv.make_input_to_slug(separator = u'_'),
                conv.test_in((
                    u'openfisca_france',
                    u'openfisca_tunisia',
                    u'openfisca_tunisia_pension',
                    )),
                conv.not_none,
                ),
            'debug': conv.pipe(conv.guess_bool, conv.default(False)),
            'global_conf': conv.set_value(global_conf),
            'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            'load_alert': conv.pipe(conv.guess_bool, conv.default(False)),
            'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            'package_name': conv.default('openfisca-web-api'),
            'realm': conv.default(u'OpenFisca Web API'),
            'reforms': conv.ini_items_list_to_ordered_dict,  # Another validation is done below.
            },
        default = 'drop',
        ))(conf))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Initialize tax-benefit system.

    country_package = importlib.import_module(conf['country_package'])
    CountryTaxBenefitSystem = country_package.init_country()

    class Scenario(CountryTaxBenefitSystem.Scenario):
        instance_and_error_couple_by_json_str_cache = weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def cached_or_new(cls):
            return conv.check(cls.json_to_cached_or_new_instance)(None)

        @classmethod
        def make_json_to_cached_or_new_instance(cls, repair, tax_benefit_system):
            def json_to_cached_or_new_instance(value, state = None):
                json_str = json.dumps(value, separators = (',', ':')) if value is not None else None
                instance_and_error_couple = cls.instance_and_error_couple_by_json_str_cache.get(json_str)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(repair, tax_benefit_system)(
                        value, state = state or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_by_json_str_cache[json_str] = ValueAndError(
                        instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    class TaxBenefitSystem(CountryTaxBenefitSystem):
        pass
    TaxBenefitSystem.Scenario = Scenario

    model.TaxBenefitSystem = TaxBenefitSystem
    model.tax_benefit_system = tax_benefit_system = TaxBenefitSystem()

    tax_benefit_system.prefill_cache()

    # Cache default decomposition.
    model.get_cached_or_new_decomposition_json(tax_benefit_system)

    # Compute and cache compact legislation for each first day of month since at least 2 legal years.
    today = periods.instant(datetime.date.today())
    first_day_of_year = today.offset('first-of', 'year')
    instant = first_day_of_year.offset(-2, 'year')
    two_years_later = first_day_of_year.offset(2, 'year')
    while instant < two_years_later:
        tax_benefit_system.get_compact_legislation(instant)
        instant = instant.offset(1, 'month')

    # Initialize lib2to3-based input variables extractor.
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(tax_benefit_system)

    # Store Git last commit SHA
    global last_commit_sha
    last_commit_sha = get_git_last_commit_sha()

    # Load reform modules and store build_reform functions.
    model.build_reform_function_by_key = build_reform_function_by_key = conv.check(
        conv.uniform_mapping(
            conv.noop,
            conv.module_function_str_to_function,
            )(conf['reforms'])
        )
    # Check that each reform builds and cache instances. Must not be used with composed reforms.
    model.reform_by_key = conv.check(
        conv.uniform_mapping(
            conv.noop,
            conv.pipe(
                conv.function(lambda build_reform: build_reform(tax_benefit_system)),
                conv.test_isinstance(reforms.AbstractReform),
                ),
            )(build_reform_function_by_key)
        )
示例#28
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            'app_conf': conv.set_value(app_conf),
            'app_dir': conv.set_value(app_dir),
            'country_package': conv.pipe(
                conv.make_input_to_slug(separator = u'_'),
                conv.test_in((
                    u'openfisca_france',
                    u'openfisca_tunisia',
                    u'openfisca_tunisia_pension',
                    )),
                conv.not_none,
                ),
            'debug': conv.pipe(conv.guess_bool, conv.default(False)),
            'global_conf': conv.set_value(global_conf),
            'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            'load_alert': conv.pipe(conv.guess_bool, conv.default(False)),
            'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            'package_name': conv.default('openfisca-web-api'),
            'realm': conv.default(u'OpenFisca Web API'),
            'reforms': conv.ini_str_to_list,  # Another validation is done below.
            },
        default = 'drop',
        ))(conf))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Initialize tax-benefit system.

    country_package = importlib.import_module(conf['country_package'])
    CountryTaxBenefitSystem = country_package.init_country()

    class Scenario(CountryTaxBenefitSystem.Scenario):
        instance_and_error_couple_cache = {} if conf['debug'] else weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def make_json_to_cached_or_new_instance(cls, ctx, repair, tax_benefit_system):
            def json_to_cached_or_new_instance(value, state = None):
                key = (unicode(ctx.lang), unicode(value), repair, tax_benefit_system)
                instance_and_error_couple = cls.instance_and_error_couple_cache.get(key)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(repair, tax_benefit_system)(
                        value, state = state or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_cache[key] = ValueAndError(instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    class TaxBenefitSystem(CountryTaxBenefitSystem):
        pass
    TaxBenefitSystem.Scenario = Scenario

    model.TaxBenefitSystem = TaxBenefitSystem
    model.tax_benefit_system = tax_benefit_system = TaxBenefitSystem()

    tax_benefit_system.prefill_cache()

    # Initialize reforms
    build_reform_functions = conv.check(
        conv.uniform_sequence(
            conv.module_and_function_str_to_function,
            )
        )(conf['reforms'])
    if build_reform_functions is not None:
        api_reforms = [
            build_reform(tax_benefit_system)
            for build_reform in build_reform_functions
            ]
        api_reforms = conv.check(
            conv.uniform_sequence(conv.test_isinstance(reforms.AbstractReform))
            )(api_reforms)
        model.build_reform_function_by_key = {
            reform.key: build_reform
            for build_reform, reform in zip(build_reform_functions, api_reforms)
            }
        model.reform_by_full_key = {
            reform.full_key: reform
            for reform in api_reforms
            }

    # Cache default decomposition.
    if hasattr(tax_benefit_system, 'DEFAULT_DECOMP_FILE'):
        model.get_cached_or_new_decomposition_json(tax_benefit_system)

    # Compute and cache compact legislation for each first day of month since at least 2 legal years.
    today = periods.instant(datetime.date.today())
    first_day_of_year = today.offset('first-of', 'year')
    instant = first_day_of_year.offset(-2, 'year')
    two_years_later = first_day_of_year.offset(2, 'year')
    while instant < two_years_later:
        tax_benefit_system.get_compact_legislation(instant)
        instant = instant.offset(1, 'month')

    # Initialize lib2to3-based input variables extractor.
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(tax_benefit_system)

    global country_package_dir_path
    country_package_dir_path = pkg_resources.get_distribution(conf['country_package']).location

    # Store Git last commit SHA
    global git_head_sha
    git_head_sha = get_git_head_sha()
    global country_package_git_head_sha
    country_package_git_head_sha = get_git_head_sha(cwd = country_package.__path__[0])

    # Cache legislation JSON with references to original XML
    legislation_json_with_references_to_xml = tax_benefit_system.get_legislation_json(with_source_file_infos = True)
    parameters_json = []
    walk_legislation_json(
        legislation_json_with_references_to_xml,
        descriptions = [],
        parameters_json = parameters_json,
        path_fragments = [],
        )
    model.parameters_json_cache = parameters_json

    # Initialize multiprocessing and load_alert
    if conf['load_alert']:
        global cpu_count
        cpu_count = multiprocessing.cpu_count()
示例#29
0
 def get_at_instant(self, instant):
     instant = str(periods.instant(instant))
     return self._get_at_instant(instant)
示例#30
0
def test_variables_as_of():
    tax_benefit_system = CountryTaxBenefitSystem()
    instant = periods.instant("2015-12-31")
    variables_asof(tax_benefit_system, instant)
示例#31
0
 def get_at_instant(self, instant):
     instant = str(periods.instant(instant))
     return self._get_at_instant(instant)
示例#32
0
def api1_parameters(req):
    ctx = contexts.Ctx(req)
    headers = wsgihelpers.handle_cross_origin_resource_sharing(ctx)

    assert req.method == 'GET', req.method
    params = req.GET
    inputs = dict(
        instant=params.get('instant'),
        names=params.getall('name'),
    )

    parameters_name = [
        parameter_json['name']
        for parameter_json in model.parameters_json_cache
    ]

    data, errors = conv.pipe(
        conv.struct(
            dict(
                instant=conv.pipe(
                    conv.empty_to_none,
                    conv.test_isinstance(basestring),
                    conv.function(lambda str: periods.instant(str)),
                ),
                names=conv.pipe(
                    conv.uniform_sequence(
                        conv.pipe(
                            conv.empty_to_none,
                            conv.test_in(parameters_name,
                                         error=u'Parameter does not exist'),
                        ),
                        drop_none_items=True,
                    ),
                    conv.empty_to_none,
                ),
            ),
            default='drop',
        ), )(inputs, state=ctx)

    if errors is not None:
        return wsgihelpers.respond_json(
            ctx,
            collections.OrderedDict(
                sorted(
                    dict(
                        apiVersion=1,
                        error=collections.OrderedDict(
                            sorted(
                                dict(
                                    code=400,  # Bad Request
                                    errors=[conv.jsonify_value(errors)],
                                    message=ctx._(
                                        u'Bad parameters in request'),
                                ).iteritems())),
                        method=req.script_name,
                        params=inputs,
                        url=req.url.decode('utf-8'),
                    ).iteritems())),
            headers=headers,
        )

    tax_benefit_system = model.tax_benefit_system

    if data['instant'] is None:
        if data['names'] is None:
            parameters_json = model.parameters_json_cache
        else:
            parameters_json = [
                parameter_json
                for parameter_json in model.parameters_json_cache
                if parameter_json['name'] in data['names']
            ]
    else:
        instant = data['instant']
        parameters_json = []
        dated_legislation_json = legislations.generate_dated_legislation_json(
            tax_benefit_system.get_legislation(),
            instant,
        )
        for name in data['names']:
            name_fragments = name.split('.')
            parameter_json = dated_legislation_json
            for name_fragment in name_fragments:
                parameter_json = parameter_json['children'][name_fragment]
            parameter_json['name'] = name
            parameter_json_in_cache = [
                parameter_json1
                for parameter_json1 in model.parameters_json_cache
                if parameter_json1['name'] == name
            ][0]
            parameter_json['description'] = parameter_json_in_cache[
                'description']
            parameters_json.append(parameter_json)

    response_dict = dict(
        apiVersion=1,
        country_package_name=conf['country_package'],
        country_package_version=environment.country_package_version,
        method=req.script_name,
        parameters=parameters_json,
        url=req.url.decode('utf-8'),
    )
    if hasattr(tax_benefit_system, 'CURRENCY'):
        response_dict['currency'] = tax_benefit_system.CURRENCY
    return wsgihelpers.respond_json(
        ctx,
        collections.OrderedDict(sorted(response_dict.iteritems())),
        headers=headers,
    )
示例#33
0
def check_max_instant_leaf(sub_parameter, instant):
    for parameter_at_instant in sub_parameter.values_list:
        assert periods.instant(parameter_at_instant.instant_str
                               ) <= instant, "Error for {}: \n {}".format(
                                   sub_parameter.name,
                                   sub_parameter.values_list)