pyetp 0.0.31__py3-none-any.whl → 0.0.33__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.
- pyetp/client.py +104 -154
- pyetp/config.py +6 -11
- pyetp/types.py +66 -1
- pyetp/uri.py +3 -4
- pyetp/utils.py +11 -2
- pyetp/utils_xml.py +21 -19
- {pyetp-0.0.31.dist-info → pyetp-0.0.33.dist-info}/METADATA +3 -5
- pyetp-0.0.33.dist-info/RECORD +14 -0
- {pyetp-0.0.31.dist-info → pyetp-0.0.33.dist-info}/WHEEL +1 -1
- pyetp-0.0.31.dist-info/RECORD +0 -14
- {pyetp-0.0.31.dist-info → pyetp-0.0.33.dist-info}/LICENSE.md +0 -0
pyetp/client.py
CHANGED
|
@@ -5,10 +5,8 @@ import sys
|
|
|
5
5
|
import typing as T
|
|
6
6
|
import uuid
|
|
7
7
|
from collections import defaultdict
|
|
8
|
-
from contextlib import asynccontextmanager
|
|
9
8
|
from types import TracebackType
|
|
10
9
|
import time
|
|
11
|
-
|
|
12
10
|
import numpy as np
|
|
13
11
|
import websockets
|
|
14
12
|
from etpproto.connection import (CommunicationProtocol, ConnectionType,
|
|
@@ -18,12 +16,16 @@ from pydantic import SecretStr
|
|
|
18
16
|
from scipy.interpolate import griddata
|
|
19
17
|
from xtgeo import RegularSurface
|
|
20
18
|
|
|
19
|
+
|
|
21
20
|
import pyetp.resqml_objects as ro
|
|
21
|
+
#import energyml.resqml.v2_0_1.resqmlv2 as ro
|
|
22
|
+
#import energyml.eml.v2_0.commonv2 as roc
|
|
22
23
|
from pyetp import utils_arrays, utils_xml
|
|
23
24
|
from pyetp.config import SETTINGS
|
|
24
25
|
from pyetp.types import *
|
|
25
26
|
from pyetp.uri import DataObjectURI, DataspaceURI
|
|
26
|
-
from pyetp.utils import short_id
|
|
27
|
+
from pyetp.utils import short_id, batched
|
|
28
|
+
from asyncio import timeout
|
|
27
29
|
|
|
28
30
|
try:
|
|
29
31
|
# for py >3.11, we can raise grouped exceptions
|
|
@@ -32,27 +34,24 @@ except ImportError:
|
|
|
32
34
|
def ExceptionGroup(msg, errors):
|
|
33
35
|
return errors[0]
|
|
34
36
|
|
|
35
|
-
try:
|
|
36
|
-
|
|
37
|
-
except ImportError:
|
|
38
|
-
|
|
37
|
+
# try:
|
|
38
|
+
# from asyncio import timeout
|
|
39
|
+
# except ImportError:
|
|
40
|
+
# import async_timeout
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
# @asynccontextmanager
|
|
43
|
+
# async def timeout(delay: T.Optional[float]) -> T.Any:
|
|
44
|
+
# try:
|
|
45
|
+
# async with async_timeout.timeout(delay):
|
|
46
|
+
# yield None
|
|
47
|
+
# except asyncio.CancelledError as e:
|
|
48
|
+
# raise asyncio.TimeoutError(f'Timeout ({delay}s)') from e
|
|
47
49
|
|
|
48
50
|
|
|
49
51
|
logger = logging.getLogger(__name__)
|
|
50
52
|
logger.setLevel(logging.INFO)
|
|
51
53
|
|
|
52
54
|
|
|
53
|
-
MAXPAYLOADSIZE = 10_000_000 # 10MB
|
|
54
|
-
|
|
55
|
-
|
|
56
55
|
class ETPError(Exception):
|
|
57
56
|
def __init__(self, message: str, code: int):
|
|
58
57
|
self.message = message
|
|
@@ -88,16 +87,16 @@ class ETPClient(ETPConnection):
|
|
|
88
87
|
_recv_events: T.Dict[int, asyncio.Event]
|
|
89
88
|
_recv_buffer: T.Dict[int, T.List[ETPModel]]
|
|
90
89
|
|
|
91
|
-
def __init__(self, ws: websockets.WebSocketClientProtocol,
|
|
90
|
+
def __init__(self, ws: websockets.WebSocketClientProtocol, timeout=10.):
|
|
92
91
|
super().__init__(connection_type=ConnectionType.CLIENT)
|
|
93
92
|
self._recv_events = {}
|
|
94
93
|
self._recv_buffer = defaultdict(lambda: list()) # type: ignore
|
|
95
|
-
self._default_duri = default_dataspace_uri
|
|
96
94
|
self.ws = ws
|
|
97
95
|
|
|
98
96
|
self.timeout = timeout
|
|
99
|
-
self.client_info.endpoint_capabilities['MaxWebSocketMessagePayloadSize'] =
|
|
97
|
+
self.client_info.endpoint_capabilities['MaxWebSocketMessagePayloadSize'] = SETTINGS.MaxWebSocketMessagePayloadSize
|
|
100
98
|
self.__recvtask = asyncio.create_task(self.__recv__())
|
|
99
|
+
self.max_concurrent_requests = 1
|
|
101
100
|
|
|
102
101
|
#
|
|
103
102
|
# client
|
|
@@ -121,7 +120,7 @@ class ETPClient(ETPConnection):
|
|
|
121
120
|
# create future recv event
|
|
122
121
|
self._recv_events[msg.header.message_id] = asyncio.Event()
|
|
123
122
|
|
|
124
|
-
|
|
123
|
+
for msg_part in msg.encode_message_generator(self.max_size, self):
|
|
125
124
|
await self.ws.send(msg_part)
|
|
126
125
|
|
|
127
126
|
return msg.header.message_id
|
|
@@ -216,21 +215,22 @@ class ETPClient(ETPConnection):
|
|
|
216
215
|
|
|
217
216
|
async def request_session(self):
|
|
218
217
|
# Handshake protocol
|
|
219
|
-
|
|
218
|
+
etp_version = Version(major=1, minor=2, revision=0, patch=0)
|
|
220
219
|
msg = await self.send(
|
|
221
220
|
RequestSession(
|
|
222
221
|
applicationName=SETTINGS.application_name,
|
|
223
222
|
applicationVersion=SETTINGS.application_version,
|
|
224
223
|
clientInstanceId=uuid.uuid4(), # type: ignore
|
|
225
224
|
requestedProtocols=[
|
|
226
|
-
SupportedProtocol(protocol=p.value, protocolVersion=
|
|
227
|
-
for p in
|
|
225
|
+
SupportedProtocol(protocol=p.value, protocolVersion=etp_version, role='store')
|
|
226
|
+
for p in CommunicationProtocol
|
|
228
227
|
],
|
|
229
228
|
supportedDataObjects=[SupportedDataObject(qualifiedType="resqml20.*"), SupportedDataObject(qualifiedType="eml20.*")],
|
|
230
229
|
currentDateTime=self.timestamp,
|
|
231
230
|
earliestRetainedChangeTime=0,
|
|
232
231
|
endpointCapabilities=dict(
|
|
233
|
-
MaxWebSocketMessagePayloadSize=DataValue(item=self.max_size)
|
|
232
|
+
MaxWebSocketMessagePayloadSize=DataValue(item=self.max_size),
|
|
233
|
+
MaxWebSocketFramePayloadSize=DataValue(item=10000)
|
|
234
234
|
)
|
|
235
235
|
)
|
|
236
236
|
)
|
|
@@ -246,10 +246,7 @@ class ETPClient(ETPConnection):
|
|
|
246
246
|
|
|
247
247
|
async def authorize(self, authorization: str, supplemental_authorization: T.Mapping[str, str] = {}):
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
Authorize
|
|
251
|
-
from etptypes.energistics.etp.v12.protocol.core.authorize_response import \
|
|
252
|
-
AuthorizeResponse
|
|
249
|
+
|
|
253
250
|
|
|
254
251
|
msg = await self.send(
|
|
255
252
|
Authorize(
|
|
@@ -275,36 +272,28 @@ class ETPClient(ETPConnection):
|
|
|
275
272
|
def timestamp(self):
|
|
276
273
|
return int(datetime.datetime.now(datetime.timezone.utc).timestamp())
|
|
277
274
|
|
|
278
|
-
@property
|
|
279
|
-
def default_dataspace_uri(self):
|
|
280
|
-
return self._default_duri
|
|
281
|
-
|
|
282
|
-
@default_dataspace_uri.setter
|
|
283
|
-
def default_dataspace_uri(self, v: T.Union[DataspaceURI, str, None]):
|
|
284
|
-
self._default_duri = None if v is None else DataspaceURI.from_any(v)
|
|
285
|
-
|
|
286
|
-
def get_dataspace_or_default_uri(self, ds: T.Union[DataspaceURI, str, None]) -> DataspaceURI:
|
|
287
|
-
"""Returns default dataspace or user spefied one"""
|
|
288
|
-
|
|
289
|
-
if ds is not None:
|
|
290
|
-
return DataspaceURI.from_any(ds)
|
|
291
|
-
|
|
292
|
-
if self._default_duri is None:
|
|
293
|
-
raise ValueError("Could not get dataspace from userinput or default")
|
|
294
|
-
|
|
295
|
-
return self._default_duri
|
|
296
275
|
|
|
276
|
+
def dataspace_uri(self, ds: str) -> DataspaceURI:
|
|
277
|
+
return DataspaceURI.from_name(ds)
|
|
278
|
+
|
|
279
|
+
def list_objects(self, dataspace_uri: DataspaceURI, depth: int = 1) -> list:
|
|
280
|
+
return self.send(GetResources(
|
|
281
|
+
scope=ContextScopeKind.TARGETS_OR_SELF,
|
|
282
|
+
context=ContextInfo(
|
|
283
|
+
uri=dataspace_uri.raw_uri,
|
|
284
|
+
depth=depth,
|
|
285
|
+
dataObjectTypes=[],
|
|
286
|
+
navigableEdges=RelationshipKind.PRIMARY,)
|
|
287
|
+
)
|
|
288
|
+
)
|
|
297
289
|
#
|
|
298
290
|
# dataspace
|
|
299
291
|
#
|
|
300
292
|
|
|
301
|
-
async def put_dataspaces(self, *
|
|
302
|
-
|
|
303
|
-
PutDataspaces
|
|
304
|
-
from etptypes.energistics.etp.v12.protocol.dataspace.put_dataspaces_response import \
|
|
305
|
-
PutDataspacesResponse
|
|
293
|
+
async def put_dataspaces(self, *dataspace_uris: DataspaceURI):
|
|
294
|
+
|
|
306
295
|
|
|
307
|
-
_uris = list(map(DataspaceURI.from_any,
|
|
296
|
+
_uris = list(map(DataspaceURI.from_any, dataspace_uris))
|
|
308
297
|
|
|
309
298
|
time = self.timestamp
|
|
310
299
|
response = await self.send(
|
|
@@ -315,23 +304,20 @@ class ETPClient(ETPConnection):
|
|
|
315
304
|
)
|
|
316
305
|
assert isinstance(response, PutDataspacesResponse), "Expected PutDataspacesResponse"
|
|
317
306
|
|
|
318
|
-
assert len(response.success) == len(
|
|
307
|
+
assert len(response.success) == len(dataspace_uris), f"expected {len(dataspace_uris)} success's"
|
|
319
308
|
|
|
320
309
|
return response.success
|
|
321
310
|
|
|
322
|
-
async def put_dataspaces_no_raise(self, *
|
|
311
|
+
async def put_dataspaces_no_raise(self, *dataspace_uris: DataspaceURI):
|
|
323
312
|
try:
|
|
324
|
-
return await self.put_dataspaces(*
|
|
313
|
+
return await self.put_dataspaces(*dataspace_uris)
|
|
325
314
|
except ETPError:
|
|
326
315
|
pass
|
|
327
316
|
|
|
328
|
-
async def delete_dataspaces(self, *
|
|
329
|
-
from etptypes.energistics.etp.v12.protocol.dataspace.delete_dataspaces import \
|
|
330
|
-
DeleteDataspaces
|
|
331
|
-
from etptypes.energistics.etp.v12.protocol.dataspace.delete_dataspaces_response import \
|
|
332
|
-
DeleteDataspacesResponse
|
|
317
|
+
async def delete_dataspaces(self, *dataspace_uris: DataspaceURI):
|
|
333
318
|
|
|
334
|
-
|
|
319
|
+
|
|
320
|
+
_uris = list(map(str, dataspace_uris))
|
|
335
321
|
|
|
336
322
|
response = await self.send(DeleteDataspaces(uris=dict(zip(_uris, _uris))))
|
|
337
323
|
assert isinstance(response, DeleteDataspacesResponse), "Expected DeleteDataspacesResponse"
|
|
@@ -343,11 +329,6 @@ class ETPClient(ETPConnection):
|
|
|
343
329
|
|
|
344
330
|
async def get_data_objects(self, *uris: T.Union[DataObjectURI, str]):
|
|
345
331
|
|
|
346
|
-
from etptypes.energistics.etp.v12.protocol.store.get_data_objects import \
|
|
347
|
-
GetDataObjects
|
|
348
|
-
from etptypes.energistics.etp.v12.protocol.store.get_data_objects_response import \
|
|
349
|
-
GetDataObjectsResponse
|
|
350
|
-
|
|
351
332
|
_uris = list(map(str, uris))
|
|
352
333
|
|
|
353
334
|
msg = await self.send(
|
|
@@ -360,10 +341,7 @@ class ETPClient(ETPConnection):
|
|
|
360
341
|
|
|
361
342
|
async def put_data_objects(self, *objs: DataObject):
|
|
362
343
|
|
|
363
|
-
|
|
364
|
-
PutDataObjects
|
|
365
|
-
from etptypes.energistics.etp.v12.protocol.store.put_data_objects_response import \
|
|
366
|
-
PutDataObjectsResponse
|
|
344
|
+
|
|
367
345
|
|
|
368
346
|
response = await self.send(
|
|
369
347
|
PutDataObjects(dataObjects={f"{p.resource.name}_{short_id()}": p for p in objs})
|
|
@@ -378,12 +356,10 @@ class ETPClient(ETPConnection):
|
|
|
378
356
|
data_objects = await self.get_data_objects(*uris)
|
|
379
357
|
return utils_xml.parse_resqml_objects(data_objects)
|
|
380
358
|
|
|
381
|
-
async def put_resqml_objects(self, *objs: ro.AbstractObject,
|
|
382
|
-
|
|
383
|
-
Resource
|
|
359
|
+
async def put_resqml_objects(self, *objs: ro.AbstractObject, dataspace_uri: DataspaceURI):
|
|
360
|
+
|
|
384
361
|
time = self.timestamp
|
|
385
|
-
|
|
386
|
-
uris = [DataObjectURI.from_obj(duri, obj) for obj in objs]
|
|
362
|
+
uris = [DataObjectURI.from_obj(dataspace_uri, obj) for obj in objs]
|
|
387
363
|
dobjs = [DataObject(
|
|
388
364
|
format="xml",
|
|
389
365
|
data=utils_xml.resqml_to_xml(obj),
|
|
@@ -403,10 +379,7 @@ class ETPClient(ETPConnection):
|
|
|
403
379
|
return uris
|
|
404
380
|
|
|
405
381
|
async def delete_data_objects(self, *uris: T.Union[DataObjectURI, str], pruneContainedObjects=False):
|
|
406
|
-
|
|
407
|
-
DeleteDataObjects
|
|
408
|
-
from etptypes.energistics.etp.v12.protocol.store.delete_data_objects_response import \
|
|
409
|
-
DeleteDataObjectsResponse
|
|
382
|
+
|
|
410
383
|
|
|
411
384
|
_uris = list(map(str, uris))
|
|
412
385
|
|
|
@@ -420,7 +393,6 @@ class ETPClient(ETPConnection):
|
|
|
420
393
|
assert isinstance(response, DeleteDataObjectsResponse), "Expected DeleteDataObjectsResponse"
|
|
421
394
|
|
|
422
395
|
return response.deleted_uris
|
|
423
|
-
|
|
424
396
|
#
|
|
425
397
|
# xtgeo
|
|
426
398
|
#
|
|
@@ -446,7 +418,7 @@ class ETPClient(ETPConnection):
|
|
|
446
418
|
y_ind = (y-patch.geometry.points.supporting_geometry.origin.coordinate2)/patch.geometry.points.supporting_geometry.offset[1].spacing.value
|
|
447
419
|
return round(x_ind), round(y_ind)
|
|
448
420
|
|
|
449
|
-
async def get_surface_value_x_y(self, epc_uri: T.Union[DataObjectURI, str], gri_uri: T.Union[DataObjectURI, str], x: T.Union[int, float], y: T.Union[int, float], method: T.Literal["bilinear", "nearest"]):
|
|
421
|
+
async def get_surface_value_x_y(self, epc_uri: T.Union[DataObjectURI, str], gri_uri: T.Union[DataObjectURI, str],crs_uri: T.Union[DataObjectURI, str], x: T.Union[int, float], y: T.Union[int, float], method: T.Literal["bilinear", "nearest"]):
|
|
450
422
|
gri, = await self.get_resqml_objects(gri_uri) # parallelized using subarray
|
|
451
423
|
xori = gri.grid2d_patch.geometry.points.supporting_geometry.origin.coordinate1
|
|
452
424
|
yori = gri.grid2d_patch.geometry.points.supporting_geometry.origin.coordinate2
|
|
@@ -462,7 +434,7 @@ class ETPClient(ETPConnection):
|
|
|
462
434
|
uri=str(epc_uri), pathInResource=gri.grid2d_patch.geometry.points.zvalues.values.path_in_hdf_file
|
|
463
435
|
)
|
|
464
436
|
if max_x_index_in_gri <= 10 or max_y_index_in_gri <= 10:
|
|
465
|
-
surf = await self.get_xtgeo_surface(epc_uri, gri_uri)
|
|
437
|
+
surf = await self.get_xtgeo_surface(epc_uri, gri_uri, crs_uri)
|
|
466
438
|
return surf.get_value_from_xy((x, y), sampling=method)
|
|
467
439
|
|
|
468
440
|
x_ind, y_ind = self.find_closest_index(x, y, gri.grid2d_patch)
|
|
@@ -499,21 +471,12 @@ class ETPClient(ETPConnection):
|
|
|
499
471
|
)
|
|
500
472
|
return regridded.get_value_from_xy((x, y))
|
|
501
473
|
|
|
502
|
-
async def get_xtgeo_surface(self, epc_uri: T.Union[DataObjectURI, str], gri_uri: T.Union[DataObjectURI, str], crs_uri: T.Union[DataObjectURI, str
|
|
503
|
-
|
|
504
|
-
logger.debug("NO crs")
|
|
505
|
-
gri, = await self.get_resqml_objects(gri_uri)
|
|
506
|
-
crs_uuid = gri.grid2d_patch.geometry.local_crs.uuid
|
|
507
|
-
dataspace_uri = self.get_dataspace_or_default_uri(epc_uri)
|
|
508
|
-
crs_eml = f"{dataspace_uri}/resqml20.LocalDepth3dCrs({crs_uuid})"
|
|
509
|
-
crs, = await self.get_resqml_objects(crs_eml)
|
|
510
|
-
logger.debug("got crs")
|
|
511
|
-
else:
|
|
512
|
-
gri, crs, = await self.get_resqml_objects(gri_uri, crs_uri)
|
|
474
|
+
async def get_xtgeo_surface(self, epc_uri: T.Union[DataObjectURI, str], gri_uri: T.Union[DataObjectURI, str], crs_uri: T.Union[DataObjectURI, str]):
|
|
475
|
+
gri, crs, = await self.get_resqml_objects(gri_uri, crs_uri)
|
|
513
476
|
rotation = crs.areal_rotation.value
|
|
514
477
|
# some checks
|
|
515
478
|
|
|
516
|
-
assert isinstance(gri, ro.Grid2dRepresentation), "obj must be
|
|
479
|
+
assert isinstance(gri, ro.Grid2dRepresentation), "obj must be Grid2DRepresentation"
|
|
517
480
|
sgeo = gri.grid2d_patch.geometry.points.supporting_geometry # type: ignore
|
|
518
481
|
if sys.version_info[1] != 10:
|
|
519
482
|
assert isinstance(gri.grid2d_patch.geometry.points, ro.Point3dZValueArray), "Points must be Point3dZValueArray"
|
|
@@ -537,13 +500,24 @@ class ETPClient(ETPConnection):
|
|
|
537
500
|
rotation=rotation,
|
|
538
501
|
masked=True
|
|
539
502
|
)
|
|
540
|
-
|
|
541
|
-
|
|
503
|
+
async def start_transaction(self, dataspace_uri: DataspaceURI, readOnly :bool= True) -> uuid.UUID:
|
|
504
|
+
trans_id = await self.send(StartTransaction(readOnly=readOnly, dataspaceUris=[dataspace_uri.raw_uri]))
|
|
505
|
+
return uuid.UUID(bytes=trans_id.transaction_uuid)
|
|
506
|
+
|
|
507
|
+
async def commit_transaction(self, transaction_id: uuid.UUID):
|
|
508
|
+
trans_id = await self.send(CommitTransaction(transaction_uuid=transaction_id))
|
|
509
|
+
return trans_id
|
|
510
|
+
|
|
511
|
+
async def rollback_transaction(self, transaction_id: uuid.UUID):
|
|
512
|
+
return await self.send(RollbackTransaction(transactionUuid=transaction_id))
|
|
513
|
+
|
|
514
|
+
async def put_xtgeo_surface(self, surface: RegularSurface, epsg_code: int, dataspace_uri: DataspaceURI):
|
|
542
515
|
"""Returns (epc_uri, crs_uri, gri_uri)"""
|
|
543
516
|
assert surface.values is not None, "cannot upload empty surface"
|
|
544
|
-
|
|
517
|
+
|
|
518
|
+
|
|
545
519
|
epc, crs, gri = utils_xml.parse_xtgeo_surface_to_resqml_grid(surface, epsg_code)
|
|
546
|
-
epc_uri, crs_uri, gri_uri = await self.put_resqml_objects(epc, crs, gri,
|
|
520
|
+
epc_uri, crs_uri, gri_uri = await self.put_resqml_objects(epc, crs, gri, dataspace_uri=dataspace_uri)
|
|
547
521
|
response = await self.put_array(
|
|
548
522
|
DataArrayIdentifier(
|
|
549
523
|
uri=epc_uri.raw_uri if isinstance(epc_uri, DataObjectURI) else epc_uri,
|
|
@@ -552,7 +526,7 @@ class ETPClient(ETPConnection):
|
|
|
552
526
|
surface.values.filled(np.nan).astype(np.float32)
|
|
553
527
|
)
|
|
554
528
|
|
|
555
|
-
return epc_uri,
|
|
529
|
+
return epc_uri, gri_uri, crs_uri
|
|
556
530
|
|
|
557
531
|
#
|
|
558
532
|
# resqpy meshes
|
|
@@ -562,7 +536,7 @@ class ETPClient(ETPConnection):
|
|
|
562
536
|
uns, = await self.get_resqml_objects(uns_uri)
|
|
563
537
|
|
|
564
538
|
# some checks
|
|
565
|
-
assert isinstance(uns, ro.UnstructuredGridRepresentation), "obj must be
|
|
539
|
+
assert isinstance(uns, ro.UnstructuredGridRepresentation), "obj must be UnstructuredGridRepresentation"
|
|
566
540
|
assert isinstance(uns.geometry, ro.UnstructuredGridGeometry), "geometry must be UnstructuredGridGeometry"
|
|
567
541
|
if sys.version_info[1] != 10:
|
|
568
542
|
assert isinstance(uns.geometry.points, ro.Point3dHdf5Array), "points must be Point3dHdf5Array"
|
|
@@ -706,14 +680,15 @@ class ETPClient(ETPConnection):
|
|
|
706
680
|
async def put_rddms_property(self, epc_uri: T.Union[DataObjectURI , str],
|
|
707
681
|
cprop0: T.Union[ro.ContinuousProperty, ro.DiscreteProperty],
|
|
708
682
|
propertykind0: ro.PropertyKind,
|
|
709
|
-
array_ref: np.ndarray,
|
|
683
|
+
array_ref: np.ndarray,
|
|
684
|
+
dataspace_uri: DataspaceURI ):
|
|
710
685
|
|
|
711
686
|
assert isinstance(cprop0, ro.ContinuousProperty) or isinstance(cprop0, ro.DiscreteProperty), "prop must be a Property"
|
|
712
687
|
assert len(cprop0.patch_of_values) == 1, "property obj must have exactly one patch of values"
|
|
713
688
|
|
|
714
689
|
st = time.time()
|
|
715
|
-
propkind_uri = [""] if (propertykind0 is None) else (await self.put_resqml_objects(propertykind0,
|
|
716
|
-
cprop_uri = await self.put_resqml_objects(cprop0,
|
|
690
|
+
propkind_uri = [""] if (propertykind0 is None) else (await self.put_resqml_objects(propertykind0, dataspace_uri=dataspace_uri))
|
|
691
|
+
cprop_uri = await self.put_resqml_objects(cprop0, dataspace_uri=dataspace_uri)
|
|
717
692
|
delay = time.time() - st
|
|
718
693
|
logger.debug(f"pyetp: put_rddms_property: put objects took {delay} s")
|
|
719
694
|
|
|
@@ -731,13 +706,13 @@ class ETPClient(ETPConnection):
|
|
|
731
706
|
|
|
732
707
|
async def put_epc_mesh(
|
|
733
708
|
self, epc_filename: str, title_in: str, property_titles: T.List[str], projected_epsg: int,
|
|
734
|
-
|
|
709
|
+
dataspace_uri: DataspaceURI
|
|
735
710
|
):
|
|
736
711
|
uns, crs, epc, timeseries, hexa = utils_xml.convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg)
|
|
737
|
-
epc_uri, crs_uri, uns_uri = await self.put_resqml_objects(epc, crs, uns,
|
|
712
|
+
epc_uri, crs_uri, uns_uri = await self.put_resqml_objects(epc, crs, uns, dataspace_uri=dataspace_uri)
|
|
738
713
|
timeseries_uri = ""
|
|
739
714
|
if timeseries is not None:
|
|
740
|
-
timeseries_uris = await self.put_resqml_objects(timeseries,
|
|
715
|
+
timeseries_uris = await self.put_resqml_objects(timeseries, dataspace_uri=dataspace_uri)
|
|
741
716
|
timeseries_uri = list(timeseries_uris)[0] if (len(list(timeseries_uris)) > 0) else ""
|
|
742
717
|
|
|
743
718
|
#
|
|
@@ -808,7 +783,7 @@ class ETPClient(ETPConnection):
|
|
|
808
783
|
|
|
809
784
|
cprop_uris = []
|
|
810
785
|
for cprop0, prop, time_index in zip(cprop0s, props, time_indices):
|
|
811
|
-
cprop_uri, propkind_uri = await self.put_rddms_property(epc_uri, cprop0, propertykind0, prop.array_ref(),
|
|
786
|
+
cprop_uri, propkind_uri = await self.put_rddms_property(epc_uri, cprop0, propertykind0, prop.array_ref(), dataspace_uri)
|
|
812
787
|
cprop_uris.extend(cprop_uri)
|
|
813
788
|
prop_rddms_uris[propname] = [propkind_uri, cprop_uris]
|
|
814
789
|
|
|
@@ -881,10 +856,7 @@ class ETPClient(ETPConnection):
|
|
|
881
856
|
#
|
|
882
857
|
|
|
883
858
|
async def get_array_metadata(self, *uids: DataArrayIdentifier):
|
|
884
|
-
|
|
885
|
-
GetDataArrayMetadata
|
|
886
|
-
from etptypes.energistics.etp.v12.protocol.data_array.get_data_array_metadata_response import \
|
|
887
|
-
GetDataArrayMetadataResponse
|
|
859
|
+
|
|
888
860
|
|
|
889
861
|
response = await self.send(
|
|
890
862
|
GetDataArrayMetadata(dataArrays={i.path_in_resource: i for i in uids})
|
|
@@ -898,10 +870,7 @@ class ETPClient(ETPConnection):
|
|
|
898
870
|
return [response.array_metadata[i.path_in_resource] for i in uids]
|
|
899
871
|
|
|
900
872
|
async def get_array(self, uid: DataArrayIdentifier):
|
|
901
|
-
|
|
902
|
-
GetDataArrays
|
|
903
|
-
from etptypes.energistics.etp.v12.protocol.data_array.get_data_arrays_response import \
|
|
904
|
-
GetDataArraysResponse
|
|
873
|
+
|
|
905
874
|
|
|
906
875
|
# Check if we can upload the full array in one go.
|
|
907
876
|
meta, = await self.get_array_metadata(uid)
|
|
@@ -917,12 +886,7 @@ class ETPClient(ETPConnection):
|
|
|
917
886
|
return utils_arrays.to_numpy(arrays[0])
|
|
918
887
|
|
|
919
888
|
async def put_array(self, uid: DataArrayIdentifier, data: np.ndarray):
|
|
920
|
-
|
|
921
|
-
PutDataArraysType
|
|
922
|
-
from etptypes.energistics.etp.v12.protocol.data_array.put_data_arrays import \
|
|
923
|
-
PutDataArrays
|
|
924
|
-
from etptypes.energistics.etp.v12.protocol.data_array.put_data_arrays_response import \
|
|
925
|
-
PutDataArraysResponse
|
|
889
|
+
|
|
926
890
|
|
|
927
891
|
# Check if we can upload the full array in one go.
|
|
928
892
|
if data.nbytes > self.max_array_size:
|
|
@@ -940,12 +904,7 @@ class ETPClient(ETPConnection):
|
|
|
940
904
|
starts = np.array(starts).astype(np.int64)
|
|
941
905
|
counts = np.array(counts).astype(np.int64)
|
|
942
906
|
|
|
943
|
-
|
|
944
|
-
GetDataSubarraysType
|
|
945
|
-
from etptypes.energistics.etp.v12.protocol.data_array.get_data_subarrays import \
|
|
946
|
-
GetDataSubarrays
|
|
947
|
-
from etptypes.energistics.etp.v12.protocol.data_array.get_data_subarrays_response import \
|
|
948
|
-
GetDataSubarraysResponse
|
|
907
|
+
|
|
949
908
|
|
|
950
909
|
logger.debug(f"get_subarray {starts=:} {counts=:}")
|
|
951
910
|
|
|
@@ -962,22 +921,15 @@ class ETPClient(ETPConnection):
|
|
|
962
921
|
arrays = list(response.data_subarrays.values())
|
|
963
922
|
return utils_arrays.to_numpy(arrays[0])
|
|
964
923
|
|
|
965
|
-
async def put_subarray(self, uid: DataArrayIdentifier, data: np.ndarray, starts: T.Union[np.ndarray, T.List[int]], counts: T.Union[np.ndarray, T.List[int]]
|
|
966
|
-
|
|
967
|
-
PutDataSubarraysType
|
|
968
|
-
from etptypes.energistics.etp.v12.protocol.data_array.put_data_subarrays import \
|
|
969
|
-
PutDataSubarrays
|
|
970
|
-
from etptypes.energistics.etp.v12.protocol.data_array.put_data_subarrays_response import \
|
|
971
|
-
PutDataSubarraysResponse
|
|
924
|
+
async def put_subarray(self, uid: DataArrayIdentifier, data: np.ndarray, starts: T.Union[np.ndarray, T.List[int]], counts: T.Union[np.ndarray, T.List[int]]):
|
|
925
|
+
|
|
972
926
|
|
|
973
927
|
# starts [start_X, starts_Y]
|
|
974
928
|
# counts [count_X, count_Y]
|
|
975
929
|
starts = np.array(starts).astype(np.int64) # len = 2 [x_start_index, y_start_index]
|
|
976
930
|
counts = np.array(counts).astype(np.int64) # len = 2
|
|
977
931
|
ends = starts + counts # len = 2
|
|
978
|
-
|
|
979
|
-
transport_array_type = utils_arrays.get_transport(data.dtype)
|
|
980
|
-
await self._put_uninitialized_data_array(uid, data.shape, transport_array_type=transport_array_type)
|
|
932
|
+
|
|
981
933
|
|
|
982
934
|
slices = tuple(map(lambda se: slice(se[0], se[1]), zip(starts, ends)))
|
|
983
935
|
dataarray = utils_arrays.to_data_array(data[slices])
|
|
@@ -994,7 +946,6 @@ class ETPClient(ETPConnection):
|
|
|
994
946
|
PutDataSubarrays(dataSubarrays={uid.path_in_resource: payload})
|
|
995
947
|
)
|
|
996
948
|
assert isinstance(response, PutDataSubarraysResponse), "Expected PutDataSubarraysResponse"
|
|
997
|
-
|
|
998
949
|
assert len(response.success) == 1, "expected one success"
|
|
999
950
|
return response.success
|
|
1000
951
|
|
|
@@ -1049,11 +1000,13 @@ class ETPClient(ETPConnection):
|
|
|
1049
1000
|
slices = tuple(map(lambda se: slice(se[0], se[1]), zip(starts-offset, ends-offset)))
|
|
1050
1001
|
buffer[slices] = array
|
|
1051
1002
|
return
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1003
|
+
coro = [populate(starts, counts) for starts, counts in self._get_chunk_sizes(buffer_shape, dtype, offset)]
|
|
1004
|
+
for i in batched(coro, self.max_concurrent_requests):
|
|
1005
|
+
await asyncio.gather(*i)
|
|
1006
|
+
# r = await asyncio.gather(*[
|
|
1007
|
+
# populate(starts, counts)
|
|
1008
|
+
# for starts, counts in self._get_chunk_sizes(buffer_shape, dtype, offset)
|
|
1009
|
+
# ])
|
|
1057
1010
|
|
|
1058
1011
|
return buffer
|
|
1059
1012
|
|
|
@@ -1065,18 +1018,16 @@ class ETPClient(ETPConnection):
|
|
|
1065
1018
|
coro = []
|
|
1066
1019
|
for starts, counts in self._get_chunk_sizes(data.shape, data.dtype):
|
|
1067
1020
|
params.append([starts, counts])
|
|
1021
|
+
#await self.put_subarray(uid, data, starts, counts)
|
|
1068
1022
|
coro.append(self.put_subarray(uid, data, starts, counts))
|
|
1069
|
-
|
|
1023
|
+
for i in batched(coro, self.max_concurrent_requests):
|
|
1024
|
+
await asyncio.gather(*i)
|
|
1025
|
+
#r = await asyncio.gather(*coro)
|
|
1070
1026
|
|
|
1071
1027
|
return {uid.uri: ''}
|
|
1072
1028
|
|
|
1073
1029
|
async def _put_uninitialized_data_array(self, uid: DataArrayIdentifier, shape: T.Tuple[int, ...], transport_array_type=AnyArrayType.ARRAY_OF_FLOAT, logical_array_type=AnyLogicalArrayType.ARRAY_OF_BOOLEAN):
|
|
1074
|
-
|
|
1075
|
-
PutUninitializedDataArrayType
|
|
1076
|
-
from etptypes.energistics.etp.v12.protocol.data_array.put_uninitialized_data_arrays import \
|
|
1077
|
-
PutUninitializedDataArrays
|
|
1078
|
-
from etptypes.energistics.etp.v12.protocol.data_array.put_uninitialized_data_arrays_response import \
|
|
1079
|
-
PutUninitializedDataArraysResponse
|
|
1030
|
+
|
|
1080
1031
|
|
|
1081
1032
|
payload = PutUninitializedDataArrayType(
|
|
1082
1033
|
uid=uid,
|
|
@@ -1104,7 +1055,6 @@ class connect:
|
|
|
1104
1055
|
self.authorization = authorization
|
|
1105
1056
|
self.data_partition = SETTINGS.data_partition
|
|
1106
1057
|
self.timeout = SETTINGS.etp_timeout
|
|
1107
|
-
self.default_dataspace_uri = DataspaceURI.from_name(SETTINGS.dataspace)
|
|
1108
1058
|
|
|
1109
1059
|
# ... = await connect(...)
|
|
1110
1060
|
|
|
@@ -1127,12 +1077,12 @@ class connect:
|
|
|
1127
1077
|
self.server_url,
|
|
1128
1078
|
subprotocols=[ETPClient.SUB_PROTOCOL], # type: ignore
|
|
1129
1079
|
extra_headers=headers,
|
|
1130
|
-
max_size=
|
|
1080
|
+
max_size=SETTINGS.MaxWebSocketMessagePayloadSize,
|
|
1131
1081
|
ping_timeout=self.timeout,
|
|
1132
1082
|
open_timeout=None,
|
|
1133
1083
|
)
|
|
1134
1084
|
|
|
1135
|
-
self.client = ETPClient(ws,
|
|
1085
|
+
self.client = ETPClient(ws, timeout=self.timeout)
|
|
1136
1086
|
|
|
1137
1087
|
try:
|
|
1138
1088
|
await self.client.request_session()
|
pyetp/config.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
|
-
from pydantic import AnyUrl, BaseSettings, Field
|
|
4
|
-
|
|
5
|
-
from pyetp.uri import DataspaceURI
|
|
3
|
+
from pydantic import AnyUrl, BaseSettings, Field
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class WebSocketUrl(AnyUrl):
|
|
@@ -18,17 +16,14 @@ class Settings(BaseSettings):
|
|
|
18
16
|
'redis_password': {'env': ['redis_password', 'redispass']}
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
application_name: str = Field(default='
|
|
22
|
-
application_version: str = Field(default='0.0.
|
|
19
|
+
application_name: str = Field(default='pyetp')
|
|
20
|
+
application_version: str = Field(default='0.0.33')
|
|
23
21
|
|
|
24
|
-
dataspace: str = Field(default='demo/pss-data-gateway')
|
|
22
|
+
#dataspace: str = Field(default='demo/pss-data-gateway')
|
|
25
23
|
etp_url: WebSocketUrl = Field(default='wss://host.com')
|
|
26
|
-
etp_timeout: float = Field(default=
|
|
24
|
+
etp_timeout: float = Field(default=15., description="Timeout in seconds")
|
|
27
25
|
data_partition: Optional[str] = None
|
|
28
|
-
|
|
29
|
-
@property
|
|
30
|
-
def duri(self):
|
|
31
|
-
return DataspaceURI.from_name(self.dataspace)
|
|
26
|
+
MaxWebSocketMessagePayloadSize: int = Field(default=100000)
|
|
32
27
|
|
|
33
28
|
|
|
34
29
|
SETTINGS = Settings()
|
pyetp/types.py
CHANGED
|
@@ -41,7 +41,72 @@ from etptypes.energistics.etp.v12.protocol.core.protocol_exception import \
|
|
|
41
41
|
ProtocolException
|
|
42
42
|
from etptypes.energistics.etp.v12.protocol.core.request_session import \
|
|
43
43
|
RequestSession
|
|
44
|
-
|
|
44
|
+
from etptypes.energistics.etp.v12.protocol.transaction.start_transaction import StartTransaction
|
|
45
|
+
from etptypes.energistics.etp.v12.protocol.transaction.commit_transaction import CommitTransaction
|
|
46
|
+
from etptypes.energistics.etp.v12.protocol.transaction.rollback_transaction import RollbackTransaction
|
|
47
|
+
from etptypes.energistics.etp.v12.datatypes.data_array_types.put_data_subarrays_type import \
|
|
48
|
+
PutDataSubarraysType
|
|
49
|
+
from etptypes.energistics.etp.v12.datatypes.object.relationship_kind import RelationshipKind
|
|
50
|
+
from etptypes.energistics.etp.v12.datatypes.object.context_info import ContextInfo
|
|
51
|
+
from etptypes.energistics.etp.v12.protocol.data_array.put_data_subarrays import \
|
|
52
|
+
PutDataSubarrays
|
|
53
|
+
from etptypes.energistics.etp.v12.datatypes.object.context_scope_kind import ContextScopeKind
|
|
54
|
+
from etptypes.energistics.etp.v12.protocol.data_array.put_data_subarrays_response import \
|
|
55
|
+
PutDataSubarraysResponse
|
|
56
|
+
from etptypes.energistics.etp.v12.datatypes.data_array_types.get_data_subarrays_type import \
|
|
57
|
+
GetDataSubarraysType
|
|
58
|
+
from etptypes.energistics.etp.v12.protocol.data_array.get_data_subarrays import \
|
|
59
|
+
GetDataSubarrays
|
|
60
|
+
from etptypes.energistics.etp.v12.protocol.data_array.get_data_subarrays_response import \
|
|
61
|
+
GetDataSubarraysResponse
|
|
62
|
+
from etptypes.energistics.etp.v12.datatypes.data_array_types.put_data_arrays_type import \
|
|
63
|
+
PutDataArraysType
|
|
64
|
+
from etptypes.energistics.etp.v12.protocol.data_array.put_data_arrays import \
|
|
65
|
+
PutDataArrays
|
|
66
|
+
from etptypes.energistics.etp.v12.protocol.data_array.put_data_arrays_response import \
|
|
67
|
+
PutDataArraysResponse
|
|
68
|
+
from etptypes.energistics.etp.v12.protocol.data_array.get_data_arrays import \
|
|
69
|
+
GetDataArrays
|
|
70
|
+
from etptypes.energistics.etp.v12.protocol.data_array.get_data_arrays_response import \
|
|
71
|
+
GetDataArraysResponse
|
|
72
|
+
from etptypes.energistics.etp.v12.protocol.data_array.get_data_array_metadata import \
|
|
73
|
+
GetDataArrayMetadata
|
|
74
|
+
from etptypes.energistics.etp.v12.protocol.data_array.get_data_array_metadata_response import \
|
|
75
|
+
GetDataArrayMetadataResponse
|
|
76
|
+
from etptypes.energistics.etp.v12.datatypes.data_array_types.put_uninitialized_data_array_type import \
|
|
77
|
+
PutUninitializedDataArrayType
|
|
78
|
+
from etptypes.energistics.etp.v12.protocol.data_array.put_uninitialized_data_arrays import \
|
|
79
|
+
PutUninitializedDataArrays
|
|
80
|
+
from etptypes.energistics.etp.v12.protocol.data_array.put_uninitialized_data_arrays_response import \
|
|
81
|
+
PutUninitializedDataArraysResponse
|
|
82
|
+
from etptypes.energistics.etp.v12.protocol.store.delete_data_objects import \
|
|
83
|
+
DeleteDataObjects
|
|
84
|
+
from etptypes.energistics.etp.v12.protocol.store.delete_data_objects_response import \
|
|
85
|
+
DeleteDataObjectsResponse
|
|
86
|
+
from etptypes.energistics.etp.v12.datatypes.object.resource import \
|
|
87
|
+
Resource
|
|
88
|
+
from etptypes.energistics.etp.v12.protocol.discovery.get_resources import \
|
|
89
|
+
GetResources
|
|
90
|
+
from etptypes.energistics.etp.v12.protocol.store.put_data_objects import \
|
|
91
|
+
PutDataObjects
|
|
92
|
+
from etptypes.energistics.etp.v12.protocol.store.put_data_objects_response import \
|
|
93
|
+
PutDataObjectsResponse
|
|
94
|
+
from etptypes.energistics.etp.v12.protocol.store.get_data_objects import \
|
|
95
|
+
GetDataObjects
|
|
96
|
+
from etptypes.energistics.etp.v12.protocol.store.get_data_objects_response import \
|
|
97
|
+
GetDataObjectsResponse
|
|
98
|
+
from etptypes.energistics.etp.v12.protocol.dataspace.delete_dataspaces import \
|
|
99
|
+
DeleteDataspaces
|
|
100
|
+
from etptypes.energistics.etp.v12.protocol.dataspace.delete_dataspaces_response import \
|
|
101
|
+
DeleteDataspacesResponse
|
|
102
|
+
from etptypes.energistics.etp.v12.protocol.dataspace.put_dataspaces import \
|
|
103
|
+
PutDataspaces
|
|
104
|
+
from etptypes.energistics.etp.v12.protocol.dataspace.put_dataspaces_response import \
|
|
105
|
+
PutDataspacesResponse
|
|
106
|
+
from etptypes.energistics.etp.v12.protocol.core.authorize import \
|
|
107
|
+
Authorize
|
|
108
|
+
from etptypes.energistics.etp.v12.protocol.core.authorize_response import \
|
|
109
|
+
AuthorizeResponse
|
|
45
110
|
#
|
|
46
111
|
# NOTE we want to `from etptypes.energistics.etp.v12 import datatypes, protocol` and use this
|
|
47
112
|
# however this not supported with pylance as of yet, hence so many imports are reexported here
|
pyetp/uri.py
CHANGED
|
@@ -4,12 +4,11 @@ from uuid import UUID
|
|
|
4
4
|
from etpproto.uri import DataObjectURI as _DataObjectURI
|
|
5
5
|
from etpproto.uri import DataspaceUri as _DataspaceURI
|
|
6
6
|
from pydantic import BaseConfig
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
from pyetp.resqml_objects import AbstractObject
|
|
8
|
+
#from energyml.eml.v2_0.commonv2 import AbstractObject
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class _Mixin:
|
|
12
|
-
# print full url as default
|
|
13
12
|
raw_uri: str
|
|
14
13
|
|
|
15
14
|
def __str__(self):
|
|
@@ -66,7 +65,7 @@ class DataObjectURI(_DataObjectURI, _Mixin):
|
|
|
66
65
|
return cls(f"{duri}/{domain_and_version}.{obj_type}({uuid})")
|
|
67
66
|
|
|
68
67
|
@classmethod
|
|
69
|
-
def from_obj(cls, dataspace: Union[DataspaceURI , str], obj:
|
|
68
|
+
def from_obj(cls, dataspace: Union[DataspaceURI , str], obj: AbstractObject):
|
|
70
69
|
|
|
71
70
|
objname = obj.__class__.__name__
|
|
72
71
|
if getattr(obj, 'Meta', None):
|
pyetp/utils.py
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import random
|
|
2
2
|
import string
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
from itertools import islice
|
|
4
|
+
from typing import Iterable
|
|
5
5
|
def short_id(length=8):
|
|
6
6
|
return ''.join([random.choice(string.ascii_letters + string.digits + '-_') for _ in range(length)])
|
|
7
|
+
|
|
8
|
+
def batched(iterable:Iterable, n: int):
|
|
9
|
+
"Batch data into tuples of length n. The last batch may be shorter."
|
|
10
|
+
# batched('ABCDEFG', 3) --> ABC DEF G
|
|
11
|
+
if n < 1:
|
|
12
|
+
raise ValueError('n must be at least one')
|
|
13
|
+
it = iter(iterable)
|
|
14
|
+
while batch := tuple(islice(it, n)):
|
|
15
|
+
yield batch
|
pyetp/utils_xml.py
CHANGED
|
@@ -2,15 +2,21 @@ import datetime
|
|
|
2
2
|
import logging
|
|
3
3
|
import typing as T
|
|
4
4
|
from uuid import uuid4
|
|
5
|
-
|
|
5
|
+
import numpy as np
|
|
6
6
|
import lxml.etree as ET
|
|
7
7
|
from xsdata.formats.dataclass.context import XmlContext
|
|
8
8
|
from xsdata.formats.dataclass.parsers import XmlParser
|
|
9
9
|
from xsdata.formats.dataclass.serializers import XmlSerializer
|
|
10
10
|
from xsdata.formats.dataclass.serializers.config import SerializerConfig
|
|
11
11
|
from xsdata.models.datatype import XmlDateTime
|
|
12
|
+
import resqpy.model as rq
|
|
13
|
+
import resqpy.time_series as rts
|
|
14
|
+
import resqpy.unstructured as rug
|
|
12
15
|
|
|
16
|
+
import resqpy.property as rqp
|
|
13
17
|
import pyetp.resqml_objects as ro
|
|
18
|
+
#import energyml.resqml.v2_0_1.resqmlv2 as ro
|
|
19
|
+
#import energyml.eml.v2_0.commonv2 as roc
|
|
14
20
|
from pyetp.config import SETTINGS
|
|
15
21
|
from pyetp.types import DataObject
|
|
16
22
|
|
|
@@ -21,8 +27,7 @@ if T.TYPE_CHECKING:
|
|
|
21
27
|
from xtgeo import RegularSurface
|
|
22
28
|
|
|
23
29
|
|
|
24
|
-
schema_version = "2.0"
|
|
25
|
-
|
|
30
|
+
schema_version = "2.0.1"
|
|
26
31
|
|
|
27
32
|
def get_data_object_type(obj: ro.AbstractObject):
|
|
28
33
|
return obj.__class__.__name__
|
|
@@ -83,8 +88,8 @@ def create_common_crs(title: str, projected_epsg, rotation: float = 0.0):
|
|
|
83
88
|
projected_uom=ro.LengthUom.M,
|
|
84
89
|
vertical_uom=ro.LengthUom.M,
|
|
85
90
|
zincreasing_downward=True,
|
|
86
|
-
vertical_crs=ro.
|
|
87
|
-
|
|
91
|
+
vertical_crs=ro.VerticalCrsEpsgCode(
|
|
92
|
+
epsg_code=projected_epsg
|
|
88
93
|
),
|
|
89
94
|
projected_crs=ro.ProjectedCrsEpsgCode(
|
|
90
95
|
epsg_code=projected_epsg,
|
|
@@ -139,7 +144,7 @@ def instantiate_resqml_grid(name: str, rotation: float, x0: float, y0: float, dx
|
|
|
139
144
|
fastest_axis_count=ny,
|
|
140
145
|
slowest_axis_count=nx,
|
|
141
146
|
geometry=ro.PointGeometry(
|
|
142
|
-
local_crs=ro.DataObjectReference(
|
|
147
|
+
local_crs= ro.DataObjectReference(
|
|
143
148
|
# NOTE: See Energistics Identifier Specification 4.0
|
|
144
149
|
# (it is downloaded alongside the RESQML v2.0.1
|
|
145
150
|
# standard) section 4.1 for an explanation on the
|
|
@@ -147,7 +152,8 @@ def instantiate_resqml_grid(name: str, rotation: float, x0: float, y0: float, dx
|
|
|
147
152
|
content_type=f"application/x-resqml+xml;version={schema_version};type={get_data_object_type(crs)}",
|
|
148
153
|
title=crs.citation.title,
|
|
149
154
|
uuid=crs.uuid,
|
|
150
|
-
)
|
|
155
|
+
)
|
|
156
|
+
,
|
|
151
157
|
points=ro.Point3dZValueArray(
|
|
152
158
|
supporting_geometry=ro.Point3dLatticeArray(
|
|
153
159
|
origin=ro.Point3d(
|
|
@@ -237,7 +243,7 @@ def uom_for_prop_title(pt: str):
|
|
|
237
243
|
return ro.ResqmlUom.VALUE
|
|
238
244
|
return ro.ResqmlUom.EUC
|
|
239
245
|
|
|
240
|
-
def create_resqml_property(prop_title, continuous, indexable_element, uns, epc, min_val=0.0, max_val=1.0,
|
|
246
|
+
def create_resqml_property(prop_title:str, continuous: bool, indexable_element: ro.IndexableElements, uns: ro.UnstructuredGridRepresentation, epc: ro.EpcExternalPartReference, min_val=0.0, max_val=1.0,
|
|
241
247
|
timeseries=None, time_index=-1, pre_existing_propertykind = None):
|
|
242
248
|
timeindex_ref = None
|
|
243
249
|
use_timeseries = timeseries is not None
|
|
@@ -253,7 +259,6 @@ def create_resqml_property(prop_title, continuous, indexable_element, uns, epc,
|
|
|
253
259
|
)
|
|
254
260
|
|
|
255
261
|
r_uom = ro.ResqmlUom( value= uom_for_prop_title(prop_title) )
|
|
256
|
-
# r_uom = ro.ResqmlUom( uom )
|
|
257
262
|
|
|
258
263
|
if (pre_existing_propertykind is None):
|
|
259
264
|
pk_uuid = uuid4()
|
|
@@ -357,8 +362,8 @@ def create_resqml_property(prop_title, continuous, indexable_element, uns, epc,
|
|
|
357
362
|
)
|
|
358
363
|
return cprop0, propertykind0
|
|
359
364
|
|
|
360
|
-
def create_resqml_mesh(rmdi, rmdts, geotimes, projected_epsg): #(rddms_mesh_data_initial, rddms_upload_data_timestep)
|
|
361
|
-
|
|
365
|
+
def create_resqml_mesh(rmdi, rmdts, geotimes, projected_epsg: int): #(rddms_mesh_data_initial, rddms_upload_data_timestep)
|
|
366
|
+
|
|
362
367
|
ro_timestamps = []
|
|
363
368
|
for i in geotimes:
|
|
364
369
|
ro_timestamps.append(
|
|
@@ -432,7 +437,7 @@ def create_resqml_mesh(rmdi, rmdts, geotimes, projected_epsg): #(rddms_mesh_dat
|
|
|
432
437
|
node_count=node_count,
|
|
433
438
|
face_count=face_count,
|
|
434
439
|
cell_shape=cellshape,
|
|
435
|
-
points=ro.
|
|
440
|
+
points=ro.Point3DHdf5Array(
|
|
436
441
|
coordinates=ro.Hdf5Dataset(
|
|
437
442
|
path_in_hdf_file=f"/RESQML/{str(hexa_uuid)}/points",
|
|
438
443
|
hdf_proxy=ro.DataObjectReference(
|
|
@@ -514,10 +519,8 @@ def create_resqml_mesh(rmdi, rmdts, geotimes, projected_epsg): #(rddms_mesh_dat
|
|
|
514
519
|
return uns, crs, epc, timeseries
|
|
515
520
|
|
|
516
521
|
|
|
517
|
-
def convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg):
|
|
518
|
-
|
|
519
|
-
import resqpy.time_series as rts
|
|
520
|
-
import resqpy.unstructured as rug
|
|
522
|
+
def convert_epc_mesh_to_resqml_mesh(epc_filename: str, title_in: str, projected_epsg: int):
|
|
523
|
+
|
|
521
524
|
|
|
522
525
|
title = title_in or "hexamesh"
|
|
523
526
|
|
|
@@ -661,9 +664,8 @@ def convert_epc_mesh_to_resqml_mesh(epc_filename, title_in, projected_epsg):
|
|
|
661
664
|
return uns, crs, epc, timeseries, hexa
|
|
662
665
|
|
|
663
666
|
|
|
664
|
-
def convert_epc_mesh_property_to_resqml_mesh(epc_filename, hexa, prop_title, uns, epc, timeseries=None, time_indices: list[int] = []):
|
|
665
|
-
|
|
666
|
-
import resqpy.property as rqp
|
|
667
|
+
def convert_epc_mesh_property_to_resqml_mesh(epc_filename, hexa, prop_title, uns:ro.UnstructuredGridRepresentation, epc:ro.EpcExternalPartReference, timeseries=None, time_indices: list[int] = []):
|
|
668
|
+
|
|
667
669
|
|
|
668
670
|
model = rq.Model(epc_filename)
|
|
669
671
|
assert model is not None
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pyetp
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.33
|
|
4
4
|
Summary: Interface with OSDU RDDMS using ETP protocol
|
|
5
5
|
Author: Adam Cheng
|
|
6
6
|
Author-email: 52572642+adamchengtkc@users.noreply.github.com
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.11,<3.13
|
|
8
8
|
Classifier: Development Status :: 3 - Alpha
|
|
9
9
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
13
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
13
|
Requires-Dist: async-lru (>=2.0.4,<3.0.0)
|
|
16
14
|
Requires-Dist: async-timeout (>=5.0,<6.0) ; python_version < "3.11"
|
|
17
|
-
Requires-Dist: etpproto (>=1.0.
|
|
15
|
+
Requires-Dist: etpproto (>=1.0.7,<2.0.0)
|
|
18
16
|
Requires-Dist: lxml (>=4.9.4,<6.0)
|
|
19
17
|
Requires-Dist: numpy (>=1.26.3,<2.0.0)
|
|
20
18
|
Requires-Dist: pyarrow (>=15.0.0,<16.0.0)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
pyetp/__init__.py,sha256=FSlPJ3AXoMe3vDQ0z8k417aKJWwt7sxbNPsLgdc21tI,123
|
|
2
|
+
pyetp/client.py,sha256=71DV3WPXpOX4fL119aR_5z09L3NDsS5zMP1mSMHGr9s,46154
|
|
3
|
+
pyetp/config.py,sha256=BmCWo09GXO9CoAwtmmmAflNeRHF-5d14JFwsBBrKnQA,865
|
|
4
|
+
pyetp/resqml_objects/__init__.py,sha256=Sr_1bktzS8JMmE9oi6pcW6BuERm7gH0u50rBs58zI7Q,50492
|
|
5
|
+
pyetp/resqml_objects/generated.py,sha256=P-hfL8btOE6uAmtaGXbSdWMl8Z9iJx-r6FRzSvmzHvU,783914
|
|
6
|
+
pyetp/types.py,sha256=HMNZ4_cJqhxqzXiYsNT-Ywvtfji9PARX4d6MixoQn1k,6397
|
|
7
|
+
pyetp/uri.py,sha256=6NE_-QvtaL_z5NCUbxehc28ul-70DgXpMiEGaIJPqNc,2996
|
|
8
|
+
pyetp/utils.py,sha256=4U_9ndZGzN3B0xMoeSglmxdg7jgfYP5v_mE6tF2Lqmc,518
|
|
9
|
+
pyetp/utils_arrays.py,sha256=HHhw23La4SG7UJyd5Q_OJ5WlMq98QpwHBk553YyyYOk,4331
|
|
10
|
+
pyetp/utils_xml.py,sha256=VLTelVsUZrUDZEGES4xMU8MA9zSW-C83IDiHD_B8wT0,33861
|
|
11
|
+
pyetp-0.0.33.dist-info/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
+
pyetp-0.0.33.dist-info/METADATA,sha256=38-PLw8E-sAbkpTIdZqzyviKXEXlIPvO9m7adac2NHw,2293
|
|
13
|
+
pyetp-0.0.33.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
14
|
+
pyetp-0.0.33.dist-info/RECORD,,
|
pyetp-0.0.31.dist-info/RECORD
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
pyetp/__init__.py,sha256=FSlPJ3AXoMe3vDQ0z8k417aKJWwt7sxbNPsLgdc21tI,123
|
|
2
|
-
pyetp/client.py,sha256=MJmS-HfQKmbcfMriakDcwwoBdVgMQAF6LcpgdFx20TU,49638
|
|
3
|
-
pyetp/config.py,sha256=Z0Q3dH0olM4CKLckDA_EV23XK_al2Ey8D9JrKb3s5R0,949
|
|
4
|
-
pyetp/resqml_objects/__init__.py,sha256=Sr_1bktzS8JMmE9oi6pcW6BuERm7gH0u50rBs58zI7Q,50492
|
|
5
|
-
pyetp/resqml_objects/generated.py,sha256=P-hfL8btOE6uAmtaGXbSdWMl8Z9iJx-r6FRzSvmzHvU,783914
|
|
6
|
-
pyetp/types.py,sha256=E-CvzI74kiQ52J42DQ-5wGUC84l3-glYs3NQ36HIs1I,2559
|
|
7
|
-
pyetp/uri.py,sha256=57wTOH7EAGXluDiGxIe34DAiftPR91jEnbRB5thaG8k,2963
|
|
8
|
-
pyetp/utils.py,sha256=WxfG13bItprl457H3EEsckF1uDwF-hzPhVG7QRX0LB8,158
|
|
9
|
-
pyetp/utils_arrays.py,sha256=HHhw23La4SG7UJyd5Q_OJ5WlMq98QpwHBk553YyyYOk,4331
|
|
10
|
-
pyetp/utils_xml.py,sha256=mBnWERnlMEjoPb6D9EYalkUShDvEOvo7zxw-Hz0dJ1A,33647
|
|
11
|
-
pyetp-0.0.31.dist-info/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
-
pyetp-0.0.31.dist-info/METADATA,sha256=KOsETuuwuuBEw64Zz5WI4GC87oIof-mtE27hLOzinsY,2393
|
|
13
|
-
pyetp-0.0.31.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
14
|
-
pyetp-0.0.31.dist-info/RECORD,,
|
|
File without changes
|