#4576 Python: Improve error handling and add example

This commit is contained in:
Gaute Lindkvist
2019-08-14 09:14:12 +02:00
parent 84495641f9
commit 197279ccbf
8 changed files with 99 additions and 67 deletions

View File

@@ -25,14 +25,8 @@ class Commands:
self.commands = CmdRpc.CommandsStub(channel)
def __execute(self, **commandParams):
try:
return self.commands.Execute(Cmd.CommandParams(**commandParams))
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found", commandParams.keys())
else:
print("Other error", e)
return self.commands.Execute(Cmd.CommandParams(**commandParams))
########################
# Case Control Commands
########################
@@ -71,8 +65,6 @@ class Commands:
"""
commandReply = self.__execute(loadCase=Cmd.FilePathRequest(path=path))
assert(commandReply is not None)
assert(commandReply.HasField("loadCaseResult"))
return Case(self.channel, commandReply.loadCaseResult.id)
def replaceCase(self, newGridFile, caseId=0):
@@ -107,14 +99,10 @@ class Commands:
A case group id and name
"""
commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=casePaths))
assert(commandReply is not None)
assert(commandReply.HasField("createGridCaseGroupResult"))
return (commandReply.createGridCaseGroupResult.groupId, commandReply.createGridCaseGroupResult.groupName)
def createStatisticsCase(self, caseGroupId):
commandReply = self.__execute(createStatisticsCase=Cmd.CreateStatisticsCaseRequest(caseGroupId=caseGroupId))
assert(commandReply is not None)
assert(commandReply.HasField("createStatisticsCaseResult"))
return commandReply.createStatisticsCaseResult.caseId;
##################

View File

@@ -12,7 +12,14 @@ from Definitions_pb2 import ClientToServerStreamReply
class Properties:
""" Class for streaming properties to and from ResInsight
"""
Attributes:
chunkSize(int): The size of each chunk during value streaming.
A good chunk size is 64KiB = 65536B.
Meaning the ideal number of doubles would be 8192.
However we need overhead space, so the default is 8160.
This leaves 256B for overhead.
"""
def __init__(self, case):
"""
Arguments:
@@ -20,6 +27,8 @@ class Properties:
"""
self.case = case
self.propertiesStub = Properties_pb2_grpc.PropertiesStub(self.case.channel)
self.chunkSize = 8160
def __generatePropertyInputIterator(self, values_iterator, parameters):
chunk = Properties_pb2.PropertyInputChunk()
@@ -32,11 +41,7 @@ class Properties:
yield chunk
def __generatePropertyInputChunks(self, array, parameters):
# Each double is 8 bytes. A good chunk size is 64KiB = 65536B
# Meaning ideal number of doubles would be 8192.
# However we need overhead space, so if we choose 8160 in chunk size
# We have 256B left for overhead which should be plenty
chunkSize = 44431
index = -1
while index < len(array):
chunk = Properties_pb2.PropertyInputChunk()
@@ -44,7 +49,7 @@ class Properties:
chunk.params.CopyFrom(parameters)
index += 1
else:
actualChunkSize = min(len(array) - index + 1, chunkSize)
actualChunkSize = min(len(array) - index + 1, self.chunkSize)
chunk.values.CopyFrom(Properties_pb2.PropertyChunk(values = array[index:index+actualChunkSize]))
index += actualChunkSize
@@ -184,15 +189,10 @@ class Properties:
property_name = propertyName,
time_step = timeStep,
porosity_model = porosityModelEnum)
try:
request_iterator = self.__generatePropertyInputIterator(values_iterator, request)
self.propertiesStub.SetActiveCellProperty(request_iterator)
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found")
else:
print("Other error", e)
request_iterator = self.__generatePropertyInputIterator(values_iterator, request)
self.propertiesStub.SetActiveCellProperty(request_iterator)
def setActiveCellProperty(self, values, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'):
"""Set a cell property for all active cells.
@@ -210,17 +210,10 @@ class Properties:
property_name = propertyName,
time_step = timeStep,
porosity_model = porosityModelEnum)
try:
request_iterator = self.__generatePropertyInputChunks(values, request)
reply = self.propertiesStub.SetActiveCellProperty(request_iterator)
if reply.values_accepted != len(values):
print("ERROR: Attempted to write outside bounds of " + propertyName + " data storage");
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found")
else:
print("Other error", e)
request_iterator = self.__generatePropertyInputChunks(values, request)
reply = self.propertiesStub.SetActiveCellProperty(request_iterator)
if reply.accepted_value_count < len(values):
raise IndexError
def setGridProperty(self, values, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'):
"""Set a cell property for all grid cells.
@@ -241,14 +234,8 @@ class Properties:
time_step = timeStep,
grid_index = gridIndex,
porosity_model = porosityModelEnum)
try:
request_iterator = self.__generatePropertyInputChunks(values, request)
reply = self.propertiesStub.SetGridProperty(request_iterator)
if reply.values_accepted != len(values):
print("ERROR: Attempted to write outside bounds of " + propertyName + " data storage");
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
print("Command not found")
else:
print("Other error", e)
request_iterator = self.__generatePropertyInputChunks(values, request)
reply = self.propertiesStub.SetGridProperty(request_iterator)
if reply.accepted_value_count < len(values):
raise IndexError

View File

@@ -0,0 +1,52 @@
import rips
import grpc
resInsight = rips.Instance.find()
case = None
# Try loading a non-existing case. We should get a grpc.RpcError exception from the server
try:
case = resInsight.project.loadCase("Nonsense")
except grpc.RpcError as e:
print("Expected Server Exception Received: ", e)
case = resInsight.project.case(id=0)
if case is not None:
results = case.properties.activeCellProperty('STATIC_NATIVE', 'PORO', 0)
activeCellCount = len(results)
# Send the results back to ResInsight inside try / except construct
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0)
print("Everything went well as expected")
except: # Match any exception, but it should not happen
print("Ooops!")
# Add another value, so this is outside the bounds of the active cell result storage
results.append(1.0)
# This time we should get a grpc.RpcError exception, which is a server side error.
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0)
print("Everything went well??")
except grpc.RpcError as e:
print("Expected Server Exception Received: ", e)
except IndexError:
print ("Got index out of bounds error. This shouldn't happen here")
# With a chunk size exactly matching the active cell count the server will not
# be able to see any error as it will successfully close the stream after receiving
# the correct number of values, even if the python client has more chunks to send
case.properties.chunkSize = activeCellCount
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0)
print("Everything went well??")
except grpc.RpcError as e:
print("Got unexpected server exception", e, "This should not happen now")
except IndexError:
print ("Got expected index out of bounds error on client side")

View File

@@ -1,5 +1,6 @@
import rips
import time
import grpc
resInsight = rips.Instance.find()
start = time.time()
@@ -12,7 +13,11 @@ results = []
for (poro, permx) in zip(poroResults, permxResults):
results.append(poro * permx)
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROPERMXSY', 0)
try:
case.properties.setActiveCellProperty(results, 'GENERATED', 'POROPERMXSY', 0)
except grpc.RpcError as e:
print("Exception Received: ", e)
end = time.time()
print("Time elapsed: ", end - start)