runtimepy 5.15.2__tar.gz → 5.15.4__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 (326) hide show
  1. {runtimepy-5.15.2/runtimepy.egg-info → runtimepy-5.15.4}/PKG-INFO +5 -5
  2. {runtimepy-5.15.2 → runtimepy-5.15.4}/README.md +2 -2
  3. {runtimepy-5.15.2 → runtimepy-5.15.4}/pyproject.toml +1 -1
  4. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/__init__.py +2 -2
  5. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/base.py +5 -0
  6. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/command/__init__.py +35 -0
  7. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/file.py +4 -0
  8. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/dummy_load.yaml +14 -0
  9. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/ChannelTable.js +4 -0
  10. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/TabInterface.js +13 -0
  11. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/init.js +4 -2
  12. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/ClientConnectionConfig.yaml +1 -0
  13. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +3 -0
  14. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/PeerProcessConfig.yaml +1 -0
  15. runtimepy-5.15.4/runtimepy/data/schemas/TwoTupleArray.yaml +9 -0
  16. runtimepy-5.15.4/runtimepy/data/schemas/has_views.yaml +4 -0
  17. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/base.py +16 -0
  18. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/config/__init__.py +5 -1
  19. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/config/codec.py +5 -0
  20. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/factory/connection.py +6 -1
  21. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/__init__.py +11 -6
  22. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/widgets.py +20 -4
  23. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/struct/__init__.py +1 -0
  24. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/task/basic/periodic.py +1 -0
  25. {runtimepy-5.15.2 → runtimepy-5.15.4/runtimepy.egg-info}/PKG-INFO +5 -5
  26. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy.egg-info/SOURCES.txt +2 -0
  27. {runtimepy-5.15.2 → runtimepy-5.15.4}/LICENSE +0 -0
  28. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/__main__.py +0 -0
  29. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/app.py +0 -0
  30. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/__init__.py +0 -0
  31. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/__init__.py +0 -0
  32. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/array.py +0 -0
  33. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/command/parser.py +0 -0
  34. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/command/processor.py +0 -0
  35. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/command/result.py +0 -0
  36. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/create.py +0 -0
  37. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/sample.py +0 -0
  38. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/environment/telemetry.py +0 -0
  39. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/event/__init__.py +0 -0
  40. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/event/header.py +0 -0
  41. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/channel/registry.py +0 -0
  42. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/codec/__init__.py +0 -0
  43. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/codec/protocol/__init__.py +0 -0
  44. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/codec/protocol/base.py +0 -0
  45. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/codec/protocol/json.py +0 -0
  46. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/codec/protocol/receiver.py +0 -0
  47. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/codec/system/__init__.py +0 -0
  48. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/__init__.py +0 -0
  49. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/all.py +0 -0
  50. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/arbiter.py +0 -0
  51. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/common.py +0 -0
  52. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/mtu.py +0 -0
  53. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/server.py +0 -0
  54. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/task.py +0 -0
  55. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/tftp.py +0 -0
  56. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/commands/tui.py +0 -0
  57. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/control/__init__.py +0 -0
  58. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/control/env/__init__.py +0 -0
  59. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/control/source.py +0 -0
  60. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/control/step.py +0 -0
  61. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/404.md +0 -0
  62. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/base.yaml +0 -0
  63. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/browser.yaml +0 -0
  64. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/css/bootstrap_extra.css +0 -0
  65. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/css/font.css +0 -0
  66. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/css/main.css +0 -0
  67. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/factories.yaml +0 -0
  68. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/favicon.ico +0 -0
  69. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/DataConnection.js +0 -0
  70. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/JsonConnection.js +0 -0
  71. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/audio.js +0 -0
  72. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/App.js +0 -0
  73. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/DataConnection.js +0 -0
  74. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/JsonConnection.js +0 -0
  75. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/OverlayManager.js +0 -0
  76. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/Plot.js +0 -0
  77. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
  78. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/PlotManager.js +0 -0
  79. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
  80. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/PointBuffer.js +0 -0
  81. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/PointManager.js +0 -0
  82. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/TabFilter.js +0 -0
  83. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/UnitSystem.js +0 -0
  84. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/WindowHashManager.js +0 -0
  85. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/classes/WorkerInterface.js +0 -0
  86. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/events.js +0 -0
  87. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/main.js +0 -0
  88. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/markdown_page.js +0 -0
  89. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/sample.js +0 -0
  90. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/tab/env.js +0 -0
  91. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/tab/sound.js +0 -0
  92. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
  93. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/unused/pyodide.js +0 -0
  94. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/util.js +0 -0
  95. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/js/worker.js +0 -0
  96. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/md/Connection.md +0 -0
  97. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/md/PeriodicTask.md +0 -0
  98. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/md/RuntimeStruct.md +0 -0
  99. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/md/RuntimepyPeer.md +0 -0
  100. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/md/SinusoidTask.md +0 -0
  101. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/sample_telemetry.yaml +0 -0
  102. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/BitFields.yaml +0 -0
  103. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/Channel.yaml +0 -0
  104. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
  105. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
  106. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
  107. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/FindFile.yaml +0 -0
  108. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
  109. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
  110. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/StructConfig.yaml +0 -0
  111. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/TaskConfig.yaml +0 -0
  112. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/channel_controls.yaml +0 -0
  113. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/has_config.yaml +0 -0
  114. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/has_factory.yaml +0 -0
  115. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/has_markdown.yaml +0 -0
  116. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/has_name.yaml +0 -0
  117. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
  118. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/server.yaml +0 -0
  119. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/server_base.yaml +0 -0
  120. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/server_dev.yaml +0 -0
  121. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/css/bootstrap-icons.min.css +0 -0
  122. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/css/bootstrap.min.css +0 -0
  123. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/css/fonts/bootstrap-icons.woff +0 -0
  124. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/css/fonts/bootstrap-icons.woff2 +0 -0
  125. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/js/bootstrap.bundle.min.js +0 -0
  126. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/js/webglplot.umd.min.js +0 -0
  127. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/1024x1024.png +0 -0
  128. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/128x128.png +0 -0
  129. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/16x16.png +0 -0
  130. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/1920x1920.png +0 -0
  131. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/24x24.png +0 -0
  132. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/256x256.png +0 -0
  133. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/32x32.png +0 -0
  134. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/512x512.png +0 -0
  135. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/png/chip-circle-bootstrap/64x64.png +0 -0
  136. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/svg/chip-circle-bootstrap.svg +0 -0
  137. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/svg/outline-dark.svg +0 -0
  138. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/svg/outline-light.svg +0 -0
  139. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaCode-Bold.woff2 +0 -0
  140. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaCode-BoldItalic.woff2 +0 -0
  141. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaCode-Italic.woff2 +0 -0
  142. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaCode-Regular.woff2 +0 -0
  143. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaMono-Bold.woff2 +0 -0
  144. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaMono-BoldItalic.woff2 +0 -0
  145. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaMono-Italic.woff2 +0 -0
  146. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/CascadiaMono-Regular.woff2 +0 -0
  147. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/static/woff2/README.md +0 -0
  148. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/data/tftp_server.yaml +0 -0
  149. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/dev_requirements.txt +0 -0
  150. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/entry.py +0 -0
  151. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/enum/__init__.py +0 -0
  152. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/enum/registry.py +0 -0
  153. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/enum/types.py +0 -0
  154. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mapping.py +0 -0
  155. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/message/__init__.py +0 -0
  156. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/message/handlers.py +0 -0
  157. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/message/interface.py +0 -0
  158. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/message/types.py +0 -0
  159. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/metrics/__init__.py +0 -0
  160. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/metrics/channel.py +0 -0
  161. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/metrics/connection.py +0 -0
  162. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/metrics/task.py +0 -0
  163. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/__init__.py +0 -0
  164. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/async_command.py +0 -0
  165. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/enum.py +0 -0
  166. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/environment.py +0 -0
  167. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/finalize.py +0 -0
  168. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/logging.py +0 -0
  169. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/psutil.py +0 -0
  170. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/regex.py +0 -0
  171. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/mixins/trig.py +0 -0
  172. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/__init__.py +0 -0
  173. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/apps/__init__.py +0 -0
  174. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/__init__.py +0 -0
  175. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/config/util.py +0 -0
  176. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/factory/__init__.py +0 -0
  177. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/factory/task.py +0 -0
  178. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
  179. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/imports/__init__.py +0 -0
  180. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/imports/util.py +0 -0
  181. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/info.py +0 -0
  182. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/result.py +0 -0
  183. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/struct/__init__.py +0 -0
  184. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/task.py +0 -0
  185. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
  186. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/tcp/json.py +0 -0
  187. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/udp.py +0 -0
  188. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/arbiter/websocket.py +0 -0
  189. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/backoff.py +0 -0
  190. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/connection.py +0 -0
  191. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/factories/__init__.py +0 -0
  192. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/html/__init__.py +0 -0
  193. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/html/arbiter.py +0 -0
  194. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/html/bootstrap/__init__.py +0 -0
  195. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/html/bootstrap/elements.py +0 -0
  196. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/html/bootstrap/tabs.py +0 -0
  197. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/http/__init__.py +0 -0
  198. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/http/common.py +0 -0
  199. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/http/header.py +0 -0
  200. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/http/request_target.py +0 -0
  201. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/http/response.py +0 -0
  202. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/http/state.py +0 -0
  203. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/http/version.py +0 -0
  204. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/manager.py +0 -0
  205. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/mixin.py +0 -0
  206. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/mtu.py +0 -0
  207. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/__init__.py +0 -0
  208. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/base.py +0 -0
  209. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/create.py +0 -0
  210. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/elements.py +0 -0
  211. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/__init__.py +0 -0
  212. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/modal.py +0 -0
  213. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/settings.py +0 -0
  214. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
  215. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/tab/base.py +0 -0
  216. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/tab/controls.py +0 -0
  217. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/tab/html.py +0 -0
  218. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/env/tab/message.py +0 -0
  219. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/files.py +0 -0
  220. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/landing_page.py +0 -0
  221. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/placeholder.py +0 -0
  222. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/pyodide.py +0 -0
  223. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/sound.py +0 -0
  224. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/app/tab.py +0 -0
  225. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/html.py +0 -0
  226. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/json.py +0 -0
  227. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/markdown.py +0 -0
  228. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/mux.py +0 -0
  229. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/struct/__init__.py +0 -0
  230. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/websocket/__init__.py +0 -0
  231. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/server/websocket/state.py +0 -0
  232. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/ssl.py +0 -0
  233. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/stream/__init__.py +0 -0
  234. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/stream/base.py +0 -0
  235. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/stream/json/__init__.py +0 -0
  236. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/stream/string.py +0 -0
  237. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/__init__.py +0 -0
  238. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/connection.py +0 -0
  239. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/create.py +0 -0
  240. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/http/__init__.py +0 -0
  241. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/protocol.py +0 -0
  242. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/scpi/__init__.py +0 -0
  243. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/telnet/__init__.py +0 -0
  244. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/telnet/codes.py +0 -0
  245. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
  246. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/__init__.py +0 -0
  247. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/connection.py +0 -0
  248. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/create.py +0 -0
  249. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/protocol.py +0 -0
  250. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/queue.py +0 -0
  251. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/tftp/__init__.py +0 -0
  252. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/tftp/base.py +0 -0
  253. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/tftp/endpoint.py +0 -0
  254. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/tftp/enums.py +0 -0
  255. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/udp/tftp/io.py +0 -0
  256. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/util.py +0 -0
  257. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/websocket/__init__.py +0 -0
  258. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/net/websocket/connection.py +0 -0
  259. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/noise/__init__.py +0 -0
  260. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/__init__.py +0 -0
  261. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/array/__init__.py +0 -0
  262. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/base.py +0 -0
  263. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/bool.py +0 -0
  264. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/byte_order.py +0 -0
  265. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/evaluation.py +0 -0
  266. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/field/__init__.py +0 -0
  267. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/field/fields.py +0 -0
  268. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/field/manager/__init__.py +0 -0
  269. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/field/manager/base.py +0 -0
  270. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/float.py +0 -0
  271. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/int.py +0 -0
  272. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/scaling.py +0 -0
  273. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/serializable/__init__.py +0 -0
  274. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/serializable/base.py +0 -0
  275. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/serializable/fixed.py +0 -0
  276. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/serializable/framer.py +0 -0
  277. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/serializable/prefixed.py +0 -0
  278. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/string.py +0 -0
  279. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/types/__init__.py +0 -0
  280. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/types/base.py +0 -0
  281. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/types/bool.py +0 -0
  282. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/types/bounds.py +0 -0
  283. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/types/float.py +0 -0
  284. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/primitives/types/int.py +0 -0
  285. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/py.typed +0 -0
  286. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/registry/__init__.py +0 -0
  287. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/registry/bool.py +0 -0
  288. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/registry/item.py +0 -0
  289. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/registry/name.py +0 -0
  290. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/requirements.txt +0 -0
  291. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/sample/__init__.py +0 -0
  292. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/sample/peer.py +0 -0
  293. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/sample/program.py +0 -0
  294. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/schemas.py +0 -0
  295. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/subprocess/__init__.py +0 -0
  296. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/subprocess/interface.py +0 -0
  297. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/subprocess/peer.py +0 -0
  298. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/subprocess/program.py +0 -0
  299. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/subprocess/protocol.py +0 -0
  300. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/task/__init__.py +0 -0
  301. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/task/asynchronous.py +0 -0
  302. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/task/basic/__init__.py +0 -0
  303. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/task/basic/manager.py +0 -0
  304. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/task/sample.py +0 -0
  305. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/task/trig/__init__.py +0 -0
  306. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/telemetry/__init__.py +0 -0
  307. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/telemetry/sample.py +0 -0
  308. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/tui/__init__.py +0 -0
  309. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/tui/channels/__init__.py +0 -0
  310. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/tui/cursor.py +0 -0
  311. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/tui/mixin.py +0 -0
  312. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/tui/mock.py +0 -0
  313. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/tui/task.py +0 -0
  314. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/ui/__init__.py +0 -0
  315. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/ui/controls.py +0 -0
  316. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy/util.py +0 -0
  317. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy.egg-info/dependency_links.txt +0 -0
  318. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy.egg-info/entry_points.txt +0 -0
  319. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy.egg-info/requires.txt +2 -2
  320. {runtimepy-5.15.2 → runtimepy-5.15.4}/runtimepy.egg-info/top_level.txt +0 -0
  321. {runtimepy-5.15.2 → runtimepy-5.15.4}/setup.cfg +0 -0
  322. {runtimepy-5.15.2 → runtimepy-5.15.4}/setup.py +0 -0
  323. {runtimepy-5.15.2 → runtimepy-5.15.4}/tests/test_entry.py +0 -0
  324. {runtimepy-5.15.2 → runtimepy-5.15.4}/tests/test_mapping.py +0 -0
  325. {runtimepy-5.15.2 → runtimepy-5.15.4}/tests/test_resources.py +0 -0
  326. {runtimepy-5.15.2 → runtimepy-5.15.4}/tests/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runtimepy
