Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make parameters node accessible through the Web API #694

Merged
merged 11 commits into from
Aug 3, 2018
Merged

Conversation

fpagnoux
Copy link
Member

@fpagnoux fpagnoux commented Jul 24, 2018

Fixes #678 (See discussions there about route spec)

  • Use / rather than . in the path to access a parameter:

    • For instance /parameter/benefits.basic_income becomes /parameter/benefits/basic_income
    • Using . is for now still supported, but is considered deprecated and will be turned to a 301 redirection in the next major version.
  • Expose parameters metadata and source in the Web API and:

For instance, /parameter/benefits/basic_income contains:

{
  "description": "Amount of the basic income",
  "id": "benefits.basic_income",
  "metadata": {
    "reference": "https://law.gov.example/basic-income/amount",
    "unit": "currency-EUR"
  },
  "source": "https://github.com/openfisca/country-template/blob/3.2.2/openfisca_country_template/parameters/benefits/basic_income.yaml",
  "values": {
    "2015-12-01": 600.0
  }
}
  • Expose parameters nodes in the Web API
    • For instance, /parameter/benefits now exists and contains:
{
  "description": "Social benefits",
  "id": "benefits",
  "source": "https://github.com/openfisca/country-template/blob/3.2.2/openfisca_country_template/parameters/benefits",
  "subparams": {
    "basic_income": {
      "description": "Amount of the basic income"
    },
    "housing_allowance": {
      "description": "Housing allowance amount (as a fraction of the rent)"
    }
  }
}

@fpagnoux
Copy link
Member Author

Anyone for a review? @sandcha @maukoquiroga @Anna-Livia

@fpagnoux
Copy link
Member Author

fpagnoux commented Aug 1, 2018

Question from @sandcha from slack (freely translated):

Isn't there some kind of inconsistency to expose nodes under parameter/ and not parameters/, while they represent a group of parameters and not a single parameter.

Yep, I thought about that aspect too. The distinction between parameters/ and parameter/ doesn't seem to be as clear now that the Web API expose nodes and reflects the tree structure of the parameters.

Exposing leafs under /parameter and nodes under /parameters would be a pain though. I can't know in advance if /benefits/basic_income is a leaf or a node, and I don't want to have to send two requests to figure it out.

The way I'd see the two routes is the following:

  • /parameter is a parametric route to explore the parameter graph. It exposes each nodes and leafs.
  • /parameters is a single "directory" route that exposes, in a flatten structure, basic information about all nodes and leafs.

I'm not fully satisfied with that, but I can't think of something better.

@MattiSG any light on the matter?

@MattiSG
Copy link
Member

MattiSG commented Aug 2, 2018

Bluntly because I'm short on time: I see a stable point in renaming /parameter to /parameters, using it as the single way to explore parameters, keeping plural even for accessing a single resource (authority argument 1, 2, 3), and renaming the current /parameters to something else, that would quite likely offer an overview of both parameters and variables in a single endpoint to reflect its only known use case (the legislation explorer).

@fpagnoux
Copy link
Member Author

fpagnoux commented Aug 2, 2018

/overview 😄 ?

```

* Expose parameters nodes in the Web API
- For instance, `/parameter/benefits` now exists and contains:
Copy link
Collaborator

@sandcha sandcha Aug 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Already said above) Shouldn't it be /parameters for a node as it's not a parameter? 🤔

if parameter is None:
# Try legacy route
parameter_new_id = parameter_id.replace('.', '/')
parameter = data['parameters'].get(parameter_new_id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look for the parameter only when parameter_new_id differs from parameter_id to avoid looking into all parameters in that case (+2000 parameters in french model for example)?

Copy link
Member Author

@fpagnoux fpagnoux Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not looking into all parameters. The get method of a dictionary has a O(1) average complexity as it uses hashes.

@@ -1,9 +0,0 @@
# -*- coding: utf-8 -*-
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And delete tests/web_api/basic_case/ now empty directory?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Git only tracks files, not directory. If the directory is empty, it's not tracked by Git. So the directory you see on your machine is only local 🙂 .

assert_equal(parameter['values'], {u'2016-12-01': None, u'2010-01-01': 0.25})


def test_bareme():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to test_scale?

'/parameter/with%20url%20encoding': NOT_FOUND,
'/parameter/taxes.income_tax_rate/': OK,
'/parameter/taxes.income_tax_rate/too-much-nesting': NOT_FOUND,
'/parameter//taxes.income_tax_rate/': NOT_FOUND,
Copy link
Collaborator

@sandcha sandcha Aug 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to/Add '/parameter//taxes/income_tax_rate/': NOT_FOUND, ?

}
```

* Expose parameters nodes in the Web API
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicit that it exposes 1 level of depth only?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK (see node below)

@@ -3,12 +3,12 @@
from openfisca_core.parameters import Parameter, ParameterNode, Scale


def transform_values_history(values_history):
values_history_transformed = {}
def build_api_values_history(values_history):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

def walk_node(node, parameters, path_fragments):
def build_source_url(absolute_file_path, country_package_metadata):
relative_path = absolute_file_path.replace(country_package_metadata['location'], '')
return u'{}/blob/{}{}'.format(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use tree url rather than blob?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think tree is for directories, and blob for files, so

  • either we detect whether the path is a file or a tree, and adjust the URL accordingly
  • or we just let GitHub redirect us when relevant, which is pretty transparent

I'm more in favor of 2.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in favour of 2.
I missed something in the definition of blob-jects. 😬'



def walk_node(node, parameters, path_fragments):
def build_source_url(absolute_file_path, country_package_metadata):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For taxes/income_tax_rate.yaml parameter, we get "source": "https://github.com/openfisca/openfisca-country-template/blob/3.2.2/openfisca_country_template/parameters/taxes/income_tax_rate.yaml" that leads to 404 error. Fix this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


```JSON
{
"description": "Social benefits",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicit that a node might have metadata? 🤔

@fpagnoux
Copy link
Member Author

fpagnoux commented Aug 2, 2018

Bluntly because I'm short on time: I see a stable point in renaming /parameter to /parameters, using it as the single way to explore parameters, keeping plural even for accessing a single resource (authority argument 1, 2, 3), and renaming the current /parameters to something else, that would quite likely offer an overview of both parameters and variables in a single endpoint to reflect its only known use case (the legislation explorer).

I agree with the target, but I'm wondering what would be a good strategy to go towards that while

I think the most straight-forward strategy would be to

  • expose the nodes under /parameter as proposed by this PR
  • rename it to /parameters in v25 with the other changes

As much as it doesn't feel entirely satisfying to extend a route to rename it 2 months later, I think it won't be that bad for users, as they'll have to adapt their /parameter calls anyway.

@fpagnoux fpagnoux requested a review from sandcha August 2, 2018 20:27
@fpagnoux fpagnoux merged commit ae9ffdb into master Aug 3, 2018
@fpagnoux fpagnoux deleted the expose-nodes branch August 3, 2018 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants