## Copyright (c) 2016-2025 Deephaven Data Labs and Patent Pending#"""This module supports embedding a Deephaven server in Python."""importatexitimportsysfromtypingimportList,Optionalfrom.start_jvmimportstart_jvm# These classes are explicitly not JObjectWrapper, as that would require importing deephaven and jpy# before the JVM was running.
[docs]classServerConfig:""" Represents the configuration of a Deephaven server. """def__init__(self,j_server_config):self.j_server_config=j_server_config@propertydefj_object(self):returnself.j_server_config@propertydeftarget_url_or_default(self)->str:""" Returns the target URL to bring up the Web UI. Returns: The target URL to bring up the Web UI. """returnself.j_server_config.targetUrlOrDefault()
[docs]classAuthenticationHandler:""" Represents an authentication handler for a Deephaven server. """def__init__(self,j_authentication_handler):self.j_authentication_handler=j_authentication_handler@propertydefj_object(self):returnself.j_authentication_handler@propertydefauth_type(self)->str:""" Get the authentication type for this handler. Returns: The authentication type for this handler. """returnself.j_authentication_handler.getAuthType()
[docs]defurls(self,target_url:str)->List[str]:""" Get the URLs for this authentication handler. Args: target_url: The target URL where the Web UI is hosted. Returns: The URLs provided by this authentication handler to open the Web UI with authentication. For example, with pre-shared key authentication, it could add a query param with the pre-shared key. """returnlist(self.j_authentication_handler.urls(target_url).toArray())
[docs]classServer:""" Represents a Deephaven server that can be created from Python. """instance=None@propertydefj_object(self):returnself.j_server@propertydefport(self)->int:""" Get the port the server is running on. Returns: The port the server is running on. """returnself.j_server.getPort()@propertydefserver_config(self)->ServerConfig:""" Get the configuration of the server. Returns: The configuration of the server. """returnServerConfig(self.j_server.serverConfig())@propertydefauthentication_handlers(self)->List[AuthenticationHandler]:""" Get the authentication handlers for the server. Returns: The authentication handlers for the server. """return[AuthenticationHandler(j_auth_handler)forj_auth_handlerinself.j_server.authenticationHandlers().toArray()]def__init__(self,host:Optional[str]=None,port:Optional[int]=None,jvm_args:Optional[List[str]]=None,extra_classpath:Optional[List[str]]=None,default_jvm_args:Optional[List[str]]=None,):""" Creates a Deephaven embedded server. Only one instance can be created at this time. Args: host (Optional[str]): The host to bind the server to, defaults to None. When None, if a user defined configuration file is present and 'http.host' is specified in it, use its value, otherwise, use the default 'localhost'. Refer to the Deephaven documentation for more information on the configuration file. port (Optional[int]): The port to bind the server to, defaults to None. When None, if a user defined configuration file is present and 'http.port' is specified in it, use that port, otherwise, use the default 10000. Refer to the Deephaven documentation for more information on the configuration file. jvm_args (Optional[List[str]]): The common, user specific JVM arguments, such as JVM heap size, and other related JVM options. Defaults to None. extra_classpath (Optional[List[str]]): The extra classpath to use. default_jvm_args (Optional[List[str]]): The advanced JVM arguments to use instead of the default ones that Deephaven recommends, such as a specific garbage collector and related tuning parameters, or whether to let Python or Java handle signals. Defaults to None, the Deephaven defaults. """# TODO deephaven-core#2453 consider providing @dataclass for arguments# If the server was already created, emit an error to warn away from trying againifServer.instanceisnotNone:fromdeephavenimportDHErrorraiseDHError("Cannot create more than one instance of the server")ifextra_classpathisNone:extra_classpath=[]# given the jvm args, ensure that the jvm has startedstart_jvm(jvm_args=jvm_args,default_jvm_args=default_jvm_args,extra_classpath=extra_classpath,)# it is now safe to import jpyimportjpy# Create a python-wrapped java server that we can reference to talk to the platformself.j_server=jpy.get_type("io.deephaven.python.server.EmbeddedServer")(host,port)# Obtain references to the deephaven logbuffer and redirect stdout/stderr to it. Note that we should not import# this until after jpy has started.fromdeephaven_internal.streamimportTeeStreamsys.stdout=TeeStream.split(sys.stdout,self.j_server.getStdout())sys.stderr=TeeStream.split(sys.stderr,self.j_server.getStderr())# Keep a reference to the server so we know it is runningServer.instance=self# On halt, prevent the JVM from writing to sys.out and sys.erratexit.register(self.j_server.prepareForShutdown)
[docs]defstart(self)->None:""" Starts the server. Presently once the server is started, it cannot be stopped until the python process halts. """self.j_server.start()