3
- Version: 5.15.2
3
+ Version: 5.15.4
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/libre-embedded/runtimepy
6
6
  Author: Libre Embedded
@@ -17,11 +17,11 @@ Classifier: Development Status :: 5 - Production/Stable
17
17
  Requires-Python: >=3.12
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
+ Requires-Dist: vcorelib>=3.6.3
21
+ Requires-Dist: websockets
20
22
  Requires-Dist: svgen>=0.8.0
21
23
  Requires-Dist: aiofiles
22
24
  Requires-Dist: psutil
23
- Requires-Dist: vcorelib>=3.6.3
24
- Requires-Dist: websockets
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint; extra == "test"
27
27
  Requires-Dist: flake8; extra == "test"
@@ -51,11 +51,11 @@ Dynamic: requires-python
51
51
  =====================================
52
52
  generator=datazen
53
53
  version=3.2.3
54
- hash=f1c75c9b812e8ff29fdda46f58009aef
54
+ hash=99eea1986d2105483ebb2fe566128f5f
55
55
  =====================================
56
56
  -->
57
57
 
58
- # runtimepy ([5.15.2](https://pypi.org/project/runtimepy/))
58
+ # runtimepy ([5.15.4](https://pypi.org/project/runtimepy/))
59
59
 
60
60
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
61
61
  ![Build Status](https://github.com/libre-embedded/runtimepy/workflows/Python%20Package/badge.svg)
@@ -2,11 +2,11 @@
2
2
  =====================================
3
3
  generator=datazen
4
4
  version=3.2.3
5
- hash=f1c75c9b812e8ff29fdda46f58009aef
5
+ hash=99eea1986d2105483ebb2fe566128f5f
6
6
  =====================================
7
7
  -->
8
8
 
9
- # runtimepy ([5.15.2](https://pypi.org/project/runtimepy/))
9
+ # runtimepy ([5.15.4](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/libre-embedded/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.15.2"
7
+ version = "5.15.4"
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.2.3
4
- # hash=839ec3c3fa52de16f775789c0d38bf3e
4
+ # hash=b0f0463a508c9a1312a071f5c0b06f3b
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.15.2"
13
+ VERSION = "5.15.4"
14
14
 
15
15
  # runtimepy-specific content.
16
16
  METRICS_NAME = "metrics"
@@ -54,6 +54,7 @@ class BaseChannelEnvironment(_NamespaceMixin, FinalizeMixin):
54
54
  fields: _Iterable[_BitFields] = None,
55
55
  namespace: Namespace = None,
56
56
  namespace_delim: str = DEFAULT_DELIM,
57
+ views: dict[str, str] = None,
57
58
  ) -> None:
