fmu-sumo 2.4.3__py3-none-any.whl → 2.4.5__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.
- fmu/sumo/explorer/_version.py +2 -2
- fmu/sumo/explorer/objects/_search_context.py +113 -143
- {fmu_sumo-2.4.3.dist-info → fmu_sumo-2.4.5.dist-info}/METADATA +1 -1
- {fmu_sumo-2.4.3.dist-info → fmu_sumo-2.4.5.dist-info}/RECORD +7 -7
- {fmu_sumo-2.4.3.dist-info → fmu_sumo-2.4.5.dist-info}/WHEEL +0 -0
- {fmu_sumo-2.4.3.dist-info → fmu_sumo-2.4.5.dist-info}/licenses/LICENSE +0 -0
- {fmu_sumo-2.4.3.dist-info → fmu_sumo-2.4.5.dist-info}/top_level.txt +0 -0
fmu/sumo/explorer/_version.py
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import uuid
|
|
5
4
|
import warnings
|
|
6
5
|
from datetime import datetime
|
|
7
|
-
from io import BytesIO
|
|
8
6
|
from typing import TYPE_CHECKING, Any, Dict, List, Tuple, Union
|
|
9
7
|
|
|
10
8
|
import deprecation
|
|
@@ -1164,6 +1162,46 @@ class SearchContext:
|
|
|
1164
1162
|
def grid_properties(self) -> SearchContext:
|
|
1165
1163
|
return self._context_for_class("cpgrid_property")
|
|
1166
1164
|
|
|
1165
|
+
@property
|
|
1166
|
+
def parameters(self) -> SearchContext:
|
|
1167
|
+
return self.filter(
|
|
1168
|
+
complex={
|
|
1169
|
+
"bool": {
|
|
1170
|
+
"must": [
|
|
1171
|
+
{"term": {"data.name.keyword": "parameters"}},
|
|
1172
|
+
{"term": {"data.content.keyword": "parameters"}},
|
|
1173
|
+
],
|
|
1174
|
+
"should": [
|
|
1175
|
+
{
|
|
1176
|
+
"bool": {
|
|
1177
|
+
"must": [
|
|
1178
|
+
{"term": {"class.keyword": "dictionary"}},
|
|
1179
|
+
{
|
|
1180
|
+
"exists": {
|
|
1181
|
+
"field": "fmu.realization.id"
|
|
1182
|
+
}
|
|
1183
|
+
},
|
|
1184
|
+
]
|
|
1185
|
+
}
|
|
1186
|
+
},
|
|
1187
|
+
{
|
|
1188
|
+
"bool": {
|
|
1189
|
+
"must": [
|
|
1190
|
+
{"term": {"class.keyword": "table"}},
|
|
1191
|
+
{
|
|
1192
|
+
"exists": {
|
|
1193
|
+
"field": "fmu.aggregation.operation"
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
]
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
],
|
|
1200
|
+
"minimum_should_match": 1,
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
)
|
|
1204
|
+
|
|
1167
1205
|
def _get_object_by_class_and_uuid(self, cls, uuid) -> Any:
|
|
1168
1206
|
obj = self.get_object(uuid)
|
|
1169
1207
|
if obj.metadata["class"] != cls:
|
|
@@ -1484,12 +1522,10 @@ class SearchContext:
|
|
|
1484
1522
|
"""
|
|
1485
1523
|
return await self._get_object_by_class_and_uuid_async("table", uuid)
|
|
1486
1524
|
|
|
1487
|
-
def
|
|
1488
|
-
|
|
1489
|
-
) -> Tuple[Dict, List[str], List[int]]:
|
|
1490
|
-
query = {
|
|
1525
|
+
def __prepare_verify_aggregation_query(self) -> Dict:
|
|
1526
|
+
return {
|
|
1491
1527
|
"query": self._query,
|
|
1492
|
-
"size":
|
|
1528
|
+
"size": 0,
|
|
1493
1529
|
"track_total_hits": True,
|
|
1494
1530
|
"aggs": {
|
|
1495
1531
|
k: {"terms": {"field": k + ".keyword", "size": 1}}
|
|
@@ -1497,85 +1533,83 @@ class SearchContext:
|
|
|
1497
1533
|
"fmu.case.uuid",
|
|
1498
1534
|
"class",
|
|
1499
1535
|
"fmu.ensemble.name",
|
|
1536
|
+
"fmu.entity.uuid",
|
|
1500
1537
|
"data.name",
|
|
1501
1538
|
"data.tagname",
|
|
1502
1539
|
"data.content",
|
|
1503
1540
|
]
|
|
1504
1541
|
},
|
|
1505
1542
|
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1543
|
+
|
|
1544
|
+
def __verify_aggregation_operation(
|
|
1545
|
+
self, sres
|
|
1546
|
+
) -> Tuple[str, str, str, str]:
|
|
1547
|
+
tot_hits = sres["hits"]["total"]["value"]
|
|
1548
|
+
if tot_hits == 0:
|
|
1508
1549
|
raise Exception("No matching realizations found.")
|
|
1509
|
-
prototype = sres["hits"]["hits"][0]
|
|
1510
1550
|
conflicts = [
|
|
1511
1551
|
k
|
|
1512
1552
|
for (k, v) in sres["aggregations"].items()
|
|
1513
1553
|
if (
|
|
1514
|
-
("sum_other_doc_count" in v)
|
|
1554
|
+
("sum_other_doc_count" in v)
|
|
1555
|
+
and (v["sum_other_doc_count"] > 0)
|
|
1556
|
+
or v["buckets"][0]["doc_count"] != tot_hits
|
|
1515
1557
|
)
|
|
1516
1558
|
]
|
|
1517
1559
|
if len(conflicts) > 0:
|
|
1518
1560
|
raise Exception(f"Conflicting values for {conflicts}")
|
|
1561
|
+
entityuuid = sres["aggregations"]["fmu.entity.uuid"]["buckets"][0][
|
|
1562
|
+
"key"
|
|
1563
|
+
]
|
|
1564
|
+
caseuuid = sres["aggregations"]["fmu.case.uuid"]["buckets"][0]["key"]
|
|
1565
|
+
ensemblename = sres["aggregations"]["fmu.ensemble.name"]["buckets"][0][
|
|
1566
|
+
"key"
|
|
1567
|
+
]
|
|
1568
|
+
classname = sres["aggregations"]["class"]["buckets"][0]["key"]
|
|
1569
|
+
return caseuuid, classname, entityuuid, ensemblename
|
|
1519
1570
|
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
return
|
|
1571
|
+
def _verify_aggregation_operation(
|
|
1572
|
+
self, columns, operation
|
|
1573
|
+
) -> Tuple[str, str, str, str]:
|
|
1574
|
+
assert columns is None or len(columns) == 1, (
|
|
1575
|
+
"Exactly one column required for collection aggregation."
|
|
1576
|
+
)
|
|
1577
|
+
sc = self if columns is None else self.filter(column=columns)
|
|
1578
|
+
query = sc.__prepare_verify_aggregation_query()
|
|
1579
|
+
sres = sc._sumo.post("/search", json=query).json()
|
|
1580
|
+
return sc.__verify_aggregation_operation(sres)
|
|
1530
1581
|
|
|
1531
|
-
def
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
or columns is not None
|
|
1535
|
-
and len(columns) == 1
|
|
1536
|
-
), "Exactly one column required for collection aggregation."
|
|
1537
|
-
prototype, uuids, rids = self.filter(
|
|
1538
|
-
column=columns
|
|
1539
|
-
)._verify_aggregation_operation()
|
|
1582
|
+
def __prepare_aggregation_spec(
|
|
1583
|
+
self, caseuuid, classname, entityuuid, ensemblename, operation, columns
|
|
1584
|
+
):
|
|
1540
1585
|
spec = {
|
|
1541
|
-
"
|
|
1586
|
+
"case_uuid": caseuuid,
|
|
1587
|
+
"class": classname,
|
|
1588
|
+
"entity_uuid": entityuuid,
|
|
1589
|
+
"ensemble_name": ensemblename,
|
|
1590
|
+
"iteration_name": ensemblename,
|
|
1542
1591
|
"operations": [operation],
|
|
1543
1592
|
}
|
|
1544
|
-
del prototype["_source"]["fmu"]["realization"]
|
|
1545
|
-
del prototype["_source"]["_sumo"]
|
|
1546
|
-
del prototype["_source"]["file"]
|
|
1547
|
-
if "context" in prototype["_source"]["fmu"]:
|
|
1548
|
-
prototype["_source"]["fmu"]["context"]["stage"] = "ensemble"
|
|
1549
|
-
pass
|
|
1550
|
-
prototype["_source"]["fmu"]["aggregation"] = {
|
|
1551
|
-
"id": str(uuid.uuid4()),
|
|
1552
|
-
"realization_ids": rids,
|
|
1553
|
-
"operation": operation,
|
|
1554
|
-
}
|
|
1555
1593
|
if columns is not None:
|
|
1556
1594
|
spec["columns"] = columns
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
pass
|
|
1595
|
+
return spec
|
|
1596
|
+
|
|
1597
|
+
def _aggregate(self, columns=None, operation=None) -> objects.Child:
|
|
1598
|
+
caseuuid, classname, entityuuid, ensemblename = (
|
|
1599
|
+
self._verify_aggregation_operation(columns, operation)
|
|
1600
|
+
)
|
|
1601
|
+
spec = self.__prepare_aggregation_spec(
|
|
1602
|
+
caseuuid, classname, entityuuid, ensemblename, operation, columns
|
|
1603
|
+
)
|
|
1604
|
+
spec["object_ids"] = self.uuids
|
|
1568
1605
|
try:
|
|
1569
1606
|
res = self._sumo.post("/aggregations", json=spec)
|
|
1570
1607
|
except httpx.HTTPStatusError as ex:
|
|
1571
1608
|
print(ex.response.reason_phrase)
|
|
1572
1609
|
print(ex.response.text)
|
|
1573
1610
|
raise ex
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
assert isinstance(res, objects.Child)
|
|
1577
|
-
res._blob = blob
|
|
1578
|
-
return res
|
|
1611
|
+
res = self._sumo.poll(res).json()
|
|
1612
|
+
return self._to_sumo(res)
|
|
1579
1613
|
|
|
1580
1614
|
def aggregate(self, columns=None, operation=None) -> objects.Child:
|
|
1581
1615
|
if len(self.hidden) > 0:
|
|
@@ -1586,103 +1620,39 @@ class SearchContext:
|
|
|
1586
1620
|
)
|
|
1587
1621
|
|
|
1588
1622
|
async def _verify_aggregation_operation_async(
|
|
1589
|
-
self,
|
|
1590
|
-
) -> Tuple[
|
|
1591
|
-
query = {
|
|
1592
|
-
"query": self._query,
|
|
1593
|
-
"size": 1,
|
|
1594
|
-
"track_total_hits": True,
|
|
1595
|
-
"aggs": {
|
|
1596
|
-
k: {"terms": {"field": k + ".keyword", "size": 1}}
|
|
1597
|
-
for k in [
|
|
1598
|
-
"fmu.case.uuid",
|
|
1599
|
-
"class",
|
|
1600
|
-
"fmu.ensemble.name",
|
|
1601
|
-
"data.name",
|
|
1602
|
-
"data.tagname",
|
|
1603
|
-
"data.content",
|
|
1604
|
-
]
|
|
1605
|
-
},
|
|
1606
|
-
}
|
|
1607
|
-
sres = (await self._sumo.post_async("/search", json=query)).json()
|
|
1608
|
-
if len(sres["hits"]["hits"]) == 0:
|
|
1609
|
-
raise Exception("No matching realizations found.")
|
|
1610
|
-
prototype = sres["hits"]["hits"][0]
|
|
1611
|
-
conflicts = [
|
|
1612
|
-
k
|
|
1613
|
-
for (k, v) in sres["aggregations"].items()
|
|
1614
|
-
if (
|
|
1615
|
-
("sum_other_doc_count" in v) and (v["sum_other_doc_count"] > 0)
|
|
1616
|
-
)
|
|
1617
|
-
]
|
|
1618
|
-
if len(conflicts) > 0:
|
|
1619
|
-
raise Exception(f"Conflicting values for {conflicts}")
|
|
1620
|
-
|
|
1621
|
-
hits = await self._search_all_async(select=["fmu.realization.id"])
|
|
1622
|
-
|
|
1623
|
-
if any(
|
|
1624
|
-
hit["_source"]["fmu"].get("realization") is None for hit in hits
|
|
1625
|
-
):
|
|
1626
|
-
raise Exception("Selection contains non-realization data.")
|
|
1627
|
-
|
|
1628
|
-
uuids = [hit["_id"] for hit in hits]
|
|
1629
|
-
rids = [hit["_source"]["fmu"]["realization"]["id"] for hit in hits]
|
|
1630
|
-
return prototype, uuids, rids
|
|
1631
|
-
|
|
1632
|
-
async def _aggregate_async(
|
|
1633
|
-
self, columns=None, operation=None
|
|
1634
|
-
) -> objects.Child:
|
|
1623
|
+
self, columns, operation
|
|
1624
|
+
) -> Tuple[str, str, str, str]:
|
|
1635
1625
|
assert (
|
|
1636
1626
|
operation != "collection"
|
|
1637
1627
|
or columns is not None
|
|
1638
1628
|
and len(columns) == 1
|
|
1639
1629
|
), "Exactly one column required for collection aggregation."
|
|
1630
|
+
sc = self if columns is None else self.filter(column=columns)
|
|
1631
|
+
query = sc.__prepare_verify_aggregation_query()
|
|
1632
|
+
sres = (await self._sumo.post_async("/search", json=query)).json()
|
|
1633
|
+
return sc.__verify_aggregation_operation(sres)
|
|
1634
|
+
|
|
1635
|
+
async def _aggregate_async(
|
|
1636
|
+
self, columns=None, operation=None
|
|
1637
|
+
) -> objects.Child:
|
|
1640
1638
|
(
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
}
|
|
1651
|
-
del prototype["_source"]["fmu"]["realization"]
|
|
1652
|
-
del prototype["_source"]["_sumo"]
|
|
1653
|
-
del prototype["_source"]["file"]
|
|
1654
|
-
if "context" in prototype["_source"]["fmu"]:
|
|
1655
|
-
prototype["_source"]["fmu"]["context"]["stage"] = "ensemble"
|
|
1656
|
-
pass
|
|
1657
|
-
prototype["_source"]["fmu"]["aggregation"] = {
|
|
1658
|
-
"id": str(uuid.uuid4()),
|
|
1659
|
-
"realization_ids": rids,
|
|
1660
|
-
"operation": operation,
|
|
1661
|
-
}
|
|
1662
|
-
if columns is not None:
|
|
1663
|
-
spec["columns"] = columns
|
|
1664
|
-
cols = columns[:]
|
|
1665
|
-
table_index = prototype["_source"]["data"].get("table_index")
|
|
1666
|
-
if (
|
|
1667
|
-
table_index is not None
|
|
1668
|
-
and len(table_index) != 0
|
|
1669
|
-
and table_index[0] not in cols
|
|
1670
|
-
):
|
|
1671
|
-
cols.insert(0, table_index[0])
|
|
1672
|
-
pass
|
|
1673
|
-
prototype["_source"]["data"]["spec"]["columns"] = cols
|
|
1674
|
-
pass
|
|
1639
|
+
caseuuid,
|
|
1640
|
+
classname,
|
|
1641
|
+
entityuuid,
|
|
1642
|
+
ensemblename,
|
|
1643
|
+
) = await self._verify_aggregation_operation_async(columns, operation)
|
|
1644
|
+
spec = self.__prepare_aggregation_spec(
|
|
1645
|
+
caseuuid, classname, entityuuid, ensemblename, operation, columns
|
|
1646
|
+
)
|
|
1647
|
+
spec["object_ids"] = await self.uuids_async
|
|
1675
1648
|
try:
|
|
1676
1649
|
res = await self._sumo.post_async("/aggregations", json=spec)
|
|
1677
1650
|
except httpx.HTTPStatusError as ex:
|
|
1678
1651
|
print(ex.response.reason_phrase)
|
|
1679
1652
|
print(ex.response.text)
|
|
1680
1653
|
raise ex
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
assert isinstance(res, objects.Child)
|
|
1684
|
-
res._blob = blob
|
|
1685
|
-
return res
|
|
1654
|
+
res = self._sumo.poll(res).json()
|
|
1655
|
+
return self._to_sumo(res)
|
|
1686
1656
|
|
|
1687
1657
|
async def aggregate_async(
|
|
1688
1658
|
self, columns=None, operation=None
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
fmu/__init__.py,sha256=ftS-xRPSH-vU7fIHlnZQaCTWbNvs4owJivNW65kzsIM,85
|
|
2
2
|
fmu/sumo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
fmu/sumo/explorer/__init__.py,sha256=Bc1wd1lQO3HP3tsVyPbqaesf2boZwGdtookWp8lmG-k,317
|
|
4
|
-
fmu/sumo/explorer/_version.py,sha256=
|
|
4
|
+
fmu/sumo/explorer/_version.py,sha256=agt6014xoIR-2Pjd3clvPyl78U4pI7z7EzFGI5OfP8k,511
|
|
5
5
|
fmu/sumo/explorer/cache.py,sha256=uvz8TciwBnDEwJIHa9wneC0WVWuzhUqyF3dzk4kvGNk,1037
|
|
6
6
|
fmu/sumo/explorer/explorer.py,sha256=_3nUTO1E_nf6jqpivjgjKcX6rX1fx_mIG76YOM8xb-8,2931
|
|
7
7
|
fmu/sumo/explorer/filters.py,sha256=_t2PmHeTY9XiBvQeEGM-BpudWUaxIfyUSdNyG70xfRU,875
|
|
@@ -10,7 +10,7 @@ fmu/sumo/explorer/objects/__init__.py,sha256=72G0yfWWMTXA-oZw5GMRkrWvQqAYfadjerE
|
|
|
10
10
|
fmu/sumo/explorer/objects/_child.py,sha256=RrH3W3GF5Nhje7VnhmlEwG_jhX0z6CloJgdGJJzk3po,6035
|
|
11
11
|
fmu/sumo/explorer/objects/_document.py,sha256=uPAkNzcOk8U4LCtXthWkm7kfU9W4HYHrrqV9HERDhe8,1835
|
|
12
12
|
fmu/sumo/explorer/objects/_metrics.py,sha256=WITAFAV-3VRd-AqTg0tUwWpOChW4YFfF8ffT2fvOrAo,8144
|
|
13
|
-
fmu/sumo/explorer/objects/_search_context.py,sha256=
|
|
13
|
+
fmu/sumo/explorer/objects/_search_context.py,sha256=ozyl7xUmun2kouoSnDvNhWgPK8ANJebb7KjDAN0AcEY,63162
|
|
14
14
|
fmu/sumo/explorer/objects/case.py,sha256=fKp7X43ETLE1RaH3rMYxZiIuduRmf0JSnJ5gRoUgNPE,3813
|
|
15
15
|
fmu/sumo/explorer/objects/cases.py,sha256=i2bnvk7NWIkzbdWMs3BXU7TCqD5tH2r7pg1m1QXUj3o,561
|
|
16
16
|
fmu/sumo/explorer/objects/cpgrid.py,sha256=nuRgZ6FVEOPZT1ibd-rJhlbYYZ6BuUxXZPzovcH0kVc,2548
|
|
@@ -26,8 +26,8 @@ fmu/sumo/explorer/objects/realization.py,sha256=Th3zr_nT2I1HYHkBojOAKnf_RSIPc-Ti
|
|
|
26
26
|
fmu/sumo/explorer/objects/realizations.py,sha256=4agtQFJ5pxLyWMeIzdJbkBMc8__Md-tZOj8Un4ol22c,1562
|
|
27
27
|
fmu/sumo/explorer/objects/surface.py,sha256=zHBtjLCIfkRHBv39OeJjA9lq3puLTfTII6TndZTtxVI,1627
|
|
28
28
|
fmu/sumo/explorer/objects/table.py,sha256=vLor3YTddHkDWZSMyWPQsddFNQ2_VXE_O-stmPIWIaQ,4900
|
|
29
|
-
fmu_sumo-2.4.
|
|
30
|
-
fmu_sumo-2.4.
|
|
31
|
-
fmu_sumo-2.4.
|
|
32
|
-
fmu_sumo-2.4.
|
|
33
|
-
fmu_sumo-2.4.
|
|
29
|
+
fmu_sumo-2.4.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
30
|
+
fmu_sumo-2.4.5.dist-info/METADATA,sha256=ZZESEXOqjSMgM6fPAaCrC5nyr01h3q2SqZPjJktyHF0,14781
|
|
31
|
+
fmu_sumo-2.4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
32
|
+
fmu_sumo-2.4.5.dist-info/top_level.txt,sha256=Z-FIY3pxn0UK2Wxi9IJ7fKoLSraaxuNGi1eokiE0ShM,4
|
|
33
|
+
fmu_sumo-2.4.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|