runtimepy 5.7.9__tar.gz → 5.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. {runtimepy-5.7.9/runtimepy.egg-info → runtimepy-5.8.0}/PKG-INFO +6 -6
  2. {runtimepy-5.7.9 → runtimepy-5.8.0}/README.md +2 -2
  3. {runtimepy-5.7.9 → runtimepy-5.8.0}/pyproject.toml +1 -1
  4. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/__init__.py +2 -2
  5. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/css/bootstrap_extra.css +4 -0
  6. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/dummy_load.yaml +18 -1
  7. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/TaskConfig.yaml +1 -0
  8. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/config/__init__.py +1 -0
  9. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/housekeeping/__init__.py +8 -5
  10. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/connection.py +1 -1
  11. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/html/bootstrap/elements.py +1 -0
  12. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/__init__.py +5 -8
  13. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/tab/base.py +1 -1
  14. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/tab/message.py +1 -3
  15. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/websocket/state.py +20 -3
  16. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/websocket/connection.py +10 -15
  17. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/requirements.txt +2 -2
  18. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/struct/__init__.py +1 -1
  19. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/subprocess/interface.py +1 -1
  20. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/task/basic/periodic.py +6 -2
  21. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/util.py +9 -0
  22. {runtimepy-5.7.9 → runtimepy-5.8.0/runtimepy.egg-info}/PKG-INFO +6 -6
  23. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy.egg-info/SOURCES.txt +2 -1
  24. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy.egg-info/requires.txt +3 -3
  25. runtimepy-5.8.0/tests/test_util.py +19 -0
  26. {runtimepy-5.7.9 → runtimepy-5.8.0}/LICENSE +0 -0
  27. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/__main__.py +0 -0
  28. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/app.py +0 -0
  29. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/__init__.py +0 -0
  30. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/__init__.py +0 -0
  31. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/array.py +0 -0
  32. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/base.py +0 -0
  33. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/command/__init__.py +0 -0
  34. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/command/parser.py +0 -0
  35. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/command/processor.py +0 -0
  36. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/command/result.py +0 -0
  37. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/create.py +0 -0
  38. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/file.py +0 -0
  39. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/sample.py +0 -0
  40. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/environment/telemetry.py +0 -0
  41. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/event/__init__.py +0 -0
  42. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/event/header.py +0 -0
  43. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/channel/registry.py +0 -0
  44. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/codec/__init__.py +0 -0
  45. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/codec/protocol/__init__.py +0 -0
  46. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/codec/protocol/base.py +0 -0
  47. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/codec/protocol/json.py +0 -0
  48. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/codec/system/__init__.py +0 -0
  49. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/__init__.py +0 -0
  50. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/all.py +0 -0
  51. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/arbiter.py +0 -0
  52. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/common.py +0 -0
  53. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/mtu.py +0 -0
  54. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/server.py +0 -0
  55. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/task.py +0 -0
  56. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/tftp.py +0 -0
  57. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/commands/tui.py +0 -0
  58. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/control/__init__.py +0 -0
  59. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/control/env/__init__.py +0 -0
  60. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/control/source.py +0 -0
  61. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/control/step.py +0 -0
  62. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/404.html +0 -0
  63. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/browser.yaml +0 -0
  64. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/css/font.css +0 -0
  65. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/css/main.css +0 -0
  66. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/factories.yaml +0 -0
  67. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/favicon.ico +0 -0
  68. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/DataConnection.js +0 -0
  69. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/JsonConnection.js +0 -0
  70. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/audio.js +0 -0
  71. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/App.js +0 -0
  72. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/ChannelTable.js +0 -0
  73. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/DataConnection.js +0 -0
  74. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/JsonConnection.js +0 -0
  75. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/OverlayManager.js +0 -0
  76. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/Plot.js +0 -0
  77. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
  78. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/PlotManager.js +0 -0
  79. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
  80. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/PointBuffer.js +0 -0
  81. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/PointManager.js +0 -0
  82. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/TabFilter.js +0 -0
  83. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/TabInterface.js +0 -0
  84. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/UnitSystem.js +0 -0
  85. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/WindowHashManager.js +0 -0
  86. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/classes/WorkerInterface.js +0 -0
  87. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/events.js +0 -0
  88. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/init.js +0 -0
  89. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/main.js +0 -0
  90. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/markdown_page.js +0 -0
  91. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/tab/env.js +0 -0
  92. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/tab/sound.js +0 -0
  93. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
  94. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/unused/pyodide.js +0 -0
  95. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/util.js +0 -0
  96. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/js/worker.js +0 -0
  97. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/md/Connection.md +0 -0
  98. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/md/PeriodicTask.md +0 -0
  99. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/md/RuntimeStruct.md +0 -0
  100. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/md/RuntimepyPeer.md +0 -0
  101. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/md/SinusoidTask.md +0 -0
  102. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/sample_telemetry.yaml +0 -0
  103. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/BitFields.yaml +0 -0
  104. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/Channel.yaml +0 -0
  105. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
  106. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
  107. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/ClientConnectionConfig.yaml +0 -0
  108. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +0 -0
  109. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
  110. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/FindFile.yaml +0 -0
  111. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/PeerProcessConfig.yaml +0 -0
  112. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
  113. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
  114. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/StructConfig.yaml +0 -0
  115. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/channel_controls.yaml +0 -0
  116. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/has_config.yaml +0 -0
  117. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/has_factory.yaml +0 -0
  118. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/has_markdown.yaml +0 -0
  119. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/has_name.yaml +0 -0
  120. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
  121. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/server.yaml +0 -0
  122. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/server_base.yaml +0 -0
  123. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/server_dev.yaml +0 -0
  124. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/svg/chip-circle-bootstrap.svg +0 -0
  125. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaCode-Bold.woff2 +0 -0
  126. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaCode-BoldItalic.woff2 +0 -0
  127. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaCode-Italic.woff2 +0 -0
  128. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaCode-Regular.woff2 +0 -0
  129. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaMono-Bold.woff2 +0 -0
  130. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaMono-BoldItalic.woff2 +0 -0
  131. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaMono-Italic.woff2 +0 -0
  132. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/CascadiaMono-Regular.woff2 +0 -0
  133. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/static/woff2/README.md +0 -0
  134. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/data/tftp_server.yaml +0 -0
  135. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/dev_requirements.txt +0 -0
  136. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/entry.py +0 -0
  137. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/enum/__init__.py +0 -0
  138. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/enum/registry.py +0 -0
  139. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/enum/types.py +0 -0
  140. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mapping.py +0 -0
  141. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/message/__init__.py +0 -0
  142. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/message/handlers.py +0 -0
  143. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/message/interface.py +0 -0
  144. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/message/types.py +0 -0
  145. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/metrics/__init__.py +0 -0
  146. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/metrics/channel.py +0 -0
  147. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/metrics/connection.py +0 -0
  148. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/metrics/task.py +0 -0
  149. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/__init__.py +0 -0
  150. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/async_command.py +0 -0
  151. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/enum.py +0 -0
  152. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/environment.py +0 -0
  153. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/finalize.py +0 -0
  154. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/logging.py +0 -0
  155. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/psutil.py +0 -0
  156. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/regex.py +0 -0
  157. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/mixins/trig.py +0 -0
  158. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/__init__.py +0 -0
  159. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/apps/__init__.py +0 -0
  160. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/__init__.py +0 -0
  161. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/base.py +0 -0
  162. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/config/codec.py +0 -0
  163. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/config/util.py +0 -0
  164. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/factory/__init__.py +0 -0
  165. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/factory/connection.py +0 -0
  166. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/factory/task.py +0 -0
  167. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/imports/__init__.py +0 -0
  168. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/imports/util.py +0 -0
  169. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/info.py +0 -0
  170. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/result.py +0 -0
  171. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/struct/__init__.py +0 -0
  172. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/task.py +0 -0
  173. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
  174. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/tcp/json.py +0 -0
  175. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/udp.py +0 -0
  176. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/arbiter/websocket.py +0 -0
  177. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/backoff.py +0 -0
  178. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/factories/__init__.py +0 -0
  179. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/html/__init__.py +0 -0
  180. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/html/arbiter.py +0 -0
  181. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/html/bootstrap/__init__.py +0 -0
  182. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/html/bootstrap/tabs.py +0 -0
  183. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/http/__init__.py +0 -0
  184. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/http/common.py +0 -0
  185. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/http/header.py +0 -0
  186. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/http/request_target.py +0 -0
  187. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/http/response.py +0 -0
  188. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/http/state.py +0 -0
  189. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/http/version.py +0 -0
  190. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/manager.py +0 -0
  191. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/mixin.py +0 -0
  192. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/mtu.py +0 -0
  193. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/__init__.py +0 -0
  194. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/base.py +0 -0
  195. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/create.py +0 -0
  196. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/elements.py +0 -0
  197. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/__init__.py +0 -0
  198. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/modal.py +0 -0
  199. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/settings.py +0 -0
  200. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
  201. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/tab/controls.py +0 -0
  202. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/tab/html.py +0 -0
  203. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/env/widgets.py +0 -0
  204. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/files.py +0 -0
  205. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/landing_page.py +0 -0
  206. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/placeholder.py +0 -0
  207. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/pyodide.py +0 -0
  208. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/sound.py +0 -0
  209. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/app/tab.py +0 -0
  210. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/html.py +0 -0
  211. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/json.py +0 -0
  212. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/struct/__init__.py +0 -0
  213. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/server/websocket/__init__.py +0 -0
  214. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/ssl.py +0 -0
  215. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/stream/__init__.py +0 -0
  216. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/stream/base.py +0 -0
  217. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/stream/json/__init__.py +0 -0
  218. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/stream/string.py +0 -0
  219. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/__init__.py +0 -0
  220. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/connection.py +0 -0
  221. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/create.py +0 -0
  222. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/http/__init__.py +0 -0
  223. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/protocol.py +0 -0
  224. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/scpi/__init__.py +0 -0
  225. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/telnet/__init__.py +0 -0
  226. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/telnet/codes.py +0 -0
  227. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
  228. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/__init__.py +0 -0
  229. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/connection.py +0 -0
  230. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/create.py +0 -0
  231. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/protocol.py +0 -0
  232. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/queue.py +0 -0
  233. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/tftp/__init__.py +0 -0
  234. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/tftp/base.py +0 -0
  235. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/tftp/endpoint.py +0 -0
  236. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/tftp/enums.py +0 -0
  237. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/udp/tftp/io.py +0 -0
  238. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/util.py +0 -0
  239. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/net/websocket/__init__.py +0 -0
  240. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/noise/__init__.py +0 -0
  241. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/__init__.py +0 -0
  242. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/array/__init__.py +0 -0
  243. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/base.py +0 -0
  244. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/bool.py +0 -0
  245. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/byte_order.py +0 -0
  246. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/evaluation.py +0 -0
  247. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/field/__init__.py +0 -0
  248. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/field/fields.py +0 -0
  249. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/field/manager/__init__.py +0 -0
  250. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/field/manager/base.py +0 -0
  251. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/float.py +0 -0
  252. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/int.py +0 -0
  253. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/scaling.py +0 -0
  254. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/serializable/__init__.py +0 -0
  255. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/serializable/base.py +0 -0
  256. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/serializable/fixed.py +0 -0
  257. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/serializable/framer.py +0 -0
  258. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/serializable/prefixed.py +0 -0
  259. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/string.py +0 -0
  260. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/types/__init__.py +0 -0
  261. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/types/base.py +0 -0
  262. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/types/bool.py +0 -0
  263. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/types/bounds.py +0 -0
  264. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/types/float.py +0 -0
  265. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/primitives/types/int.py +0 -0
  266. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/py.typed +0 -0
  267. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/registry/__init__.py +0 -0
  268. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/registry/bool.py +0 -0
  269. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/registry/item.py +0 -0
  270. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/registry/name.py +0 -0
  271. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/sample/__init__.py +0 -0
  272. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/sample/peer.py +0 -0
  273. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/sample/program.py +0 -0
  274. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/schemas.py +0 -0
  275. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/subprocess/__init__.py +0 -0
  276. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/subprocess/peer.py +0 -0
  277. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/subprocess/program.py +0 -0
  278. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/subprocess/protocol.py +0 -0
  279. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/task/__init__.py +0 -0
  280. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/task/asynchronous.py +0 -0
  281. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/task/basic/__init__.py +0 -0
  282. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/task/basic/manager.py +0 -0
  283. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/task/sample.py +0 -0
  284. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/task/trig/__init__.py +0 -0
  285. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/telemetry/__init__.py +0 -0
  286. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/telemetry/sample.py +0 -0
  287. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/tui/__init__.py +0 -0
  288. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/tui/channels/__init__.py +0 -0
  289. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/tui/cursor.py +0 -0
  290. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/tui/mixin.py +0 -0
  291. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/tui/mock.py +0 -0
  292. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/tui/task.py +0 -0
  293. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/ui/__init__.py +0 -0
  294. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy/ui/controls.py +0 -0
  295. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy.egg-info/dependency_links.txt +0 -0
  296. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy.egg-info/entry_points.txt +0 -0
  297. {runtimepy-5.7.9 → runtimepy-5.8.0}/runtimepy.egg-info/top_level.txt +0 -0
  298. {runtimepy-5.7.9 → runtimepy-5.8.0}/setup.cfg +0 -0
  299. {runtimepy-5.7.9 → runtimepy-5.8.0}/setup.py +0 -0
  300. {runtimepy-5.7.9 → runtimepy-5.8.0}/tests/test_entry.py +0 -0
  301. {runtimepy-5.7.9 → runtimepy-5.8.0}/tests/test_mapping.py +0 -0
  302. {runtimepy-5.7.9 → runtimepy-5.8.0}/tests/test_resources.py +0 -0
