Skip to content

Commit 9bd8bcf

Browse files
authored
Merge pull request #33 from OpenEnergyPlatform/release/v0.3.2
Release/v0.3.2
2 parents ecbad03 + 736d201 commit 9bd8bcf

File tree

5 files changed

+75
-73
lines changed

5 files changed

+75
-73
lines changed

CHANGELOG.md

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,34 @@ Template:
2626
### Removed
2727
- basic description [#PR/#Issue/#Commit]
2828
```
29-
## Current
29+
## [Unreleased] - 20XX-MM-DD
3030

3131
### Added
3232

3333
### Changed
34-
---
35-
## [0.3.1] - 2022-10-24
34+
35+
### Removed
36+
37+
______________________________________________________________________
38+
## [0.3.2] - 2022-11-29
3639

3740
### Added
41+
- token can be passed as parameter (to support usage in APIs)
42+
43+
### Changed
44+
- Error is raised if schema does not exist
45+
- Metadata compilance checks now inculue optinal jsonschema validation for metadata (PR#32)
46+
- MetadataError is thrown if uploading metadata to OEP fails
47+
48+
______________________________________________________________________
49+
## [0.3.1] - 2022-10-24
3850

3951
### Changed
4052
- fix module not installed error after pip install and import of oem2orm PR(#26)
53+
4154
______________________________________________________________________
4255
## [0.3.0] - 2022-10-24
56+
4357
### Added
4458
- Option to create tables from OEM JSON instead of file
4559
- New module to check if metadata is oep compliant. Can check (omi's 1 parse 2 compile) oemetadata v1.5 and v1.4 (PR#23)
@@ -55,10 +69,12 @@ ______________________________________________________________________
5569
- enable console usage [PR#8]
5670
- new package requirement "omi"
5771
- support for sqlachemy "numeric" data type
72+
5873
### Changed
5974
- fix missing dependency that made pip install fail [ISSUE#1;PR#8]
75+
6076
### Removed
61-
- concolse script, remove table delete
77+
- console script, remove table delete
6278

6379
______________________________________________________________________
6480
## [0.2.6] - 2020-09-23
@@ -67,13 +83,13 @@ ______________________________________________________________________
6783
- support for datatypes "hstore" and "decimal"
6884
- provide new example files that work with oem2orm
6985

70-
### Changed
71-
86+
______________________________________________________________________
7287
## [0.2.5] - 2020-08-06
7388

7489
### Changed
7590
- fix installation error caused by jmespath package dependency
7691

92+
______________________________________________________________________
7793
## [0.2.4] - 2020-07-20
7894

7995
### Added
@@ -85,20 +101,20 @@ ______________________________________________________________________
85101
### Changed
86102
- change functions names
87103

88-
104+
______________________________________________________________________
89105
## [0.2.3] - 2020-06-02
90106

91107
### Added
92108
- provide a minimal working example as jupyter notebook tutorial
93109
- New OEP-API related functions: Prepare the oemetadata string to send to api
94-
Simple User Input function to set the OEP-API-Token
110+
- Simple User Input function to set the OEP-API-Token
95111

96112
### Changed
97113
- Update README
98114
- include OEP public schema (whitelist) check
99115
- Spatial types from Geoalchemy2 do not set a spatial_index anymore
100116

101-
117+
______________________________________________________________________
102118
## [0.2.2] - 2020-06-02
103119

104120
### Added
@@ -109,7 +125,7 @@ ______________________________________________________________________
109125
- extended description in changelog
110126
- Fix logging
111127

112-
128+
______________________________________________________________________
113129
## [0.2.0] - 2020-05-27
114130

115131
### Added
@@ -118,7 +134,7 @@ ______________________________________________________________________
118134
- new function: tables are collected and ordered by fk (increase usability)
119135

120136
### Changed
121-
- added docstrings
137+
- added docstrings
122138

123139
### Removed
124140
- the user is no longer required to use a for loop in the main function to collect tables

oem2orm/oep_compliance.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,23 @@
66
77
88
"""
9-
10-
from distutils.errors import CompileError
9+
import logging
1110
import pathlib
11+
import json
12+
1213
from omi.dialects.oep.parser import ParserException
1314
from omi.structure import Compilable
1415

1516
from omi.dialects.oep import OEP_V_1_4_Dialect, OEP_V_1_5_Dialect
1617
from omi.dialects.oep.compiler import JSONCompiler
1718

18-
import json
19+
from omi.dialects.oep.parser import JSONParser
1920

2021
# instances of metadata parsers / compilers, order of priority
2122
METADATA_PARSERS = [OEP_V_1_5_Dialect(), OEP_V_1_4_Dialect()]
2223
METADATA_COMPILERS = [OEP_V_1_5_Dialect(), OEP_V_1_4_Dialect(), JSONCompiler()]
2324

25+
logger = logging.getLogger()
2426

2527
def read_input_json(file_path: pathlib.Path = "tests/data/metadata_v15.json"):
2628
with open(file_path, "r", encoding="utf-8") as f:
@@ -38,11 +40,6 @@ def try_parse_metadata(inp):
3840
The first component is the result of the parsing procedure or `None` if
3941
the parsing failed. The second component is None, if the parsing failed,
4042
otherwise an error message.
41-
Examples:
42-
>>> from api.actions import try_parse_metadata
43-
>>> result, error = try_parse_metadata('{"id":"id"}')
44-
>>> error is None
45-
True
4643
"""
4744

4845
if isinstance(inp, Compilable):
@@ -126,12 +123,12 @@ def check_oemetadata_is_oep_compatible(metadata):
126123
# -------------------------------------------
127124

128125

129-
def run_metadata_checks(oemetadata: dict = None, oemetadata_path: str = None):
126+
def run_metadata_checks(oemetadata: dict = None, oemetadata_path: str = None, check_jsonschema: bool = False):
130127
"""
131128
Runs metadata checks includes:
132129
- basic oep compliant check - tested by using omi's parsing and compiling
133130
134-
Not included:
131+
Optional - included:
135132
- jsonschema valdiation
136133
137134
Args:
@@ -159,8 +156,19 @@ def run_metadata_checks(oemetadata: dict = None, oemetadata_path: str = None):
159156
if oemetadata is not None and oemetadata_path is None:
160157
metadata = oemetadata
161158

159+
logger.info("Check if metadata is parsable and compileable by omi.")
162160
check_oemetadata_is_oep_compatible(metadata=metadata)
163161

162+
if check_jsonschema:
163+
logger.info("Check if metadata is valid against the jsonschema.")
164+
parser_validation = JSONParser()
165+
schema = parser_validation.get_schema_by_metadata_version(metadata=metadata)
166+
result = parser_validation.is_valid(inp=metadata, schema=schema)
167+
if result is False:
168+
result = result, parser_validation.validate(metadata=metadata, save_report=True)
169+
170+
return result
171+
164172

165173
if __name__ == "__main__":
166174
correct_v15_test_data = "tests/data/metadata_v15.json"
@@ -169,7 +177,7 @@ def run_metadata_checks(oemetadata: dict = None, oemetadata_path: str = None):
169177

170178
meta = read_input_json(file_path=correct_v15_test_data)
171179
print("Check v15 metadata from file!")
172-
run_metadata_checks(oemetadata_path=correct_v15_test_data)
180+
result = run_metadata_checks(oemetadata_path=correct_v15_test_data, check_jsonschema=True)
173181
print("Check v15 metadata from object!")
174182
run_metadata_checks(oemetadata=meta)
175183

oem2orm/oep_oedialect_oem2orm.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ def setup_db_connection(engine="postgresql+oedialect", host="openenergy-platform
7979
return DB(engine, metadata)
8080

8181

82-
def setupApiAction(schema, table):
82+
def setupApiAction(schema, table, token=None):
8383
API_ACTION = namedtuple("API_Action", ["dest_url", "headers"])
8484
OEP_URL = "https://openenergy-platform.org"
8585

8686
url = OEP_URL + "/api/v0/schema/{schema}/tables/{table}/meta/".format(
8787
schema=schema, table=table
8888
)
8989

90-
token = setUserToken()
90+
token = token if token else setUserToken()
9191
headers = {
9292
"Authorization": "Token %s" % token,
9393
"Accept": "application/json",
@@ -108,20 +108,22 @@ def create_tables(db: DB, tables: List[sa.Table]):
108108
"""
109109
for table in tables:
110110
if not db.engine.dialect.has_schema(db.engine, table.schema):
111-
logging.info(
112-
f'The provided database schema: "{table.schema}" does not exist. Please use an existing schema'
113-
)
111+
error_msg = f'The provided database schema: "{table.schema}" does not exist. Please use an existing schema'
112+
logging.info(error_msg)
113+
raise DatabaseError(error_msg)
114114
else:
115115
if not db.engine.dialect.has_table(db.engine, table.name, table.schema):
116116
try:
117117
table.create(checkfirst=True)
118118
logging.info(f"Created table {table.name}")
119119
except oedialect.engine.ConnectionException as ce:
120-
logging.error(f'Error when uploading table "{table.name}".')
121-
raise ce
122-
except sa.exc.ProgrammingError:
123-
logging.error(f'Table "{table.name}" already exists')
124-
raise
120+
error_msg = f'Error when uploading table "{table.name}".'
121+
logging.error(error_msg)
122+
raise DatabaseError(error_msg) from ce
123+
except sa.exc.ProgrammingError as pe:
124+
error_msg = f'Table "{table.name}" already exists.'
125+
logging.error(error_msg)
126+
raise DatabaseError(error_msg) from pe
125127

126128

127129
def delete_tables(db: DB, tables: List[sa.Table]):
@@ -366,27 +368,29 @@ def parseDatapackageToString(oem_folder_path, datapackage_name=None, table_name=
366368
raise NotImplemented
367369

368370

369-
def api_updateMdOnTable(metadata):
371+
def api_updateMdOnTable(metadata, token=None):
370372
""" """
371373
schema = getTableSchemaNameFromOEM(metadata)[0]
372374
table = getTableSchemaNameFromOEM(metadata)[1]
373375

374376
logging.info("UPDATE METADATA")
375-
api_action = setupApiAction(schema, table)
377+
api_action = setupApiAction(schema, table, token)
376378
resp = requests.post(api_action.dest_url, json=metadata, headers=api_action.headers)
377-
if resp.status_code == "200":
379+
if resp.status_code == 200:
378380
logging.info(" ok.")
379381
logging.info(api_action.dest_url)
380382
else:
381-
logging.info(resp.json())
383+
error_msg = resp.json()
384+
logging.info(error_msg)
382385
logging.info("HTTP status code: ")
383386
logging.info(resp.status_code)
387+
raise MetadataError(f"Uploading of metadata failed. Response from OEP: {error_msg}")
384388

385389

386-
def api_downloadMd(schema, table):
390+
def api_downloadMd(schema, table, token=None):
387391
""" """
388392
logging.info("DOWNLOAD_METADATA")
389-
api_action = setupApiAction(schema, table)
393+
api_action = setupApiAction(schema, table, token)
390394
res = requests.get(api_action.dest_url)
391395
res = res.json()
392396
logging.info(" ok.")
@@ -404,8 +408,8 @@ def moveTableToSchema(engine, destination_schema):
404408

405409

406410
# TODO: rename or remove this function - functionality moved to oep_complicance module, keep to avoide 3. party implementation errors
407-
def omi_validateMd(data: dict):
408-
run_metadata_checks(oemetadata=data)
411+
def omi_validateMd(data: dict, jsonschema_validation=False):
412+
run_metadata_checks(oemetadata=data, check_jsonschema=jsonschema_validation)
409413

410414

411415
def getTableSchemaNameFromOEM(metadata):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setuptools.setup(
1010
name="oem2orm",
11-
version="0.3.1",
11+
version="0.3.2",
1212
author="henhuy, jh-RLI",
1313
author_email="Hendrik.Huyskens@rl-institut.de",
1414
description="SQLAlchemy module to generate ORM, read from data model (oedatamodel) in open-energy-metadata JSON format",

0 commit comments

Comments
 (0)