quantnet-agent 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. quantnet_agent-1.0.0/LICENSE +41 -0
  2. quantnet_agent-1.0.0/MANIFEST.in +7 -0
  3. quantnet_agent-1.0.0/PKG-INFO +83 -0
  4. quantnet_agent-1.0.0/README.md +57 -0
  5. quantnet_agent-1.0.0/config/logging.conf +34 -0
  6. quantnet_agent-1.0.0/pyproject.toml +35 -0
  7. quantnet_agent-1.0.0/quantnet_agent/__init__.py +1 -0
  8. quantnet_agent-1.0.0/quantnet_agent/cli.py +80 -0
  9. quantnet_agent-1.0.0/quantnet_agent/common/__init__.py +2 -0
  10. quantnet_agent-1.0.0/quantnet_agent/common/calibration_status.py +7 -0
  11. quantnet_agent-1.0.0/quantnet_agent/common/config.py +135 -0
  12. quantnet_agent-1.0.0/quantnet_agent/common/constants.py +28 -0
  13. quantnet_agent-1.0.0/quantnet_agent/common/logging.py +60 -0
  14. quantnet_agent-1.0.0/quantnet_agent/hal/HAL.py +231 -0
  15. quantnet_agent-1.0.0/quantnet_agent/hal/__init__.py +0 -0
  16. quantnet_agent-1.0.0/quantnet_agent/hal/driver/OZoptics.py +46 -0
  17. quantnet_agent-1.0.0/quantnet_agent/hal/driver/Thorlabs.py +39 -0
  18. quantnet_agent-1.0.0/quantnet_agent/hal/driver/__init__.py +0 -0
  19. quantnet_agent-1.0.0/quantnet_agent/hal/driver/artiq.py +124 -0
  20. quantnet_agent-1.0.0/quantnet_agent/hal/driver/dummy.py +373 -0
  21. quantnet_agent-1.0.0/quantnet_agent/hal/driver/overlayepc.py +27 -0
  22. quantnet_agent-1.0.0/quantnet_agent/hal/driver/overlayexpframework.py +47 -0
  23. quantnet_agent-1.0.0/quantnet_agent/hal/driver/overlaylightsrc.py +125 -0
  24. quantnet_agent-1.0.0/quantnet_agent/hal/driver/overlaymeter.py +58 -0
  25. quantnet_agent-1.0.0/quantnet_agent/hal/driver/simulator.py +345 -0
  26. quantnet_agent-1.0.0/quantnet_agent/hal/hwclasses.py +148 -0
  27. quantnet_agent-1.0.0/quantnet_agent/hal/interpreter/__init__.py +0 -0
  28. quantnet_agent-1.0.0/quantnet_agent/hal/interpreter/calibration.py +101 -0
  29. quantnet_agent-1.0.0/quantnet_agent/hal/interpreter/calibration_interpreter.py +43 -0
  30. quantnet_agent-1.0.0/quantnet_agent/hal/interpreter/dummy_cavity_calibration.py +16 -0
  31. quantnet_agent-1.0.0/quantnet_agent/hal/interpreter/dummy_lsrc_calibration.py +16 -0
  32. quantnet_agent-1.0.0/quantnet_agent/hal/interpreter/exp_framework.py +75 -0
  33. quantnet_agent-1.0.0/quantnet_agent/hal/interpreter/scheduler.py +35 -0
  34. quantnet_agent-1.0.0/quantnet_agent/hal/local_task_manager.py +249 -0
  35. quantnet_agent-1.0.0/quantnet_agent/hal/node.py +205 -0
  36. quantnet_agent-1.0.0/quantnet_agent/interpreter/test_interpreter.py +32 -0
  37. quantnet_agent-1.0.0/quantnet_agent/scheduler/__init__.py +0 -0
  38. quantnet_agent-1.0.0/quantnet_agent/scheduler/scheduler.py +483 -0
  39. quantnet_agent-1.0.0/quantnet_agent/service/__init__.py +1 -0
  40. quantnet_agent-1.0.0/quantnet_agent/service/agent.py +98 -0
  41. quantnet_agent-1.0.0/quantnet_agent/service/register.py +77 -0
  42. quantnet_agent-1.0.0/quantnet_agent.egg-info/PKG-INFO +83 -0
  43. quantnet_agent-1.0.0/quantnet_agent.egg-info/SOURCES.txt +47 -0
  44. quantnet_agent-1.0.0/quantnet_agent.egg-info/dependency_links.txt +1 -0
  45. quantnet_agent-1.0.0/quantnet_agent.egg-info/entry_points.txt +2 -0
  46. quantnet_agent-1.0.0/quantnet_agent.egg-info/requires.txt +12 -0
  47. quantnet_agent-1.0.0/quantnet_agent.egg-info/top_level.txt +1 -0
  48. quantnet_agent-1.0.0/requirements.txt +12 -0
  49. quantnet_agent-1.0.0/setup.cfg +4 -0
