Skip to content

Commit 1197858

Browse files
authored
Merge branch 'main' into main
2 parents 74fb8ab + fb453cc commit 1197858

7 files changed

Lines changed: 152 additions & 96 deletions

File tree

datacontract/cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
from datacontract.data_contract import DataContract, ExportFormat
1616
from datacontract.imports.importer import ImportFormat, Spec
1717
from datacontract.init.init_template import get_init_template
18-
from datacontract.integration.datamesh_manager import (
19-
publish_data_contract_to_datamesh_manager,
18+
from datacontract.integration.entropy_data import (
19+
publish_data_contract_to_entropy_data,
2020
)
2121
from datacontract.lint.resolve import resolve_data_contract_dict
2222
from datacontract.model.exceptions import DataContractException
@@ -406,7 +406,7 @@ def publish(
406406
"""
407407
enable_debug_logging(debug)
408408

409-
publish_data_contract_to_datamesh_manager(
409+
publish_data_contract_to_entropy_data(
410410
data_contract_dict=resolve_data_contract_dict(location),
411411
ssl_verification=ssl_verification,
412412
)

datacontract/data_contract.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from datacontract.export.exporter_factory import exporter_factory
2525
from datacontract.imports.importer_factory import importer_factory
2626
from datacontract.init.init_template import get_init_template
27-
from datacontract.integration.datamesh_manager import publish_test_results_to_datamesh_manager
27+
from datacontract.integration.entropy_data import publish_test_results_to_entropy_data
2828
from datacontract.lint import resolve
2929
from datacontract.model.data_contract_specification import DataContractSpecification, Info
3030
from datacontract.model.exceptions import DataContractException
@@ -151,7 +151,7 @@ def test(self) -> Run:
151151
run.finish()
152152

153153
if self._publish_url is not None or self._publish_test_results:
154-
publish_test_results_to_datamesh_manager(run, self._publish_url, self._ssl_verification)
154+
publish_test_results_to_entropy_data(run, self._publish_url, self._ssl_verification)
155155

156156
return run
157157

datacontract/integration/datamesh_manager.py

Lines changed: 0 additions & 86 deletions
This file was deleted.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import os
2+
from urllib.parse import urlparse
3+
4+
import requests
5+
6+
from datacontract.model.run import Run
7+
8+
# used to retrieve the HTML location of the published data contract or test results
9+
RESPONSE_HEADER_LOCATION_HTML = "location-html"
10+
11+
12+
def publish_test_results_to_entropy_data(run: Run, publish_url: str, ssl_verification: bool):
13+
try:
14+
host = publish_url
15+
if publish_url is None:
16+
# this url supports Data Mesh Manager and Data Contract Manager
17+
host = _get_host()
18+
url = "%s/api/test-results" % host
19+
else:
20+
url = publish_url
21+
22+
api_key = _get_api_key()
23+
24+
if run.dataContractId is None:
25+
raise Exception("Cannot publish run results for unknown data contract ID")
26+
27+
headers = {"Content-Type": "application/json", "x-api-key": api_key}
28+
request_body = run.model_dump_json()
29+
# print("Request Body:", request_body)
30+
response = requests.post(
31+
url,
32+
data=request_body,
33+
headers=headers,
34+
verify=ssl_verification,
35+
)
36+
# print("Status Code:", response.status_code)
37+
# print("Response Body:", response.text)
38+
if response.status_code != 200:
39+
display_host = _extract_hostname(host)
40+
run.log_error(f"Error publishing test results to {display_host}: {response.text}")
41+
return
42+
run.log_info("Published test results successfully")
43+
44+
location_html = response.headers.get(RESPONSE_HEADER_LOCATION_HTML)
45+
if location_html is not None and len(location_html) > 0:
46+
print(f"🚀 Open {location_html}")
47+
48+
except Exception as e:
49+
run.log_error(f"Failed publishing test results. Error: {str(e)}")
50+
51+
52+
def publish_data_contract_to_entropy_data(data_contract_dict: dict, ssl_verification: bool):
53+
try:
54+
api_key = _get_api_key()
55+
host = _get_host()
56+
headers = {"Content-Type": "application/json", "x-api-key": api_key}
57+
id = data_contract_dict["id"]
58+
url = f"{host}/api/datacontracts/{id}"
59+
response = requests.put(
60+
url=url,
61+
json=data_contract_dict,
62+
headers=headers,
63+
verify=ssl_verification,
64+
)
65+
if response.status_code != 200:
66+
display_host = _extract_hostname(host)
67+
print(f"Error publishing data contract to {display_host}: {response.text}")
68+
exit(1)
69+
70+
print("✅ Published data contract successfully")
71+
72+
location_html = response.headers.get(RESPONSE_HEADER_LOCATION_HTML)
73+
if location_html is not None and len(location_html) > 0:
74+
print(f"🚀 Open {location_html}")
75+
76+
except Exception as e:
77+
print(f"Failed publishing data contract. Error: {str(e)}")
78+
79+
80+
def _get_api_key() -> str:
81+
"""
82+
Get API key from environment variables with fallback priority:
83+
1. ENTROPY_DATA_API_KEY
84+
2. DATAMESH_MANAGER_API_KEY
85+
3. DATACONTRACT_MANAGER_API_KEY
86+
"""
87+
api_key = os.getenv("ENTROPY_DATA_API_KEY")
88+
if api_key is None:
89+
api_key = os.getenv("DATAMESH_MANAGER_API_KEY")
90+
if api_key is None:
91+
api_key = os.getenv("DATACONTRACT_MANAGER_API_KEY")
92+
if api_key is None:
93+
raise Exception(
94+
"Cannot publish, as neither ENTROPY_DATA_API_KEY, DATAMESH_MANAGER_API_KEY, nor DATACONTRACT_MANAGER_API_KEY is set"
95+
)
96+
return api_key
97+
98+
99+
def _get_host() -> str:
100+
"""
101+
Get host from environment variables with fallback priority:
102+
1. ENTROPY_DATA_HOST
103+
2. DATAMESH_MANAGER_HOST
104+
3. DATACONTRACT_MANAGER_HOST
105+
4. Default: https://api.entropy-data.com
106+
"""
107+
host = os.getenv("ENTROPY_DATA_HOST")
108+
if host is None:
109+
host = os.getenv("DATAMESH_MANAGER_HOST")
110+
if host is None:
111+
host = os.getenv("DATACONTRACT_MANAGER_HOST")
112+
if host is None:
113+
host = "https://api.entropy-data.com"
114+
return host
115+
116+
117+
def _extract_hostname(url: str) -> str:
118+
"""
119+
Extract the hostname (including subdomains and top-level domain) from a URL.
120+
121+
Examples:
122+
- https://app.entropy-data.com/path -> app.entropy-data.com
123+
- http://api.example.com:8080/api -> api.example.com
124+
"""
125+
parsed = urlparse(url)
126+
return parsed.netloc.split(":")[0] if parsed.netloc else url

datacontract/lint/urls.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,22 @@ def fetch_resource(url: str):
2828
def _set_api_key(headers, url):
2929
hostname = urlparse(url).hostname
3030

31+
entropy_data_api_key = os.getenv("ENTROPY_DATA_API_KEY")
3132
datamesh_manager_api_key = os.getenv("DATAMESH_MANAGER_API_KEY")
3233
datacontract_manager_api_key = os.getenv("DATACONTRACT_MANAGER_API_KEY")
3334

34-
if hostname == "datamesh-manager.com" or hostname.endswith(".datamesh-manager.com"):
35+
if hostname == "entropy-data.com" or hostname.endswith(".entropy-data.com"):
36+
if entropy_data_api_key is None or entropy_data_api_key == "":
37+
print("Error: Entropy Data API key is not set. Set env variable ENTROPY_DATA_API_KEY.")
38+
raise DataContractException(
39+
type="lint",
40+
name=f"Reading data contract from {url}",
41+
reason="Error: Entropy Data API key is not set. Set env variable ENTROPY_DATA_API_KEY.",
42+
engine="datacontract",
43+
result="error",
44+
)
45+
headers["x-api-key"] = entropy_data_api_key
46+
elif hostname == "datamesh-manager.com" or hostname.endswith(".datamesh-manager.com"):
3547
if datamesh_manager_api_key is None or datamesh_manager_api_key == "":
3648
print("Error: Data Mesh Manager API key is not set. Set env variable DATAMESH_MANAGER_API_KEY.")
3749
raise DataContractException(
@@ -54,7 +66,9 @@ def _set_api_key(headers, url):
5466
)
5567
headers["x-api-key"] = datacontract_manager_api_key
5668

57-
if datamesh_manager_api_key is not None and datamesh_manager_api_key != "":
58-
headers["x-api-key"] = datamesh_manager_api_key
5969
if datacontract_manager_api_key is not None and datacontract_manager_api_key != "":
6070
headers["x-api-key"] = datacontract_manager_api_key
71+
if datamesh_manager_api_key is not None and datamesh_manager_api_key != "":
72+
headers["x-api-key"] = datamesh_manager_api_key
73+
if entropy_data_api_key is not None and entropy_data_api_key != "":
74+
headers["x-api-key"] = entropy_data_api_key
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
)
1616
def test_remote_data_contract():
1717
data_contract = DataContract(
18-
data_contract_file="https://app.datamesh-manager.com/checker1/datacontracts/verbraucherpreisindex-61111-0002zzz",
19-
publish_url="https://api.datamesh-manager.com/api/test-results",
18+
data_contract_file="https://app.entropy-data.com/checker1/datacontracts/verbraucherpreisindex-61111-0002zzz",
19+
publish_url="https://api.entropy-data.com/api/test-results",
2020
)
2121

2222
run = data_contract.test()

tests/test_test_oracle.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
oracleContainer = OracleDbContainer("gvenzl/oracle-free:slim-faststart")
99
ORACLE_SERVER_PORT: int = 1521
1010

11+
1112
@pytest.fixture(scope="module", autouse=True)
1213
def oracle_container(request):
1314
oracleContainer.start()
@@ -60,6 +61,7 @@ def _init_sql(sql_file_path):
6061
except DatabaseError as e:
6162
print(f"Error executing SQL command: {e}", sql_command)
6263

64+
6365
def _setup_datacontract(datacontract):
6466
with open(datacontract) as data_contract_file:
6567
data_contract_str = data_contract_file.read()

0 commit comments

Comments
 (0)