runtimepy 5.7.8__py3-none-any.whl → 5.7.10__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 +2 -2
- runtimepy/data/css/bootstrap_extra.css +3 -0
- runtimepy/net/arbiter/housekeeping/__init__.py +8 -5
- runtimepy/net/server/__init__.py +5 -8
- runtimepy/net/server/app/env/tab/message.py +1 -3
- runtimepy/net/server/websocket/state.py +21 -3
- runtimepy/requirements.txt +1 -1
- runtimepy/util.py +9 -0
- {runtimepy-5.7.8.dist-info → runtimepy-5.7.10.dist-info}/METADATA +6 -6
- {runtimepy-5.7.8.dist-info → runtimepy-5.7.10.dist-info}/RECORD +14 -14
- {runtimepy-5.7.8.dist-info → runtimepy-5.7.10.dist-info}/WHEEL +1 -1
- {runtimepy-5.7.8.dist-info → runtimepy-5.7.10.dist-info}/LICENSE +0 -0
- {runtimepy-5.7.8.dist-info → runtimepy-5.7.10.dist-info}/entry_points.txt +0 -0
- {runtimepy-5.7.8.dist-info → runtimepy-5.7.10.dist-info}/top_level.txt +0 -0
runtimepy/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# =====================================
|
|
2
2
|
# generator=datazen
|
|
3
3
|
# version=3.1.4
|
|
4
|
-
# hash=
|
|
4
|
+
# hash=01934a9c90fba4488654f035acc8b84e
|
|
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.
|
|
13
|
+
VERSION = "5.7.10"
|
|
14
14
|
|
|
15
15
|
# runtimepy-specific content.
|
|
16
16
|
METRICS_NAME = "metrics"
|
|
@@ -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
|
|
runtimepy/net/server/__init__.py
CHANGED
|
@@ -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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
199
|
-
result = await path_fd.read()
|
|
196
|
+
result = await read_binary(candidate)
|
|
200
197
|
|
|
201
198
|
break
|
|
202
199
|
|
|
@@ -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
|
-
|
|
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,18 +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)
|
|
61
|
-
self._loggers
|
|
74
|
+
self._loggers.clear()
|
|
75
|
+
|
|
76
|
+
self.tab_logger.drain_str()
|
|
77
|
+
|
|
78
|
+
self.clear_telemetry()
|
|
62
79
|
|
|
63
80
|
def add_logger(self, logger: logging.Logger) -> None:
|
|
64
81
|
"""Add a logger."""
|
|
65
82
|
|
|
66
|
-
logger
|
|
67
|
-
|
|
83
|
+
if logger not in self._loggers:
|
|
84
|
+
logger.addHandler(self.tab_logger)
|
|
85
|
+
self._loggers.append(logger)
|
|
68
86
|
|
|
69
87
|
@staticmethod
|
|
70
88
|
def create() -> "TabState":
|
runtimepy/requirements.txt
CHANGED
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.
|
|
3
|
+
Version: 5.7.10
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/vkottler/runtimepy
|
|
6
6
|
Author: Vaughn Kottler
|
|
@@ -17,11 +17,11 @@ 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.5
|
|
20
21
|
Requires-Dist: websockets
|
|
21
|
-
Requires-Dist: svgen >=0.6.8
|
|
22
|
-
Requires-Dist: aiofiles
|
|
23
22
|
Requires-Dist: psutil
|
|
24
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: aiofiles
|
|
24
|
+
Requires-Dist: svgen >=0.6.8
|
|
25
25
|
Provides-Extra: test
|
|
26
26
|
Requires-Dist: pylint ; extra == 'test'
|
|
27
27
|
Requires-Dist: flake8 ; extra == 'test'
|
|
@@ -45,11 +45,11 @@ Requires-Dist: uvloop ; (sys_platform != "win32" and sys_platform != "cygwin") a
|
|
|
45
45
|
=====================================
|
|
46
46
|
generator=datazen
|
|
47
47
|
version=3.1.4
|
|
48
|
-
hash=
|
|
48
|
+
hash=1e8298e9f6423ee6f9836f5ec04cc3ab
|
|
49
49
|
=====================================
|
|
50
50
|
-->
|
|
51
51
|
|
|
52
|
-
# runtimepy ([5.7.
|
|
52
|
+
# runtimepy ([5.7.10](https://pypi.org/project/runtimepy/))
|
|
53
53
|
|
|
54
54
|
[](https://pypi.org/project/runtimepy/)
|
|
55
55
|

|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
runtimepy/__init__.py,sha256=
|
|
1
|
+
runtimepy/__init__.py,sha256=xlFe4KOw9V-9A2MlIEX9gtA5eOEck1Z8uclAZojzciU,391
|
|
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=
|
|
8
|
+
runtimepy/requirements.txt,sha256=ntjU97UnQ5N7tqfwM7ljg77V5MBFFNBTfVuKS_KGwP0,124
|
|
9
9
|
runtimepy/schemas.py,sha256=zTgxPm9DHZ0R_bmmOjNQMTXdtM_Hb1bE-Fog40jDCgg,839
|
|
10
|
-
runtimepy/util.py,sha256=
|
|
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
|
|
@@ -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
|
|
54
|
+
runtimepy/data/css/bootstrap_extra.css,sha256=sNyeeW2WlPvFx7l1YPCa679I-W7nwE012ybQPLYh_b4,1867
|
|
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
|
|
@@ -159,7 +159,7 @@ runtimepy/net/arbiter/config/util.py,sha256=MezLSil5mEwioI5kxDOZa9y118st1_t0El8D
|
|
|
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
|
|
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
|
|
@@ -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=
|
|
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
|
|
@@ -199,10 +199,10 @@ runtimepy/net/server/app/env/tab/__init__.py,sha256=stTVKyHljLQWnnhxkWPwa7bLdZtj
|
|
|
199
199
|
runtimepy/net/server/app/env/tab/base.py,sha256=v5-Zbo_NqRqoLuceYclz348oFHcL68T2mbEh4EDWtTg,1162
|
|
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
|
|
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=
|
|
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
|
|
@@ -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.
|
|
288
|
-
runtimepy-5.7.
|
|
289
|
-
runtimepy-5.7.
|
|
290
|
-
runtimepy-5.7.
|
|
291
|
-
runtimepy-5.7.
|
|
292
|
-
runtimepy-5.7.
|
|
287
|
+
runtimepy-5.7.10.dist-info/LICENSE,sha256=s2ILEylm2dAJJXL25nM92IWLRKmJW92zQRQe_cfdsHo,1071
|
|
288
|
+
runtimepy-5.7.10.dist-info/METADATA,sha256=iZiw-hLuQS1VPCwPvhZBTYUy-vmUeqO9Oqak235w63s,9310
|
|
289
|
+
runtimepy-5.7.10.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
290
|
+
runtimepy-5.7.10.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
|
|
291
|
+
runtimepy-5.7.10.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
|
|
292
|
+
runtimepy-5.7.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|