hestia-earth-models 0.65.5__py3-none-any.whl → 0.65.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of hestia-earth-models might be problematic. Click here for more details.

Files changed (57) hide show
  1. hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +9 -5
  2. hestia_earth/models/config/Cycle.json +2193 -0
  3. hestia_earth/models/config/ImpactAssessment.json +2041 -0
  4. hestia_earth/models/config/Site.json +471 -0
  5. hestia_earth/models/config/__init__.py +71 -0
  6. hestia_earth/models/config/run-calculations.json +42 -0
  7. hestia_earth/models/config/trigger-calculations.json +43 -0
  8. hestia_earth/models/hestia/landCover.py +70 -22
  9. hestia_earth/models/ipcc2019/animal/hoursWorkedPerDay.py +38 -0
  10. hestia_earth/models/mocking/search-results.json +833 -829
  11. hestia_earth/models/site/management.py +82 -22
  12. hestia_earth/models/utils/crop.py +5 -1
  13. hestia_earth/models/version.py +1 -1
  14. hestia_earth/orchestrator/__init__.py +40 -0
  15. hestia_earth/orchestrator/log.py +62 -0
  16. hestia_earth/orchestrator/models/__init__.py +118 -0
  17. hestia_earth/orchestrator/models/emissions/__init__.py +0 -0
  18. hestia_earth/orchestrator/models/emissions/deleted.py +15 -0
  19. hestia_earth/orchestrator/models/transformations.py +103 -0
  20. hestia_earth/orchestrator/strategies/__init__.py +0 -0
  21. hestia_earth/orchestrator/strategies/merge/__init__.py +42 -0
  22. hestia_earth/orchestrator/strategies/merge/merge_append.py +29 -0
  23. hestia_earth/orchestrator/strategies/merge/merge_default.py +1 -0
  24. hestia_earth/orchestrator/strategies/merge/merge_list.py +103 -0
  25. hestia_earth/orchestrator/strategies/merge/merge_node.py +59 -0
  26. hestia_earth/orchestrator/strategies/run/__init__.py +8 -0
  27. hestia_earth/orchestrator/strategies/run/add_blank_node_if_missing.py +85 -0
  28. hestia_earth/orchestrator/strategies/run/add_key_if_missing.py +9 -0
  29. hestia_earth/orchestrator/strategies/run/always.py +6 -0
  30. hestia_earth/orchestrator/utils.py +116 -0
  31. {hestia_earth_models-0.65.5.dist-info → hestia_earth_models-0.65.7.dist-info}/METADATA +27 -5
  32. {hestia_earth_models-0.65.5.dist-info → hestia_earth_models-0.65.7.dist-info}/RECORD +57 -13
  33. tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +1 -1
  34. tests/models/hestia/test_landCover.py +2 -1
  35. tests/models/ipcc2019/animal/test_hoursWorkedPerDay.py +22 -0
  36. tests/models/test_config.py +115 -0
  37. tests/orchestrator/__init__.py +0 -0
  38. tests/orchestrator/models/__init__.py +0 -0
  39. tests/orchestrator/models/emissions/__init__.py +0 -0
  40. tests/orchestrator/models/emissions/test_deleted.py +21 -0
  41. tests/orchestrator/models/test_transformations.py +29 -0
  42. tests/orchestrator/strategies/__init__.py +0 -0
  43. tests/orchestrator/strategies/merge/__init__.py +0 -0
  44. tests/orchestrator/strategies/merge/test_merge_append.py +33 -0
  45. tests/orchestrator/strategies/merge/test_merge_default.py +7 -0
  46. tests/orchestrator/strategies/merge/test_merge_list.py +327 -0
  47. tests/orchestrator/strategies/merge/test_merge_node.py +95 -0
  48. tests/orchestrator/strategies/run/__init__.py +0 -0
  49. tests/orchestrator/strategies/run/test_add_blank_node_if_missing.py +114 -0
  50. tests/orchestrator/strategies/run/test_add_key_if_missing.py +14 -0
  51. tests/orchestrator/strategies/run/test_always.py +5 -0
  52. tests/orchestrator/test_models.py +69 -0
  53. tests/orchestrator/test_orchestrator.py +27 -0
  54. tests/orchestrator/test_utils.py +109 -0
  55. {hestia_earth_models-0.65.5.dist-info → hestia_earth_models-0.65.7.dist-info}/LICENSE +0 -0
  56. {hestia_earth_models-0.65.5.dist-info → hestia_earth_models-0.65.7.dist-info}/WHEEL +0 -0
  57. {hestia_earth_models-0.65.5.dist-info → hestia_earth_models-0.65.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,114 @@
1
+ from unittest.mock import patch
2
+
3
+ from hestia_earth.orchestrator.strategies.run.add_blank_node_if_missing import should_run
4
+
5
+ class_path = 'hestia_earth.orchestrator.strategies.run.add_blank_node_if_missing'
6
+ FAKE_EMISSION = {'@id': 'n2OToAirExcretaDirect', 'termType': 'emission'}
7
+
8
+
9
+ @patch(f"{class_path}.get_required_model_param", return_value='')
10
+ @patch(f"{class_path}.find_term_match")
11
+ def test_should_run(mock_node_exists, *args):
12
+ data = {}
13
+ model = {}
14
+
15
+ # node does not exists => run
16
+ mock_node_exists.return_value = None
17
+ assert should_run(data, model) is True
18
+
19
+ # node exists but no value => run
20
+ mock_node_exists.return_value = {}
21
+ assert should_run(data, model) is True
22
+
23
+ # node exists with value + no params => no run
24
+ node = {'value': 10}
25
+ mock_node_exists.return_value = node
26
+ assert not should_run(data, model)
27
+
28
+ # node exists with added value `0` and `Emission` => run
29
+ node = {'@type': 'Emission', 'value': [0], 'added': ['value']}
30
+ mock_node_exists.return_value = node
31
+ assert should_run(data, model) is True
32
+
33
+
34
+ @patch(f"{class_path}.get_required_model_param", return_value='')
35
+ @patch(f"{class_path}.find_term_match")
36
+ def test_should_run_skipEmptyValue(mock_node_exists, *args):
37
+ data = {}
38
+
39
+ # no value and not skip => run
40
+ mock_node_exists.return_value = {}
41
+ model = {'runArgs': {'skipEmptyValue': False}}
42
+ assert should_run(data, model) is True
43
+
44
+ # no value and skip => no run
45
+ mock_node_exists.return_value = {}
46
+ model = {'runArgs': {'skipEmptyValue': True}}
47
+ assert not should_run(data, model)
48
+
49
+
50
+ @patch(f"{class_path}.get_required_model_param", return_value='')
51
+ def test_should_run_skipAggregated(*args):
52
+ data = {}
53
+ model = {'runArgs': {'skipAggregated': True}}
54
+
55
+ # not aggregated => run
56
+ data = {'aggregated': False}
57
+ assert should_run(data, model) is True
58
+
59
+ # aggregated => no run
60
+ data = {'aggregated': True}
61
+ assert not should_run(data, model)
62
+
63
+
64
+ @patch(f"{class_path}.get_required_model_param", return_value='')
65
+ @patch(f"{class_path}.find_term_match")
66
+ def test_should_run_runNonAddedTerm(mock_node_exists, *args):
67
+ data = {}
68
+ node = {'value': 10}
69
+ mock_node_exists.return_value = node
70
+ model = {'runArgs': {'runNonAddedTerm': True}}
71
+
72
+ # term has been added => no run
73
+ node['added'] = ['term']
74
+ assert not should_run(data, model)
75
+
76
+ # term has not been added => run
77
+ node['added'] = []
78
+ assert should_run(data, model) is True
79
+
80
+
81
+ @patch(f"{class_path}.get_required_model_param", return_value='')
82
+ @patch(f"{class_path}.find_term_match")
83
+ def test_should_run_runNonMeasured(mock_node_exists, *args):
84
+ data = {}
85
+ node = {'value': 10}
86
+ mock_node_exists.return_value = node
87
+ model = {'runArgs': {'runNonMeasured': True}}
88
+
89
+ # term measured => no run
90
+ node['methodTier'] = 'measured'
91
+ assert not should_run(data, model)
92
+
93
+ # term not measured => run
94
+ node['methodTier'] = 'background'
95
+ assert should_run(data, model) is True
96
+
97
+
98
+ @patch(f"{class_path}.get_table_value", return_value='Cycle')
99
+ @patch(f"{class_path}.download_hestia", return_value=FAKE_EMISSION)
100
+ @patch(f"{class_path}.get_required_model_param", return_value='')
101
+ @patch(f"{class_path}.find_term_match")
102
+ def test_should_run_check_typeAllowed(mock_node_exists, *args):
103
+ data = {}
104
+ node = {'term': FAKE_EMISSION}
105
+ mock_node_exists.return_value = node
106
+ model = {}
107
+
108
+ # type is not allowed => no run
109
+ data['@type'] = 'Transformation'
110
+ assert not should_run(data, model)
111
+
112
+ # type is allowed => run
113
+ data['@type'] = 'Cycle'
114
+ assert should_run(data, model) is True
@@ -0,0 +1,14 @@
1
+ from hestia_earth.orchestrator.strategies.run.add_key_if_missing import should_run
2
+
3
+
4
+ def test_should_run():
5
+ data = {}
6
+ key = 'model-key'
7
+ model = {'key': key}
8
+
9
+ # key not in data => run
10
+ assert should_run(data, model) is True
11
+
12
+ # key in data => no run
13
+ data[key] = 10
14
+ assert not should_run(data, model)
@@ -0,0 +1,5 @@
1
+ from hestia_earth.orchestrator.strategies.run.always import should_run
2
+
3
+
4
+ def test_should_run():
5
+ assert should_run({}, {}) is True
@@ -0,0 +1,69 @@
1
+ from unittest.mock import patch
2
+ import pytest
3
+ import json
4
+ import os
5
+
6
+ from tests.utils import fixtures_path
7
+ from hestia_earth.orchestrator.models import run, _run_parallel, _filter_models_stage
8
+
9
+ class_path = 'hestia_earth.orchestrator.models'
10
+ folder_path = os.path.join(fixtures_path, 'orchestrator', 'cycle')
11
+
12
+
13
+ @patch('hestia_earth.orchestrator.strategies.merge._merge_version', return_value='0.0.0')
14
+ def test_run(*args):
15
+ with open(os.path.join(folder_path, 'config.json'), encoding='utf-8') as f:
16
+ config = json.load(f)
17
+ with open(os.path.join(folder_path, 'cycle.jsonld'), encoding='utf-8') as f:
18
+ cycle = json.load(f)
19
+ with open(os.path.join(folder_path, 'result.jsonld'), encoding='utf-8') as f:
20
+ expected = json.load(f)
21
+
22
+ result = run(cycle, config.get('models'))
23
+ assert result == expected
24
+
25
+
26
+ @patch(f"{class_path}._run_model", side_effect=Exception('error'))
27
+ def test_run_parallel_with_errors(*args):
28
+ data = {
29
+ '@type': 'Cycle',
30
+ '@id': 'cycle'
31
+ }
32
+ model = [{'key': 'model1'}, {'key': 'model2'}]
33
+
34
+ with pytest.raises(Exception):
35
+ _run_parallel(data, model, [])
36
+
37
+
38
+ def test_filter_models_stage():
39
+ models = json.load(open(os.path.join(fixtures_path, 'orchestrator', 'stages', 'config.json'))).get('models')
40
+ assert _filter_models_stage(models) == models
41
+ assert _filter_models_stage(models, 1) == [
42
+ {
43
+ "key": "model1",
44
+ "stage": 1
45
+ },
46
+ {
47
+ "key": "model2",
48
+ "stage": 1
49
+ }
50
+ ]
51
+ assert _filter_models_stage(models, 2) == [
52
+ [
53
+ {
54
+ "key": "model3",
55
+ "stage": 2
56
+ },
57
+ {
58
+ "key": "model4",
59
+ "stage": 2
60
+ }
61
+ ]
62
+ ]
63
+ assert _filter_models_stage(models, 3) == [
64
+ {
65
+ "key": "model5",
66
+ "stage": 3
67
+ }
68
+ ]
69
+ assert _filter_models_stage(models, [1, 2, 3]) == models
@@ -0,0 +1,27 @@
1
+ from unittest.mock import patch
2
+ import pytest
3
+
4
+ from hestia_earth.orchestrator import run
5
+
6
+ config = {'models': []}
7
+
8
+
9
+ @patch('hestia_earth.orchestrator.run_models', return_value={})
10
+ def test_run(mock_run_models, *args):
11
+ run({'@type': 'Cycle'}, config)
12
+ mock_run_models.assert_called_once()
13
+
14
+
15
+ def test_run_missing_type():
16
+ with pytest.raises(Exception, match='Please provide an "@type" key in your data.'):
17
+ run({}, config)
18
+
19
+
20
+ def test_run_missing_config():
21
+ with pytest.raises(Exception, match='Please provide a valid configuration.'):
22
+ run({'@type': 'Cycle'}, None)
23
+
24
+
25
+ def test_run_missing_models():
26
+ with pytest.raises(Exception, match='Please provide a valid configuration.'):
27
+ run({'@type': 'Cycle'}, {})
@@ -0,0 +1,109 @@
1
+ from hestia_earth.orchestrator.utils import update_node_version
2
+
3
+ version = '2'
4
+
5
+
6
+ def test_update_node_version():
7
+ current_data = {
8
+ 'key1': 50,
9
+ 'key2': 100
10
+ }
11
+ new_data = {
12
+ 'key2': 200,
13
+ 'key3': 300,
14
+ 'key4': {}
15
+ }
16
+ assert update_node_version(version, new_data, current_data) == {
17
+ **new_data,
18
+ 'added': ['key3', 'key4'],
19
+ 'addedVersion': [version, version],
20
+ 'updated': ['key2'],
21
+ 'updatedVersion': [version]
22
+ }
23
+
24
+
25
+ def test_update_node_version_deep():
26
+ current_data = {
27
+ 'object': {
28
+ 'first': True
29
+ },
30
+ 'values': [
31
+ {
32
+ 'term': {'@type': 'Term'},
33
+ 'value': [500],
34
+ 'properties': [
35
+ {
36
+ 'term': {'@type': 'Term', '@id': 'Prop1'},
37
+ 'value': 100
38
+ }
39
+ ]
40
+ }
41
+ ]
42
+ }
43
+ new_data = {
44
+ 'object': {
45
+ 'first': True,
46
+ 'second': False
47
+ },
48
+ 'values': [
49
+ {
50
+ 'term': {'@type': 'Term'},
51
+ 'value': [500],
52
+ 'min': [100],
53
+ 'properties': [
54
+ {
55
+ 'term': {'@type': 'Term', '@id': 'Prop1'},
56
+ 'value': 10
57
+ },
58
+ {
59
+ 'term': {'@type': 'Term', '@id': 'Prop2'},
60
+ 'value': 20
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ 'term': {'@type': 'Term', '@id': 'Test2'}
66
+ }
67
+ ]
68
+ }
69
+ result = update_node_version(version, new_data, current_data)
70
+ assert result == {
71
+ 'object': {
72
+ 'first': True,
73
+ 'second': False,
74
+ 'added': ['second'],
75
+ 'addedVersion': [version]
76
+ },
77
+ 'values': [
78
+ {
79
+ 'term': {'@type': 'Term'},
80
+ 'value': [500],
81
+ 'min': [100],
82
+ 'properties': [
83
+ {
84
+ 'term': {'@type': 'Term', '@id': 'Prop1'},
85
+ 'value': 10,
86
+ 'updated': ['value'],
87
+ 'updatedVersion': [version]
88
+ },
89
+ {
90
+ 'term': {'@type': 'Term', '@id': 'Prop2'},
91
+ 'value': 20,
92
+ 'added': ['term', 'value'],
93
+ 'addedVersion': [version, version]
94
+ }
95
+ ],
96
+ 'added': ['min'],
97
+ 'addedVersion': [version],
98
+ 'updated': ['properties'],
99
+ 'updatedVersion': [version]
100
+ },
101
+ {
102
+ 'term': {'@type': 'Term', '@id': 'Test2'},
103
+ 'added': ['term'],
104
+ 'addedVersion': [version]
105
+ }
106
+ ],
107
+ 'updated': ['object', 'values'],
108
+ 'updatedVersion': [version, version]
109
+ }