runtimepy 5.7.9__py3-none-any.whl → 5.8.0__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.
runtimepy/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
3
  # version=3.1.4
4
- # hash=5d30f53776c61076df3ffeca2fdb30a1
4
+ # hash=3f66411c94ea81080e4fff8589bd828b
5
5
  # =====================================
6
6
 
7
7
  """
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
10
10
 
11
11
  DESCRIPTION = "A framework for implementing Python services."
12
12
  PKG_NAME = "runtimepy"
13
- VERSION = "5.7.9"
13
+ VERSION = "5.8.0"
14
14
 
15
15
  # runtimepy-specific content.
16
16
  METRICS_NAME = "metrics"
@@ -88,6 +88,10 @@ textarea.text-logs {
88
88
  flex-shrink: 0;
89
89
  }
90
90
 
91
+ pre {
92
+ color: var(--bs-code-color);
93
+ }
94
+
91
95
  .vertical-divider:hover {
92
96
  cursor: col-resize;
93
97
  background-color: var(--bs-highlight-bg) !important;
@@ -2,7 +2,24 @@
2
2
  # Add some sample tasks.
3
3
  tasks:
4
4
  # Chaos.
5
- - {name: sample1, factory: Sample, period_s: 0.9}
5
+ - name: sample1
6
+ factory: Sample
7
+ period_s: 0.9
8
+ config:
9
+ a: 1
10
+ b: 2
11
+ c: 3
12
+ markdown: |
13
+ # This is a Test
14
+
15
+ ```
16
+ todo
17
+
18
+ does this work?
19
+
20
+ todo
21
+ ```
22
+
6
23
  - {name: sample2, factory: Sample, period_s: 1.0}
7
24
  - {name: sample3, factory: Sample, period_s: 1.1}
8
25
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  includes:
3
+ - has_config.yaml
3
4
  - has_factory.yaml
4
5
  - has_name.yaml
5
6
  - has_markdown.yaml
@@ -203,6 +203,7 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
203
203
  period_s=task["period_s"],
204
204
  average_depth=task["average_depth"],
205
205
  markdown=task.get("markdown"),
206
+ config=task.get("config"),
206
207
  ), f"Couldn't register task '{name}' ({factory})!"
207
208
 
208
209
  # Register structs.
@@ -21,6 +21,8 @@ TASK_NAME = "housekeeping"
21
21
  class ConnectionMetricsPoller(_ArbiterTask):
22
22
  """A class that periodically polls connection metrics."""
23
23
 
24
+ processors: list[Awaitable[None]]
25
+
24
26
  def __init__(
25
27
  self,
26
28
  name: str,
@@ -31,6 +33,7 @@ class ConnectionMetricsPoller(_ArbiterTask):
31
33
 
32
34
  super().__init__(name, **kwargs)
33
35
  self.manager = manager
36
+ self.processors = []
34
37
 
35
38
  def _init_state(self) -> None:
36
39
  """Add channels to this instance's channel environment."""
@@ -51,7 +54,6 @@ class ConnectionMetricsPoller(_ArbiterTask):
51
54
  self.manager.poll_metrics()
52
55
 
53
56
  # Handle any incoming commands.
54
- processors: list[Awaitable[None]] = []
55
57
  for mapping in (
56
58
  self.app.connections.values(),
57
59
  self.app.tasks.values(),
@@ -59,14 +61,15 @@ class ConnectionMetricsPoller(_ArbiterTask):
59
61
  ):
60
62
  for item in mapping:
61
63
  if isinstance(item, AsyncCommandProcessingMixin):
62
- processors.append(item.process_command_queue())
64
+ self.processors.append(item.process_command_queue())
63
65
 
64
66
  # Service connection tasks. The connection manager should probably do
65
67
  # this on its own at some point.
66
- processors += list(self.app.conn_manager.connection_tasks)
68
+ self.processors += list(self.app.conn_manager.connection_tasks)
67
69
 
68
- if processors:
69
- await asyncio.gather(*processors)
70
+ if self.processors:
71
+ await asyncio.gather(*self.processors)
72
+ self.processors.clear()
70
73
 
71
74
  return True
72
75
 
@@ -13,7 +13,7 @@ from typing import Union as _Union
13
13
 
14
14
  # third-party
15
15
  from vcorelib.asyncio import log_exceptions as _log_exceptions
16
- from vcorelib.io import MarkdownMixin
16
+ from vcorelib.io.markdown import MarkdownMixin
17
17
  from vcorelib.logging import LoggerType as _LoggerType
18
18
 
19
19
  # internal
@@ -193,6 +193,7 @@ def centered_markdown(
193
193
  text=stream.getvalue(),
194
194
  parent=horiz_container,
195
195
  class_str="text-body p-3 pb-0",
196
+ preformatted=True,
196
197
  )
197
198
 
198
199
  div(parent=horiz_container)
@@ -11,7 +11,6 @@ from pathlib import Path
11
11
  from typing import Any, Optional, TextIO, Union
12
12
 
13
13
  # third-party
14
- import aiofiles
15
14
  from vcorelib import DEFAULT_ENCODING
16
15
  from vcorelib.io import IndentedFileWriter, JsonObject
17
16
  from vcorelib.paths import Pathlike, find_file, normalize
@@ -26,7 +25,7 @@ from runtimepy.net.http.response import ResponseHeader
26
25
  from runtimepy.net.server.html import HtmlApp, HtmlApps, get_html, html_handler
27
26
  from runtimepy.net.server.json import encode_json, json_handler
28
27
  from runtimepy.net.tcp.http import HttpConnection
