cgse-common 2024.1.1__py3-none-any.whl
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.
- cgse_common-2024.1.1.dist-info/METADATA +64 -0
- cgse_common-2024.1.1.dist-info/RECORD +32 -0
- cgse_common-2024.1.1.dist-info/WHEEL +4 -0
- cgse_common-2024.1.1.dist-info/entry_points.txt +2 -0
- egse/bits.py +318 -0
- egse/command.py +699 -0
- egse/config.py +289 -0
- egse/control.py +429 -0
- egse/decorators.py +419 -0
- egse/device.py +269 -0
- egse/env.py +279 -0
- egse/exceptions.py +88 -0
- egse/mixin.py +464 -0
- egse/monitoring.py +96 -0
- egse/observer.py +41 -0
- egse/obsid.py +161 -0
- egse/persistence.py +58 -0
- egse/plugin.py +97 -0
- egse/process.py +460 -0
- egse/protocol.py +607 -0
- egse/proxy.py +522 -0
- egse/reload.py +122 -0
- egse/resource.py +438 -0
- egse/services.py +212 -0
- egse/services.yaml +51 -0
- egse/settings.py +379 -0
- egse/settings.yaml +981 -0
- egse/setup.py +1180 -0
- egse/state.py +173 -0
- egse/system.py +1499 -0
- egse/version.py +178 -0
- egse/zmq_ser.py +69 -0
egse/version.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the version for the Common-EGSE release. Whenever a version number
|
|
3
|
+
or the release number is needed, this module shall be imported. The version and release
|
|
4
|
+
number is then available as:
|
|
5
|
+
|
|
6
|
+
>>> import egse.version
|
|
7
|
+
>>> print(f"version = {egse.version.VERSION}")
|
|
8
|
+
|
|
9
|
+
The actual numbers are updated for each release in the `settings.yaml` configuration file.
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
# WARNING: Make sure you are not importing any `egse` packages at the module level.
|
|
15
|
+
# This module is magically loaded by pip to determine the VERSION number before the
|
|
16
|
+
# package has been installed (see pyproject.py).
|
|
17
|
+
# Any imports from an 'egse' package will result in a ModuleNotFound error.
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import subprocess
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
from egse.system import get_package_location
|
|
24
|
+
|
|
25
|
+
HERE = Path(__file__).parent.resolve()
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"get_version_installed",
|
|
29
|
+
"get_version_from_git",
|
|
30
|
+
"get_version_from_settings",
|
|
31
|
+
"VERSION",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_version_from_settings_file_raw(group_name: str, location: Path | str = None) -> str:
|
|
36
|
+
"""
|
|
37
|
+
Reads the VERSION field from the `settings.yaml` file in raw mode, meaning the file
|
|
38
|
+
is not read using the PyYAML module, but using the `readline()` function of the file
|
|
39
|
+
descriptor.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
group_name: major group name that contains the VERSION field, i.e. Common-EGSE or PLATO_TEST_SCRIPTS.
|
|
43
|
+
location: the location of the `settings.yaml` file or None in which case the location of this file is used.
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
A RuntimeError when the group_name is incorrect and unknown or the VERSION field is not found.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
The version from the `settings.yaml` file as a string.
|
|
50
|
+
"""
|
|
51
|
+
basedir = location or os.path.dirname(__file__)
|
|
52
|
+
|
|
53
|
+
with open(os.path.join(basedir, "settings.yaml"), mode="r") as yaml_fd:
|
|
54
|
+
line = yaml_fd.readline()
|
|
55
|
+
if not line.startswith(group_name):
|
|
56
|
+
raise RuntimeError(f"Incompatible format for the settings.yaml file, should start with '{group_name}'")
|
|
57
|
+
|
|
58
|
+
line = yaml_fd.readline().lstrip()
|
|
59
|
+
if not line.startswith("VERSION"):
|
|
60
|
+
raise RuntimeError("Incompatible format for the settings.yaml file, no VERSION found.")
|
|
61
|
+
_, version = line.split(":")
|
|
62
|
+
|
|
63
|
+
# remove possible trailing comment starting with '#'
|
|
64
|
+
version, *_ = version.split("#")
|
|
65
|
+
version = version.strip()
|
|
66
|
+
|
|
67
|
+
return version
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def get_version_from_settings(group_name: str, location: Path = None):
|
|
71
|
+
"""
|
|
72
|
+
Reads the VERSION field from the `settings.yaml` file. This function first tries to load the proper Settings
|
|
73
|
+
and Group and if that fails uses the raw method.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
group_name: major group name that contains the VERSION field, i.e. Common-EGSE or PLATO_TEST_SCRIPTS.
|
|
77
|
+
location: the location of the `settings.yaml` file or None in which case the location of this file is used.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
A RuntimeError when the group_name is incorrect and unknown or the VERSION field is not found.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The version from the `settings.yaml` file as a string.
|
|
84
|
+
"""
|
|
85
|
+
from egse.settings import Settings, SettingsError
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
settings = Settings.load(group_name, location=location)
|
|
89
|
+
version = settings.VERSION
|
|
90
|
+
except (ModuleNotFoundError, SettingsError):
|
|
91
|
+
version = get_version_from_settings_file_raw(group_name, location=location)
|
|
92
|
+
|
|
93
|
+
return version
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def get_version_from_git(location: str = None):
|
|
97
|
+
"""
|
|
98
|
+
Returns the Git version number for the repository at the given location.
|
|
99
|
+
|
|
100
|
+
The returned string has the following format: YYYY.X.Y+REPO.TH-N-HASH, where:
|
|
101
|
+
|
|
102
|
+
* YYYY is the year
|
|
103
|
+
* X is the major version number and equal to the week number of the release
|
|
104
|
+
* Y is the minor version patch number
|
|
105
|
+
* REPO is the name of the repository, i.e. CGSE or TS
|
|
106
|
+
* TH is the name of the test house, i.e. CSL1, CSL2, IAS, INTA, SRON
|
|
107
|
+
* N is the number of commits since the release
|
|
108
|
+
* HASH is the Git hash number of the commit
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
location: The absolute path of the root or a sub-folder of the repo.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
The Git version number.
|
|
115
|
+
"""
|
|
116
|
+
from egse.system import chdir
|
|
117
|
+
|
|
118
|
+
location = location or Path().cwd()
|
|
119
|
+
|
|
120
|
+
with chdir(location):
|
|
121
|
+
try:
|
|
122
|
+
std_out = subprocess.check_output(
|
|
123
|
+
["git", "describe", "--tags", "--long", "--always"], stderr=subprocess.PIPE
|
|
124
|
+
)
|
|
125
|
+
version = std_out.strip().decode("ascii")
|
|
126
|
+
if "cgse" not in version.lower() and "ts" not in version.lower():
|
|
127
|
+
version = None
|
|
128
|
+
except subprocess.CalledProcessError as exc:
|
|
129
|
+
version = None
|
|
130
|
+
|
|
131
|
+
return version
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def get_version_installed(package_name: str) -> str:
|
|
135
|
+
"""
|
|
136
|
+
Returns the version that is installed, i.e. read from the metadata in the import lib.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
package_name: the name of the installed package, e.g. cgse or cgse-ts
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
The version of the installed repo.
|
|
143
|
+
"""
|
|
144
|
+
from egse.system import chdir
|
|
145
|
+
|
|
146
|
+
with chdir(Path(__file__).parent):
|
|
147
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
version = version(package_name)
|
|
151
|
+
except PackageNotFoundError as exc:
|
|
152
|
+
version = None
|
|
153
|
+
|
|
154
|
+
return version
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
VERSION = get_version_from_settings_file_raw("Common-EGSE", location=HERE)
|
|
158
|
+
|
|
159
|
+
# The __PYPI_VERSION__ is the version number that will be used for the installation.
|
|
160
|
+
# The version will appear in PyPI and also as the `installed version`.
|
|
161
|
+
|
|
162
|
+
__PYPI_VERSION__ = VERSION.split('+')[0]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
if __name__ == "__main__":
|
|
166
|
+
import rich
|
|
167
|
+
from egse.system import get_module_location
|
|
168
|
+
from egse.plugin import entry_points
|
|
169
|
+
|
|
170
|
+
if VERSION:
|
|
171
|
+
rich.print(f"CGSE version in Settings: [bold default]{VERSION}[/]")
|
|
172
|
+
|
|
173
|
+
if git_version := get_version_from_git(os.getcwd()):
|
|
174
|
+
rich.print(f"git version (current project) = [bold default]{git_version}[/]")
|
|
175
|
+
|
|
176
|
+
for ep in entry_points("cgse.version"):
|
|
177
|
+
if installed_version := get_version_installed(ep.name):
|
|
178
|
+
rich.print(f"Installed version for {ep.name}= [bold default]{installed_version}[/]")
|
egse/zmq_ser.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import pickle
|
|
2
|
+
import zlib
|
|
3
|
+
from enum import IntEnum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def connect_address(transport, address, port):
|
|
7
|
+
"""Returns a properly formatted URL to connect to."""
|
|
8
|
+
return f"{transport}://{address}:{port}"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def bind_address(transport, port):
|
|
12
|
+
"""Returns a properly formatted url to bind a socket to."""
|
|
13
|
+
return f"{transport}://*:{port}"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def set_address_port(url: str, port: int):
|
|
17
|
+
"""Returns a url where the 'port' part is replaced with the given port."""
|
|
18
|
+
transport, address, old_port = split_address(url)
|
|
19
|
+
|
|
20
|
+
return f"{transport}://{address}:{port}"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def split_address(url: str):
|
|
24
|
+
|
|
25
|
+
transport, address, port = url.split(":")
|
|
26
|
+
if address.startswith("//"):
|
|
27
|
+
address = address[2:]
|
|
28
|
+
return transport, address, port
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def send_zipped_pickle(socket, obj, flags=0, protocol=-1):
|
|
32
|
+
"""pickle an object, and zip the pickle before sending it"""
|
|
33
|
+
p = pickle.dumps(obj, protocol)
|
|
34
|
+
z = zlib.compress(p)
|
|
35
|
+
return socket.send(z, flags=flags)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def recv_zipped_pickle(socket, flags=0, protocol=-1):
|
|
39
|
+
"""inverse of send_zipped_pickle"""
|
|
40
|
+
z = socket.recv(flags)
|
|
41
|
+
p = zlib.decompress(z)
|
|
42
|
+
return pickle.loads(p)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class MessageIdentifier(IntEnum):
|
|
46
|
+
"""
|
|
47
|
+
The first item in a multipart message that can be used to subscribe, filter and identify
|
|
48
|
+
messages.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
# ALL shall not be used in the multipart message itself, but exists as an indicator for
|
|
52
|
+
# subscribing to all messages. The ALL shall be converted into b'' when subscribing.
|
|
53
|
+
|
|
54
|
+
ALL = 0x00
|
|
55
|
+
|
|
56
|
+
# Synchronisation to DPU Processor at time of reception
|
|
57
|
+
|
|
58
|
+
SYNC_TIMECODE = 0x80
|
|
59
|
+
SYNC_HK_PACKET = 0x81
|
|
60
|
+
SYNC_DATA_PACKET = 0x82
|
|
61
|
+
SYNC_ERROR_FLAGS = 0x85
|
|
62
|
+
SYNC_HK_DATA = 0x86
|
|
63
|
+
|
|
64
|
+
N_FEE_REGISTER_MAP = 0x83
|
|
65
|
+
NUM_CYCLES = 0x84
|
|
66
|
+
|
|
67
|
+
# Sending out all kinds of information
|
|
68
|
+
|
|
69
|
+
HDF5_FILENAMES = 0x90
|