58
59
  """Initialize this channel environment."""
59
60
 
@@ -105,6 +106,10 @@ class BaseChannelEnvironment(_NamespaceMixin, FinalizeMixin):
105
106
  if values is not None:
106
107
  self.apply(values)
107
108
 
109
+ if not views:
110
+ views = {}
111
+ self.views = views
112
+
108
113
  def __setitem__(self, key: _RegistryKey, value: ChannelValue) -> None:
109
114
  """Mapping-set interface."""
110
115
  return self.set(key, value)
@@ -12,7 +12,9 @@ from typing import Any, Iterator, Optional, cast
12
12
 
13
13
  # third-party
14
14
  from vcorelib import DEFAULT_ENCODING
15
+ from vcorelib.dict import GenericStrDict
15
16
  from vcorelib.io import ARBITER, JsonObject
17
+ from vcorelib.io.bus import BUS
16
18
  from vcorelib.logging import DEFAULT_TIME_FORMAT, LoggerMixin
17
19
  from vcorelib.math import default_time_ns, nano_str
18
20
  from vcorelib.names import name_search
@@ -25,6 +27,7 @@ from runtimepy.channel.environment.command.processor import (
25
27
  CommandHook,
26
28
  EnvironmentMap,
27
29
  )
30
+ from runtimepy.channel.environment.command.result import CommandResult
28
31
  from runtimepy.channel.registry import ParsedEvent
