hestia-earth-utils 0.15.15__tar.gz → 0.16.1__tar.gz

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.
Files changed (60) hide show
  1. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/PKG-INFO +20 -8
  2. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/lookup_utils.py +6 -2
  3. hestia_earth_utils-0.16.1/hestia_earth/utils/version.py +1 -0
  4. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth_utils.egg-info/PKG-INFO +21 -9
  5. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth_utils.egg-info/SOURCES.txt +16 -4
  6. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth_utils.egg-info/requires.txt +1 -1
  7. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth_utils.egg-info/top_level.txt +0 -1
  8. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/setup.py +4 -5
  9. hestia_earth_utils-0.16.1/tests/test_api.py +169 -0
  10. hestia_earth_utils-0.16.1/tests/test_blank_node.py +59 -0
  11. hestia_earth_utils-0.16.1/tests/test_calculation_status.py +40 -0
  12. hestia_earth_utils-0.16.1/tests/test_cycle.py +18 -0
  13. hestia_earth_utils-0.16.1/tests/test_date.py +17 -0
  14. hestia_earth_utils-0.16.1/tests/test_descriptive_stats.py +49 -0
  15. hestia_earth_utils-0.16.1/tests/test_emission.py +62 -0
  16. hestia_earth_utils-0.16.1/tests/test_lookup.py +147 -0
  17. hestia_earth_utils-0.16.1/tests/test_lookup_utils.py +104 -0
  18. hestia_earth_utils-0.16.1/tests/test_model.py +69 -0
  19. hestia_earth_utils-0.16.1/tests/test_pipeline.py +212 -0
  20. hestia_earth_utils-0.16.1/tests/test_request.py +9 -0
  21. hestia_earth_utils-0.16.1/tests/test_stats.py +194 -0
  22. hestia_earth_utils-0.16.1/tests/test_table.py +11 -0
  23. hestia_earth_utils-0.16.1/tests/test_term.py +19 -0
  24. hestia_earth_utils-0.16.1/tests/test_tools.py +153 -0
  25. hestia_earth_utils-0.15.15/hestia_earth/__init__.py +0 -1
  26. hestia_earth_utils-0.15.15/hestia_earth/utils/__init__.py +0 -3
  27. hestia_earth_utils-0.15.15/hestia_earth/utils/version.py +0 -1
  28. hestia_earth_utils-0.15.15/tests/pivot/test_pivot_csv.py +0 -267
  29. hestia_earth_utils-0.15.15/tests/pivot/test_pivot_json.py +0 -231
  30. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/MANIFEST.in +0 -0
  31. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/README.md +0 -0
  32. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/bin/hestia-format-upload +0 -0
  33. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/bin/hestia-pivot-csv +0 -0
  34. {hestia_earth_utils-0.15.15/hestia_earth/utils/pivot → hestia_earth_utils-0.16.1/hestia_earth/utils}/__init__.py +0 -0
  35. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/api.py +0 -0
  36. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/blank_node.py +0 -0
  37. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/calculation_status.py +0 -0
  38. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/cycle.py +0 -0
  39. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/date.py +0 -0
  40. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/descriptive_stats.py +0 -0
  41. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/emission.py +0 -0
  42. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/lookup.py +0 -0
  43. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/model.py +0 -0
  44. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/pipeline.py +0 -0
  45. {hestia_earth_utils-0.15.15/tests → hestia_earth_utils-0.16.1/hestia_earth/utils}/pivot/__init__.py +0 -0
  46. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/pivot/_shared.py +0 -0
  47. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/pivot/pivot_csv.py +0 -0
  48. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/pivot/pivot_json.py +0 -0
  49. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/request.py +0 -0
  50. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/stats.py +0 -0
  51. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/storage/__init__.py +0 -0
  52. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/storage/_azure_client.py +0 -0
  53. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/storage/_local_client.py +0 -0
  54. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/storage/_s3_client.py +0 -0
  55. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/storage/_sns_client.py +0 -0
  56. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/table.py +0 -0
  57. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/term.py +0 -0
  58. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth/utils/tools.py +0 -0
  59. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/hestia_earth_utils.egg-info/dependency_links.txt +0 -0
  60. {hestia_earth_utils-0.15.15 → hestia_earth_utils-0.16.1}/setup.cfg +0 -0
