def prepare_locals(args): from malcolm.core import Process from malcolm.yamlutil import make_include_creator if args.yaml: proc_name = os.path.basename(args.yaml).split(".")[-2] proc = Process(proc_name) controllers, parts = make_include_creator(args.yaml)() assert not parts, "%s defines parts" % (args.yaml, ) for controller in controllers: proc.add_controller(controller) proc_name = "%s - imalcolm" % proc_name else: proc = Process("Process") proc_name = "imalcolm" # set terminal title sys.stdout.write("\x1b]0;%s\x07" % proc_name) if args.client: if args.client.startswith("ws://"): from malcolm.modules.web.controllers import WebsocketClientComms hostname, port = args.client[5:].split(":") comms = WebsocketClientComms(mri="%s:%s" % (hostname, port), hostname=hostname, port=int(port)) elif args.client == "pva": from malcolm.modules.pva.controllers import PvaClientComms comms = PvaClientComms(mri="pva") else: raise ValueError("Don't know how to create client to %s" % args.client) proc.add_controller(comms) proc.start(timeout=60) return proc
def test_make_include(self): with patch("malcolm.yamlutil.open", mock_open(read_data=include_yaml), create=True) as m: include_creator = make_include_creator("/tmp/__init__.py", "include.yaml") assert include_creator.__name__ == "include" m.assert_called_once_with("/tmp/include.yaml") process = Mock() parts = include_creator(process, dict(something="blah")) assert len(parts) == 1 part = parts[0] self.assertIsInstance(part, StringPart) assert part.name == "scannable" assert part.params.initialValue == "blah"
def test_make_include(self): with patch("malcolm.yamlutil.open", mock_open(read_data=include_yaml), create=True) as m: include_creator = make_include_creator("/tmp/__init__.py", "include.yaml") assert include_creator.__name__ == "include" m.assert_called_once_with("/tmp/include.yaml") controllers, parts = include_creator() assert len(controllers) == 0 assert len(parts) == 1 part = parts[0] self.assertIsInstance(part, StringPart) assert part.name == "scannable" assert part.attr.value == "nothing"
def test_make_include(self): yaml = """ - parameters.string: name: something description: my description - parts.builtin.StringPart: name: scannable description: Scannable name for motor initialValue: $(something) """ include_creator = make_include_creator(yaml) process = Mock() blocks, parts = include_creator(process, dict(something="blah")) self.assertEquals(len(blocks), 0) self.assertEquals(len(parts), 1) part = parts[0] self.assertIsInstance(part, StringPart) self.assertEqual(part.name, "scannable") self.assertEqual(part.params.initialValue, "blah")
from malcolm.yamlutil import make_include_creator, check_yaml_names adbase_parts = make_include_creator(__file__, "adbase_parts.yaml") filewriting_collection = make_include_creator(__file__, "filewriting_collection.yaml") ndarraybase_parts = make_include_creator(__file__, "ndarraybase_parts.yaml") ndpluginbase_parts = make_include_creator(__file__, "ndpluginbase_parts.yaml") __all__ = check_yaml_names(globals())
from malcolm.yamlutil import check_yaml_names, make_include_creator compoundmotor_collection = make_include_creator( __file__, "compoundmotor_collection.yaml") cs_collection = make_include_creator(__file__, "cs_collection.yaml") motor_records = make_include_creator(__file__, "motor_records.yaml") rawmotor_collection = make_include_creator(__file__, "rawmotor_collection.yaml") trajectory_collection = make_include_creator(__file__, "trajectory_collection.yaml") __all__ = check_yaml_names(globals())
def make_process(): import sys import threading import argparse import logging from os import environ parser = argparse.ArgumentParser( description="Interactive shell for malcolm") parser.add_argument( '--client', '-c', help="Add a client to given server, like ws://localhost:8080 or pva") parser.add_argument( '--log', default="INFO", help="Lowest level of logs to see. One of: ERROR, WARNING, INFO, DEBUG " "Default is INFO") parser.add_argument( 'yaml', nargs="?", help="The YAML file containing the blocks to be loaded") args = parser.parse_args() # assuming loglevel is bound to the string value obtained from the # command line argument. Convert to upper case to allow the user to # specify --log=DEBUG or --log=debug numeric_level = getattr(logging, args.log.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % args.log) logging.basicConfig(level=numeric_level) from malcolm.core import SyncFactory, Process from malcolm.yamlutil import make_include_creator sf = SyncFactory("Sync") if args.yaml: proc_name = os.path.basename(args.yaml).split(".")[-2] proc = Process(proc_name, sf) with open(args.yaml) as f: assembly = make_include_creator(f.read()) params = assembly.MethodMeta.prepare_input_map() assembly(proc, params) proc_name = "%s - imalcolm" % proc_name else: proc = Process("Process", sf) proc_name = "imalcolm" # set terminal title sys.stdout.write("\x1b]0;%s\x07" % proc_name) if args.client: if args.client.startswith("ws://"): from malcolm.comms.websocket import WebsocketClientComms hostname, port = args.client[5:].split(":") comms = WebsocketClientComms( proc, dict(hostname=hostname, port=int(port))) proc.add_comms(comms) else: raise ValueError("Don't know how to create client to %s" % args.client) def gui(block): global opener opener.open_gui(block, proc) try: environ['DISPLAY'] # If this environment variable doesn't exist then there is probably no # X server for us to talk to. except KeyError: pass else: from PyQt4.Qt import QApplication # Start qt def start_qt(): global app app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(False) from malcolm.gui.guiopener import GuiOpener global opener opener = GuiOpener() app.exec_() qt_thread = threading.Thread(target=start_qt) qt_thread.start() return proc, gui
def make_process(): import sys import threading import argparse import atexit import os import getpass import json from ruamel import yaml # These are the locals that we will pass to the console locals_d = {} parser = argparse.ArgumentParser( description="Interactive shell for malcolm") parser.add_argument( '--client', '-c', help="Add a client to given server, like ws://localhost:8080 or pva") parser.add_argument('--logcfg', help="Logging dict config in JSON or YAML file") parser.add_argument("--profiledir", help="Directory to store profiler results in", default="/tmp/imalcolm_profiles") parser.add_argument( 'yaml', nargs="?", help="The YAML file containing the blocks to be loaded") args = parser.parse_args() log_config = { "version": 1, "disable_existing_loggers": False, "formatters": { "simple": { "format": "%(name)s: %(message)s" }, "extended": { "format": "%(asctime)s - %(levelname)6s - %(name)s\n" " %(message)s" }, }, "handlers": { "console": { "class": "logging.StreamHandler", "level": "WARNING", "formatter": "simple", "stream": "ext://sys.stdout" }, # "local_file_handler": { # "class": "logging.handlers.RotatingFileHandler", # "level": "DEBUG", # "formatter": "extended", # "filename": "/tmp/debug.log", # "maxBytes": 100048576, # "backupCount": 4, # "encoding": "utf8" # }, "graylog_gelf": { "class": "pygelf.GelfUdpHandler", # Obviously a DLS-specific configuration: the graylog server # address and port "host": "cs04r-sc-serv-14.diamond.ac.uk", "port": 12202, "debug": True, "level": "DEBUG", # The following custom fields will be disabled if setting this # False "include_extra_fields": True, "username": getpass.getuser(), "pid": os.getpid() } }, # "loggers": { # # Fine-grained logging configuration for individual modules or # # classes # # Use this to set different log levels without changing 'real' code. # "myclasses": { # "level": "DEBUG", # "propagate": True # }, # "usermessages": { # "level": "INFO", # "propagate": True, # "handlers": ["console"] # } # }, "root": { "level": "DEBUG", "handlers": ["graylog_gelf", "console"], } } if args.logcfg: with open(args.logcfg) as f: text = f.read() if args.logcfg.endswith(".json"): file_config = json.loads(text) else: file_config = yaml.load(text, Loader=yaml.RoundTripLoader) if file_config: log_config = file_config # Start it off, and tell it to stop when we quit listener = make_async_logging(log_config) listener.start() atexit.register(listener.stop) # Setup Qt gui, must be done before any malcolm imports otherwise cothread # starts in the wrong thread try: os.environ['DISPLAY'] # If this environment variable doesn't exist then there is probably no # X server for us to talk to. except KeyError: qt_thread = None else: from PyQt4.Qt import QApplication # Start qt def start_qt(): app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(False) locals_d["app"] = app from malcolm.gui.guiopener import GuiOpener global opener opener = GuiOpener() app.exec_() qt_thread = threading.Thread(target=start_qt) qt_thread.setDaemon(True) def gui(block): global opener opener.open_gui(block, proc) locals_d["gui"] = gui # Setup profiler dir try: from malcolm.modules.profiling.parts import ProfilingViewerPart from malcolm.modules.profiling.profiler import Profiler except ImportError: raise else: if not os.path.isdir(args.profiledir): os.mkdir(args.profiledir) ProfilingViewerPart.profiledir = args.profiledir locals_d["profiler"] = Profiler(args.profiledir) #locals_d["profiler"].start() from malcolm.core import Process, call_with_params, Context, Queue from malcolm.modules.builtin.blocks import proxy_block from malcolm.yamlutil import make_include_creator if args.yaml: proc_name = os.path.basename(args.yaml).split(".")[-2] proc = Process(proc_name) assembly = make_include_creator(args.yaml) call_with_params(assembly, proc) proc_name = "%s - imalcolm" % proc_name else: proc = Process("Process") proc_name = "imalcolm" # set terminal title sys.stdout.write("\x1b]0;%s\x07" % proc_name) if args.client: if args.client.startswith("ws://"): from malcolm.modules.web.controllers import WebsocketClientComms hostname, port = args.client[5:].split(":") comms = call_with_params(WebsocketClientComms, proc, [], mri="%s:%s" % (hostname, port), hostname=hostname, port=int(port)) elif args.client == "pva": from malcolm.modules.pva.controllers import PvaClientComms comms = call_with_params(PvaClientComms, proc, [], mri="pva") else: raise ValueError("Don't know how to create client to %s" % args.client) proc.add_controller(comms.mri, comms) class UserContext(Context): def make_queue(self): return Queue(user_facing=True) def post(self, path, params=None, timeout=None): try: return super(UserContext, self).post(path, params, timeout) except KeyboardInterrupt: self.post([path[0], "abort"]) raise def make_proxy(self, comms, mri): call_with_params(proxy_block, proc, comms=comms, mri=mri) locals_d["self"] = UserContext(proc) if qt_thread: qt_thread.start() proc.start() locals_d["process"] = proc return locals_d
def make_process(): import sys import threading import argparse import logging from os import environ parser = argparse.ArgumentParser( description="Interactive shell for malcolm") parser.add_argument( '--client', '-c', help="Add a client to given server, like ws://localhost:8080 or pva") parser.add_argument( '--log', default="INFO", help="Lowest level of logs to see. One of: ERROR, WARNING, INFO, DEBUG " "Default is INFO") parser.add_argument( 'yaml', nargs="?", help="The YAML file containing the blocks to be loaded" ) args = parser.parse_args() # assuming loglevel is bound to the string value obtained from the # command line argument. Convert to upper case to allow the user to # specify --log=DEBUG or --log=debug numeric_level = getattr(logging, args.log.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % args.log) logging.basicConfig(level=numeric_level) from malcolm.core import SyncFactory, Process from malcolm.yamlutil import make_include_creator try: environ['DISPLAY'] # If this environment variable doesn't exist then there is probably no # X server for us to talk to. except KeyError: pass else: from PyQt4.Qt import QApplication # Start qt def start_qt(): global app app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(False) from malcolm.gui.guiopener import GuiOpener global opener opener = GuiOpener() app.exec_() qt_thread = threading.Thread(target=start_qt) qt_thread.start() sf = SyncFactory("Sync") if args.yaml: proc_name = os.path.basename(args.yaml).split(".")[-2] proc = Process(proc_name, sf) with open(args.yaml) as f: assembly = make_include_creator(f.read()) assembly(proc, {}) proc_name = "%s - imalcolm" % proc_name else: proc = Process("Process", sf) proc_name = "imalcolm" # set terminal title sys.stdout.write("\x1b]0;%s\x07" % proc_name) if args.client: if args.client.startswith("ws://"): from malcolm.comms.websocket import WebsocketClientComms hostname, port = args.client[5:].split(":") comms = WebsocketClientComms( proc, dict(hostname=hostname, port=int(port))) proc.add_comms(comms) else: raise ValueError( "Don't know how to create client to %s" % args.client) def gui(block): global opener opener.open_gui(block, proc) return proc, gui