29
32
  from runtimepy.mapping import DEFAULT_PATTERN
30
33
 
@@ -243,6 +246,38 @@ GLOBAL = GlobalEnvironment()
243
246
  ENVIRONMENTS = GLOBAL
244
247
 
245
248
 
249
+ def global_command(env: str, value: str) -> Optional[CommandResult]:
250
+ """Handle a global command."""
251
+
252
+ result = None
253
+ if env in GLOBAL:
254
+ result = GLOBAL[env].command(value)
255
+ else:
256
+ GLOBAL.logger.error(
257
+ "Couldn't run command env='%s' value='%s'.", env, value
258
+ )
259
+ return result
260
+
261
+
262
+ def global_commands(*cmds: tuple[str, str]) -> None:
263
+ """Handle a global command."""
264
+ for env, value in cmds:
265
+ global_command(env, value)
266
+
267
+
268
+ async def global_command_bus(payload: GenericStrDict) -> None:
269
+ """Handle a bus message."""
270
+
271
+ if "env" in payload and "value" in payload:
272
+ global_command(payload["env"], payload["value"])
273
+ elif "cmds" in payload:
274
+ global_commands(*payload["cmds"])
275
+
276
+
277
+ BUS.register_ro("command", global_command_bus)
278
+ BUS.register_ro("cmd", global_command_bus)
279
+
280
+
246
281
  def clear_env() -> None:
