-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ENH] Added interface with Liquid Earth
- Loading branch information
Showing
5 changed files
with
271 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,3 +73,6 @@ venv.bak/ | |
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
|
||
.local_settings.json |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import json | ||
import uuid | ||
from enum import Enum, auto | ||
|
||
import requests | ||
|
||
|
||
class DataTypes(Enum): | ||
static_mesh = "static_mesh" | ||
collars = "wells/collars" | ||
cylinder = "wells/cylinders" | ||
volumes = "volumes" | ||
|
||
|
||
class LiquidEarthClient(): | ||
token: str | ||
user_id: str | ||
|
||
# Move to local settings | ||
host = "https://apim-liquidearth.azure-api.net/" | ||
|
||
@property | ||
def header(self): | ||
header_dict = { | ||
"Authorization": f"Bearer {self.token}" | ||
} | ||
return header_dict | ||
|
||
def login(self, username: str, password: str): | ||
end_point = "user/#_b2c" | ||
|
||
data = { | ||
"username": username, | ||
"password": password, | ||
"grant_type": "password", | ||
"client_id": "685e08c0-0aac-42f6-80a9-c57440cd2962", | ||
"scope": "openid 685e08c0-0aac-42f6-80a9-c57440cd2962 offline_access" | ||
} | ||
|
||
response = requests.post(self.host + end_point, data=data) | ||
if response.status_code == 400: | ||
raise Exception(f"Request failed: {response.text}") | ||
elif response.status_code == 200: | ||
_json = response.json() | ||
self.token = _json["access_token"] | ||
self.user_id = username | ||
|
||
def get_available_projects(self): | ||
end_point = "cosmos-le/v1/available_projects/" | ||
response = requests.get(self.host + end_point, headers=self.header) | ||
|
||
if response.status_code >= 400: | ||
raise Exception(f"Request failed: {response.text}") | ||
elif response.status_code >= 200: | ||
print(response.json()) | ||
return response.json() | ||
|
||
def add_new_project(self, project_name, extent, project_id=None): | ||
if project_id is None: | ||
project_id = str(uuid.uuid4()) | ||
|
||
available_projects: list = self.get_available_projects() | ||
|
||
for project in available_projects: | ||
if project["project_id"] == project_id: | ||
raise ValueError("This Project already exists") | ||
|
||
new_project = { | ||
"project_name": project_name, | ||
"project_id": project_id | ||
} | ||
available_projects.append(new_project) | ||
self._post_available_projects(available_projects) | ||
|
||
new_project_meta = { | ||
"remote_name": project_name, | ||
"id": project_id, | ||
"owner": self.user_id, | ||
"extent": extent, | ||
"static_data_address": [] | ||
} | ||
self._post_project_meta(new_project_meta) | ||
return project_id | ||
|
||
def add_data_to_project(self, project_id: str, data_name: str, data_type: DataTypes, | ||
header: json, body: bytearray): | ||
|
||
self._post_update_meta_data(project_id, data_name, data_type) | ||
self._put_file_in_project(project_id, data_name + ".le", data_type, body) | ||
self._put_file_in_project(project_id, data_name + ".json", data_type, json.dumps(header)) | ||
|
||
def _put_file_in_project(self, project_id: str, data_name, data_type: DataTypes, file): | ||
blob_path = data_type.value + "/" + data_name | ||
|
||
end_point = f"container/{project_id}/{blob_path}" | ||
response = requests.put(self.host + end_point, data=file, headers=self.header) | ||
|
||
if response.status_code >= 400: | ||
raise Exception(f"Request failed: {response.text}") | ||
elif response.status_code >= 200: | ||
print(response.text) | ||
|
||
def _post_update_meta_data(self, project_id: str, data_name: str, data_type: DataTypes): | ||
|
||
query_param = f"?project_id={project_id}&data_id={data_name}&data_type={data_type.value}" | ||
end_point = "http://localhost:7071/api/update_project_meta" + query_param | ||
|
||
response = requests.post(end_point) | ||
|
||
if response.status_code >= 400: | ||
raise Exception(f"Request failed: {response.text}") | ||
elif response.status_code >= 200: | ||
print(response.text) | ||
|
||
def _post_available_projects(self, available_projects: list): | ||
end_point = "cosmos-le/v1/available_projects/" | ||
response = requests.post(self.host + end_point, json=available_projects, | ||
headers=self.header) | ||
|
||
if response.status_code >= 400: | ||
raise Exception(f"Request failed: {response.text}") | ||
elif response.status_code >= 200: | ||
print("Available Projects Posted") | ||
|
||
def _post_project_meta(self, meta_data: dict): | ||
project_id = meta_data["id"] | ||
|
||
end_point = f"cosmos-le/v1/project_meta/?project_id={project_id}" | ||
response = requests.post(self.host + end_point, json=meta_data, headers=self.header) | ||
|
||
if response.status_code >= 400: | ||
raise Exception(f"Request failed: {response.text}") | ||
elif response.status_code >= 200: | ||
print("Project Metadata Posted") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import pytest | ||
|
||
import subsurface | ||
from subsurface.interfaces.liquid_earth.rest_client import LiquidEarthClient, DataTypes | ||
from subsurface.reader.read_netcdf import read_unstruct, read_struct | ||
|
||
from subsurface.reader.mesh.surface_reader import dxf_to_mesh | ||
import trimesh | ||
import numpy as np | ||
import pandas | ||
|
||
|
||
@pytest.mark.skip(reason="This functionality is under development and it is supposed to be trigger" | ||
"only manually.") | ||
class TestLiquidEarthClient: | ||
|
||
@pytest.fixture(scope="module") | ||
def liquid_earth_client(self): | ||
c = LiquidEarthClient() | ||
c.login( | ||
"yourUser", # TODO: Add your LiquidEarth Credentials here! | ||
"yourPassword" | ||
) | ||
return c | ||
|
||
def test_upload_data_to_new_project(self, liquid_earth_client, data_path): | ||
liquid_earth_client.add_new_project( | ||
"Shafts", | ||
project_id="museum", | ||
extent=[5.87907467e+05, 5.88328512e+05, 6.64175515e+06, 6.64232280e+06, -2.45600098e+02, | ||
7.30000000e+01] | ||
) | ||
|
||
unstruc = self.test_dataset2(data_path) | ||
|
||
body, header = unstruc.to_binary() | ||
|
||
liquid_earth_client.add_data_to_project( | ||
project_id="museum", | ||
data_name="shafts_meshes", | ||
data_type=DataTypes.static_mesh, | ||
header=header, | ||
body=body | ||
) | ||
|
||
def test_get_valid_token(self): | ||
client = LiquidEarthClient() | ||
client.login("miguel@terranigma-solutions.com", "demoaccount") | ||
|
||
def test_get_available_projects(self, liquid_earth_client): | ||
liquid_earth_client.get_available_projects() | ||
|
||
def test_add_new_project(self, liquid_earth_client): | ||
liquid_earth_client.add_new_project( | ||
"subsurface_project", | ||
project_id="52f88baa-c84c-4082-bbba-869ef3819004", | ||
extent=[0, 10, -10, 0, 0, 10] | ||
) | ||
|
||
def test_add_data_to_project(self, liquid_earth_client, data_path): | ||
us = read_unstruct(data_path + '/interpolator_meshes.nc') | ||
print(us.extent) | ||
body, header = us.to_binary() | ||
|
||
liquid_earth_client.add_data_to_project( | ||
project_id="52f88baa-c84c-4082-bbba-869ef3819004", | ||
data_name="data_from_subsurface", | ||
data_type=DataTypes.static_mesh, | ||
header=header, | ||
body=body | ||
) | ||
|
||
def test_update_meta_data(self, liquid_earth_client): | ||
liquid_earth_client._post_update_meta_data( | ||
project_id="52f88baa-c84c-4082-bbba-869ef3819004", | ||
data_name="data_from_subsurface.le", | ||
data_type=DataTypes.static_mesh | ||
) | ||
|
||
return | ||
|
||
def test_dataset1(self, data_path): | ||
us = read_unstruct(data_path + '/interpolator_meshes.nc') | ||
|
||
def test_dataset2(self, data_path): | ||
path = data_path + '/surfaces/shafts.dxf' | ||
|
||
vertex, cells, cell_attr_int, cell_attr_map = dxf_to_mesh(path) | ||
|
||
tri = trimesh.Trimesh(vertex, faces=cells) | ||
|
||
unstruct = subsurface.UnstructuredData.from_array( | ||
np.array(tri.vertices), | ||
np.array(tri.faces), | ||
cells_attr=pandas.DataFrame(cell_attr_int, columns=["Shaft id"]), | ||
xarray_attributes={"bounds": tri.bounds.tolist(), | ||
"cell_attr_map": cell_attr_map | ||
}, | ||
) | ||
|
||
print(unstruct.extent) | ||
if True: | ||
trisurf = subsurface.TriSurf(unstruct) | ||
s = subsurface.visualization.to_pyvista_mesh(trisurf) | ||
subsurface.visualization.pv_plot([s], image_2d=True) | ||
|
||
return unstruct | ||
|
||
def test_put_file_in_project(self, liquid_earth_client, data_path): | ||
us = read_unstruct(data_path + '/interpolator_meshes.nc') | ||
print(us.extent) | ||
body, header = us.to_binary() | ||
|
||
liquid_earth_client._put_file_in_project( | ||
project_id="52f88baa-c84c-4082-bbba-869ef3819004", | ||
data_name="data_from_subsurface.le", | ||
data_type=DataTypes.static_mesh, | ||
file=body | ||
) | ||
|
||
liquid_earth_client._put_file_in_project( | ||
project_id="52f88baa-c84c-4082-bbba-869ef3819004", | ||
data_name="data_from_subsurface.json", | ||
data_type=DataTypes.static_mesh, | ||
file=header | ||
) |