@@ -0,0 +1,41 @@
1
+ QUANT-NET Control Plane Framework (QNCP) Copyright (c) 2025, The Regents of the
2
+ University of California, through Lawrence Berkeley National Laboratory (subject
3
+ to receipt of any required approvals from the U.S. Dept. of Energy). All rights
4
+ reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification,
7
+ are permitted provided that the following conditions are met:
8
+
9
+ (1) Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ (2) Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation and/or
14
+ other materials provided with the distribution.
15
+
16
+ (3) Neither the name of the University of California, Lawrence Berkeley National
17
+ Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used
18
+ to endorse or promote products derived from this software without specific prior
19
+ written permission.
20
+
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ You are under no obligation whatsoever to provide any bug fixes, patches, or
34
+ upgrades to the features, functionality or performance of the source code
35
+ ("Enhancements") to anyone; however, if you choose to make your Enhancements
36
+ available either publicly, or directly to Lawrence Berkeley National Laboratory,
37
+ without imposing a separate written license agreement for such Enhancements,
38
+ then you hereby grant the following license: a non-exclusive, royalty-free
39
+ perpetual license to install, use, modify, prepare derivative works, incorporate
40
+ into other computer software, distribute, and sublicense such enhancements or
41
+ derivative works thereof, in binary and source code form.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+ include requirements.txt
4
+
5
+ recursive-exclude * __pycache__
6
+ recursive-exclude * *.py[co]
7
+
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.4
2
+ Name: quantnet-agent
3
+ Version: 1.0.0
4
+ Summary: The QN Agent for Quant-Net Control Plane
5
+ Author-email: ESnet <quantum@es.net>
6
+ License-Expression: BSD-3-Clause-LBNL
7
+ Project-URL: Homepage, https://github.com/quant-net/quant-net-agent
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: asyncio-mqtt==0.16.1
14
+ Requires-Dist: click==8.1.3
15
+ Requires-Dist: uvloop==0.21.0
16
+ Requires-Dist: ThorlabsPM100
17
+ Requires-Dist: numpy==1.26.2
18
+ Requires-Dist: pyserial==3.3
19
+ Requires-Dist: configobj==5.0.9
20
+ Requires-Dist: apscheduler==3.10.4
21
+ Requires-Dist: pydantic==2.7.3
22
+ Requires-Dist: pyyaml==6.0.1
23
+ Requires-Dist: networkx==3.4.2
24
+ Requires-Dist: quantnet-mq
25
+ Dynamic: license-file
26
+
27
+
28
+ # Quant-Net Agent
29
+
30
+ The QUANT-NET Control Plane (QNCP) runs as a distributed system. This Agent
31
+ registers resources, interfaces with devices, and interprets protocol commands
32
+ from a Controller instance. The Agent package includes the concept of extensible
33
+ command interpreters, which define the behavior of the Agents when processing
34
+ protocol messages and interacting with the underlying hardware or simulation
35
+ devices.
36
+
37
+ The Agent includes a hardware abstraction layer (HAL) that defines a base set of
38
+ hardware classes for managing the interaction with quantum devices and external
39
+ experiment control frameworks.
40
+
41
+ ## Development Install
42
+
43
+ Pull requirements and install package in edit mode.
44
+
45
+ ```
46
+ pip3 install -e .
47
+ ```
48
+
49
+ The `quantnet_agent` script will be available in your local path, or check `~/.local/bin`
50
+
51
+ ```
52
+ $ quantnet_agent --help
53
+ Usage: quantnet_agent [OPTIONS]
54
+
55
+ Options:
56
+ -c, --config TEXT Main configuration file [default:
57
+ ./config/agent.cfg]
58
+ -n, --node-config TEXT Node configuration file [default: ~/.quant-
59
+ net/node.json]
60
+ -a, --agent_id TEXT Specify an agent identifier [default: ]
61
+ --mq-broker-host TEXT Message queue broker host
62
+ --mq-broker-port INTEGER Message queue broker port
63
+ -d, --debug Enable debug logging
64
+ --interpreter-path TEXT Location of additional command interpreters
65
+ --schema-path TEXT Specify a path containing additional schema files
66
+ --help Show this message and exit.
67
+ ```
68
+
69
+ ## Example usage
70
+
71
+ An MQTT broker should be available for the agent to connect to. A development docker-compose file that starts an Eclipse Mosquitto instance is available in `quant-net-docker:docker-compose-backend.yml`
72
+
73
+ Testing node config files exist in `quant-net-mq:quant-net-mq/schemas/examples`
74
+
75
+ Running the agent:
76
+
77
+ ```
78
+ quantnet_agent --mq-broker-host <broker> -n <path_to>/quant-net-mq/quantnet_mq/schema/examples/conf_qnode.json
79
+ ```
80
+
81
+
82
+
83
+
@@ -0,0 +1,57 @@
1
+
2
+ # Quant-Net Agent
3
+
4
+ The QUANT-NET Control Plane (QNCP) runs as a distributed system. This Agent
5
+ registers resources, interfaces with devices, and interprets protocol commands
6
+ from a Controller instance. The Agent package includes the concept of extensible
7
+ command interpreters, which define the behavior of the Agents when processing
8
+ protocol messages and interacting with the underlying hardware or simulation
9
+ devices.
10
+
11
+ The Agent includes a hardware abstraction layer (HAL) that defines a base set of
12
+ hardware classes for managing the interaction with quantum devices and external
13
+ experiment control frameworks.
14
+
15
+ ## Development Install
16
+
17
+ Pull requirements and install package in edit mode.
18
+
19
+ ```
20
+ pip3 install -e .
21
+ ```
22
+
23
+ The `quantnet_agent` script will be available in your local path, or check `~/.local/bin`
24
+
25
+ ```
26
+ $ quantnet_agent --help
27
+ Usage: quantnet_agent [OPTIONS]
28
+
29
+ Options:
30
+ -c, --config TEXT Main configuration file [default:
31
+ ./config/agent.cfg]
32
+ -n, --node-config TEXT Node configuration file [default: ~/.quant-
33
+ net/node.json]
34
+ -a, --agent_id TEXT Specify an agent identifier [default: ]
35
+ --mq-broker-host TEXT Message queue broker host
36
+ --mq-broker-port INTEGER Message queue broker port
37
+ -d, --debug Enable debug logging
38
+ --interpreter-path TEXT Location of additional command interpreters
39
+ --schema-path TEXT Specify a path containing additional schema files
40
+ --help Show this message and exit.
41
+ ```
42
+
43
+ ## Example usage
44
+
45
+ An MQTT broker should be available for the agent to connect to. A development docker-compose file that starts an Eclipse Mosquitto instance is available in `quant-net-docker:docker-compose-backend.yml`
46
+
47
+ Testing node config files exist in `quant-net-mq:quant-net-mq/schemas/examples`
48
+
49
+ Running the agent:
50
+
51
+ ```
52
+ quantnet_agent --mq-broker-host <broker> -n <path_to>/quant-net-mq/quantnet_mq/schema/examples/conf_qnode.json
53
+ ```
54
+
55
+
56
+
57
+
@@ -0,0 +1,34 @@
1
+ [loggers]
2
+ keys=root,quantnet_agent,gmqtt
3
+
4
+ [handlers]
5
+ keys=console
6
+
7
+ [formatters]
8
+ keys=simple
9
+
10
+ [logger_root]
11
+ level=INFO
12
+ handlers=console
13
+
14
+ [logger_quantnet_agent]
15
+ level=DEBUG
16
+ handlers=console
17
+ qualname=agent
18
+ propagate=0
19
+
20
+ [logger_gmqtt]
21
+ level=CRITICAL
22
+ handlers=console
23
+ qualname=gmqtt
24
+ propagate=0
25
+
26
+ [handler_console]
27
+ class=StreamHandler
28
+ level=DEBUG
29
+ formatter=simple
30
+ args=(sys.stdout,)
31
+
32
+ [formatter_simple]
33
+ format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
34
+ datefmt=
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools >= 77.0.3"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "quantnet-agent"
7
+ authors = [
8
+ { name="ESnet", email="quantum@es.net" },
9
+ ]
10
+ description = "The QN Agent for Quant-Net Control Plane"
11
+ readme = "README.md"
12
+ requires-python = ">=3.10"
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ license = "BSD-3-Clause-LBNL"
18
+ license-files = ["LICEN[CS]E*"]
19
+ dynamic = [
20
+ "version",
21
+ "dependencies"
22
+ ]
23
+
24
+ [project.urls]
25
+ Homepage = "https://github.com/quant-net/quant-net-agent"
26
+
27
+ [tool.setuptools.dynamic]
28
+ dependencies = {file = ["requirements.txt"]}
29
+ version = {attr = "quantnet_agent.__version__"}
30
+
31
+ [tool.setuptools.packages.find]
32
+ include = ["quantnet_agent", "quantnet_agent.*"]
33
+
34
+ [project.scripts]
35
+ quantnet_agent = "quantnet_agent.cli:main"
@@ -0,0 +1 @@
1
+ __version__ = "1.0.0"
@@ -0,0 +1,80 @@
1
+ import socket
2
+ import click
3
+ import sys
4
+ from quantnet_agent.service import QuantnetAgent
5
+ from quantnet_agent.common import Constants, Config
6
+ from quantnet_agent.common.logging import setup_logging
7
+
8
+
9
+ @click.command("Quantnet Agent")
10
+ @click.option("-c",
11
+ "--config",
12
+ default=Constants.DEFAULT_CONFIG_FILE,
13
+ help="Main configuration file",
14
+ show_default=True)
15
+ @click.option("-n",
16
+ "--node-config",
17
+ default=None,
18
+ help="Node configuration file",
19
+ show_default=True)
20
+ @click.option("-a",
21
+ "--agent_id",
22
+ default=socket.getfqdn(),
23
+ help="Specify an agent identifier",
24
+ show_default=True)
25
+ @click.option("--mq-broker-host",
26
+ "mq_broker_host",
27
+ type=str,
28
+ help="Message queue broker host",
29
+ show_default=True)
30
+ @click.option("--mq-broker-port",
31
+ "mq_broker_port",
32
+ type=int,
33
+ help="Message queue broker port",
34
+ show_default=True)
35
+ @click.option("-d",
36
+ "--debug",
37
+ is_flag=True,
38
+ show_default=True,
39
+ default=False,
40
+ help="Enable debug logging")
41
+ @click.option("--interpreter-path",
42
+ "interpreter_path",
43
+ type=str,
44
+ help="Location of additional command interpreters",
45
+ show_default=True)
46
+ @click.option("--schema-path",
47
+ "schema_path",
48
+ type=str,
49
+ help="Specify a path containing additional schema files",
50
+ show_default=True
51
+ )
52
+ def main(config,
53
+ agent_id,
54
+ node_config,
55
+ mq_broker_host,
56
+ mq_broker_port,
57
+ debug,
58
+ interpreter_path,
59
+ schema_path):
60
+ cobj = Config(config,
61
+ node_config,
62
+ debug,
63
+ agent_id,
64
+ mq_broker_host,
65
+ mq_broker_port,
66
+ interpreter_path,
67
+ schema_path)
68
+
69
+ if cobj.node_file is None:
70
+ print("No node configuration file specified. Use --node-config (-n) to provide one.")
71
+ sys.exit(1)
72
+
73
+ setup_logging(cobj)
74
+
75
+ agent = QuantnetAgent(cobj)
76
+ agent.run()
77
+
78
+
79
+ if __name__ == "__main__":
80
+ sys.exit(main()) # pragma: no cover
@@ -0,0 +1,2 @@
1
+ from .constants import Constants
2
+ from .config import Config
@@ -0,0 +1,7 @@
1
+ from enum import Enum
2
+
3
+
4
+ class Calibration_status(Enum):
5
+ FULL = "Full_scale_calibration"
6
+ LIGHT = "Lightweight_calibration"
7
+ CHECK = "Status_check"
@@ -0,0 +1,135 @@
1
+ import os
2
+ import logging
3
+ import configobj
4
+ import json
5
+ from quantnet_agent.common.constants import Constants
6
+
7
+ log = logging.getLogger(__name__)
8
+
9
+
10
+ def get_config(config_file):
11
+ config_files = []
12
+ if config_file:
13
+ config_files.append(config_file)
14
+ if "QUANTNET_HOME" in os.environ:
15
+ config_files.append(f"{os.environ['QUANTNET_HOME']}/etc/agent.cfg")
16
+ else:
17
+ config_files.append("/etc/quantnet/agent.cfg")
18
+
19
+ for cf in config_files:
20
+ try:
21
+ config = configobj.ConfigObj(cf)
22
+ except IOError:
23
+ continue
24
+ return config
25
+
26
+
27
+ class Config:
28
+ def __init__(
29
+ self,
30
+ config_file: str = None,
31
+ node_file: str = None,
32
+ debug: bool = False,
33
+ agent_id: str = None,
34
+ mq_broker_host: str = None,
35
+ mq_broker_port: int = None,
36
+ interpreter_path: str = None,
37
+ schema_path: str = None,
38
+ ):
39
+ self._config = None
40
+ self.devices = {}
41
+
42
+ self._config = get_config(config_file)
43
+
44
+ if not self._config:
45
+ log.warning("No configuration file found, continuing with defaults")
46
+
47
+ if node_file:
48
+ self.node_file = node_file
49
+ else:
50
+ self.node_file = self.config_get("agent", "node_file", raise_exception=False)
51
+
52
+ if mq_broker_host:
53
+ self.mq_broker_host = mq_broker_host
54
+ else:
55
+ self.mq_broker_host = self.config_get("mq", "host", default="127.0.0.1")
56
+
57
+ if mq_broker_port:
58
+ self.mq_broker_port = mq_broker_port
59
+ else:
60
+ self.mq_broker_port = self.config_get("mq", "port", default="1883")
61
+
62
+ self.threads = int(self.config_get("agent", "threads", default=8))
63
+
64
+ if debug:
65
+ self.debug = debug
66
+ else:
67
+ self.config_get("agent", "debug", default=False)
68
+
69
+ if agent_id:
70
+ self.cid = agent_id
71
+ else:
72
+ try:
73
+ self.cid = self.config_get("agent", "agent_id")
74
+ except Exception:
75
+ self.cid = None
76
+
77
+ if interpreter_path:
78
+ self.interpreter_path = interpreter_path
79
+ else:
80
+ self.interpreter_path = self.config_get("interpreters", "path", raise_exception=False)
81
+
82
+ if "protocols" in self._config and len(self._config["protocols"]) > 0:
83
+ if self.interpreter_path is None:
84
+ raise Exception("Interpreter location for protocols is not found")
85
+ self.proto_plugins = self._config["protocols"]
86
+ else:
87
+ self.proto_plugins = {}
88
+
89
+ if schema_path:
90
+ self.schema_path = schema_path
91
+ else:
92
+ self.schema_path = self.config_get("schemas", "path", raise_exception=False)
93
+
94
+ if "devices" in self._config:
95
+ self.devices = self._config["devices"]
96
+
97
+ self.tasks = []
98
+ self.task_properties = {}
99
+
100
+ if "tasks" in self._config:
101
+ for task, property in self._config["tasks"].items():
102
+ try:
103
+ if type(property) is configobj.Section:
104
+ with open(os.path.join(Constants.DEFAULT_TASK_PATH, property["path"]), "r") as file:
105
+ calibration_task = json.load(file)
106
+ if float(calibration_task["Periodicity"]) <= Constants.SLOTSIZE.total_seconds():
107
+ raise Exception(
108
+ f"Task {task} interval is too short."
109
+ "It should be larger than the TDMA slot size "
110
+ f"{Constants.SLOTSIZE.total_seconds() * 1e3 }"
111
+ )
112
+ self.tasks.append(calibration_task)
113
+ else:
114
+ self.task_properties[task] = property
115
+ except Exception as e:
116
+ log.error(f"Cannot load local task {task} : {e}")
117
+
118
+ def config_get(self, section, option, raise_exception=True, default=None, check_config_table=True):
119
+ """
120
+ Return the string value for a given option in a section
121
+
122
+ :param section: the named section.
123
+ :param option: the named option.
124
+ :param raise_exception: Boolean to raise or not NoOptionError or NoSectionError.
125
+ :param default: the default value if not found.
126
+ :param check_config_table: if not set, avoid looking at config table
127
+ .
128
+ :returns: the configuration value.
129
+ """
130
+ try:
131
+ return self._config[section][option]
132
+ except (configobj.ConfigObjError, KeyError) as err:
133
+ if raise_exception and default is None:
134
+ raise err
135
+ return default
@@ -0,0 +1,28 @@
1
+ import os
2
+ from datetime import timedelta
3
+ import quantnet_agent
4
+
5
+
6
+ class Constants:
7
+ DEFAULT_CONFIG_FILE = "./config/agent.cfg"
8
+ DEFAULT_NODE_CONFIG_FILE = "./config/conf-alice.json"
9
+ DEFAULT_LOGGING_CONFIG_FILE = "./config/logging.conf"
10
+ DEFAULT_INTERPRETERS = {
11
+ "scheduler": "scheduler.py",
12
+ "calibration": "calibration.py",
13
+ "experiment": "exp_framework.py",
14
+ }
15
+ DEFAULT_TASK_PATH = os.path.join(os.path.dirname(os.path.dirname(quantnet_agent.__file__)), "config/")
16
+ DEFAULT_TASK_INTERPRETER = os.path.join(
17
+ os.path.dirname(quantnet_agent.__file__), "hal/interpreter/calibration_interpreter.py"
18
+ )
19
+ DEFAULT_TASK_NS = "quantnet_agent.task"
20
+ HEARTBEAT_INTERVAL = 10
21
+ REGISTRATION_RETRY_INTERVAL = 10
22
+ MAX_TIMESLOTS = 20000
23
+ SLOTSIZE = timedelta(milliseconds=100)
24
+ SCHEDULER_GRACE_PERIOD = timedelta(milliseconds=50)
25
+ # TODO: Check SCHEDULER_GRACE_PERIOD < SLOTSIZE * MAX_TIMESLOTS
26
+ UPDATE_INTERVAL = SLOTSIZE * MAX_TIMESLOTS / 2
27
+ # TODO: Check if update_interval is appropriate
28
+ DAG_CHECK_INTERVAL = timedelta(milliseconds=1000)
@@ -0,0 +1,60 @@
1
+ import os
2
+ import sys
3
+ import logging
4
+ import logging.config
5
+
6
+
7
+ def quantnet_log_formatter(cobj=None):
8
+ config_logformat = cobj.config_get(
9
+ "common",
10
+ "logformat",
11
+ raise_exception=False,
12
+ default="{asctime} {name:<29} {process} {levelname:>8} {message}",
13
+ )
14
+ return logging.Formatter(fmt=config_logformat, style='{')
15
+
16
+
17
+ def setup_default_logging(cobj=None):
18
+ """
19
+ Configures the logging by setting the output stream to stdout and
20
+ configures log level and log format.
21
+ """
22
+ config_loglevel = getattr(logging, cobj.config_get("common", "loglevel",
23
+ raise_exception=False, default="INFO").upper())
24
+
25
+ stdouthandler = logging.StreamHandler(stream=sys.stdout)
26
+ stdouthandler.setFormatter(quantnet_log_formatter(cobj))
27
+ stdouthandler.setLevel(config_loglevel)
28
+ logging.basicConfig(level=config_loglevel, handlers=[stdouthandler])
29
+
30
+
31
+ def setup_logging(cobj=None):
32
+ """
33
+ Configures the logging by setting the output stream to stdout and
34
+ configures log level and log format.
35
+ """
36
+
37
+ configfiles = list()
38
+
39
+ if cobj:
40
+ logging_config_path = cobj.config_get("common", "logging_config", raise_exception=False, default=None)
41
+ if logging_config_path:
42
+ configfiles.append(logging_config_path)
43
+
44
+ for i in ["QUANTNET_HOME", "VIRTUAL_ENV"]:
45
+ if i in os.environ:
46
+ configfiles.append(f"{os.environ[i]}/etc/logging.conf")
47
+ configfiles.append("/opt/quantnet/etc/logging.conf")
48
+
49
+ has_config = False
50
+ for configfile in configfiles:
51
+ try:
52
+ logging.config.fileConfig(configfile, disable_existing_loggers=False)
53
+ has_config = True
54
+ except Exception:
55
+ has_config = False
56
+ if has_config:
57
+ break
58
+
59
+ if not has_config and cobj:
60
+ setup_default_logging(cobj)