@@ -1,16 +1,30 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: hestia_earth_utils
3
- Version: 0.15.15
3
+ Version: 0.16.1
4
4
  Summary: HESTIA's utils library
5
5
  Home-page: https://gitlab.com/hestia-earth/hestia-utils
6
6
  Author: HESTIA Team
7
7
  Author-email: guillaumeroyer.mail@gmail.com
8
8
  License: MIT
9
- Platform: UNKNOWN
10
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
- Classifier: Programming Language :: Python :: 3.9
12
- Requires-Python: >=3.9
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Requires-Python: >=3.12
13
11
  Description-Content-Type: text/markdown
12
+ Requires-Dist: hestia-earth-schema>=35.0.1
13
+ Requires-Dist: requests>=2.24.0
14
+ Requires-Dist: urllib3~=1.26.0
15
+ Requires-Dist: python-dateutil>=2.8.1
16
+ Requires-Dist: numpy<2,>=1.25.0
17
+ Requires-Dist: flatten_json
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license
25
+ Dynamic: requires-dist
26
+ Dynamic: requires-python
27
+ Dynamic: summary
14
28
 
15
29
  # HESTIA Utils
16
30
 
@@ -60,5 +74,3 @@ from hestia_earth.utils.lookup import download_lookup
60
74
 
61
75
  df = download_lookup('crop.csv')
62
76
  ```
63
-
64
-
@@ -64,11 +64,15 @@ def is_model_siteType_allowed(model: str, term_id: str, data: dict):
64
64
 
65
65
 
66
66
  def is_model_product_id_allowed(model: str, term_id: str, data: dict):
67
- products = data.get('products', [])
68
- values = _blank_node_term_values(products)
67
+ values = _blank_node_term_values(data.get('products', []))
69
68
  return _is_model_value_allowed(model, term_id, values, 'productTermIdsAllowed')
70
69
 
71
70
 
71
+ def is_model_measurement_id_allowed(model: str, term_id: str, data: dict):
72
+ values = _blank_node_term_values(data.get('measurements', []))
73
+ return _is_model_value_allowed(model, term_id, values, 'measurementIdsAllowed')
74
+
75
+
72
76
  @lru_cache()
73
77
  def _allowed_mapping(term_id: str, column: str):
74
78
  mapping = _allowed_mapping_data()
@@ -0,0 +1 @@
1
+ VERSION = '0.16.1'
@@ -1,16 +1,30 @@
1
- Metadata-Version: 2.1
2
- Name: hestia-earth-utils
3
- Version: 0.15.15
1
+ Metadata-Version: 2.4
2
+ Name: hestia_earth_utils
3
+ Version: 0.16.1
4
4
  Summary: HESTIA's utils library
5
5
  Home-page: https://gitlab.com/hestia-earth/hestia-utils
6
6
  Author: HESTIA Team
7
7
  Author-email: guillaumeroyer.mail@gmail.com
8
8
  License: MIT
9
- Platform: UNKNOWN
10
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
- Classifier: Programming Language :: Python :: 3.9
12
- Requires-Python: >=3.9
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Requires-Python: >=3.12
13
11
  Description-Content-Type: text/markdown
12
+ Requires-Dist: hestia-earth-schema>=35.0.1
13
+ Requires-Dist: requests>=2.24.0
14
+ Requires-Dist: urllib3~=1.26.0
15
+ Requires-Dist: python-dateutil>=2.8.1
16
+ Requires-Dist: numpy<2,>=1.25.0
17
+ Requires-Dist: flatten_json
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license
25
+ Dynamic: requires-dist
26
+ Dynamic: requires-python
27
+ Dynamic: summary
14
28
 
15
29
  # HESTIA Utils
16
30
 
@@ -60,5 +74,3 @@ from hestia_earth.utils.lookup import download_lookup
60
74
 
61
75
  df = download_lookup('crop.csv')
62
76
  ```