247
282
  """Reset the global environment mapping."""
248
283
  GLOBAL.clear()
@@ -42,6 +42,8 @@ ENUMS_FILE = f"{ENUMS_KEY}.json"
42
42
  VALUES_FILE = f"{VALUES_KEY}.json"
43
43
  FIELDS_FILE = f"{FIELDS_KEY}.json"
44
44
  NAMES_FILE = f"{NAMES_KEY}.json"
45
+ VIEWS_KEY = "views"
46
+ # VIEWS_FILE = f"{VIEWS_KEY}.json"
45
47
 
46
48
 
47
49
  class FileChannelEnvironment(_BaseChannelEnvironment):
@@ -64,6 +66,7 @@ class FileChannelEnvironment(_BaseChannelEnvironment):
64
66
  VALUES_KEY: _cast(
65
67
  _JsonObject, self.values(resolve_enum=resolve_enum)
66
68
  ),
69
+ VIEWS_KEY: _cast(_JsonObject, self.views),
67
70
  }
68
71
 
69
72
  def export(
@@ -143,6 +146,7 @@ class FileChannelEnvironment(_BaseChannelEnvironment):
143
146
  enums=enum_reg,
144
147
  values=_cast(_Optional[_ValueMap], data.get(VALUES_KEY)),
145
148
  fields=_fields_from_dict(data[FIELDS_KEY]),
149
+ views=_cast(dict[str, str], data.get(VIEWS_KEY, {})),
146
150
  )
147
151
 
148
152
  # Typically, externally loaded environments should be final at load
@@ -9,6 +9,9 @@ tasks:
9
9
  a: 1
10
10
  b: 2
11
11
  c: 3
12
+ views:
13
+ - [zero, "\\.0\\."]
14
+ - [one, "\\.1\\."]
12
15
  markdown: |
13
16
  # This is a Test
14
17
 
@@ -29,6 +32,9 @@ tasks:
29
32
  - name: wave3
30
33
  factory: sinusoid
31
34
  period_s: 0.03
35
+ config:
36
+ views:
37
+ - [trig, sin cos]
32
38
  markdown: |
33
39
  # Markdown for wave3
34
40
 
@@ -50,6 +56,10 @@ clients:
50
56
  defer: true
51
57
  kwargs:
52
58
  remote_addr: [localhost, "$udp_json"]
59
+ views:
60
+ - [metrics, metrics]
61
+ - [transmit, tx]
62
+ - [receive, rx]
53
63
  markdown: |
54
64
  # `udp_json_client`
55
65
 
@@ -107,3 +117,7 @@ processes:
107
117
  app: runtimepy.sample.program.run
108
118
 
109
119
  program: runtimepy.sample.program.SampleProgram
120
+
121
+ commands:
122
+ - [udp_json_client, "set log_level warning"]
123
+ - [proc1.peer, "set log_level warning"]
@@ -56,6 +56,10 @@ class ChannelTable {
56
56
 
57
57
  if (Number.isInteger(val)) {
58
58
  /* Handle integer formatting. */
59
+ } else if (typeof val == "boolean") {
60
+ /* Use glyphs for booleans. */
61
+ val = val ? '<i class="bi bi-circle-fill"></i>'
62
+ : '<i class="bi bi-circle"></i>';
59
63
  } else {
60
64
  /* Handle floating-point numbers. */
61
65
  let checkFloat = Number.parseFloat(val);
@@ -263,6 +263,19 @@ class TabInterface {
263
263
  this.updateChannelStyles(this.channelFilter.value);
264
264
  };
265
265
  }
266
+
267
+ /* Initialize channel view dropdown. */
268
+ let channelView = this.query("#filter-view");
269
+ if (channelView) {
270
+ channelView.onchange = () => {
271
+ if (!channelView.value || channelView.value == '-') {
272
+ this.channelFilter.value = "";
273
+ } else {
274
+ this.channelFilter.value = channelView.value;
275
+ }
276
+ this.updateChannelStyles(this.channelFilter.value);
277
+ };
278
+ }
266
279
  }
