import time import deephaven import jpy import dill import wrapt import base64 import numpy import argparse import getpass import sys from deephaven import AuthenticationManager from deephaven import TableTools if sys.version_info[0] < 3: input = raw_input # the method changed names # In general you want to have these arguments, but by setting this to false, # you can purposefully leave them off and see how start_jvm will respond to the # null arguments. requireArguments = True parser = argparse.ArgumentParser(description="This script provides a sequence of tests for executing a local Python " "script with table proxies and remote queries against a local remote " "query dispatcher.") parser.add_argument("-v", "--verbose", action="store_true") parser.add_argument("-w", "--workspace", help="Deephaven workspace directory", default=None, required=requireArguments) parser.add_argument("-d", "--devroot", help="Deephaven installation root", default=None, required=requireArguments) parser.add_argument("-c", "--config", required=requireArguments, help="Configuration.rootFile for Deephaven system.") parser.add_argument("-k", "--keyfile", help="Default private key file", default=None, required=requireArguments) parser.add_argument("-a", "--address", help="Server IP address", default=None, required=requireArguments) parser.add_argument("-p", "--password", help="Use password authentication", action='store_true') parser.add_argument("-cp", "--class_path", help="Values to add to the JVM Classpath", action='append', nargs="+") parser.add_argument("-skip", "--skip_default_classpath", action="store_true", help="Use only explicitly set class path values") args = parser.parse_args() #jpy.diag.flags = jpy.diag.F_ALL if args.class_path is not None: cpFlat = [] for sublist in args.class_path: for item in sublist: cpFlat.append(item) args.class_path = cpFlat # Initialize the JVM deephaven.start_jvm(devroot=args.devroot, workspace=args.workspace, propfile=args.config, keyfile=args.keyfile, verbose=args.verbose, jvm_classpath=args.class_path, skip_default_classpath=args.skip_default_classpath, jvm_properties={'service.name': 'iris_console'}) # Ask the user for a username/password if args.password: username = input("Username: ") password = getpass.getpass("Password: ") AuthenticationManager().DEFAULT.passwordAuthentication(username, password, username) # Create a RemoteQueryClient rqc = deephaven.RemoteQueryClient(args.address, 22013) # Create a remote database db = rqc.getRemoteDB(1200, "Default") # This uses our local DB object to create a TimeTable proxy, then perform an update operation against it. tt = db.timeTable("00:00:01").update("Diff=Timestamp-Timestamp_[0]") origSize = tt.size() time.sleep(3) newSize = tt.size() if origSize >= newSize: raise RuntimeError("Table did not tick!") col = tt.getColumn("Diff") direct = col.getDirect() if len(direct) < newSize: raise RuntimeError("Direct is the wrong size!") for ii in range(0, len(direct)): if direct[ii] != ii * 1000000000: raise RuntimeError("Direct[%d] is %d" % (ii, direct[ii])) # Execute a simple remote query using the DB object instantiated by the Jpy Holder class RemoteQueryReturningTable: def execute(self, db): print("Inside of Table Query") return db.i("DbInternal", "QueryOperationPerformanceLog").select().update("DataReads=FirstTimeDataReads+RepeatedDataReads") qopl = db.executeQuery(RemoteQueryReturningTable()) print("QOPL.size(): %d" % (qopl.size())) try: qopl.getColumn("Quux") except Exception as e: if not "columnName=Quux not found" in str(e): print(e) raise RuntimeError("Not expected exception text.") dataReads = qopl.getColumn("DataReads") colType = dataReads.getType() if colType != int: # this was long? I don't know... raise RuntimeError("Unexpected type: %s" % colType) # This creats another table proxy, but is slightly more interesting than # timeTable; because the i() method is defaulted in the Interface. pqsl = db.i("DbInternal", "PersistentQueryStateLog") pqsl = pqsl.where("Date=currentDateNy()") # Dump out our globals on the remote side class DumpGlobals: def execute(self, db): print("pyGlobals: " + str(globals())) print("pyLocals: " + str(locals())) return True db.executeQuery(DumpGlobals()) # This is a simple remote query that demonstrates two things: (1) we can do # something with numpy on the worker, and (2) we can also call # deephaven.TableTools on the worker. class NumPyRemoteQuery: def execute(self, db): import numpy from deephaven import QueryScope from deephaven import TableTools a = numpy.arange(0, 15).reshape(3, 5).ndim QueryScope.addParam("a", a) return TableTools.emptyTable(1).update("X=a") npr = db.executeQuery(NumPyRemoteQuery()) TableTools.show(npr) if npr.getColumn("X").get(0) != 2: raise RuntimeError("Expected dimension of 2!") # This tests among other things printing out an array as a String; which used # to not work with JEP, but does work with JPy as our Python integration. class GetFirstDate: def execute(self, db): dates = db.i( "DbInternal", "PersistentQueryStateLog").selectDistinct("Date") if dates.size() <= 0: raise RuntimeError("Cannot operate on table PersistentQueryStateLog from namespace " "DbInternal because it has no data!") x = dates.getColumn("Date").getDirect() print("Array Print: %s" % (str(x))) return x[0] firstDate = db.executeQuery(GetFirstDate()) # This returns not just a Single value, but an entire array class GetDateArray: def execute(self, db): dates = db.i("DbInternal", "PersistentQueryStateLog").selectDistinct("Date") x = dates.getColumn("Date").getDirect() return x res = db.executeQuery(GetDateArray()) first = True for x in res: if first: first = False if x != firstDate: raise RuntimeError("First date doesn't match: %s != %s" % (firstDate, x)) class DoMyPow: def myPow(self, x): return 2**x def execute(self, db): return self.myPow(4) powResult = db.executeQuery(DoMyPow()) if powResult != 16: raise RuntimeError("Pow result %s" % powResult) class NestedClasses: def execute(self, db): return DoMyPow().myPow(5) db.pushClass(DoMyPow) nestedResult = db.executeQuery(NestedClasses()) if nestedResult != 32: raise RuntimeError("NestedResult result %s" % powResult) class IntegerHolder: def __init__(self, value): self.value = value def getValue(self): return self.value seventySix = IntegerHolder(76) if seventySix.getValue() != 76: raise RuntimeError("Value %s" % seventySix.getValue()) db.pushClass(IntegerHolder) class ReturnClass: def execute(self, db): return IntegerHolder(1492) rc = db.executeQuery(ReturnClass()) if type(rc) != type(seventySix): raise RuntimeError("Bad Type: %s " % type(rc)) if rc.getValue() != 1492: raise RuntimeError("Value %s" % rc.getValue())