29
- from runtimepy.util import normalize_root, path_has_part
28
+ from runtimepy.util import normalize_root, path_has_part, read_binary
30
29
 
31
30
  MIMETYPES_INIT = False
32
31
 
@@ -158,10 +157,9 @@ class RuntimepyServerConnection(HttpConnection):
158
157
  ) -> bytes:
159
158
  """Render a markdown file as HTML and return the result."""
160
159
 
161
- async with aiofiles.open(path, mode="r") as path_fd:
162
- return self.render_markdown(
163
- await path_fd.read(), response, **kwargs
164
- )
160
+ return self.render_markdown(
161
+ (await read_binary(path)).decode(), response, **kwargs
162
+ )
165
163
 
166
164
  async def try_file(
167
165
  self, path: PathMaybeQuery, response: ResponseHeader
@@ -195,8 +193,7 @@ class RuntimepyServerConnection(HttpConnection):
195
193
  self.logger.info("Serving '%s' (MIME: %s)", candidate, mime)
196
194
 
197
195
  # Return the file data.
198
- async with aiofiles.open(candidate, mode="rb") as path_fd:
199
- result = await path_fd.read()
196
+ result = await read_binary(candidate)
200
197
 
201
198
  break
202
199
 
@@ -3,7 +3,7 @@ A module implementing a channel-environment tab HTML interface.
3
3
  """
4
4
 
5
5
  # third-party
6
- from vcorelib.io import MarkdownMixin
6
+ from vcorelib.io.markdown import MarkdownMixin
7
7
  from vcorelib.logging import LoggerMixin
8
8
  from vcorelib.math import RateLimiter
9
9
 
@@ -69,9 +69,7 @@ class ChannelEnvironmentTabMessaging(ChannelEnvironmentTabBase):
69
69
  for name in env.names:
70
70
  self._setup_callback(name, state)
71
71
  else:
72
- # Remove callbacks for primitives.
73
- for name, val in state.callbacks.items():
74
- state.primitives[name].remove_callback(val)
72
+ state.clear_telemetry()
75
73
 
76
74
  # Save current UI state.
77
75
  state.latest_ui_values.update(latest)
@@ -53,19 +53,36 @@ class TabState:
53
53
 
54
54
  return result
55
55
 
56
+ def clear_telemetry(self) -> None:
57
+ """Clear all telemetry interactions."""
58
+
59
+ # Remove callbacks for primitives.
60
+ for name, val in self.callbacks.items():
61
+ self.primitives[name].remove_callback(val)
62
+ self.callbacks.clear()
63
+ self.primitives.clear()
64
+
65
+ # Clear points.
66
+ self.points.clear()
67
+
56
68
  def clear_loggers(self) -> None:
57
69
  """Clear all logging handlers."""
58
70
 
71
+ # Remove handlers.
59
72
  for logger in self._loggers:
60
73
  logger.removeHandler(self.tab_logger)
74
+ self._loggers.clear()
75
+
61
76
  self.tab_logger.drain_str()
62
- self._loggers = []
77
+
78
+ self.clear_telemetry()
63
79
 
64
80
  def add_logger(self, logger: logging.Logger) -> None:
65
81
  """Add a logger."""
66
82
 
67
- logger.addHandler(self.tab_logger)
68
- self._loggers.append(logger)
83
+ if logger not in self._loggers:
84
+ logger.addHandler(self.tab_logger)
85
+ self._loggers.append(logger)
69
86
 
70
87
  @staticmethod
71
88
  def create() -> "TabState":
@@ -21,15 +21,11 @@ from typing import Union as _Union
21
21
  # third-party
22
22
  from vcorelib.asyncio import log_exceptions as _log_exceptions
23
23
  import websockets
24
- from websockets.client import (
25
- WebSocketClientProtocol as _WebSocketClientProtocol,
26
- )
24
+ from websockets.asyncio.client import ClientConnection as _ClientConnection
25
+ from websockets.asyncio.server import Server as _Server
26
+ from websockets.asyncio.server import ServerConnection as _ServerConnection
27
+ from websockets.asyncio.server import serve as _serve
27
28
  from websockets.exceptions import ConnectionClosed as _ConnectionClosed
28
- from websockets.server import (
29
- WebSocketServerProtocol as _WebSocketServerProtocol,
30
- )
31
- from websockets.server import WebSocketServer as _WebSocketServer
32
- from websockets.server import serve as _serve
33
29
 
34
30
  # internal
35
31
  from runtimepy.net import sockname as _sockname
@@ -50,7 +46,7 @@ class WebsocketConnection(Connection):
50
46
 
51
47
  def __init__(
52
48
  self,
53
- protocol: _Union[_WebSocketClientProtocol, _WebSocketServerProtocol],
49
+ protocol: _Union[_ClientConnection, _ServerConnection],
54
50
  **kwargs,
55
51
  ) -> None:
56
52
  """Initialize this connection."""
@@ -125,13 +121,13 @@ class WebsocketConnection(Connection):
125
121
  init: ConnectionInit[T] = None,
126
122
  stop_sig: _asyncio.Event = None,
127
123
  manager: _ConnectionManager = None,
128
- ) -> _Callable[[_WebSocketServerProtocol], _Awaitable[None]]:
124
+ ) -> _Callable[[_ServerConnection], _Awaitable[None]]:
129
125
  """
130
126
  A wrapper for passing in a websocket handler and initializing a
131
127
  connection.
132
128
  """
133
129
 
134
- async def _handler(protocol: _WebSocketServerProtocol) -> None:
130
+ async def _handler(protocol: _ServerConnection) -> None:
135
131
  """A handler that runs the callers initialization function."""
136
132
 
137
133
  conn = cls(protocol)
@@ -176,12 +172,11 @@ class WebsocketConnection(Connection):
176
172
 
177
173
  server_conn: _Optional[T] = None
178
174
 
179
- async def server_init(protocol: _WebSocketServerProtocol) -> bool:
175
+ async def server_init(protocol: _ServerConnection) -> None:
180
176
  """Create one side of the connection and update the reference."""
181
177
  nonlocal server_conn
182
178
  assert server_conn is None
183
179
  server_conn = cls(protocol)
184
- return True
185
180
 
186
181
  async with _AsyncExitStack() as stack:
187
182
  if serve_kwargs is None:
@@ -213,7 +208,7 @@ class WebsocketConnection(Connection):
213
208
  stop_sig: _asyncio.Event = None,
214
209
  manager: _ConnectionManager = None,
215
210
  **kwargs,
216
- ) -> _AsyncIterator[_WebSocketServer]:
211
+ ) -> _AsyncIterator[_Server]:
217
212
  """Serve a WebSocket server."""
218
213
 
219
214
  kwargs = handle_possible_ssl(client=False, **kwargs)
@@ -237,7 +232,7 @@ class WebsocketConnection(Connection):
237
232
  stop_sig: _asyncio.Event,
238
233
  init: ConnectionInit[T] = None,
239
234
  manager: _ConnectionManager = None,
240
- serving_callback: _Callable[[_WebSocketServer], None] = None,
235
+ serving_callback: _Callable[[_Server], None] = None,
241
236
  **kwargs,
242
237
  ) -> None:
243
238
  """Run a WebSocket-server application."""
@@ -1,6 +1,6 @@
1
1
  aiofiles
2
- vcorelib>=3.4.5
3
- svgen>=0.6.8
2
+ vcorelib>=3.4.7
3
+ svgen>=0.7.4
4
4
  websockets
5
5
  psutil
6
6
  windows-curses; sys_platform == 'win32' and python_version < '3.12'
@@ -9,7 +9,7 @@ from logging import getLogger as _getLogger
9
9
  from typing import Optional
10
10
 
11
11
  # third-party
12
- from vcorelib.io import MarkdownMixin
12
+ from vcorelib.io.markdown import MarkdownMixin
13
13
  from vcorelib.io.types import JsonObject as _JsonObject
14
14
 
15
15
  # internal
@@ -12,7 +12,7 @@ from logging import INFO, getLogger
12
12
  from typing import Optional
13
13
 
14
14
  # third-party
15
- from vcorelib.io import MarkdownMixin
15
+ from vcorelib.io.markdown import MarkdownMixin
16
16
  from vcorelib.io.types import JsonObject
17
17
  from vcorelib.math import RateLimiter
18
18
 
@@ -13,7 +13,8 @@ from logging import getLogger as _getLogger
13
13
  from typing import Optional as _Optional
14
14
 
15
15
  # third-party
16
- from vcorelib.io import MarkdownMixin
16
+ from vcorelib.io.markdown import MarkdownMixin
17
+ from vcorelib.io.types import JsonObject as _JsonObject
17
18
  from vcorelib.math import DEFAULT_DEPTH as _DEFAULT_DEPTH
18
19
  from vcorelib.math import MovingAverage as _MovingAverage
19
20
  from vcorelib.math import RateTracker as _RateTracker
@@ -50,11 +51,14 @@ class PeriodicTask(
50
51
  env: ChannelEnvironment = None,
51
52
  period_controls: Controlslike = "period",
52
53
  markdown: str = None,
54
+ config: _JsonObject = None,
53
55
  ) -> None:
54
56
  """Initialize this task."""
55
57
 
56
58
  self.name = name
57
- self.set_markdown(markdown=markdown, package=PKG_NAME)
59
+
60
+ self.set_markdown(markdown=markdown, config=config, package=PKG_NAME)
61
+
58
62
  LoggerMixinLevelControl.__init__(self, logger=_getLogger(self.name))
59
63
  self._task: _Optional[_asyncio.Task[None]] = None
60
64
 
runtimepy/util.py CHANGED
@@ -8,11 +8,20 @@ from pathlib import Path
8
8
  from typing import Iterator, Union
9
9
 
10
10
  # third-party
11
+ import aiofiles
11
12
  from vcorelib.paths import normalize
12
13
 
13
14
  ROOT_PATH = Path(sep)
14
15
 
15
16
 
17
+ async def read_binary(path: Path) -> bytes:
18
+ """An async wrapper for reading file contents."""
19
+
20
+ async with aiofiles.open(path, mode="rb") as path_fd:
21
+ result = await path_fd.read()
22
+ return result # type: ignore
23
+
24
+
16
25
  def normalize_root(*src_parts: Union[str, Path]) -> Path:
17
26
  """Make paths absolute that aren't. Useful for HTTP-request pathing."""
18
27
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runtimepy
3
- Version: 5.7.9
3
+ Version: 5.8.0
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/vkottler/runtimepy
6
6
  Author: Vaughn Kottler
@@ -17,39 +17,39 @@ Classifier: License :: OSI Approved :: MIT License
17
17
  Requires-Python: >=3.12
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
+ Requires-Dist: vcorelib>=3.4.7
21
+ Requires-Dist: svgen>=0.7.4
20
22
  Requires-Dist: aiofiles
21
- Requires-Dist: svgen >=0.6.8
22
23
  Requires-Dist: websockets
23
- Requires-Dist: vcorelib >=3.4.5
24
24
  Requires-Dist: psutil
25
25
  Provides-Extra: test
26
- Requires-Dist: pylint ; extra == 'test'
27
- Requires-Dist: flake8 ; extra == 'test'
28
- Requires-Dist: black ; extra == 'test'
29
- Requires-Dist: ruff ; extra == 'test'
30
- Requires-Dist: mypy ; extra == 'test'
31
- Requires-Dist: isort ; extra == 'test'
32
- Requires-Dist: yamllint ; extra == 'test'
33
- Requires-Dist: yambs ; extra == 'test'
34
- Requires-Dist: vmklib >=2.0.3 ; extra == 'test'
35
- Requires-Dist: sphinx ; extra == 'test'
36
- Requires-Dist: sphinx-book-theme ; extra == 'test'
37
- Requires-Dist: pytest-asyncio ; extra == 'test'
38
- Requires-Dist: pytest-timeout ; extra == 'test'
39
- Requires-Dist: types-psutil ; extra == 'test'
40
- Requires-Dist: setuptools-wrapper ; extra == 'test'
41
- Requires-Dist: types-setuptools ; extra == 'test'
42
- Requires-Dist: uvloop ; (sys_platform != "win32" and sys_platform != "cygwin") and extra == 'test'
26
+ Requires-Dist: pylint; extra == "test"
27
+ Requires-Dist: flake8; extra == "test"
28
+ Requires-Dist: black; extra == "test"
29
+ Requires-Dist: ruff; extra == "test"
30
+ Requires-Dist: mypy; extra == "test"
31
+ Requires-Dist: isort; extra == "test"
32
+ Requires-Dist: yamllint; extra == "test"
33
+ Requires-Dist: yambs; extra == "test"
34
+ Requires-Dist: vmklib>=2.0.3; extra == "test"
35
+ Requires-Dist: sphinx; extra == "test"
36
+ Requires-Dist: sphinx-book-theme; extra == "test"
37
+ Requires-Dist: pytest-asyncio; extra == "test"
38
+ Requires-Dist: pytest-timeout; extra == "test"
39
+ Requires-Dist: types-psutil; extra == "test"
40
+ Requires-Dist: setuptools-wrapper; extra == "test"
41
+ Requires-Dist: types-setuptools; extra == "test"
42
+ Requires-Dist: uvloop; (sys_platform != "win32" and sys_platform != "cygwin") and extra == "test"
43
43
 
44
44
  <!--
45
45
  =====================================
46
46
  generator=datazen
47
47
  version=3.1.4
48
- hash=9fbafffa1da655b349a05dfa48addf0b
48
+ hash=0cb0fecd5f4e84d1b639d4c155ab541c
49
49
  =====================================
50
50
  -->
51
51
 
52
- # runtimepy ([5.7.9](https://pypi.org/project/runtimepy/))
52
+ # runtimepy ([5.8.0](https://pypi.org/project/runtimepy/))
53
53
 
54
54
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
55
55
  ![Build Status](https://github.com/vkottler/runtimepy/workflows/Python%20Package/badge.svg)
@@ -1,13 +1,13 @@
1
- runtimepy/__init__.py,sha256=GL1as0g7a1sU6w4kqUfDAJXvMjjsu7qwNr2fYa4Jpes,390
1
+ runtimepy/__init__.py,sha256=AXS9vK0HOthW_mVWBe2WqD_erCrngAMT5kE6QuWldAk,390
2
2
  runtimepy/__main__.py,sha256=OPAed6hggoQdw-6QAR62mqLC-rCkdDhOq0wyeS2vDRI,332
3
3
  runtimepy/app.py,sha256=sTvatbsGZ2Hdel36Si_WUbNMtg9CzsJyExr5xjIcxDE,970
4
4
  runtimepy/dev_requirements.txt,sha256=j0dh11ztJAzfaUL0iFheGjaZj9ppDzmTkclTT8YKO8c,230
5
5
  runtimepy/entry.py,sha256=3672ccoslf2h8Wg5M_SuW6SoEx0oslRoi0ngZsgjNz8,1954
6
6
  runtimepy/mapping.py,sha256=VQK1vzmQVvYYKI85_II37-hIEbvgL3PzNy-WI6TTo80,5091
7
7
  runtimepy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- runtimepy/requirements.txt,sha256=ntjU97UnQ5N7tqfwM7ljg77V5MBFFNBTfVuKS_KGwP0,124
8
+ runtimepy/requirements.txt,sha256=z6YEkhMxILetIJNG6hL-cwxNCpuNUvU5u5K1mwSDLP8,124
9
9
  runtimepy/schemas.py,sha256=zTgxPm9DHZ0R_bmmOjNQMTXdtM_Hb1bE-Fog40jDCgg,839
10
- runtimepy/util.py,sha256=1279Ea7CNHa1U_JvUydGAb2oEI2TxilXkq5V1RseCwU,1437
10
+ runtimepy/util.py,sha256=GuyIHVFGMS02OR6-O3LnlV3DqG5hj4-IUud0QM6WicA,1684
11
11
  runtimepy/channel/__init__.py,sha256=pf0RJ5g37_FVV8xoUNgzFGuIfbZEYSBA_cQlJSDTPDo,4774
12
12
  runtimepy/channel/registry.py,sha256=nk36qM_Bf6qK6AFR0plaZHR1PU7b4LZqbQ0feJqk4lc,4784
13
13
  runtimepy/channel/environment/__init__.py,sha256=0Jj8g7Y4bdDvmWtzpegB9D4milGPhsZokoYxmps5zgU,1612
@@ -43,7 +43,7 @@ runtimepy/control/step.py,sha256=2LdZTpMHLwHLdpPVinpC2qByTs5I5LTDt-xONn_6Fc8,549
43
43
  runtimepy/control/env/__init__.py,sha256=RHJqysY7Pv4VDs2SGk0X-qc5xp_SrQ_oxb5Deug8HEM,1339
44
44
  runtimepy/data/404.html,sha256=sn0Mcntzb1-AekukYZAQqz43xfmZtTWa2n2HD2ItqDM,4697
45
45
  runtimepy/data/browser.yaml,sha256=oc5KEV1C1uAJ4MkhNo4hyVVfJtZvHelRNqzNvD313Ow,79
46
- runtimepy/data/dummy_load.yaml,sha256=89BPHLaHJOgiiZSVACBA0_xmlN_N6v2fpcCauB03ZkE,1830
46
+ runtimepy/data/dummy_load.yaml,sha256=eCsWVfEJJ7pUl_JFAD3iDy-nFkw6cf03y9fBqZnaPUM,1986
47
47
  runtimepy/data/factories.yaml,sha256=Jm0QPwW2BQgnj1fIFQwygsWXzT78QJuf7auVRtRzWKQ,1847
48
48
  runtimepy/data/favicon.ico,sha256=iPOtqnqrFVr5tNBM6kTsw7nh0KullEz4TpS6CEQ2HVM,362870
49
49
  runtimepy/data/sample_telemetry.yaml,sha256=OpdFurkvtWJGaNl9LMlU2rKo15AaVVr-U_hoZfsbp-Y,695
@@ -51,7 +51,7 @@ runtimepy/data/server.yaml,sha256=wS_Ceiu2TpkfPurpqoYoPlgzc9DAWtUd24MW7t-S5rU,97
51
51
  runtimepy/data/server_base.yaml,sha256=R_varVgGPGV4nxWYYwKUnHC9ufINi4V92YVhxCCC5wg,875
52
52
  runtimepy/data/server_dev.yaml,sha256=nQsPh7LuQig3pzHfdg_aD3yOUiCj1sKKfI-WwW3hXmQ,523
53
53
  runtimepy/data/tftp_server.yaml,sha256=-bFOWJSagI-fEQQcT8k7eDMJVfSPm2XAxLVG3dqUTa4,204
54
- runtimepy/data/css/bootstrap_extra.css,sha256=sNyeeW2WlPvFx7l1YPCa679I-W7nwE012ybQPLYh_b4,1867
54
+ runtimepy/data/css/bootstrap_extra.css,sha256=kJLOp8j-vRxnWzQOf_eOz4kL8Mbrwxuwk3YNh90HgWM,1907
55
55
  runtimepy/data/css/font.css,sha256=Pe82E66rNi-cwlQ-_1GHAuhPGu5L4x5KqgV0dbDe51w,977
56
56
  runtimepy/data/css/main.css,sha256=OSg5g7FYbjsHY7QNbFCTPAD1MlypeoYfaOyAfvnT2kI,680
57
57
  runtimepy/data/js/DataConnection.js,sha256=DnX8FMehjJXqmI62UMYXSvl_XdfQMzq3XUDFbLu2GgI,98
@@ -100,7 +100,7 @@ runtimepy/data/schemas/PeerProcessConfig.yaml,sha256=_YhfZ2pHCSKqcZqz8-sQAVrwPzF
100
100
  runtimepy/data/schemas/RuntimeEnum.yaml,sha256=dN5bl-lOB3JON02aP1fdwAEP7BhadG1wo_oX6rn5d80,430
101
101
  runtimepy/data/schemas/ServerConnectionConfig.yaml,sha256=IqQUQB09xte4zGmM6Qi0-LTm5McDkoi2tehYspoNUXM,100
102
102
  runtimepy/data/schemas/StructConfig.yaml,sha256=3ifuvRIVzS4AzYu0c9k6TdmLs0PG5y8u25aRphTrxg0,73
103
- runtimepy/data/schemas/TaskConfig.yaml,sha256=iE2RBKsn6TrK6UXFGBlWpsrUl0TeRzwlymJ06SUfNKw,227
103
+ runtimepy/data/schemas/TaskConfig.yaml,sha256=upEfToPllsqEcDoJf9D3rbvXk08nc0slmlUSMyCOYcQ,247
104
104
  runtimepy/data/schemas/channel_controls.yaml,sha256=pctqV_fVjRpiKdaPqET7yyoGVYQuUtOYc1FLQUdfVJc,546
105
105
  runtimepy/data/schemas/has_config.yaml,sha256=SMuJ9tNWw06tsgDasz4myO9SSmMZGep9xBfJ89GJnqA,80
106
106
  runtimepy/data/schemas/has_factory.yaml,sha256=Rsqrxv3HEBUGxPcW6CN7QczA96iBSgtm0gQNsu2P8LM,106
@@ -139,7 +139,7 @@ runtimepy/mixins/regex.py,sha256=kpCj4iL1akzt_KPPiMP-bTbuLBHOpkUrwbCTRe8HSUk,106
139
139
  runtimepy/mixins/trig.py,sha256=vkDd9Rh8080gvH5OHkSYmjImVgM_ZZ7RzMxsczKx5N4,2480
140
140
  runtimepy/net/__init__.py,sha256=leveti9T8P1WAg3M5N7yT_JrUZRCXwZQ8mRsxel-KP4,830
141
141
  runtimepy/net/backoff.py,sha256=IVloxQd-gEK62gFAlU2aOwgTEXhsNUTBfS16eiOqKG8,1080
142
- runtimepy/net/connection.py,sha256=rTzF4dUcZHryx0PUOMcp0IOeQyxWYNfGvsN18kKlIEg,12861
142
+ runtimepy/net/connection.py,sha256=c504S2gK5dsFdQu3pZ6zgRVgJEdP-tzxmFdX33MoUtg,12870
143
143
  runtimepy/net/manager.py,sha256=-M-ZSB9izay6HK1ytTayAYnSHYAz34dcwxaiNhC4lWg,4264
144
144
  runtimepy/net/mixin.py,sha256=5UlFK4lRrJ2O0nEUuScGbkYd4-El-RruFt_UcQR0aic,3039
145
145
  runtimepy/net/mtu.py,sha256=XnLXAFMsDxK1Lj5v_zgWaBrC3lNqf81DkbDc6hpMdmI,3495
@@ -153,13 +153,13 @@ runtimepy/net/arbiter/result.py,sha256=PHZo5qj4SI08ZeWPFk_8OZ1umI6L0dp5nJpjjS8QU
153
153
  runtimepy/net/arbiter/task.py,sha256=APcc5QioAG8uueIzxJU-vktIn8Ys3yJd_CFlRWb6Ieo,795
154
154
  runtimepy/net/arbiter/udp.py,sha256=-ecHJs-utcsiTfr5wSb73hUUuYFBeRVT_D1znYp5q6A,893
155
155
  runtimepy/net/arbiter/websocket.py,sha256=vYTDA7sXMUTTqW3i1zTWUdaxGKxfrQcQoVSYZtmCvfQ,1524
156
- runtimepy/net/arbiter/config/__init__.py,sha256=uQ7EkeMBknKyZg95n_W31qypBkOxrUeYKSF8hugRXPQ,8432
156
+ runtimepy/net/arbiter/config/__init__.py,sha256=m7g7nrOQuMuzc0qShJpqJ3fW55HpAuZl4Jn6D0etWBM,8475
157
157
  runtimepy/net/arbiter/config/codec.py,sha256=TQj8UXEb1EvhiCqRdyq5BkeubMytEZAs9B4E5ZYsEuY,2511
158
158
  runtimepy/net/arbiter/config/util.py,sha256=MezLSil5mEwioI5kxDOZa9y118st1_t0El8DYH6hFU8,1254
159
159
  runtimepy/net/arbiter/factory/__init__.py,sha256=jC1szUYucH4Us3jbb0mhFgnklHlorya5DYGGw2pqfe4,334
160
160
  runtimepy/net/arbiter/factory/connection.py,sha256=uSwnvIWGJcDd2ReK-s9lBx-NcRQ1JH_7VbwkWjE_8zA,3690
161
161
  runtimepy/net/arbiter/factory/task.py,sha256=YLRv55dnDBqHRJIMYgO9_uHi0AW-8hwa0n3wHAKyncE,1959
162
- runtimepy/net/arbiter/housekeeping/__init__.py,sha256=mgrYnDdL1DSP6fXdtk2VU9uqTvtgX2VX5q2Q9EfcJus,3545
162
+ runtimepy/net/arbiter/housekeeping/__init__.py,sha256=-6P2x_qSWp1juml0wKZGJ343c-atrbp8YkDRWn162UA,3622
163
163
  runtimepy/net/arbiter/imports/__init__.py,sha256=W7-kkM4B_zDU42Fyh0PmZL56JslS_0_qzvpzUhN6aDU,5041
164
164
  runtimepy/net/arbiter/imports/util.py,sha256=d4_HnWphrkiHQkyYr8YJKvSSTXoMf3Bct_7jg_CS9eA,1086
165
165
  runtimepy/net/arbiter/struct/__init__.py,sha256=Vr38dp2X0PZOrAbjKsZ9xZdQ1j3z92s4QuvRtYYVuNI,5990
@@ -169,7 +169,7 @@ runtimepy/net/factories/__init__.py,sha256=rPdBVpgzzQYF61w6efQrEre71yMPHd6kanBpM
169
169
  runtimepy/net/html/__init__.py,sha256=BQeGpZWfGSmMg1R0N9GaOZfyFn4UQGHKoFOhd-1G75Q,3983
170
170
  runtimepy/net/html/arbiter.py,sha256=SkZZm-CmyCxbAcWZbvCLH-RwFUJPvrvR5yWysVVuvCM,951
171
171
  runtimepy/net/html/bootstrap/__init__.py,sha256=ONhwx68piWjsrf88FMpda84TWSPqgi-RZCBuWCci_ak,1444
172
- runtimepy/net/html/bootstrap/elements.py,sha256=8sq79EPR8TF9oYV_4I0Sba_PikHOpEaxUvQ7bqtm0ow,4800
172
+ runtimepy/net/html/bootstrap/elements.py,sha256=DJYCsheNtW1lpooBVTAeN2LgAdw4uu2v0PsMk8u3i2k,4831
173
173
  runtimepy/net/html/bootstrap/tabs.py,sha256=7-0lJOD9SALmsViUYGJAXF0PTSqtffc4mpoFwmYcnXE,3842
174
174
  runtimepy/net/http/__init__.py,sha256=4TjFp_ajAVcOEvwtjlF6mG-9EbEePqFZht-QpWIKVBo,1802
175
175
  runtimepy/net/http/common.py,sha256=vpoO6XwRmrZmTkCu9bkI0HnyaD8MWTpV7ADesCNrfRE,2237
@@ -178,7 +178,7 @@ runtimepy/net/http/request_target.py,sha256=EE1aI5VSARw1h93jyZvP56ir5O5fjd6orYK-
178
178
  runtimepy/net/http/response.py,sha256=Sup8W_A0ADNzR5olKrQsVNhsQXUwPOD-eJLlLOgYlAY,2316
179
179
  runtimepy/net/http/state.py,sha256=qCMN8aWfCRfU9XP-cIhSOo2RqfljTjbQRCflfcy2bfY,1626
180
180
  runtimepy/net/http/version.py,sha256=mp6rgIM7-VUVKLCA0Uw96CmBkL0ET860lDVVEewpZ7w,1098
181
- runtimepy/net/server/__init__.py,sha256=ZsJGvak5OPHyuGPDThwj9roOj8ZcwqrOrzTD27hJhCo,9621
181
+ runtimepy/net/server/__init__.py,sha256=sYvvt7p3yTFCR2YXf4Qx3bKo_AafW0OjQ_30KKbg2DM,9488
182
182
  runtimepy/net/server/html.py,sha256=ufg0PQF_iUE7PT0n3Pn3jTcun7mspZUI6_ooblcNnvI,1217
183
183
  runtimepy/net/server/json.py,sha256=a7vM5yfq2er4DexzFqEMnxoMGDeuywKkVH4-uNJBAik,2522
184
184
  runtimepy/net/server/app/__init__.py,sha256=beU67t7zoKGlO7aldjQMUwYLm9mSlc78eMQazri-otw,3012
@@ -196,13 +196,13 @@ runtimepy/net/server/app/env/modal.py,sha256=HTipCYgQaAUtsmlBjXKfhAM5JyhLqoIIwEw
196
196
  runtimepy/net/server/app/env/settings.py,sha256=DboR8vXrdGeB_ehP9USvnyUtzgo4JR5CyYV9AGLYHGI,1720
197
197
  runtimepy/net/server/app/env/widgets.py,sha256=ccrkJNikL5VEKDaTMd8FSI9VzjYYHcpuIRdDjvpQtug,5306
198
198
  runtimepy/net/server/app/env/tab/__init__.py,sha256=stTVKyHljLQWnnhxkWPwa7bLdZtjhiMFbiVFgbiYaFI,647
199
- runtimepy/net/server/app/env/tab/base.py,sha256=v5-Zbo_NqRqoLuceYclz348oFHcL68T2mbEh4EDWtTg,1162
199
+ runtimepy/net/server/app/env/tab/base.py,sha256=QBTBBvsdihbzK5MqrJBf6K5N61b3i8Ms0P6Xq_h1mbs,1171
200
200
  runtimepy/net/server/app/env/tab/controls.py,sha256=bifFMvshDNsar3UiqeXOCYi71JGFRlMnyixKXrdLAEI,4728
201
201
  runtimepy/net/server/app/env/tab/html.py,sha256=IfKCQ_2qupIRtWIuodIBM8XAal1esSXovht1SeGyvb4,7173
202
- runtimepy/net/server/app/env/tab/message.py,sha256=OWqBIPRt6UdBHAXk5qvFMbnWuvIRUyp34lzb3GYdthk,4070
202
+ runtimepy/net/server/app/env/tab/message.py,sha256=-J8wBo1KH0XoBi9VcUvl9LXZCaoFAmvFyMf_YFJVF6Q,3945
203
203
  runtimepy/net/server/struct/__init__.py,sha256=Zy37r6RLFu-XFr9vsanSq80BJdS6Dxr7zmPzQbb7xdw,1799
204
204
  runtimepy/net/server/websocket/__init__.py,sha256=KISuFUUQwNn6BXo8BOMuMOXyoVqE7Jw94ZQiSCQuRQE,5279
205
- runtimepy/net/server/websocket/state.py,sha256=a5xNeq13VPaz48HCqcIQdf1r3WV1a3iVernXM6w7P9g,1828
205
+ runtimepy/net/server/websocket/state.py,sha256=tClzw_3pOV9fzsiqnmss0FUsZZPhInL2CnDi_jyrayI,2291
206
206
  runtimepy/net/stream/__init__.py,sha256=1PNossiE4S9wtPYoiHVsTeAMJFGtiak5vbsoIkVGfZs,2374
207
207
  runtimepy/net/stream/base.py,sha256=Dg4vcR0n9y2122AyJ-9W-jkEhNla_EHO-DqJJPfGD4k,1977
208
208
  runtimepy/net/stream/string.py,sha256=61mgserU3p6j5gAcK0oe0aKqL6vDh7NtgJvbPoiAUPM,784
@@ -227,7 +227,7 @@ runtimepy/net/udp/tftp/endpoint.py,sha256=so60LdPTG66N5tdhHhiX7j_TBHvNOTi4JIgLcg
227
227
  runtimepy/net/udp/tftp/enums.py,sha256=06juMd__pJZsyL8zO8p3hRucnOratt1qtz9zcxzMg4s,1579
228
228
  runtimepy/net/udp/tftp/io.py,sha256=w6cnUt-T-Ma6Vg8BWoRbsNnIWUv0HTY4am6bcLWxNJs,803
229
229
  runtimepy/net/websocket/__init__.py,sha256=YjSmoxiigmsI_hcQw6nueX7bxhrRGerEERnPvgLVEVA,313
230
- runtimepy/net/websocket/connection.py,sha256=c1p6UvWraxd4hrsO5NG5_n1jcG57BoiqWiJbhGguQeU,9134
230
+ runtimepy/net/websocket/connection.py,sha256=BMR58bLpHuulCdbLGnmMdFJOF53wVxYcUe52WbdzKEM,9025
231
231
  runtimepy/noise/__init__.py,sha256=EJM7h3t_z74wwrn6FAFQwYE2yUcOZQ1K1IQqOb8Z0AI,384
232
232
  runtimepy/primitives/__init__.py,sha256=nwWJH1e0KN2NsVwQ3wvRtUpl9s9Ap8Q32NNZLGol0wU,2323
233
233
  runtimepy/primitives/base.py,sha256=BaGPUTeVMnLnTPcpjqnS2lzPN74Pe5C0XaQdgrTfW7A,9185
@@ -261,9 +261,9 @@ runtimepy/registry/name.py,sha256=uhxmijwUT7x59NUYV4hJSe7VcnAbLDUSAPaKhR6K-N0,17
261
261
  runtimepy/sample/__init__.py,sha256=N7P6hnCLF9NwnkZA1h3LzS2C334SAO48Fu8adHxWGLU,56
262
262
  runtimepy/sample/peer.py,sha256=uNlIPAv1-wjGUWdR0AM3L9NUMjnIMJBqQ9ZsHdTLx3Q,1688
263
263
  runtimepy/sample/program.py,sha256=I8_JGjEAh-d3eEw4M9l9CxEw4KG4s8f4i8STwRei5IY,2355
264
- runtimepy/struct/__init__.py,sha256=wFjLwX83ztCF1CuFxnldetzMOoBs_UMirLV778GBGZc,2220
264
+ runtimepy/struct/__init__.py,sha256=Q7t1qKpuYGjtRGXdC_x8IwJyyCQ1Xy2wYriud89XJnk,2229
265
265
  runtimepy/subprocess/__init__.py,sha256=VAiFrYFCU5ETDVoWLOVlrrSsx2d1_atYXUfXYc_OQ9g,4059
266
- runtimepy/subprocess/interface.py,sha256=rYvM8bgoT4DoXGhdidhfmivzrjmEoW6788DjGyAdJ7A,8032
266
+ runtimepy/subprocess/interface.py,sha256=4nGVUfDThaZrfqgn2nZHMt1hfUwHezSvFjykBXGT36g,8041
267
267
  runtimepy/subprocess/peer.py,sha256=oYw9a0yKAPR18Z6Qt24wYWrcX6EizeQE64htL11WVjM,7593
268
268
  runtimepy/subprocess/program.py,sha256=UCKBvmIc4JBitWju396TA8Kxdtmko50jQ3ZPKNkBjFk,6792
269
269
  runtimepy/subprocess/protocol.py,sha256=LYApfKZ0bXSj6gGqLdNfwsIjxWyrdVUK0Jz_qc33ik4,3074
@@ -272,7 +272,7 @@ runtimepy/task/asynchronous.py,sha256=w4oEUCyj-X-zDVFmlsAtRL1gv66ahQ78QKE0GmLGT1
272
272
  runtimepy/task/sample.py,sha256=_nbLj5Julwa1NJC_-WQsotI0890G-TlOWftVHEKiclY,2735
273
273
  runtimepy/task/basic/__init__.py,sha256=NryfG-JmSyqYh-TNG4NLO6-9RJFVq5vn1Z-oV3qTVvg,243
274
274
  runtimepy/task/basic/manager.py,sha256=2P_swKZlFfPHCmX6sMVGSYePWEZOqXp9B4YPyRYSGCo,1858
275
- runtimepy/task/basic/periodic.py,sha256=6tOaWSvF5lqdNpz8Csb4a51XyvSc5yzurqkk0eW1ERQ,6823
275
+ runtimepy/task/basic/periodic.py,sha256=NF_DCVH3hlecYX19Yy9HTGhnApuTLqTd_5p333Sd4gQ,6941
276
276
  runtimepy/task/trig/__init__.py,sha256=GuGNb9eLuFEnl3nAI7Mi_eS5mqJ4MOhEy2Wfv48RFic,785
277
277
  runtimepy/telemetry/__init__.py,sha256=G_JLZsp0EZMGaxSQ12fYgbG2kN4QkvVG4lExV_TzEhM,268
278
278
  runtimepy/telemetry/sample.py,sha256=1weoGSH-yGg-fOaLysZAsO3dSTM6yAXX3XdulAiqi3s,3216
@@ -284,9 +284,9 @@ runtimepy/tui/task.py,sha256=nUZo9fuOC-k1Wpqdzkv9v1tQirCI28fZVgcC13Ijvus,1093
284
284
  runtimepy/tui/channels/__init__.py,sha256=evDaiIn-YS9uGhdo8ZGtP9VK1ek6sr_P1nJ9JuSET0o,4536
285
285
  runtimepy/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
286
286
  runtimepy/ui/controls.py,sha256=yvT7h3thbYaitsakcIAJ90EwKzJ4b-jnc6p3UuVf_XE,1241
287
- runtimepy-5.7.9.dist-info/LICENSE,sha256=s2ILEylm2dAJJXL25nM92IWLRKmJW92zQRQe_cfdsHo,1071
288
- runtimepy-5.7.9.dist-info/METADATA,sha256=n3bYpGmFzA7nS0zhHK2DNNzcTizdlZCfzCC2kRuKQoc,9308
289
- runtimepy-5.7.9.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
290
- runtimepy-5.7.9.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
291
- runtimepy-5.7.9.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
292
- runtimepy-5.7.9.dist-info/RECORD,,
287
+ runtimepy-5.8.0.dist-info/LICENSE,sha256=s2ILEylm2dAJJXL25nM92IWLRKmJW92zQRQe_cfdsHo,1071
288
+ runtimepy-5.8.0.dist-info/METADATA,sha256=rSmBh9NTKlNaifVXKN_qJbJfzpqvg2Piym7WJY2h9lo,9288
289
+ runtimepy-5.8.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
290
+ runtimepy-5.8.0.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
291
+ runtimepy-5.8.0.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
292
+ runtimepy-5.8.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5