63
-
64
-
@@ -3,7 +3,6 @@ README.md
3
3
  setup.py
4
4
  bin/hestia-format-upload
5
5
  bin/hestia-pivot-csv
6
- hestia_earth/__init__.py
7
6
  hestia_earth/utils/__init__.py
8
7
  hestia_earth/utils/api.py
9
8
  hestia_earth/utils/blank_node.py
@@ -36,6 +35,19 @@ hestia_earth_utils.egg-info/SOURCES.txt
36
35
  hestia_earth_utils.egg-info/dependency_links.txt
37
36
  hestia_earth_utils.egg-info/requires.txt
38
37
  hestia_earth_utils.egg-info/top_level.txt
39
- tests/pivot/__init__.py
40
- tests/pivot/test_pivot_csv.py
41
- tests/pivot/test_pivot_json.py
38
+ tests/test_api.py
39
+ tests/test_blank_node.py
40
+ tests/test_calculation_status.py
41
+ tests/test_cycle.py
42
+ tests/test_date.py
43
+ tests/test_descriptive_stats.py
44
+ tests/test_emission.py
45
+ tests/test_lookup.py
46
+ tests/test_lookup_utils.py
47
+ tests/test_model.py
48
+ tests/test_pipeline.py
49
+ tests/test_request.py
50
+ tests/test_stats.py
51
+ tests/test_table.py
52
+ tests/test_term.py
53
+ tests/test_tools.py
@@ -1,4 +1,4 @@
1
- hestia_earth.schema>=24.3.0
1
+ hestia-earth-schema>=35.0.1
2
2
  requests>=2.24.0
3
3
  urllib3~=1.26.0
4
4
  python-dateutil>=2.8.1
@@ -1,5 +1,5 @@
1
1
  import pathlib
2
- from setuptools import find_packages, setup
2
+ from setuptools import find_namespace_packages, setup
3
3
 
4
4
  from hestia_earth.utils.version import VERSION
5
5
 
