np-services 0.1.59__py3-none-any.whl → 0.1.73__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.
- np_services/__init__.py +8 -8
- np_services/open_ephys.py +377 -378
- np_services/protocols.py +185 -185
- np_services/proxies.py +1489 -1488
- np_services/resources/mvr_connector.py +260 -260
- np_services/resources/zro.py +325 -325
- np_services/scripts/pretest.py +170 -73
- np_services/stim_computer_theme_changer.py +41 -41
- np_services/utils.py +167 -167
- {np_services-0.1.59.dist-info → np_services-0.1.73.dist-info}/METADATA +7 -8
- np_services-0.1.73.dist-info/RECORD +15 -0
- {np_services-0.1.59.dist-info → np_services-0.1.73.dist-info}/WHEEL +2 -1
- {np_services-0.1.59.dist-info → np_services-0.1.73.dist-info}/entry_points.txt +1 -1
- np_services-0.1.73.dist-info/top_level.txt +1 -0
- np_services/.mypy_cache/.gitignore +0 -2
- np_services/.mypy_cache/3.9/@plugins_snapshot.json +0 -1
- np_services/.mypy_cache/3.9/__future__.data.json +0 -1
- np_services/.mypy_cache/3.9/__future__.meta.json +0 -1
- np_services/.mypy_cache/3.9/_ast.data.json +0 -1
- np_services/.mypy_cache/3.9/_ast.meta.json +0 -1
- np_services/.mypy_cache/3.9/_codecs.data.json +0 -1
- np_services/.mypy_cache/3.9/_codecs.meta.json +0 -1
- np_services/.mypy_cache/3.9/_collections_abc.data.json +0 -1
- np_services/.mypy_cache/3.9/_collections_abc.meta.json +0 -1
- np_services/.mypy_cache/3.9/_ctypes.data.json +0 -1
- np_services/.mypy_cache/3.9/_ctypes.meta.json +0 -1
- np_services/.mypy_cache/3.9/_decimal.data.json +0 -1
- np_services/.mypy_cache/3.9/_decimal.meta.json +0 -1
- np_services/.mypy_cache/3.9/_random.data.json +0 -1
- np_services/.mypy_cache/3.9/_random.meta.json +0 -1
- np_services/.mypy_cache/3.9/_socket.data.json +0 -1
- np_services/.mypy_cache/3.9/_socket.meta.json +0 -1
- np_services/.mypy_cache/3.9/_thread.data.json +0 -1
- np_services/.mypy_cache/3.9/_thread.meta.json +0 -1
- np_services/.mypy_cache/3.9/_typeshed/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/_typeshed/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/_warnings.data.json +0 -1
- np_services/.mypy_cache/3.9/_warnings.meta.json +0 -1
- np_services/.mypy_cache/3.9/_weakref.data.json +0 -1
- np_services/.mypy_cache/3.9/_weakref.meta.json +0 -1
- np_services/.mypy_cache/3.9/_weakrefset.data.json +0 -1
- np_services/.mypy_cache/3.9/_weakrefset.meta.json +0 -1
- np_services/.mypy_cache/3.9/_winapi.data.json +0 -1
- np_services/.mypy_cache/3.9/_winapi.meta.json +0 -1
- np_services/.mypy_cache/3.9/abc.data.json +0 -1
- np_services/.mypy_cache/3.9/abc.meta.json +0 -1
- np_services/.mypy_cache/3.9/array.data.json +0 -1
- np_services/.mypy_cache/3.9/array.meta.json +0 -1
- np_services/.mypy_cache/3.9/atexit.data.json +0 -1
- np_services/.mypy_cache/3.9/atexit.meta.json +0 -1
- np_services/.mypy_cache/3.9/builtins.data.json +0 -1
- np_services/.mypy_cache/3.9/builtins.meta.json +0 -1
- np_services/.mypy_cache/3.9/codecs.data.json +0 -1
- np_services/.mypy_cache/3.9/codecs.meta.json +0 -1
- np_services/.mypy_cache/3.9/collections/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/collections/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/collections/abc.data.json +0 -1
- np_services/.mypy_cache/3.9/collections/abc.meta.json +0 -1
- np_services/.mypy_cache/3.9/contextlib.data.json +0 -1
- np_services/.mypy_cache/3.9/contextlib.meta.json +0 -1
- np_services/.mypy_cache/3.9/ctypes/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/ctypes/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/datetime.data.json +0 -1
- np_services/.mypy_cache/3.9/datetime.meta.json +0 -1
- np_services/.mypy_cache/3.9/decimal.data.json +0 -1
- np_services/.mypy_cache/3.9/decimal.meta.json +0 -1
- np_services/.mypy_cache/3.9/email/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/email/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/email/charset.data.json +0 -1
- np_services/.mypy_cache/3.9/email/charset.meta.json +0 -1
- np_services/.mypy_cache/3.9/email/contentmanager.data.json +0 -1
- np_services/.mypy_cache/3.9/email/contentmanager.meta.json +0 -1
- np_services/.mypy_cache/3.9/email/errors.data.json +0 -1
- np_services/.mypy_cache/3.9/email/errors.meta.json +0 -1
- np_services/.mypy_cache/3.9/email/header.data.json +0 -1
- np_services/.mypy_cache/3.9/email/header.meta.json +0 -1
- np_services/.mypy_cache/3.9/email/message.data.json +0 -1
- np_services/.mypy_cache/3.9/email/message.meta.json +0 -1
- np_services/.mypy_cache/3.9/email/policy.data.json +0 -1
- np_services/.mypy_cache/3.9/email/policy.meta.json +0 -1
- np_services/.mypy_cache/3.9/enum.data.json +0 -1
- np_services/.mypy_cache/3.9/enum.meta.json +0 -1
- np_services/.mypy_cache/3.9/errno.data.json +0 -1
- np_services/.mypy_cache/3.9/errno.meta.json +0 -1
- np_services/.mypy_cache/3.9/fractions.data.json +0 -1
- np_services/.mypy_cache/3.9/fractions.meta.json +0 -1
- np_services/.mypy_cache/3.9/genericpath.data.json +0 -1
- np_services/.mypy_cache/3.9/genericpath.meta.json +0 -1
- np_services/.mypy_cache/3.9/importlib/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/importlib/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/importlib/abc.data.json +0 -1
- np_services/.mypy_cache/3.9/importlib/abc.meta.json +0 -1
- np_services/.mypy_cache/3.9/importlib/machinery.data.json +0 -1
- np_services/.mypy_cache/3.9/importlib/machinery.meta.json +0 -1
- np_services/.mypy_cache/3.9/importlib/metadata/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/importlib/metadata/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/io.data.json +0 -1
- np_services/.mypy_cache/3.9/io.meta.json +0 -1
- np_services/.mypy_cache/3.9/json/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/json/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/json/decoder.data.json +0 -1
- np_services/.mypy_cache/3.9/json/decoder.meta.json +0 -1
- np_services/.mypy_cache/3.9/json/encoder.data.json +0 -1
- np_services/.mypy_cache/3.9/json/encoder.meta.json +0 -1
- np_services/.mypy_cache/3.9/logging/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/logging/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/math.data.json +0 -1
- np_services/.mypy_cache/3.9/math.meta.json +0 -1
- np_services/.mypy_cache/3.9/mmap.data.json +0 -1
- np_services/.mypy_cache/3.9/mmap.meta.json +0 -1
- np_services/.mypy_cache/3.9/np_services/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/np_services/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/np_services/config.data.json +0 -1
- np_services/.mypy_cache/3.9/np_services/config.meta.json +0 -1
- np_services/.mypy_cache/3.9/np_services/protocols.data.json +0 -1
- np_services/.mypy_cache/3.9/np_services/protocols.meta.json +0 -1
- np_services/.mypy_cache/3.9/np_services/zro.data.json +0 -1
- np_services/.mypy_cache/3.9/np_services/zro.meta.json +0 -1
- np_services/.mypy_cache/3.9/ntpath.data.json +0 -1
- np_services/.mypy_cache/3.9/ntpath.meta.json +0 -1
- np_services/.mypy_cache/3.9/numbers.data.json +0 -1
- np_services/.mypy_cache/3.9/numbers.meta.json +0 -1
- np_services/.mypy_cache/3.9/os/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/os/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/os/path.data.json +0 -1
- np_services/.mypy_cache/3.9/os/path.meta.json +0 -1
- np_services/.mypy_cache/3.9/pathlib.data.json +0 -1
- np_services/.mypy_cache/3.9/pathlib.meta.json +0 -1
- np_services/.mypy_cache/3.9/pickle.data.json +0 -1
- np_services/.mypy_cache/3.9/pickle.meta.json +0 -1
- np_services/.mypy_cache/3.9/platform.data.json +0 -1
- np_services/.mypy_cache/3.9/platform.meta.json +0 -1
- np_services/.mypy_cache/3.9/posixpath.data.json +0 -1
- np_services/.mypy_cache/3.9/posixpath.meta.json +0 -1
- np_services/.mypy_cache/3.9/random.data.json +0 -1
- np_services/.mypy_cache/3.9/random.meta.json +0 -1
- np_services/.mypy_cache/3.9/re.data.json +0 -1
- np_services/.mypy_cache/3.9/re.meta.json +0 -1
- np_services/.mypy_cache/3.9/shutil.data.json +0 -1
- np_services/.mypy_cache/3.9/shutil.meta.json +0 -1
- np_services/.mypy_cache/3.9/socket.data.json +0 -1
- np_services/.mypy_cache/3.9/socket.meta.json +0 -1
- np_services/.mypy_cache/3.9/sre_compile.data.json +0 -1
- np_services/.mypy_cache/3.9/sre_compile.meta.json +0 -1
- np_services/.mypy_cache/3.9/sre_constants.data.json +0 -1
- np_services/.mypy_cache/3.9/sre_constants.meta.json +0 -1
- np_services/.mypy_cache/3.9/sre_parse.data.json +0 -1
- np_services/.mypy_cache/3.9/sre_parse.meta.json +0 -1
- np_services/.mypy_cache/3.9/string.data.json +0 -1
- np_services/.mypy_cache/3.9/string.meta.json +0 -1
- np_services/.mypy_cache/3.9/subprocess.data.json +0 -1
- np_services/.mypy_cache/3.9/subprocess.meta.json +0 -1
- np_services/.mypy_cache/3.9/sys.data.json +0 -1
- np_services/.mypy_cache/3.9/sys.meta.json +0 -1
- np_services/.mypy_cache/3.9/threading.data.json +0 -1
- np_services/.mypy_cache/3.9/threading.meta.json +0 -1
- np_services/.mypy_cache/3.9/time.data.json +0 -1
- np_services/.mypy_cache/3.9/time.meta.json +0 -1
- np_services/.mypy_cache/3.9/types.data.json +0 -1
- np_services/.mypy_cache/3.9/types.meta.json +0 -1
- np_services/.mypy_cache/3.9/typing.data.json +0 -1
- np_services/.mypy_cache/3.9/typing.meta.json +0 -1
- np_services/.mypy_cache/3.9/typing_extensions.data.json +0 -1
- np_services/.mypy_cache/3.9/typing_extensions.meta.json +0 -1
- np_services/.mypy_cache/3.9/warnings.data.json +0 -1
- np_services/.mypy_cache/3.9/warnings.meta.json +0 -1
- np_services/.mypy_cache/3.9/weakref.data.json +0 -1
- np_services/.mypy_cache/3.9/weakref.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/_typing.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/_typing.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/backend/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/backend/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/backend/select.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/backend/select.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/constants.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/constants.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/error.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/error.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/attrsettr.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/attrsettr.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/context.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/context.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/frame.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/frame.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/poll.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/poll.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/socket.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/socket.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/tracker.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/tracker.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/version.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/sugar/version.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/utils/__init__.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/utils/__init__.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/utils/interop.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/utils/interop.meta.json +0 -1
- np_services/.mypy_cache/3.9/zmq/utils/jsonapi.data.json +0 -1
- np_services/.mypy_cache/3.9/zmq/utils/jsonapi.meta.json +0 -1
- np_services/.mypy_cache/CACHEDIR.TAG +0 -3
- np_services/resources/black_desktop.ps1 +0 -66
- np_services/resources/grey_desktop.ps1 +0 -66
- np_services/resources/reset_desktop.ps1 +0 -66
- np_services-0.1.59.dist-info/RECORD +0 -206
np_services/utils.py
CHANGED
|
@@ -1,168 +1,168 @@
|
|
|
1
|
-
import contextlib
|
|
2
|
-
import datetime
|
|
3
|
-
import functools
|
|
4
|
-
import logging
|
|
5
|
-
import math
|
|
6
|
-
import os
|
|
7
|
-
import pathlib
|
|
8
|
-
import shutil
|
|
9
|
-
import subprocess
|
|
10
|
-
import sys
|
|
11
|
-
import time
|
|
12
|
-
from typing import Any, Generator, Literal, Mapping, Optional, Sequence, Type
|
|
13
|
-
|
|
14
|
-
import np_config
|
|
15
|
-
import np_logging
|
|
16
|
-
|
|
17
|
-
import np_services.protocols as protocols
|
|
18
|
-
import np_services.resources.zro as zro
|
|
19
|
-
|
|
20
|
-
logger = np_logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def config_from_zk(rig: Optional[Literal[0, 1, 2]] = None) -> Mapping[str, Any]:
|
|
24
|
-
"Common `services` config plus rig-specific `services`"
|
|
25
|
-
common_config = np_config.from_zk("/projects/np_workflows/defaults/configuration")[
|
|
26
|
-
"services"
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
if rig:
|
|
30
|
-
rig_config = np_config.Rig(rig).config["services"]
|
|
31
|
-
else:
|
|
32
|
-
rig_config = np_config.Rig().config["services"]
|
|
33
|
-
|
|
34
|
-
for k, v in rig_config.items():
|
|
35
|
-
common_config[k] = common_config.get(k, {}) | v
|
|
36
|
-
return common_config
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def start_rsc_app(host, app_id) -> None:
|
|
40
|
-
rsc_node = zro.Proxy(host, 6000)
|
|
41
|
-
if rsc_node.p_status().get(app_id) == 0:
|
|
42
|
-
logger.info("Launching %s on %s via RSC", app_id, host)
|
|
43
|
-
rsc_node.p_start(app_id)
|
|
44
|
-
time.sleep(1)
|
|
45
|
-
if rsc_node.p_status().get(app_id) == 0:
|
|
46
|
-
logger.warning("%s not confirmed as launched - may be slow to start", app_id)
|
|
47
|
-
return
|
|
48
|
-
logger.info("%s is running on %s", app_id, host)
|
|
49
|
-
|
|
50
|
-
def kill_rsc_app(host, app_id) -> None:
|
|
51
|
-
"Does the same as the `kill` action in the RSC gui"
|
|
52
|
-
rsc_node = zro.Proxy(host, 6000)
|
|
53
|
-
rsc_node.p_stop(app_id)
|
|
54
|
-
time.sleep(1)
|
|
55
|
-
if rsc_node.p_status().get(app_id) != 0:
|
|
56
|
-
logger.warning("%s not confirmed as killed - may be slow to shutdown", app_id)
|
|
57
|
-
return
|
|
58
|
-
logger.info("%s killed on %s", app_id, host)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def start_rsc_apps() -> None:
|
|
62
|
-
rsc_app_ids_required = np_config.Rig().config["rsc_app_ids_required"]
|
|
63
|
-
rig = np_config.Rig()
|
|
64
|
-
for host in (rig.Sync, rig.Stim, rig.Mon, rig.Acq):
|
|
65
|
-
rsc_node = zro.Proxy(host, 6000)
|
|
66
|
-
status = rsc_node.p_status()
|
|
67
|
-
if any(
|
|
68
|
-
apps_required_in_node := [_ for _ in rsc_app_ids_required if _ in status]
|
|
69
|
-
):
|
|
70
|
-
for app in apps_required_in_node:
|
|
71
|
-
rsc_node.p_start(app)
|
|
72
|
-
|
|
73
|
-
@contextlib.contextmanager
|
|
74
|
-
def stop_on_error(*objs: protocols.Stoppable, reraise=True):
|
|
75
|
-
for obj in objs:
|
|
76
|
-
if not isinstance(obj, protocols.Stoppable):
|
|
77
|
-
raise TypeError(f"{obj} does not support stop()")
|
|
78
|
-
try:
|
|
79
|
-
yield
|
|
80
|
-
except Exception as exc:
|
|
81
|
-
with contextlib.suppress(Exception):
|
|
82
|
-
for obj in objs:
|
|
83
|
-
obj.stop()
|
|
84
|
-
logger.info("%s interrupted by error and stopped", obj.__name__)
|
|
85
|
-
obj.exc = exc
|
|
86
|
-
if reraise:
|
|
87
|
-
raise exc
|
|
88
|
-
logger.error("Error suppressed: continuing despite raised exception", exc_info=exc)
|
|
89
|
-
|
|
90
|
-
def is_online(host: str) -> bool:
|
|
91
|
-
"Use OS's `ping` cmd to check if `host` is online."
|
|
92
|
-
command = ["ping", "-n" if "win" in sys.platform else "-c", "1", host]
|
|
93
|
-
try:
|
|
94
|
-
return subprocess.call(command, stdout=subprocess.PIPE, timeout=1.0) == 0
|
|
95
|
-
except subprocess.TimeoutExpired:
|
|
96
|
-
return False
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def unc_to_local(path: pathlib.Path) -> pathlib.Path:
|
|
100
|
-
"Convert UNC path to local path if on Windows."
|
|
101
|
-
if "win" not in sys.platform:
|
|
102
|
-
return path
|
|
103
|
-
comp = os.environ["COMPUTERNAME"]
|
|
104
|
-
if comp in path.drive:
|
|
105
|
-
drive = path.drive.split("\\")[-1]
|
|
106
|
-
drive = drive[:-1] if drive[-1] == "$" else drive
|
|
107
|
-
drive = drive + ":" if drive[-1] != ":" else drive
|
|
108
|
-
drive += "\\"
|
|
109
|
-
path = pathlib.Path(drive, path.relative_to(path.drive))
|
|
110
|
-
return path
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def free_gb(path: str | bytes | os.PathLike) -> float:
|
|
114
|
-
"Return free space at `path`, to .1 GB. Raises FileNotFoundError if `path` not accessible."
|
|
115
|
-
path = pathlib.Path(path)
|
|
116
|
-
path = unc_to_local(path)
|
|
117
|
-
return round(shutil.disk_usage(path).free / 1e9, 1)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def get_files_created_between(
|
|
121
|
-
path: str | bytes | os.PathLike,
|
|
122
|
-
glob: str = "*",
|
|
123
|
-
start: float | datetime.datetime = 0,
|
|
124
|
-
end: Optional[float | datetime.datetime] = None,
|
|
125
|
-
) -> list[pathlib.Path]:
|
|
126
|
-
path = pathlib.Path(path)
|
|
127
|
-
if not path.is_dir():
|
|
128
|
-
path = path.parent
|
|
129
|
-
if not end:
|
|
130
|
-
end = time.time()
|
|
131
|
-
start = start.timestamp() if isinstance(start, datetime.datetime) else start
|
|
132
|
-
end = end.timestamp() if isinstance(end, datetime.datetime) else end
|
|
133
|
-
ctime = lambda x: x.stat().st_ctime
|
|
134
|
-
files = (file for file in path.glob(glob) if int(start) <= ctime(file) <= end)
|
|
135
|
-
return sorted(files, key=ctime)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def is_file_growing(path: str | bytes | os.PathLike) -> bool:
|
|
139
|
-
"Compares size of most recent .sync data file at two time-points - will block for up to 20s depending on file-size."
|
|
140
|
-
path = pathlib.Path(path)
|
|
141
|
-
size_0 = path.stat().st_size
|
|
142
|
-
# for sync: file is appended periodically in chunks that scale non-linearly with size
|
|
143
|
-
if ".sync" == path.suffix:
|
|
144
|
-
time.sleep(2 * math.log10(size_0))
|
|
145
|
-
else:
|
|
146
|
-
time.sleep(0.5 * math.log10(size_0))
|
|
147
|
-
if path.stat().st_size == size_0:
|
|
148
|
-
return False
|
|
149
|
-
return True
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def normalize_time(t) -> str:
|
|
153
|
-
"""
|
|
154
|
-
>>> normalize_time(datetime.datetime(2023, 2, 14, 13, 30, 00))
|
|
155
|
-
'20230214133000'
|
|
156
|
-
>>> normalize_time(1676410200.0)
|
|
157
|
-
'20230214133000'
|
|
158
|
-
>>> normalize_time(1676410200)
|
|
159
|
-
'20230214133000'
|
|
160
|
-
>>> normalize_time('1676410200.0')
|
|
161
|
-
'20230214133000'
|
|
162
|
-
>>> normalize_time('1676410200')
|
|
163
|
-
'20230214133000'
|
|
164
|
-
>>> normalize_time('2023-02-14T13:30:00')
|
|
165
|
-
'20230214133000'
|
|
166
|
-
"""
|
|
167
|
-
# moved to np_config Feb 2023
|
|
1
|
+
import contextlib
|
|
2
|
+
import datetime
|
|
3
|
+
import functools
|
|
4
|
+
import logging
|
|
5
|
+
import math
|
|
6
|
+
import os
|
|
7
|
+
import pathlib
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
import time
|
|
12
|
+
from typing import Any, Generator, Literal, Mapping, Optional, Sequence, Type
|
|
13
|
+
|
|
14
|
+
import np_config
|
|
15
|
+
import np_logging
|
|
16
|
+
|
|
17
|
+
import np_services.protocols as protocols
|
|
18
|
+
import np_services.resources.zro as zro
|
|
19
|
+
|
|
20
|
+
logger = np_logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def config_from_zk(rig: Optional[Literal[0, 1, 2]] = None) -> Mapping[str, Any]:
|
|
24
|
+
"Common `services` config plus rig-specific `services`"
|
|
25
|
+
common_config = np_config.from_zk("/projects/np_workflows/defaults/configuration")[
|
|
26
|
+
"services"
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
if rig:
|
|
30
|
+
rig_config = np_config.Rig(rig).config["services"]
|
|
31
|
+
else:
|
|
32
|
+
rig_config = np_config.Rig().config["services"]
|
|
33
|
+
|
|
34
|
+
for k, v in rig_config.items():
|
|
35
|
+
common_config[k] = common_config.get(k, {}) | v
|
|
36
|
+
return common_config
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def start_rsc_app(host, app_id) -> None:
|
|
40
|
+
rsc_node = zro.Proxy(host, 6000)
|
|
41
|
+
if rsc_node.p_status().get(app_id) == 0:
|
|
42
|
+
logger.info("Launching %s on %s via RSC", app_id, host)
|
|
43
|
+
rsc_node.p_start(app_id)
|
|
44
|
+
time.sleep(1)
|
|
45
|
+
if rsc_node.p_status().get(app_id) == 0:
|
|
46
|
+
logger.warning("%s not confirmed as launched - may be slow to start", app_id)
|
|
47
|
+
return
|
|
48
|
+
logger.info("%s is running on %s", app_id, host)
|
|
49
|
+
|
|
50
|
+
def kill_rsc_app(host, app_id) -> None:
|
|
51
|
+
"Does the same as the `kill` action in the RSC gui"
|
|
52
|
+
rsc_node = zro.Proxy(host, 6000)
|
|
53
|
+
rsc_node.p_stop(app_id)
|
|
54
|
+
time.sleep(1)
|
|
55
|
+
if rsc_node.p_status().get(app_id) != 0:
|
|
56
|
+
logger.warning("%s not confirmed as killed - may be slow to shutdown", app_id)
|
|
57
|
+
return
|
|
58
|
+
logger.info("%s killed on %s", app_id, host)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def start_rsc_apps() -> None:
|
|
62
|
+
rsc_app_ids_required = np_config.Rig().config["rsc_app_ids_required"]
|
|
63
|
+
rig = np_config.Rig()
|
|
64
|
+
for host in (rig.Sync, rig.Stim, rig.Mon, rig.Acq):
|
|
65
|
+
rsc_node = zro.Proxy(host, 6000)
|
|
66
|
+
status = rsc_node.p_status()
|
|
67
|
+
if any(
|
|
68
|
+
apps_required_in_node := [_ for _ in rsc_app_ids_required if _ in status]
|
|
69
|
+
):
|
|
70
|
+
for app in apps_required_in_node:
|
|
71
|
+
rsc_node.p_start(app)
|
|
72
|
+
|
|
73
|
+
@contextlib.contextmanager
|
|
74
|
+
def stop_on_error(*objs: protocols.Stoppable, reraise=True):
|
|
75
|
+
for obj in objs:
|
|
76
|
+
if not isinstance(obj, protocols.Stoppable):
|
|
77
|
+
raise TypeError(f"{obj} does not support stop()")
|
|
78
|
+
try:
|
|
79
|
+
yield
|
|
80
|
+
except Exception as exc:
|
|
81
|
+
with contextlib.suppress(Exception):
|
|
82
|
+
for obj in objs:
|
|
83
|
+
obj.stop()
|
|
84
|
+
logger.info("%s interrupted by error and stopped", obj.__name__)
|
|
85
|
+
obj.exc = exc
|
|
86
|
+
if reraise:
|
|
87
|
+
raise exc
|
|
88
|
+
logger.error("Error suppressed: continuing despite raised exception", exc_info=exc)
|
|
89
|
+
|
|
90
|
+
def is_online(host: str) -> bool:
|
|
91
|
+
"Use OS's `ping` cmd to check if `host` is online."
|
|
92
|
+
command = ["ping", "-n" if "win" in sys.platform else "-c", "1", host]
|
|
93
|
+
try:
|
|
94
|
+
return subprocess.call(command, stdout=subprocess.PIPE, timeout=1.0) == 0
|
|
95
|
+
except subprocess.TimeoutExpired:
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def unc_to_local(path: pathlib.Path) -> pathlib.Path:
|
|
100
|
+
"Convert UNC path to local path if on Windows."
|
|
101
|
+
if "win" not in sys.platform:
|
|
102
|
+
return path
|
|
103
|
+
comp = os.environ["COMPUTERNAME"]
|
|
104
|
+
if comp in path.drive:
|
|
105
|
+
drive = path.drive.split("\\")[-1]
|
|
106
|
+
drive = drive[:-1] if drive[-1] == "$" else drive
|
|
107
|
+
drive = drive + ":" if drive[-1] != ":" else drive
|
|
108
|
+
drive += "\\"
|
|
109
|
+
path = pathlib.Path(drive, path.relative_to(path.drive))
|
|
110
|
+
return path
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def free_gb(path: str | bytes | os.PathLike) -> float:
|
|
114
|
+
"Return free space at `path`, to .1 GB. Raises FileNotFoundError if `path` not accessible."
|
|
115
|
+
path = pathlib.Path(path)
|
|
116
|
+
path = unc_to_local(path)
|
|
117
|
+
return round(shutil.disk_usage(path).free / 1e9, 1)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def get_files_created_between(
|
|
121
|
+
path: str | bytes | os.PathLike,
|
|
122
|
+
glob: str = "*",
|
|
123
|
+
start: float | datetime.datetime = 0,
|
|
124
|
+
end: Optional[float | datetime.datetime] = None,
|
|
125
|
+
) -> list[pathlib.Path]:
|
|
126
|
+
path = pathlib.Path(path)
|
|
127
|
+
if not path.is_dir():
|
|
128
|
+
path = path.parent
|
|
129
|
+
if not end:
|
|
130
|
+
end = time.time()
|
|
131
|
+
start = start.timestamp() if isinstance(start, datetime.datetime) else start
|
|
132
|
+
end = end.timestamp() if isinstance(end, datetime.datetime) else end
|
|
133
|
+
ctime = lambda x: x.stat().st_ctime
|
|
134
|
+
files = (file for file in path.glob(glob) if int(start) <= ctime(file) <= end)
|
|
135
|
+
return sorted(files, key=ctime)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def is_file_growing(path: str | bytes | os.PathLike) -> bool:
|
|
139
|
+
"Compares size of most recent .sync data file at two time-points - will block for up to 20s depending on file-size."
|
|
140
|
+
path = pathlib.Path(path)
|
|
141
|
+
size_0 = path.stat().st_size
|
|
142
|
+
# for sync: file is appended periodically in chunks that scale non-linearly with size
|
|
143
|
+
if ".sync" == path.suffix:
|
|
144
|
+
time.sleep(2 * math.log10(size_0))
|
|
145
|
+
else:
|
|
146
|
+
time.sleep(0.5 * math.log10(size_0))
|
|
147
|
+
if path.stat().st_size == size_0:
|
|
148
|
+
return False
|
|
149
|
+
return True
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def normalize_time(t) -> str:
|
|
153
|
+
"""
|
|
154
|
+
>>> normalize_time(datetime.datetime(2023, 2, 14, 13, 30, 00))
|
|
155
|
+
'20230214133000'
|
|
156
|
+
>>> normalize_time(1676410200.0)
|
|
157
|
+
'20230214133000'
|
|
158
|
+
>>> normalize_time(1676410200)
|
|
159
|
+
'20230214133000'
|
|
160
|
+
>>> normalize_time('1676410200.0')
|
|
161
|
+
'20230214133000'
|
|
162
|
+
>>> normalize_time('1676410200')
|
|
163
|
+
'20230214133000'
|
|
164
|
+
>>> normalize_time('2023-02-14T13:30:00')
|
|
165
|
+
'20230214133000'
|
|
166
|
+
"""
|
|
167
|
+
# moved to np_config Feb 2023
|
|
168
168
|
return np_config.normalize_time(t)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: np-services
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.73
|
|
4
4
|
Summary: Tools for interfacing with devices and services used in Mindscope Neuropixels experiments at the Allen Institute.
|
|
5
|
-
Author-
|
|
5
|
+
Author-email: bjhardcastle <ben.hardcastle@alleninstitute.org>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
7
7
|
Classifier: License :: OSI Approved :: MIT License
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
|
9
9
|
Requires-Python: <4.0,>=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
10
11
|
Requires-Dist: requests<3,>=2
|
|
11
12
|
Requires-Dist: np-session>=0.6.40
|
|
12
13
|
Requires-Dist: pyzmq
|
|
@@ -15,11 +16,9 @@ Requires-Dist: pandas>=2.0
|
|
|
15
16
|
Requires-Dist: h5py<4.0.0,>=3.8.0
|
|
16
17
|
Requires-Dist: np-config>=0.4.17
|
|
17
18
|
Requires-Dist: tables<4.0.0,>=3.8.0
|
|
18
|
-
Requires-Dist: npc-sync>=0.1.
|
|
19
|
-
Requires-Dist: npc-
|
|
20
|
-
Requires-Dist: npc-stim>=0.1.4
|
|
19
|
+
Requires-Dist: npc-sync>=0.1.13
|
|
20
|
+
Requires-Dist: npc-stim>=0.1.5
|
|
21
21
|
Requires-Dist: npc-mvr>=0.1.2
|
|
22
|
-
Description-Content-Type: text/markdown
|
|
23
22
|
|
|
24
23
|
# service usage
|
|
25
|
-

|
|
24
|
+

|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
np_services/__init__.py,sha256=LV0k1Xgx9KP4r0EpSbTEhofHT53UO7E-GFG7Wgl7st0,291
|
|
2
|
+
np_services/open_ephys.py,sha256=EOZIa3T-AzyWagYLbO2nxlakbrpookRBwSc_K_bCstI,10627
|
|
3
|
+
np_services/protocols.py,sha256=bky_SreNzsDITb8RG6NiwMV1oqa7wJiuyDUvKn-Z4hg,5366
|
|
4
|
+
np_services/proxies.py,sha256=4hx1blCb5cN8kidOT9byEUpivOysvM36F_rCCuoKSRw,54422
|
|
5
|
+
np_services/stim_computer_theme_changer.py,sha256=y_v-m0h35m5n1kGWF_p_pRi6hKz_tHsrOKhzpWt8msw,1993
|
|
6
|
+
np_services/utils.py,sha256=w7uZX6IHcLO65aKPCHqRn_2Wr1qMjgKeaqhvaHxMFjE,5603
|
|
7
|
+
np_services/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
np_services/resources/mvr_connector.py,sha256=2kRSKiWdF1CgALvsK3EAy8Xia659yJ8taCLzbaTpe14,7970
|
|
9
|
+
np_services/resources/zro.py,sha256=-1a6knlpLnNb-muJsebeW4hZmDnUXj6ThdbHm8641JA,9921
|
|
10
|
+
np_services/scripts/pretest.py,sha256=MjyyC9dPnbdhoVu6FLnRbam5peYWA2dorXpDOCHQPp0,15612
|
|
11
|
+
np_services-0.1.73.dist-info/METADATA,sha256=AsAjzXTYU5TWgXV3A-rY80pbxL4FQAVFwzYy-X4x9PQ,849
|
|
12
|
+
np_services-0.1.73.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
13
|
+
np_services-0.1.73.dist-info/entry_points.txt,sha256=I4h7Ci2KAFSwWRSd6-ZBTpyTbEQMCBe86zwhnROd6Oc,84
|
|
14
|
+
np_services-0.1.73.dist-info/top_level.txt,sha256=JT1ozakOjqY1JyPkaLl69-9du_eSxA2KsfUKjuzQ9zc,12
|
|
15
|
+
np_services-0.1.73.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
np_services
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{".class": "MypyFile", "_fullname": "__future__", "future_import_flags": [], "is_partial_stub_package": false, "is_stub": true, "names": {".class": "SymbolTable", "TypeAlias": {".class": "SymbolTableNode", "cross_ref": "typing_extensions.TypeAlias", "kind": "Gdef", "module_hidden": true, "module_public": false}, "_Feature": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "TypeInfo", "_promote": [], "abstract_attributes": [], "bases": ["builtins.object"], "declared_metaclass": null, "defn": {".class": "ClassDef", "fullname": "__future__._Feature", "name": "_Feature", "type_vars": []}, "deletable_attributes": [], "flags": [], "fullname": "__future__._Feature", "has_param_spec_type": false, "metaclass_type": null, "metadata": {}, "module_name": "__future__", "mro": ["__future__._Feature", "builtins.object"], "names": {".class": "SymbolTable", "__init__": {".class": "SymbolTableNode", "kind": "Mdef", "node": {".class": "FuncDef", "abstract_status": 0, "arg_kinds": [0, 0, 0, 0], "arg_names": ["self", "optionalRelease", "mandatoryRelease", "compiler_flag"], "flags": [], "fullname": "__future__._Feature.__init__", "name": "__init__", "type": {".class": "CallableType", "arg_kinds": [0, 0, 0, 0], "arg_names": ["self", "optionalRelease", "mandatoryRelease", "compiler_flag"], "arg_types": ["__future__._Feature", {".class": "TypeAliasType", "args": [], "type_ref": "__future__._VersionInfo"}, {".class": "UnionType", "items": [{".class": "TypeAliasType", "args": [], "type_ref": "__future__._VersionInfo"}, {".class": "NoneType"}]}, "builtins.int"], "bound_args": [], "def_extras": {"first_arg": "self"}, "fallback": "builtins.function", "from_concatenate": false, "implicit": false, "is_ellipsis_args": false, "name": "__init__ of _Feature", "ret_type": {".class": "NoneType"}, "type_guard": null, "unpack_kwargs": false, "variables": []}}}, "compiler_flag": {".class": "SymbolTableNode", "kind": "Mdef", "node": {".class": "Var", "flags": ["is_initialized_in_class", "is_ready"], "fullname": "__future__._Feature.compiler_flag", "name": "compiler_flag", "type": "builtins.int"}}, "getMandatoryRelease": {".class": "SymbolTableNode", "kind": "Mdef", "node": {".class": "FuncDef", "abstract_status": 0, "arg_kinds": [0], "arg_names": ["self"], "flags": [], "fullname": "__future__._Feature.getMandatoryRelease", "name": "getMandatoryRelease", "type": {".class": "CallableType", "arg_kinds": [0], "arg_names": ["self"], "arg_types": ["__future__._Feature"], "bound_args": [], "def_extras": {"first_arg": "self"}, "fallback": "builtins.function", "from_concatenate": false, "implicit": false, "is_ellipsis_args": false, "name": "getMandatoryRelease of _Feature", "ret_type": {".class": "UnionType", "items": [{".class": "TypeAliasType", "args": [], "type_ref": "__future__._VersionInfo"}, {".class": "NoneType"}]}, "type_guard": null, "unpack_kwargs": false, "variables": []}}}, "getOptionalRelease": {".class": "SymbolTableNode", "kind": "Mdef", "node": {".class": "FuncDef", "abstract_status": 0, "arg_kinds": [0], "arg_names": ["self"], "flags": [], "fullname": "__future__._Feature.getOptionalRelease", "name": "getOptionalRelease", "type": {".class": "CallableType", "arg_kinds": [0], "arg_names": ["self"], "arg_types": ["__future__._Feature"], "bound_args": [], "def_extras": {"first_arg": "self"}, "fallback": "builtins.function", "from_concatenate": false, "implicit": false, "is_ellipsis_args": false, "name": "getOptionalRelease of _Feature", "ret_type": {".class": "TypeAliasType", "args": [], "type_ref": "__future__._VersionInfo"}, "type_guard": null, "unpack_kwargs": false, "variables": []}}}}, "slots": null, "tuple_type": null, "type_vars": [], "typeddict_type": null}}, "_VersionInfo": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "TypeAlias", "alias_tvars": [], "column": 0, "fullname": "__future__._VersionInfo", "line": 3, "no_args": false, "normalized": false, "target": {".class": "TupleType", "implicit": false, "items": ["builtins.int", "builtins.int", "builtins.int", "builtins.str", "builtins.int"], "partial_fallback": {".class": "Instance", "args": [{".class": "AnyType", "missing_import_name": null, "source_any": null, "type_of_any": 6}], "type_ref": "builtins.tuple"}}}}, "__all__": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "Var", "flags": ["is_inferred", "has_explicit_value"], "fullname": "__future__.__all__", "name": "__all__", "type": {".class": "Instance", "args": ["builtins.str"], "type_ref": "builtins.list"}}}, "__annotations__": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.__annotations__", "name": "__annotations__", "type": {".class": "Instance", "args": ["builtins.str", {".class": "AnyType", "missing_import_name": null, "source_any": null, "type_of_any": 6}], "type_ref": "builtins.dict"}}}, "__doc__": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.__doc__", "name": "__doc__", "type": "builtins.str"}}, "__file__": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.__file__", "name": "__file__", "type": "builtins.str"}}, "__name__": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.__name__", "name": "__name__", "type": "builtins.str"}}, "__package__": {".class": "SymbolTableNode", "kind": "Gdef", "module_public": false, "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.__package__", "name": "__package__", "type": "builtins.str"}}, "absolute_import": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.absolute_import", "name": "absolute_import", "type": "__future__._Feature"}}, "all_feature_names": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.all_feature_names", "name": "all_feature_names", "type": {".class": "Instance", "args": ["builtins.str"], "type_ref": "builtins.list"}}}, "annotations": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.annotations", "name": "annotations", "type": "__future__._Feature"}}, "barry_as_FLUFL": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.barry_as_FLUFL", "name": "barry_as_FLUFL", "type": "__future__._Feature"}}, "division": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.division", "name": "division", "type": "__future__._Feature"}}, "generator_stop": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.generator_stop", "name": "generator_stop", "type": "__future__._Feature"}}, "generators": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.generators", "name": "generators", "type": "__future__._Feature"}}, "nested_scopes": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.nested_scopes", "name": "nested_scopes", "type": "__future__._Feature"}}, "print_function": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.print_function", "name": "print_function", "type": "__future__._Feature"}}, "unicode_literals": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.unicode_literals", "name": "unicode_literals", "type": "__future__._Feature"}}, "with_statement": {".class": "SymbolTableNode", "kind": "Gdef", "node": {".class": "Var", "flags": ["is_ready"], "fullname": "__future__.with_statement", "name": "with_statement", "type": "__future__._Feature"}}}, "path": "C:\\Users\\ben.hardcastle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\np-workflows-S6vpCEsL-py3.9\\lib\\site-packages\\mypy\\typeshed\\stdlib\\__future__.pyi"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"data_mtime": 1675300530, "dep_lines": [1, 1, 1, 1], "dep_prios": [5, 5, 30, 30], "dependencies": ["typing_extensions", "builtins", "abc", "typing"], "hash": "b3e63c2093f92f412cc06fd0491ff110db6df5d102d08b4bfdab25680d5498c1", "id": "__future__", "ignore_all": true, "interface_hash": "ada412cc312c48519ba6e5e78d2a06593177b9f49c1d84f8560913c257d35f7b", "mtime": 1674086803, "options": {"allow_redefinition": false, "allow_untyped_globals": false, "always_false": [], "always_true": [], "bazel": false, "check_untyped_defs": false, "disable_bytearray_promotion": false, "disable_error_code": [], "disable_memoryview_promotion": false, "disabled_error_codes": [], "disallow_any_decorated": false, "disallow_any_explicit": false, "disallow_any_expr": false, "disallow_any_generics": false, "disallow_any_unimported": false, "disallow_incomplete_defs": false, "disallow_subclassing_any": false, "disallow_untyped_calls": false, "disallow_untyped_decorators": false, "disallow_untyped_defs": false, "enable_error_code": [], "enabled_error_codes": [], "follow_imports": "silent", "follow_imports_for_stubs": false, "ignore_errors": false, "ignore_missing_imports": true, "implicit_optional": false, "implicit_reexport": true, "local_partial_types": false, "mypyc": false, "platform": "win32", "plugins": [], "strict_concatenate": false, "strict_equality": false, "strict_optional": true, "warn_no_return": true, "warn_return_any": false, "warn_unreachable": false, "warn_unused_ignores": false}, "path": "C:\\Users\\ben.hardcastle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\np-workflows-S6vpCEsL-py3.9\\lib\\site-packages\\mypy\\typeshed\\stdlib\\__future__.pyi", "plugin_data": null, "size": 951, "suppressed": [], "version_id": "0.991"}
|