267
280
 
268
281
  setHandler(elem) {
@@ -53,8 +53,10 @@ function isModifierKeyEvent(event) {
53
53
  }
54
54
 
55
55
  function ignoreFilterKeyEvent(event) {
56
- // home end pg up pg down delete f keys
57
- return isModifierKeyEvent(event) || event.key == "Tab";
56
+ return isModifierKeyEvent(event) || event.key == "Tab" ||
57
+ (event.key.startsWith("F") && event.key.length > 1) ||
58
+ event.key.startsWith("Del") || event.key == "Home" ||
59
+ event.key == "End" || event.key == "PageUp" || event.key == "PageDown";
58
60
  }
59
61
 
60
62
  function globalKeyEvent(event) {
@@ -3,6 +3,7 @@ includes:
3
3
  - has_factory.yaml
4
4
  - has_name.yaml
5
5
  - has_markdown.yaml
6
+ - has_views.yaml
6
7
 
7
8
  properties:
8
9
  defer:
@@ -26,6 +26,9 @@ properties:
26
26
  items:
27
27
  $ref: package://runtimepy/schemas/StructConfig.yaml
28
28
 
29
+ commands:
30
+ $ref: package://runtimepy/schemas/TwoTupleArray.yaml
31
+
29
32
  tasks:
30
33
  type: array
31
34
  items:
@@ -4,6 +4,7 @@ includes:
4
4
  - has_name.yaml
5
5
  - has_config.yaml
6
6
  - has_markdown.yaml
7
+ - has_views.yaml
7
8
 
8
9
  properties:
9
10
  program:
@@ -0,0 +1,9 @@
1
+ ---
2
+ type: array
3
+ items:
4
+ type: array
5
+ minItems: 2
6
+ maxItems: 2
7
+ items:
8
+ - type: string
9
+ - type: string
@@ -0,0 +1,4 @@
1
+ ---
2
+ properties:
3
+ views:
4
+ $ref: package://runtimepy/schemas/TwoTupleArray.yaml
@@ -26,6 +26,7 @@ from vcorelib.namespace import NamespaceMixin as _NamespaceMixin
26
26
  from runtimepy.channel.environment.command import (
27
27
  clear_env,
28
28
  env_json_data,
29
+ global_commands,
29
30
  register_env,
30
31
  )
31
32
  from runtimepy.net.arbiter.housekeeping import housekeeping
@@ -145,6 +146,9 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
145
146
  # A copy of named port mappings (loaded via external config).
146
147
  self._ports: dict[str, int] = {}
147
148
 
149
+ self._commands: list[tuple[str, str]] = []
150
+ self._views: dict[str, dict[str, str]] = {}
151
+
148
152
  self._init()
149
153
 
150
154
  def _init(self) -> None:
@@ -153,6 +157,9 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
153
157
  def _register_connection(self, connection: _Connection, name: str) -> None:
154
158
  """Perform connection registration."""
155
159
 
160
+ if name in self._views:
161
+ connection.env.views.update(self._views[name])
162
+ del self._views[name]
156
163
  self._connections[name] = connection
157
164
  self.manager.queue.put_nowait(connection)
158
165
  connection.logger.info("Registered as '%s'.", name)
@@ -162,6 +169,7 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
162
169
  connection: _Union[_Connection, _Awaitable[_Connection]],
163
170
  *names: str,
164
171
  delim: str = None,
172
+ views: dict[str, str] = None,
165
173
  ) -> bool:
166
174
  """Attempt to register a connection object."""
167
175
 
@@ -170,6 +178,9 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
170
178
  with self.names_pushed(*names):
171
179
  name = self.namespace(delim=delim)
172
180
 
181
+ if views:
182
+ self._views[name] = views
183
+
173
184
  if (
174
185
  name not in self._connections
175
186
  and name not in self._deferred_connections
@@ -318,6 +329,11 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
318
329
 
319
330
  # Run initialization methods.
320
331
  result = await self._run_apps_list(self._inits, info)
332
+
333
+ # Run commands.
334
+ await _asyncio.sleep(0)
335
+ global_commands(*self._commands)
336
+
321
337
  if result == 0:
322
338
  # Get application methods.
323
339
  apps = self._apps
@@ -170,7 +170,6 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
170
170
  kwargs = dict_resolve_env_vars(
171
171
  client.get("kwargs", {}), env=self._ports # type: ignore
172
172
  )
173
- kwargs.setdefault("markdown", client.get("markdown"))
174
173
 
175
174
  assert await self.factory_client(
176
175
  factory,
@@ -179,6 +178,8 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
179
178
  defer=client["defer"],
180
179
  # Perform some known fixes for common keyword arguments.
181
180
  **fix_kwargs(kwargs),
181
+ views=client.get("views"),
182
+ markdown=client.get("markdown"),
182
183
  ), f"Couldn't register client '{name}' ({factory})!"
183
184
 
184
185
  # Register servers.
@@ -245,5 +246,8 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
245
246
  assert "root" not in config.config, config.config
246
247
  config.config["root"] = root
247
248
 
249
+ # Register commands.
250
+ self._commands = config.commands
251
+
248
252
 
249
253
  ConfigConnectionArbiter.add_search_package(PKG_NAME)
@@ -71,6 +71,11 @@ class ConnectionArbiterConfig(_RuntimepyDictCodec):
71
71
 
72
72
  self.directory = _Path(str(data.get("directory", ".")))
73
73
 
74
+ self.commands: list[tuple[str, str]] = data.get( # type: ignore
75
+ "commands",
76
+ [],
77
+ )
78
+
74
79
  def asdict(self) -> _JsonObject:
75
80
  """Obtain a dictionary representing this instance."""
76
81
  return self.data
@@ -89,12 +89,17 @@ class FactoryConnectionArbiter(_BaseConnectionArbiter):
89
89
  if factory in self._conn_factories:
90
90
  factory_inst = self._conn_factories[factory]
91
91
 
92
+ views = kwargs.pop("views", {})
93
+
92
94
  conn = factory_inst.client(name, *args, **kwargs)
93
95
  if not defer:
94
96
  conn = await conn # type: ignore
95
97
 
96
98
  result = self.register_connection(
97
- conn, *self._conn_names[factory_inst], name
99
+ conn,
100
+ *self._conn_names[factory_inst],
101
+ name,
102
+ views=views,
98
103
  )
99
104
 
100
105
  return result
@@ -18,7 +18,7 @@ from vcorelib.paths import Pathlike, find_file, normalize
18
18
 
19
19
  # internal
20
20
  from runtimepy import DEFAULT_EXT, PKG_NAME
21
- from runtimepy.channel.environment.command import GLOBAL
21
+ from runtimepy.channel.environment.command import GLOBAL, global_command
22
22
  from runtimepy.net.html import full_markdown_page
23
23
  from runtimepy.net.http.header import RequestHeader
24
24
  from runtimepy.net.http.request_target import PathMaybeQuery
@@ -270,17 +270,22 @@ class RuntimepyServerConnection(HttpConnection):
270
270
  response_data["success"] = False
271
271
  response_data["message"] = "No command executed."
272
272
 
273
- if not args or args[0] not in GLOBAL:
273
+ def cmd_usage() -> None:
274
+ """Set usage information for the response."""
274
275
  response_data["usage"] = (
275
276
  "/<environment (arg0)>/<arg1>[/.../<argN>]"
276
277
  )
277
278
  response_data["environments"] = list(GLOBAL)
278
279
 
279
- # Run command.
280
+ if args:
281
+ result = global_command(args[0], " ".join(args[1:]))
282
+ if result is None:
283
+ cmd_usage()
284
+ else:
285
+ response_data["success"] = result.success
286
+ response_data["message"] = str(result)
280
287
  else:
281
- result = GLOBAL[args[0]].command(" ".join(args[1:]))
282
- response_data["success"] = result.success
283
- response_data["message"] = str(result)
288
+ cmd_usage()
284
289
 
285
290
  # Send response.
286
291
  encode_json(stream, response, response_data)
@@ -80,6 +80,21 @@ def enum_dropdown(
80
80
  TABLE_BUTTON_CLASSES = ("border-top-0", "border-bottom-0")
81
81
 
82
82
 
83
+ def views_dropdown(parent: Element, command: ChannelCommandProcessor) -> None:
84
+ """Dropdown menu for channel environment views."""
85
+
86
+ select = select_element(
87
+ parent=div(tag="th", parent=parent, class_str="p-0"),
88
+ id="filter-view",
89
+ title="Canonical channel filters.",
90
+ ).add_class("border-end-0", "w-100")
91
+ div(tag="option", value="", text="-", parent=select)
92
+ for text, value in command.env.views.items():
93
+ div(tag="option", value=value, text=text, parent=select)
94
+ if not command.env.views:
95
+ select.booleans.add("disabled")
96
+
97
+
83
98
  def channel_table_header(
84
99
  parent: Element, command: ChannelCommandProcessor
85
100
  ) -> None:
@@ -105,7 +120,7 @@ def channel_table_header(
105
120
  ).add_class(*TABLE_BUTTON_CLASSES)
106
121
 
107
122
  _, label, box = input_box(
108
- div(tag="th", parent=ctl_row, colspan="2", class_str="p-0"),
123
+ div(tag="th", parent=ctl_row, class_str="p-0 border-end-0"),
109
124
  description="Channel name filter.",
110
125
  pattern=".* ! @ $",
111
126
  label="filter",
@@ -114,17 +129,18 @@ def channel_table_header(
114
129
  spellcheck="false",
115
130
  )
116
131
  label.add_class("border-top-0", "border-bottom-0")
117
- box.add_class("border-top-0", "border-bottom-0")
132
+ box.add_class("border-top-0", "border-bottom-0", "border-end-0")
133
+
134
+ views_dropdown(ctl_row, command)
118
135
 
119
136
  cell = flex(
120
137
  parent=div(tag="th", parent=ctl_row, colspan="2", class_str="p-0")
121
138
  )
122
139
 
123
- # Add a selection menu for custom commands.
140
+ # Add a selection menu for custom commands. (need a data source for this)
124
141
  select = select_element(
125
142
  parent=cell, id="custom-commands", title="Custom command selector."
126
143
  )
127
- select.add_class("border-start-0")
128
144
 
129
145
  if command.custom_commands:
130
146
  for key in command.custom_commands:
@@ -45,6 +45,7 @@ class RuntimeStructBase(
45
45
  self.set_markdown(config=config, markdown=markdown, package=PKG_NAME)
46
46
  LoggerMixinLevelControl.__init__(self, logger=_getLogger(self.name))
47
47
  ChannelEnvironmentMixin.__init__(self)
48
+ self.env.views.update(config.get("views", {})) # type: ignore
48
49
  if self.log_level_channel:
49
50
  self.setup_level_channel(self.env)
50
51
  self.command = ChannelCommandProcessor(self.env, self.logger)
@@ -72,6 +72,7 @@ class PeriodicTask(
72
72
  self.metrics = metrics
73
73
 
74
74
  ChannelEnvironmentMixin.__init__(self, env=env)
75
+ self.env.views.update(self.config.get("views", {})) # type: ignore
75
76
  self.setup_level_channel(self.env)
76
77
  self.command = ChannelCommandProcessor(self.env, self.logger)
77
78
  self.register_task_metrics(self.metrics)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runtimepy
3
- Version: 5.15.2
3
+ Version: 5.15.4
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/libre-embedded/runtimepy
6
6
  Author: Libre Embedded
@@ -17,11 +17,11 @@ Classifier: Development Status :: 5 - Production/Stable
17
17
  Requires-Python: >=3.12
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
+ Requires-Dist: vcorelib>=3.6.3
21
+ Requires-Dist: websockets
20
22
  Requires-Dist: svgen>=0.8.0
21
23
  Requires-Dist: aiofiles
22
24
  Requires-Dist: psutil
23
- Requires-Dist: vcorelib>=3.6.3
24
- Requires-Dist: websockets
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint; extra == "test"
27
27
  Requires-Dist: flake8; extra == "test"
@@ -51,11 +51,11 @@ Dynamic: requires-python
51
51
  =====================================
52
52
  generator=datazen
53
53
  version=3.2.3
54
- hash=f1c75c9b812e8ff29fdda46f58009aef
54
+ hash=99eea1986d2105483ebb2fe566128f5f
55
55
  =====================================
56
56
  -->
57
57
 
58
- # runtimepy ([5.15.2](https://pypi.org/project/runtimepy/))
58
+ # runtimepy ([5.15.4](https://pypi.org/project/runtimepy/))
59
59
 
60
60
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
61
61
  ![Build Status](https://github.com/libre-embedded/runtimepy/workflows/Python%20Package/badge.svg)
@@ -114,12 +114,14 @@ runtimepy/data/schemas/RuntimeEnum.yaml
114
114
  runtimepy/data/schemas/ServerConnectionConfig.yaml
115
115
  runtimepy/data/schemas/StructConfig.yaml
116
116
  runtimepy/data/schemas/TaskConfig.yaml
117
+ runtimepy/data/schemas/TwoTupleArray.yaml
117
118
  runtimepy/data/schemas/channel_controls.yaml
118
119
  runtimepy/data/schemas/has_config.yaml
119
120
  runtimepy/data/schemas/has_factory.yaml
120
121
  runtimepy/data/schemas/has_markdown.yaml
121
122
  runtimepy/data/schemas/has_name.yaml
122
123
  runtimepy/data/schemas/has_request_flag.yaml
124
+ runtimepy/data/schemas/has_views.yaml
123
125
  runtimepy/data/static/css/bootstrap-icons.min.css
124
126
  runtimepy/data/static/css/bootstrap.min.css
125
127
  runtimepy/data/static/css/fonts/bootstrap-icons.woff
File without changes
File without changes