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

chore: remove pydantic validation from dto classes #740

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

frodehk
Copy link
Contributor

@frodehk frodehk commented Dec 17, 2024

equinor/ecalc-internal#291

Why is this pull request needed?

Pydantic validation is taken care of in the Yaml classes now. It is not needed in the dto classes, here we need more flexibility.

What does this pull request change?

Remove inheritance from EcalcBaseModel (Pydantic) in Component base class. Remove: field_validators, Field definitions, ConfigDict import and usage. Remove Pydantic specific imports and replace with standard Python types if necessary. In libecalc/domain/infracstructure/energy_components/ this is done for:

  • base/component_dto.py
  • consumer_system/consumer_system_dto.py
  • electricity_consumer/electricity_consumer.py
  • generator_set_dto.py
  • installation/installation.py
  • asset/asset.py
  • legacy_consumer: All files in directory

In addition the following changes are done:

  • Implemented a new ComponentValidationException for energy components
  • Remove some redundant validation from dto layer (in GeneratorSet and Installation)
  • Remove redundant validation of user defined category in dto layer
  • Update affected tests: Use yaml classes instead of dtos, as validation is done here only (after removing redundant validation in dto)
  • Remove Component, BaseComponent, BaseEquipment and BaseConsumer from base/component_dto, and transfered functionality and parameters to individual energy components. Reduce complexity and improve readability.
  • Add test to check that new ComponentValidationException is catched in YamlModel.dto.

@frodehk frodehk self-assigned this Dec 17, 2024
@frodehk frodehk requested a review from a team as a code owner December 17, 2024 12:13
Copy link
Contributor

@jsolaas jsolaas left a comment

Choose a reason for hiding this comment

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

Very nice. Looks like a step in the right direction to me :)

The last comment about ValueError is something we should look into I think.

src/libecalc/core/models/pump/pump.py Outdated Show resolved Hide resolved
src/libecalc/presentation/yaml/mappers/component_mapper.py Outdated Show resolved Hide resolved
@@ -114,7 +135,7 @@ def to_dto(
regularity=regularity,
consumes=consumes,
component_conditions=component_conditions,
stream_conditions_priorities=TypeAdapter(YamlPriorities).dump_python(
stream_conditions_priorities=self.convert_yaml_priorities(
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably map this similar to v1/the other components, in the mapper (removing to_dto). But we'll see what we end up doing with v2, seems unnecessary to maintain if we have no plan to make users migrate.

tests/libecalc/dto/test_electricity_consumer.py Outdated Show resolved Hide resolved
@frodehk frodehk force-pushed the remove-pydantic-in-dto branch from 8662822 to 268c135 Compare January 6, 2025 09:11
@frodehk frodehk force-pushed the remove-pydantic-in-dto branch from 562b01a to f6a0b55 Compare January 7, 2025 11:45
@classmethod
def check_fuel(cls, fuel):
def validate_fuel_exist(cls, name: str, fuel: Optional[dict[Period, FuelType]], consumes: ConsumptionType):
Copy link
Contributor Author

@frodehk frodehk Jan 7, 2025

Choose a reason for hiding this comment

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

Is this needed? _resolve_fuel in ConsumerMapper (component_mapper) in from_yaml_to_dto is already checking references. It will raise a DataValidationError if references are wrong.

Update/edit: Yes, it may be needed if fuel reference name is blank/empty string.

@@ -93,7 +103,7 @@ def get_fuel_consumer(

class TestFuelConsumer:
def test_missing_fuel(self):
Copy link
Contributor Author

@frodehk frodehk Jan 7, 2025

Choose a reason for hiding this comment

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

This test is checking for a missing fuel, combined with a non-blank fuel reference. This is actually captured earlier when references are checked in the component mapper (ref comment related to validate_missing_fuel). Do we need it? I have added a new test that may be more relevant: blank fuel reference and missing fuel - this will not be catched when checking for references.

Copy link
Contributor

Choose a reason for hiding this comment

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

This can be removed then. Do we have a test for missing fuel where it is actually captured?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Working on it. Replacing this test.

assert result.suction_pressures[1].tolist() == [0, 31, 22, 13, 4]
assert result.discharge_pressures[0].tolist() == [0, 31, 22, 13, 4]
assert result.discharge_pressures[1].tolist() == [0, 31, 22, 13, 4]
assert np.array(result.rates[0]).tolist() == [0, 31, 22, 13, 4]
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the point of this? create array then convert to list again?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No point. Not sure why this has happened. Probably traces after some strange debugging.

@@ -180,7 +180,7 @@ def test_interpolation_functions():
assert not (np.asarray(chart_curve.rate_head_and_efficiency_at_minimum_rate) - [336.0, 1778.7, 0.4717]).any()
assert not (np.asarray(chart_curve.rate_head_and_efficiency_at_maximum_rate) - [1028, 1460.6, 0.7193]).any()
assert chart_curve.efficiency_as_function_of_rate(708) == 0.6683
assert chart_curve.efficiency_as_function_of_rate(456.5) == 0.546
assert np.round(chart_curve.efficiency_as_function_of_rate(456.5), 3) == 0.546
Copy link
Contributor

Choose a reason for hiding this comment

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

Did chart have rounding built in when it was pydantic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Chart is still in core, not moved to infrastructure. As far as I understand it has not been pydantic.

@@ -93,7 +103,7 @@ def get_fuel_consumer(

class TestFuelConsumer:
def test_missing_fuel(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be removed then. Do we have a test for missing fuel where it is actually captured?

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.

3 participants