@@ -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,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: aiofiles
21
- Requires-Dist: vcorelib>=3.4.5
20
+ Requires-Dist: vcorelib>=3.4.7
22
21
  Requires-Dist: websockets
22
+ Requires-Dist: aiofiles
23
+ Requires-Dist: svgen>=0.7.4
23
24
  Requires-Dist: psutil
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") an
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)
@@ -2,11 +2,11 @@
2
2
  =====================================
3
3
  generator=datazen
4
4
  version=3.1.4
5
- hash=9fbafffa1da655b349a05dfa48addf0b
5
+ hash=0cb0fecd5f4e84d1b639d4c155ab541c
6
6
  =====================================
7
7
  -->
8
8
 
9
- # runtimepy ([5.7.9](https://pypi.org/project/runtimepy/))
9
+ # runtimepy ([5.8.0](https://pypi.org/project/runtimepy/))
10
10
 
11
11
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
12
12
  ![Build Status](https://github.com/vkottler/runtimepy/workflows/Python%20Package/badge.svg)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta:__legacy__"
4
4
 
5
5
  [project]
6
6
  name = "runtimepy"
7
- version = "5.7.9"
7
+ version = "5.8.0"
8
8
  description = "A framework for implementing Python services."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -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
 
@@ -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,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: aiofiles
21
- Requires-Dist: vcorelib>=3.4.5
20
+ Requires-Dist: vcorelib>=3.4.7
22
21
  Requires-Dist: websockets
22
+ Requires-Dist: aiofiles
23
+ Requires-Dist: svgen>=0.7.4
23
24
  Requires-Dist: psutil
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") an
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)
@@ -296,4 +296,5 @@ runtimepy/ui/__init__.py
296
296
  runtimepy/ui/controls.py
297
297
  tests/test_entry.py
298
298
  tests/test_mapping.py
299
- tests/test_resources.py
299
+ tests/test_resources.py
300
+ tests/test_util.py
@@ -1,8 +1,8 @@
1
- aiofiles
2
- vcorelib>=3.4.5
1
+ vcorelib>=3.4.7
3
2
  websockets
3
+ aiofiles
4
+ svgen>=0.7.4
4
5
  psutil
5
- svgen>=0.6.8
6
6
 
7
7
  [test]
8
8
  pylint
@@ -0,0 +1,19 @@
1
+ """
2
+ Test the 'util' module.
3
+ """
4
+
5
+ # third-party
6
+ from pytest import mark
7
+
8
+ # module under test
9
+ from runtimepy.util import read_binary
10
+
11
+ # internal
12
+ from tests.resources import resource
13
+
14
+
15
+ @mark.asyncio
16
+ async def test_read_binary():
17
+ """Test 'read_binary' invocations."""
18
+
19
+ assert await read_binary(resource("test.txt"))
File without changes
File without changes