Module surrealpy.handler
Expand source code
import os
import threading
import subprocess as sp
import psutil
import shlex
import logging
import socket
# create logger object
logger = logging.getLogger("surrealpy.sync.client")
# if operation system is windows set process name to surreal.exe
if os.name == "nt":
processName = "surreal.exe"
elif os.name == "posix":
processName = "surreal"
else:
print("Unknown OS")
exit(1)
def checkIfProcessRunning(processName):
"""
Check if there is any running process that contains the given name processName.
"""
# Iterate over the all the running process
for proc in psutil.process_iter():
try:
# Check if process name contains the given name string.
if processName.lower() in proc.name().lower():
return True
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
return False
# this is a thread safe singleton class
# with this class we can start a thread to handle the database process
def getAvaiblePort():
sock = socket.socket()
sock.bind(("", 0))
return sock.getsockname()[1]
class SurrealDBHandler(threading.Thread):
def __init__(
self,
uri: str,
username: str,
password: str,
*,
host: str = "0.0.0.0",
port: int = None,
scheme: str = "http",
) -> None:
# check if surreal is already running
threading.Thread.__init__(self, daemon=True)
if checkIfProcessRunning(processName):
print("Surreal is already running")
exit(1)
# check if uri is filepath
self.__uri = uri
self.__username = username
self.__password = password
self.__host = host
self.__port = port or getAvaiblePort()
self.__canrun = True
self.__scheme = scheme
if uri == "memory":
self.__uri = "memory"
else:
self.__uri = "file://" + uri
# start the database process
self.__commandTemplate = "surreal start --log debug --user {username} --pass {password} --bind {host}:{port} {uri}"
self.__command = self.__commandTemplate.format(
username=self.username,
password=self.password,
uri=self.__uri,
host=host,
port=port,
)
self.__parsedCommand = shlex.split(self.__command)
# call the super class constructor
def run(self):
# start the database process
self.__process = sp.Popen(self.__parsedCommand)
# read the output of the process and log it
while self.__canrun:
output = self.__process.stdout.readline()
if output == "" and self.__process.poll() is not None:
break
if output:
logger.debug(output.strip())
@property
def uri(self):
return self.__uri
@property
def command(self):
return self.__command
@property
def username(self):
return self.__username
@property
def password(self):
return self.__password
@property
def host(self):
return self.__host
@property
def port(self):
return self.__port
@property
def bind(self):
return self.__host + ":" + str(self.__port)
@property
def scheme(self):
return self.__scheme
def stop(self):
self.__process.terminate()
self.__process.wait()
self.__canrun = False
logger.debug("Surreal process terminated")
@property
def sql(self):
return "{scheme}://{host}:{port}/sql".format(
scheme=self.scheme,
host=self.host,
port=self.port,
)
Functions
def checkIfProcessRunning(processName)
-
Check if there is any running process that contains the given name processName.
Expand source code
def checkIfProcessRunning(processName): """ Check if there is any running process that contains the given name processName. """ # Iterate over the all the running process for proc in psutil.process_iter(): try: # Check if process name contains the given name string. if processName.lower() in proc.name().lower(): return True except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): pass return False
def getAvaiblePort()
-
Expand source code
def getAvaiblePort(): sock = socket.socket() sock.bind(("", 0)) return sock.getsockname()[1]
Classes
class SurrealDBHandler (uri: str, username: str, password: str, *, host: str = '0.0.0.0', port: int = None, scheme: str = 'http')
-
A class that represents a thread of control.
This class can be safely subclassed in a limited fashion. There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the run() method in a subclass.
This constructor should always be called with keyword arguments. Arguments are:
group should be None; reserved for future extension when a ThreadGroup class is implemented.
target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.
name is the thread name. By default, a unique name is constructed of the form "Thread-N" where N is a small decimal number.
args is the argument tuple for the target invocation. Defaults to ().
kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.
If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.init()) before doing anything else to the thread.
Expand source code
class SurrealDBHandler(threading.Thread): def __init__( self, uri: str, username: str, password: str, *, host: str = "0.0.0.0", port: int = None, scheme: str = "http", ) -> None: # check if surreal is already running threading.Thread.__init__(self, daemon=True) if checkIfProcessRunning(processName): print("Surreal is already running") exit(1) # check if uri is filepath self.__uri = uri self.__username = username self.__password = password self.__host = host self.__port = port or getAvaiblePort() self.__canrun = True self.__scheme = scheme if uri == "memory": self.__uri = "memory" else: self.__uri = "file://" + uri # start the database process self.__commandTemplate = "surreal start --log debug --user {username} --pass {password} --bind {host}:{port} {uri}" self.__command = self.__commandTemplate.format( username=self.username, password=self.password, uri=self.__uri, host=host, port=port, ) self.__parsedCommand = shlex.split(self.__command) # call the super class constructor def run(self): # start the database process self.__process = sp.Popen(self.__parsedCommand) # read the output of the process and log it while self.__canrun: output = self.__process.stdout.readline() if output == "" and self.__process.poll() is not None: break if output: logger.debug(output.strip()) @property def uri(self): return self.__uri @property def command(self): return self.__command @property def username(self): return self.__username @property def password(self): return self.__password @property def host(self): return self.__host @property def port(self): return self.__port @property def bind(self): return self.__host + ":" + str(self.__port) @property def scheme(self): return self.__scheme def stop(self): self.__process.terminate() self.__process.wait() self.__canrun = False logger.debug("Surreal process terminated") @property def sql(self): return "{scheme}://{host}:{port}/sql".format( scheme=self.scheme, host=self.host, port=self.port, )
Ancestors
- threading.Thread
Instance variables
var bind
-
Expand source code
@property def bind(self): return self.__host + ":" + str(self.__port)
var command
-
Expand source code
@property def command(self): return self.__command
var host
-
Expand source code
@property def host(self): return self.__host
var password
-
Expand source code
@property def password(self): return self.__password
var port
-
Expand source code
@property def port(self): return self.__port
var scheme
-
Expand source code
@property def scheme(self): return self.__scheme
var sql
-
Expand source code
@property def sql(self): return "{scheme}://{host}:{port}/sql".format( scheme=self.scheme, host=self.host, port=self.port, )
var uri
-
Expand source code
@property def uri(self): return self.__uri
var username
-
Expand source code
@property def username(self): return self.__username
Methods
def run(self)
-
Method representing the thread's activity.
You may override this method in a subclass. The standard run() method invokes the callable object passed to the object's constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.
Expand source code
def run(self): # start the database process self.__process = sp.Popen(self.__parsedCommand) # read the output of the process and log it while self.__canrun: output = self.__process.stdout.readline() if output == "" and self.__process.poll() is not None: break if output: logger.debug(output.strip())
def stop(self)
-
Expand source code
def stop(self): self.__process.terminate() self.__process.wait() self.__canrun = False logger.debug("Surreal process terminated")