-
Notifications
You must be signed in to change notification settings - Fork 76
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
Create a simple computation endpoint #528
Conversation
d781d49
to
370825d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for all of this work !
openfisca_core/simulations.py
Outdated
@@ -151,7 +198,7 @@ def get_array(self, column_name, period): | |||
caller_input_variables_infos = calling_frame['input_variables_infos'] | |||
if variable_infos not in caller_input_variables_infos: | |||
caller_input_variables_infos.append(variable_infos) | |||
return self.get_or_new_holder(column_name).get_array(period) | |||
return self.get_variable_entity(column_name).get_array(period).get_holder(column_name).get_array(period) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je ne comprends pas très bien cet enchainement d'objets. C'est l'array qui est dans le holder de l'array de la variable ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Il y a clairement un get_array
de trop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Et ce n'était pas la seule erreur de regexp ^^
If the response body doesn't show in case of error in Swagger UI, it's not our fault. Upgrading Swagger UI may partially fix the problem in the legislation explorer. |
To be done:
Headers cannot be defined once for several responses:
|
CHANGELOG.md
Outdated
- Deprecate `simulation.holder_by_name`, `simulation.get_holder`, `get_or_new_holder` | ||
- These functionalities are now provided by `entity.get_holder(name)` | ||
|
||
- Deprecate constructor `Holder(simulation, column` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: missing )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
('{"a" : "x", "b"}', BAD_REQUEST, 'error', 'Invalid JSON'), | ||
('["An", "array"]', BAD_REQUEST, 'error', 'Invalid type'), | ||
('{"persons": {}}', BAD_REQUEST, 'persons', 'At least one person'), | ||
('{"persons": {"bob": {}}, "unknown_entity": {}}', BAD_REQUEST, 'unknown_entity', 'entity is not defined',), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BAD_REQUEST or NOT_FOUND ? What's the difference between an unknown entity and an unknown variable for a user ? Both come from openfisca world. NOT_FOUND for both ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During the workshop on the API, we agreed to return a 400
in the case of an unexpected entity.
The main difference is that:
- Unexpected entities rarely happen
- Unexpected variables happen more often, for instance when the user requests a deprecated or renamed variable
We just want a specific error code for the last case, so that we can easily detect it when it happens.
CHANGELOG.md
Outdated
- For instance `Simulation(simulation_json = {"persons": {...}, "households": {...}}, tax_benefit_system = tax_benefit_system)` | ||
|
||
- Allows entities to be built from a JSON using their constructor | ||
- For instance `Household(simulation, {"first_household": {...}})` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add entities_json = {"first_household": {...}}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A keyword argument is not needed in this case, as entities_json
is the second argument.
The idea is:
- There was a
Household(simulation)
constructor - Now there is also a
Household(simulation, entities_json)
constructor
openfisca_core/simulations.py
Outdated
type_map = { | ||
dict: "Object", | ||
list: "Array", | ||
str: "String" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What kind of types are they ? Json types ? Add the information in function name or in documentation ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌
openfisca_core/entities.py
Outdated
except VariableNotFound as e: # The variable doesn't exist | ||
raise SituationParsingError([self.plural, entity_id, variable_name], e.message, code = 404) | ||
|
||
holder = self.get_holder(variable_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move holder init after if condition ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
openfisca_core/entities.py
Outdated
for person_id in role_definition: | ||
if person_id not in self.simulation.persons.ids: | ||
raise SituationParsingError([self.plural, entity_id, role_id], | ||
"Unexpected value: {0}. {0} has been declared in {1} {2}, but has not been declared in {3}.".format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
||
def check_role_validity(self, role): | ||
if role is not None and not type(role) == Role: | ||
raise Exception("{} is not a valid role".format(role)) | ||
raise ValueError("{} is not a valid role".format(role)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Catch the exception where check_role_validity
is called ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check_role_validity
is not called in the entity initialization process.
This was just an opportunistic fix.
u"The Holder(simulation, column) constructor has been deprecated. " | ||
u"Please use Holder(entity = entity, column = column) instead.", | ||
Warning | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
openfisca_core/holders.py
Outdated
@@ -255,12 +266,19 @@ def put_in_cache(self, value, period, extra_params = None): | |||
raise ValueError('A period must be specified to put values in cache, except for variables with ETERNITY as as period_definition.') | |||
if ((self.column.definition_period == MONTH and period.unit != periods.MONTH) or | |||
(self.column.definition_period == YEAR and period.unit != periods.YEAR)): | |||
raise ValueError(u'Unable to set a value for variable {0} for {1}-long period {2}. {0} is only defined for {3}s. Please adapt your input. If you are the maintainer of {0}, you can consider adding it a set_input attribute to enable automatic period casting.'.format( | |||
error_message = u'Unable to set a value for variable {0} for {1}-long period {2}. {0} is only defined for {3}s. Please adapt your input. If you are the maintainer of {0}, you can consider adding it a set_input attribute to enable automatic period casting.'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add new lines in message ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
entities = entity_class(self, entities_json) | ||
else: | ||
entities = entity_class(self) | ||
self.entities[entity_class.key] = entities |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
entities = None
... at Simulation class first lines ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally, what you declare on the first lines of a class are class attributes (similar to static attributes in Java).
Using class attributes to define instances attributes default values technically works (only because the default attributes are not mutable), but it's not a good practise.
I know, we do this all over the codebase 😞
CHANGELOG.md
Outdated
- Handle `500` errors in the preview API | ||
- In this case, the API returns a JSON with details about the error. | ||
|
||
- Allows simulations to be build from a JSON using their constructor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: builT
CHANGELOG.md
Outdated
#### New features | ||
|
||
- Introduce `/calculate` route in the preview API | ||
- Allows to run calculations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explain briefly that it handles calculations with json requests format ?
openfisca_core/entities.py
Outdated
@@ -89,6 +194,22 @@ def filled_array(self, value, dtype = None): | |||
warnings.simplefilter("ignore") | |||
return np.full(self.count, value, dtype) | |||
|
|||
def get_holder(self, variable_name, init = True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def holder_value(self, variable_name, init = True)
? Or holder_property
.
5523d61
to
35ca745
Compare
35ca745
to
659de24
Compare
Connected to #520
Sorry, I'm opening this PR late.
The spec has not yet been updated. If anyone has time to do it, that would be very appreciated.