@@ -23,13 +23,12 @@ setup(
23
23
  author_email='guillaumeroyer.mail@gmail.com',
24
24
  license='MIT',
25
25
  classifiers=[
26
- 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
27
- 'Programming Language :: Python :: 3.9',
26
+ 'Programming Language :: Python :: 3.12',
28
27
  ],
29
- packages=find_packages(exclude=('tests', 'scripts')),
28
+ packages=find_namespace_packages(include=['hestia_earth.*']),
29
+ python_requires='>=3.12',
30
30
  include_package_data=True,
31
31
  install_requires=REQUIRES,
32
- python_requires='>=3.9',
33
32
  scripts=[
34
33
  'bin/hestia-pivot-csv',
35
34
  'bin/hestia-format-upload'
@@ -0,0 +1,169 @@
1
+ from unittest.mock import patch
2
+ import os
3
+ import requests
4
+ import json
5
+ from hestia_earth.schema import SchemaType
6
+ import pytest
7
+
8
+ from .utils import fixtures_path
9
+ from hestia_earth.utils.request import api_url
10
+ from hestia_earth.utils.api import (
11
+ search,
12
+ find_related,
13
+ download_hestia,
14
+ node_exists,
15
+ find_node,
16
+ find_node_exact,
17
+ find_term_ids_by_names,
18
+ )
19
+
20
+
21
+ fake_related_response = {'results': [[{'@id': 'related_id'}]]}
22
+ fake_download_response = {'@id': 'id', '@type': 'type'}
23
+
24
+
25
+ class FakeFindRelatedSuccess():
26
+ def json():
27
+ return fake_related_response
28
+
29
+
30
+ class FakeFindRelatedError():
31
+ def json():
32
+ return {}
33
+
34
+
35
+ class FakeFindRelatedException():
36
+ def json():
37
+ raise requests.exceptions.RequestException('error')
38
+
39
+
40
+ class FakeDownloadSuccess():
41
+ def json():
42
+ return fake_download_response
43
+
44
+
45
+ class FakeDownloadError():
46
+ def json():
47
+ raise requests.exceptions.RequestException('error')
48
+
49
+
50
+ class FakeNodeExistSuccess():
51
+ def json():
52
+ return fake_download_response
53
+
54
+
55
+ class FakeNodeExistError():
56
+ def json():
57
+ return {"message": "not-found", "details": {}}
58
+
59
+
60
+ class FakeElasticSearchEmptyResult:
61
+ def json():
62
+ return {"results": []}
63
+
64
+
65
+ @patch('requests.get', return_value=FakeFindRelatedSuccess)
66
+ def test_find_related_success(mock_get):
67
+ res = find_related(SchemaType.CYCLE, 'id', SchemaType.SOURCE)
68
+ assert res == fake_related_response.get('results')
69
+ mock_get.assert_called_once_with(
70
+ f"{api_url()}/cycles/id/sources?limit=100", headers={'Content-Type': 'application/json'}
71
+ )
72
+
73
+
74
+ @patch('requests.get', return_value=FakeFindRelatedError)
75
+ def test_find_related_error(*args):
76
+ res = find_related(SchemaType.CYCLE, 'id', SchemaType.SOURCE)
77
+ assert not res
78
+
79
+
80
+ @patch('requests.get', return_value=FakeFindRelatedException)
81
+ def test_find_related_exception(*args):
82
+ res = find_related(SchemaType.CYCLE, 'id', SchemaType.SOURCE)
83
+ assert not res
84
+
85
+
86
+ @patch('requests.get', return_value=FakeDownloadError) # make sure fallback is not enabled
87
+ def test_download_hestia_local_file(*args):
88
+ id = 'sandContent'
89
+ with open(f"{fixtures_path}/Term/{id}.jsonld", encoding='utf-8') as f:
90
+ expected = json.load(f)
91
+ os.environ['DOWNLOAD_FOLDER'] = fixtures_path
92
+ res = download_hestia(id, SchemaType.TERM)
93
+ assert res == expected
94
+ del os.environ['DOWNLOAD_FOLDER']
95
+
96
+
97
+ @patch('requests.get', return_value=FakeDownloadSuccess)
98
+ def test_download_hestia_success(mock_get):
99
+ res = download_hestia('id', SchemaType.SOURCE)
100
+ assert res == fake_download_response
101
+ mock_get.assert_called_once_with(
102
+ f"{api_url()}/sources/id", headers={'Content-Type': 'application/json'})
103
+
104
+
105
+ @patch('requests.get', return_value=FakeDownloadError)
106
+ def test_download_hestia_error(*args):
107
+ res = download_hestia('id', SchemaType.SOURCE)
108
+ assert not res
109
+
110
+
111
+ @patch('requests.get', return_value=FakeNodeExistError) # make sure fallback is not enabled
112
+ def test_node_exists_local_file(*args):
113
+ os.environ['DOWNLOAD_FOLDER'] = fixtures_path
114
+ id = 'sandContent'
115
+ assert node_exists(id, SchemaType.TERM)
116
+ del os.environ['DOWNLOAD_FOLDER']
117
+
118
+
119
+ @patch('requests.get', return_value=FakeNodeExistSuccess)
120
+ def test_node_exists_true(*args):
121
+ assert node_exists('id', SchemaType.SOURCE)
122
+
123
+
124
+ @patch('requests.get', return_value=FakeNodeExistError)
125
+ def test_node_exists_false(*args):
126
+ assert not node_exists('id', SchemaType.SOURCE)
127
+
128
+
129
+ def test_search():
130
+ name = 'Wheat'
131
+ res = search(query={
132
+ 'bool': {
133
+ 'must': [{'match': {'name': name}}]
134
+ }
135
+ }, limit=2)
136
+ assert res[0].get('name').startswith(name)
137
+
138
+
139
+ def test_find_node():
140
+ name = 'Wheat'
141
+ res = find_node(SchemaType.TERM, {'name': name}, 2)
142
+ assert res[0].get('name').startswith(name)
143
+
144
+
145
+ def test_find_node_exact():
146
+ name = 'Wheat'
147
+ res = find_node_exact(SchemaType.TERM, {'name': name})
148
+ assert not res
149
+
150
+ name = 'Wheat, grain'
151
+ res = find_node_exact(SchemaType.TERM, {'name': name})
152
+ assert res.get('name') == name
153
+
154
+
155
+ def test_find_term_ids_by_names():
156
+ names = ["Harris Termite Powder", "Wheat, grain", "Urea (kg N)"]
157
+ res = find_term_ids_by_names(names, 2)
158
+ assert res == {
159
+ "Wheat, grain": "wheatGrain",
160
+ "Harris Termite Powder": "harrisTermitePowder",
161
+ "Urea (kg N)": "ureaKgN",
162
+ }
163
+
164
+
165
+ @patch("requests.post", return_value=FakeElasticSearchEmptyResult)
166
+ def test_find_term_ids_by_names_error(mock):
167
+ names = ["id_not_found_name"]
168
+ with pytest.raises(Exception, match=names[0]):
169
+ find_term_ids_by_names(names)
@@ -0,0 +1,59 @@
1
+ # import os
2
+ # import json
3
+ # from pytest import mark
4
+ # from hestia_earth.schema import TermTermType
5
+
6
+ # from tests.utils import fixtures_path
7
+ # from hestia_earth.utils.blank_node import get_node_value, ArrayTreatment, get_blank_nodes_calculation_status
8
+
9
+ # fixtures_folder = os.path.join(fixtures_path, 'blank_node')
10
+ # calculation_status_folder = os.path.join(fixtures_folder, 'calculation_status')
11
+
12
+
13
+ # def test_get_node_value():
14
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': [10]}
15
+ # assert get_node_value(blank_node, 'value', default=None) == 10
16
+
17
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': [0]}
18
+ # assert get_node_value(blank_node, 'value', default=None) == 0
19
+
20
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}}
21
+ # assert get_node_value(blank_node, 'value', default=None) is None
22
+
23
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': [10, 20]}
24
+ # assert get_node_value(blank_node, 'value', default=None) == 15
25
+
26
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': True}
27
+ # assert get_node_value(blank_node, 'value', default=None) is True
28
+
29
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': 10}
30
+ # assert get_node_value(blank_node, 'value', default=None) == 10
31
+
32
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': None}
33
+ # assert get_node_value(blank_node, 'value', default=None) is None
34
+
35
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': None}
36
+ # assert get_node_value(blank_node, 'value', default=0) == 0
37
+
38
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': [10, None, 20]}
39
+ # assert get_node_value(blank_node, 'value', default=None) == 15
40
+
41
+ # blank_node = {'term': {'termType': 'crop', '@id': 'wheatGrain'}, 'value': [10, None, 20]}
42
+ # assert get_node_value(blank_node, 'value', array_treatment=ArrayTreatment.SUM) == 30
43
+
44
+
45
+ # @mark.parametrize(
46
+ # 'folder,list_key,termType',
47
+ # [
48
+ # ('cycle', 'emissions', TermTermType.EMISSION),
49
+ # ]
50
+ # )
51
+ # def test_get_blank_nodes_calculation_status(folder: str, list_key: str, termType: TermTermType):
52
+ # with open(f"{calculation_status_folder}/{folder}/node.jsonld", encoding='utf-8') as f:
53
+ # node = json.load(f)
54
+
55
+ # with open(f"{calculation_status_folder}/{folder}/{list_key}-{termType.value}.json", encoding='utf-8') as f:
56
+ # expected = json.load(f)
57
+
58
+ # result = get_blank_nodes_calculation_status(node, list_key=list_key, termType=termType)
59
+ # assert result == expected, folder
@@ -0,0 +1,40 @@
1
+ # import os
2
+ # import json
3
+
4
+ # from tests.utils import fixtures_path
5
+ # from hestia_earth.utils.calculation_status import _emissions_with_status, get_nodes_calculations_status_dataframe
6
+
7
+ # fixtures_folder = os.path.join(fixtures_path, 'calculation_status')
8
+
9
+
10
+ # def test_emissions_with_status():
11
+ # with open(os.path.join(fixtures_folder, 'nodes.json')) as f:
12
+ # nodes = json.load(f)
13
+
14
+ # result = _emissions_with_status(nodes[0])
15
+ # assert result == {
16
+ # 'emissions-total': 193,
17
+ # 'emissions-complete': 56,
18
+ # 'emissions-incomplete': 1,
19
+ # 'emissions-missing': 136,
20
+ # 'emissions': result['emissions'] # ignore
21
+ # }
22
+
23
+ # result = _emissions_with_status(nodes[1])
24
+ # assert result == {
25
+ # 'emissions-total': 193,
26
+ # 'emissions-complete': 0,
27
+ # 'emissions-incomplete': 13,
28
+ # 'emissions-missing': 180,
29
+ # 'emissions': result['emissions'] # ignore
30
+ # }
31
+
32
+
33
+ # def test_get_nodes_calculations_status_dataframe():
34
+ # with open(os.path.join(fixtures_folder, 'nodes.json')) as f:
35
+ # nodes = json.load(f)
36
+
37
+ # expected = open(os.path.join(fixtures_folder, 'result.csv'), 'r').read()
38
+
39
+ # df = get_nodes_calculations_status_dataframe(nodes, file_format='csv')
40
+ # assert df.to_csv(None, index=None) == expected
@@ -0,0 +1,18 @@
1
+ # import os
2
+ # import json
3
+
4
+ # from tests.utils import fixtures_path
5
+ # from hestia_earth.utils.cycle import get_cycle_emissions_calculation_status
6
+
7
+
8
+ # def test_get_cycle_emissions_calculation_status():
9
+ # folder = os.path.join(fixtures_path, 'blank_node', 'calculation_status', 'cycle')
10
+
11
+ # with open(f"{folder}/node.jsonld", encoding='utf-8') as f:
12
+ # cycle = json.load(f)
13
+
14
+ # with open(f"{folder}/emissions-emission-with-missing-inputs.json", encoding='utf-8') as f:
15
+ # expected = json.load(f)
16
+
17
+ # result = get_cycle_emissions_calculation_status(cycle)
18
+ # assert result == expected
@@ -0,0 +1,17 @@
1
+ from hestia_earth.utils.date import diff_in_years, is_in_days, is_in_months
2
+
3
+
4
+ def test_diff_in_years():
5
+ assert diff_in_years('1990-01-01', '1999-02-01') == 9.1
6
+
7
+
8
+ def test_is_in_days():
9
+ assert not is_in_days('2000')
10
+ assert not is_in_days('2000-01')
11
+ assert is_in_days('2000-01-01')
12
+
13
+
14
+ def test_is_in_months():
15
+ assert not is_in_months('2000')
16
+ assert is_in_months('2000-01')
17
+ assert not is_in_months('2000-01-01')
@@ -0,0 +1,49 @@
1
+ from numpy import array
2
+ from pytest import mark
3
+ from hestia_earth.schema import MeasurementStatsDefinition
4
+
5
+ from hestia_earth.utils.descriptive_stats import calc_descriptive_stats
6
+
7
+ EXPECTED_FLATTENED = {
8
+ "value": [5],
9
+ "sd": [2.581989],
10
+ "min": [1],
11
+ "max": [9],
12
+ "statsDefinition": "simulated",
13
+ "observations": [9]
14
+ }
15
+
16
+ EXPECTED_COLUMNWISE = {
17
+ "value": [4, 5, 6],
18
+ "sd": [2.44949, 2.44949, 2.44949],
19
+ "min": [1, 2, 3],
20
+ "max": [7, 8, 9],
21
+ "statsDefinition": "simulated",
22
+ "observations": [3, 3, 3]
23
+ }
24
+
25
+ EXPECTED_ROWWISE = {
26
+ "value": [2, 5, 8],
27
+ "sd": [0.816497, 0.816497, 0.816497],
28
+ "min": [1, 4, 7],
29
+ "max": [3, 6, 9],
30
+ "statsDefinition": "simulated",
31
+ "observations": [3, 3, 3]
32
+ }
33
+
34
+
35
+ @mark.parametrize(
36
+ "axis, expected",
37
+ [(None, EXPECTED_FLATTENED), (0, EXPECTED_COLUMNWISE), (1, EXPECTED_ROWWISE)],
38
+ ids=["flattened", "columnwise", "rowwise"]
39
+ )
40
+ @mark.parametrize("stats_definition", [MeasurementStatsDefinition.SIMULATED, "simulated"], ids=["Enum", "str"])
41
+ def test_calc_descriptive_stats(stats_definition, axis, expected):
42
+ ARR = array([
43
+ [1, 2, 3],
44
+ [4, 5, 6],
45
+ [7, 8, 9]
46
+ ])
47
+
48
+ result = calc_descriptive_stats(ARR, stats_definition, axis=axis)
49
+ assert result == expected
@@ -0,0 +1,62 @@
1
+ from hestia_earth.schema import SiteSiteType, TermTermType
2
+
3
+ from hestia_earth.utils.emission import cycle_emissions_in_system_boundary, emissions_in_system_boundary
4
+
5
+ class_path = 'hestia_earth.utils.emission'
6
+
7
+
8
+ def test_cycle_emissions_in_system_boundary_cropland():
9
+ cycle = {'site': {}}
10
+
11
+ cycle['products'] = [
12
+ {
13
+ 'term': {
14
+ '@id': 'wheatGrain',
15
+ 'termType': TermTermType.CROP.value
16
+ }
17
+ }
18
+ ]
19
+ cycle['site']['siteType'] = SiteSiteType.CROPLAND.value
20
+ term_ids = cycle_emissions_in_system_boundary(cycle)
21
+ assert len(term_ids) > 50
22
+
23
+ cycle['products'] = [
24
+ {
25
+ 'term': {
26
+ '@id': 'ricePlantFlooded',
27
+ 'termType': TermTermType.CROP.value
28
+ }
29
+ }
30
+ ]
31
+ cycle['site']['siteType'] = SiteSiteType.CROPLAND.value
32
+ term_ids = cycle_emissions_in_system_boundary(cycle)
33
+ assert len(term_ids) > 50
34
+
35
+ # with inputs restriction, we should have less emissions
36
+ cycle['inputs'] = [
37
+ {
38
+ 'term': {'termType': 'crop'}
39
+ }
40
+ ]
41
+ cycle['site']['siteType'] = SiteSiteType.CROPLAND.value
42
+ assert len(cycle_emissions_in_system_boundary(cycle)) < len(term_ids)
43
+
44
+
45
+ def test_cycle_emissions_in_system_boundary_animal_housing():
46
+ cycle = {'site': {}}
47
+ cycle['products'] = [
48
+ {
49
+ 'term': {
50
+ '@id': 'meatBeefCattleLiveweight',
51
+ 'termType': TermTermType.ANIMALPRODUCT.value
52
+ }
53
+ }
54
+ ]
55
+ cycle['site']['siteType'] = SiteSiteType.ANIMAL_HOUSING.value
56
+ term_ids = cycle_emissions_in_system_boundary(cycle)
57
+ assert len(term_ids) > 20
58
+
59
+
60
+ def test_emissions_in_system_boundary():
61
+ term_ids = emissions_in_system_boundary()
62
+ assert len(term_ids) > 50