runtimepy 5.6.3__tar.gz → 5.7.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 (288) hide show
  1. {runtimepy-5.6.3/runtimepy.egg-info → runtimepy-5.7.0}/PKG-INFO +8 -7
  2. {runtimepy-5.6.3 → runtimepy-5.7.0}/README.md +2 -2
  3. {runtimepy-5.6.3 → runtimepy-5.7.0}/pyproject.toml +3 -3
  4. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/__init__.py +2 -2
  5. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/command/__init__.py +1 -1
  6. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/telemetry.py +3 -1
  7. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/css/bootstrap_extra.css +13 -3
  8. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/css/main.css +4 -1
  9. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/dummy_load.yaml +34 -1
  10. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/WindowHashManager.js +29 -7
  11. runtimepy-5.7.0/runtimepy/data/md/Connection.md +3 -0
  12. runtimepy-5.7.0/runtimepy/data/md/PeriodicTask.md +3 -0
  13. runtimepy-5.7.0/runtimepy/data/md/RuntimeStruct.md +3 -0
  14. runtimepy-5.7.0/runtimepy/data/md/RuntimepyPeer.md +3 -0
  15. runtimepy-5.7.0/runtimepy/data/md/SinusoidTask.md +20 -0
  16. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/ClientConnectionConfig.yaml +1 -0
  17. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/PeerProcessConfig.yaml +1 -0
  18. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/TaskConfig.yaml +1 -0
  19. runtimepy-5.7.0/runtimepy/data/schemas/has_markdown.yaml +4 -0
  20. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mapping.py +1 -1
  21. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/message/interface.py +2 -2
  22. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/environment.py +10 -4
  23. runtimepy-5.7.0/runtimepy/mixins/logging.py +110 -0
  24. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/base.py +13 -3
  25. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/config/__init__.py +6 -2
  26. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/imports/__init__.py +5 -5
  27. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/imports/util.py +3 -1
  28. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/connection.py +7 -1
  29. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/http/common.py +5 -0
  30. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/http/header.py +5 -1
  31. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/http/response.py +1 -1
  32. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/__init__.py +3 -1
  33. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/bootstrap/elements.py +38 -1
  34. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/bootstrap/tabs.py +12 -3
  35. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/__init__.py +74 -20
  36. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/modal.py +1 -1
  37. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/settings.py +2 -2
  38. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/tab/base.py +5 -1
  39. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/tab/html.py +8 -8
  40. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/placeholder.py +1 -1
  41. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/sound.py +1 -1
  42. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/struct/__init__.py +1 -2
  43. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/websocket/state.py +3 -1
  44. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/connection.py +14 -4
  45. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/http/__init__.py +9 -7
  46. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/connection.py +11 -4
  47. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/tftp/__init__.py +1 -2
  48. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/websocket/connection.py +10 -5
  49. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/requirements.txt +2 -1
  50. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/struct/__init__.py +12 -2
  51. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/subprocess/interface.py +17 -4
  52. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/subprocess/peer.py +20 -6
  53. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/task/basic/periodic.py +7 -1
  54. runtimepy-5.7.0/runtimepy/util.py +18 -0
  55. {runtimepy-5.6.3 → runtimepy-5.7.0/runtimepy.egg-info}/PKG-INFO +8 -7
  56. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy.egg-info/SOURCES.txt +6 -0
  57. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy.egg-info/requires.txt +3 -2
  58. {runtimepy-5.6.3 → runtimepy-5.7.0}/setup.py +2 -2
  59. runtimepy-5.6.3/runtimepy/mixins/logging.py +0 -57
  60. runtimepy-5.6.3/runtimepy/util.py +0 -99
  61. {runtimepy-5.6.3 → runtimepy-5.7.0}/LICENSE +0 -0
  62. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/__main__.py +0 -0
  63. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/app.py +0 -0
  64. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/__init__.py +0 -0
  65. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/__init__.py +0 -0
  66. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/array.py +0 -0
  67. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/base.py +0 -0
  68. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/command/parser.py +0 -0
  69. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/command/processor.py +0 -0
  70. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/command/result.py +0 -0
  71. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/create.py +0 -0
  72. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/file.py +0 -0
  73. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/environment/sample.py +0 -0
  74. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/event/__init__.py +0 -0
  75. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/event/header.py +0 -0
  76. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/channel/registry.py +0 -0
  77. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/codec/__init__.py +0 -0
  78. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/codec/protocol/__init__.py +0 -0
  79. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/codec/protocol/base.py +0 -0
  80. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/codec/protocol/json.py +0 -0
  81. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/codec/system/__init__.py +0 -0
  82. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/__init__.py +0 -0
  83. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/all.py +0 -0
  84. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/arbiter.py +0 -0
  85. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/common.py +0 -0
  86. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/mtu.py +0 -0
  87. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/server.py +0 -0
  88. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/task.py +0 -0
  89. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/tftp.py +0 -0
  90. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/commands/tui.py +0 -0
  91. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/control/__init__.py +0 -0
  92. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/control/env/__init__.py +0 -0
  93. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/control/source.py +0 -0
  94. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/control/step.py +0 -0
  95. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/browser.yaml +0 -0
  96. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/factories.yaml +0 -0
  97. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/favicon.ico +0 -0
  98. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/DataConnection.js +0 -0
  99. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/JsonConnection.js +0 -0
  100. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/audio.js +0 -0
  101. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/App.js +0 -0
  102. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/ChannelTable.js +0 -0
  103. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/DataConnection.js +0 -0
  104. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/JsonConnection.js +0 -0
  105. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/OverlayManager.js +0 -0
  106. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/Plot.js +0 -0
  107. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
  108. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/PlotManager.js +0 -0
  109. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
  110. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/PointBuffer.js +0 -0
  111. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/PointManager.js +0 -0
  112. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/TabFilter.js +0 -0
  113. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/TabInterface.js +0 -0
  114. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/UnitSystem.js +0 -0
  115. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/classes/WorkerInterface.js +0 -0
  116. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/events.js +0 -0
  117. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/init.js +0 -0
  118. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/main.js +0 -0
  119. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/tab/env.js +0 -0
  120. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/tab/sound.js +0 -0
  121. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
  122. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/unused/pyodide.js +0 -0
  123. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/util.js +0 -0
  124. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/js/worker.js +0 -0
  125. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/sample_telemetry.yaml +0 -0
  126. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/BitFields.yaml +0 -0
  127. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/Channel.yaml +0 -0
  128. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
  129. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
  130. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +0 -0
  131. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
  132. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/FindFile.yaml +0 -0
  133. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
  134. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
  135. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/StructConfig.yaml +0 -0
  136. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/channel_controls.yaml +0 -0
  137. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/has_config.yaml +0 -0
  138. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/has_factory.yaml +0 -0
  139. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/has_name.yaml +0 -0
  140. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
  141. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/server.yaml +0 -0
  142. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/server_base.yaml +0 -0
  143. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/server_dev.yaml +0 -0
  144. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/data/tftp_server.yaml +0 -0
  145. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/dev_requirements.txt +0 -0
  146. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/entry.py +0 -0
  147. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/enum/__init__.py +0 -0
  148. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/enum/registry.py +0 -0
  149. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/enum/types.py +0 -0
  150. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/message/__init__.py +0 -0
  151. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/message/handlers.py +0 -0
  152. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/message/types.py +0 -0
  153. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/metrics/__init__.py +0 -0
  154. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/metrics/channel.py +0 -0
  155. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/metrics/connection.py +0 -0
  156. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/metrics/task.py +0 -0
  157. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/__init__.py +0 -0
  158. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/async_command.py +0 -0
  159. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/enum.py +0 -0
  160. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/finalize.py +0 -0
  161. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/psutil.py +0 -0
  162. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/regex.py +0 -0
  163. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/mixins/trig.py +0 -0
  164. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/__init__.py +0 -0
  165. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/apps/__init__.py +0 -0
  166. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/__init__.py +0 -0
  167. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/config/codec.py +0 -0
  168. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/config/util.py +0 -0
  169. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/factory/__init__.py +0 -0
  170. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/factory/connection.py +0 -0
  171. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/factory/task.py +0 -0
  172. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
  173. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/info.py +0 -0
  174. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/result.py +0 -0
  175. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/struct/__init__.py +0 -0
  176. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/task.py +0 -0
  177. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
  178. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/tcp/json.py +0 -0
  179. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/udp.py +0 -0
  180. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/arbiter/websocket.py +0 -0
  181. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/backoff.py +0 -0
  182. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/factories/__init__.py +0 -0
  183. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/http/__init__.py +0 -0
  184. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/http/request_target.py +0 -0
  185. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/http/state.py +0 -0
  186. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/http/version.py +0 -0
  187. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/manager.py +0 -0
  188. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/mixin.py +0 -0
  189. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/mtu.py +0 -0
  190. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/__init__.py +0 -0
  191. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/base.py +0 -0
  192. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/bootstrap/__init__.py +0 -0
  193. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/create.py +0 -0
  194. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/elements.py +0 -0
  195. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
  196. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/tab/controls.py +0 -0
  197. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/tab/message.py +0 -0
  198. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/env/widgets.py +0 -0
  199. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/files.py +0 -0
  200. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/landing_page.py +0 -0
  201. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/pyodide.py +0 -0
  202. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/app/tab.py +0 -0
  203. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/html.py +0 -0
  204. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/json.py +0 -0
  205. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/server/websocket/__init__.py +0 -0
  206. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/ssl.py +0 -0
  207. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/stream/__init__.py +0 -0
  208. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/stream/base.py +0 -0
  209. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/stream/json/__init__.py +0 -0
  210. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/stream/string.py +0 -0
  211. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/__init__.py +0 -0
  212. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/create.py +0 -0
  213. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/protocol.py +0 -0
  214. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/scpi/__init__.py +0 -0
  215. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/telnet/__init__.py +0 -0
  216. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/telnet/codes.py +0 -0
  217. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
  218. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/__init__.py +0 -0
  219. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/create.py +0 -0
  220. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/protocol.py +0 -0
  221. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/queue.py +0 -0
  222. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/tftp/base.py +0 -0
  223. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/tftp/endpoint.py +0 -0
  224. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/tftp/enums.py +0 -0
  225. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/udp/tftp/io.py +0 -0
  226. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/util.py +0 -0
  227. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/net/websocket/__init__.py +0 -0
  228. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/noise/__init__.py +0 -0
  229. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/__init__.py +0 -0
  230. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/array/__init__.py +0 -0
  231. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/base.py +0 -0
  232. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/bool.py +0 -0
  233. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/byte_order.py +0 -0
  234. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/evaluation.py +0 -0
  235. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/field/__init__.py +0 -0
  236. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/field/fields.py +0 -0
  237. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/field/manager/__init__.py +0 -0
  238. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/field/manager/base.py +0 -0
  239. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/float.py +0 -0
  240. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/int.py +0 -0
  241. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/scaling.py +0 -0
  242. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/serializable/__init__.py +0 -0
  243. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/serializable/base.py +0 -0
  244. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/serializable/fixed.py +0 -0
  245. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/serializable/framer.py +0 -0
  246. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/serializable/prefixed.py +0 -0
  247. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/string.py +0 -0
  248. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/types/__init__.py +0 -0
  249. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/types/base.py +0 -0
  250. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/types/bool.py +0 -0
  251. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/types/bounds.py +0 -0
  252. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/types/float.py +0 -0
  253. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/primitives/types/int.py +0 -0
  254. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/py.typed +0 -0
  255. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/registry/__init__.py +0 -0
  256. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/registry/bool.py +0 -0
  257. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/registry/item.py +0 -0
  258. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/registry/name.py +0 -0
  259. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/sample/__init__.py +0 -0
  260. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/sample/peer.py +0 -0
  261. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/sample/program.py +0 -0
  262. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/schemas.py +0 -0
  263. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/subprocess/__init__.py +0 -0
  264. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/subprocess/program.py +0 -0
  265. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/subprocess/protocol.py +0 -0
  266. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/task/__init__.py +0 -0
  267. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/task/asynchronous.py +0 -0
  268. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/task/basic/__init__.py +0 -0
  269. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/task/basic/manager.py +0 -0
  270. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/task/sample.py +0 -0
  271. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/task/trig/__init__.py +0 -0
  272. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/telemetry/__init__.py +0 -0
  273. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/telemetry/sample.py +0 -0
  274. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/tui/__init__.py +0 -0
  275. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/tui/channels/__init__.py +0 -0
  276. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/tui/cursor.py +0 -0
  277. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/tui/mixin.py +0 -0
  278. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/tui/mock.py +0 -0
  279. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/tui/task.py +0 -0
  280. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/ui/__init__.py +0 -0
  281. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy/ui/controls.py +0 -0
  282. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy.egg-info/dependency_links.txt +0 -0
  283. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy.egg-info/entry_points.txt +0 -0
  284. {runtimepy-5.6.3 → runtimepy-5.7.0}/runtimepy.egg-info/top_level.txt +0 -0
  285. {runtimepy-5.6.3 → runtimepy-5.7.0}/setup.cfg +0 -0
  286. {runtimepy-5.6.3 → runtimepy-5.7.0}/tests/test_entry.py +0 -0
  287. {runtimepy-5.6.3 → runtimepy-5.7.0}/tests/test_mapping.py +0 -0
  288. {runtimepy-5.6.3 → runtimepy-5.7.0}/tests/test_resources.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runtimepy
3
- Version: 5.6.3
3
+ Version: 5.7.0
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/vkottler/runtimepy
6
6
  Author: Vaughn Kottler
7
- Author-email: Vaughn Kottler <vaughnkottler@gmail.com>
8
- Maintainer-email: Vaughn Kottler <vaughnkottler@gmail.com>
7
+ Author-email: Vaughn Kottler <vaughn@libre-embedded.com>
8
+ Maintainer-email: Vaughn Kottler <vaughn@libre-embedded.com>
9
9
  Classifier: Programming Language :: Python :: 3.11
10
10
  Classifier: Programming Language :: Python :: 3.12
11
11
  Classifier: Operating System :: Microsoft :: Windows
@@ -17,10 +17,11 @@ Classifier: License :: OSI Approved :: MIT License
17
17
  Requires-Python: >=3.11
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: vcorelib>=3.3.1
20
+ Requires-Dist: vcorelib>=3.4.2
21
21
  Requires-Dist: svgen>=0.6.8
22
- Requires-Dist: psutil
23
22
  Requires-Dist: websockets
23
+ Requires-Dist: aiofiles
24
+ Requires-Dist: psutil
24
25
  Provides-Extra: test
25
26
  Requires-Dist: pylint; extra == "test"
26
27
  Requires-Dist: flake8; extra == "test"
@@ -44,11 +45,11 @@ Requires-Dist: uvloop; (sys_platform != "win32" and sys_platform != "cygwin") an
44
45
  =====================================
45
46
  generator=datazen
46
47
  version=3.1.4
47
- hash=ac4d0a4097094aeb4e3f43c5f1128115
48
+ hash=aa59dcef7f11c767458b14ad97f9de59
48
49
  =====================================
49
50
  -->
50
51
 
51
- # runtimepy ([5.6.3](https://pypi.org/project/runtimepy/))
52
+ # runtimepy ([5.7.0](https://pypi.org/project/runtimepy/))
52
53
 
53
54
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
54
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=ac4d0a4097094aeb4e3f43c5f1128115
5
+ hash=aa59dcef7f11c767458b14ad97f9de59
6
6
  =====================================
7
7
  -->
8
8
 
9
- # runtimepy ([5.6.3](https://pypi.org/project/runtimepy/))
9
+ # runtimepy ([5.7.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,15 +4,15 @@ build-backend = "setuptools.build_meta:__legacy__"
4
4
 
5
5
  [project]
6
6
  name = "runtimepy"
7
- version = "5.6.3"
7
+ version = "5.7.0"
8
8
  description = "A framework for implementing Python services."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  authors = [
12
- {name = "Vaughn Kottler", email = "vaughnkottler@gmail.com"}
12
+ {name = "Vaughn Kottler", email = "vaughn@libre-embedded.com"}
13
13
  ]
14
14
  maintainers = [
15
- {name = "Vaughn Kottler", email = "vaughnkottler@gmail.com"}
15
+ {name = "Vaughn Kottler", email = "vaughn@libre-embedded.com"}
16
16
  ]
17
17
  classifiers = [
18
18
  "Programming Language :: Python :: 3.11",
@@ -1,7 +1,7 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
3
  # version=3.1.4
4
- # hash=9547492b6c819241db9f6c010450b6ce
4
+ # hash=c51f4ac6cf134b3c3fa872a096e83489
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.6.3"
13
+ VERSION = "5.7.0"
14
14
 
15
15
  # runtimepy-specific content.
16
16
  METRICS_NAME = "metrics"
@@ -15,6 +15,7 @@ from vcorelib import DEFAULT_ENCODING
15
15
  from vcorelib.io import ARBITER, JsonObject
16
16
  from vcorelib.logging import DEFAULT_TIME_FORMAT, LoggerMixin
17
17
  from vcorelib.math import default_time_ns, nano_str
18
+ from vcorelib.names import name_search
18
19
 
19
20
  # internal
20
21
  from runtimepy.channel.environment import ChannelEnvironment
@@ -26,7 +27,6 @@ from runtimepy.channel.environment.command.processor import (
26
27
  )
27
28
  from runtimepy.channel.registry import ParsedEvent
28
29
  from runtimepy.mapping import DEFAULT_PATTERN
29
- from runtimepy.util import name_search
30
30
 
31
31
  # Declared so we re-export FieldOrChannel after moving where it's declared.
32
32
  __all__ = [
@@ -6,6 +6,9 @@ A module implementing channel-environment telemetry registration.
6
6
  from contextlib import ExitStack, contextmanager
7
7
  from typing import BinaryIO, Iterator, Optional, cast
8
8
 
9
+ # third-party
10
+ from vcorelib.names import name_search
11
+
9
12
  # internal
10
13
  from runtimepy.channel.environment.base import (
11
14
  BaseChannelEnvironment as _BaseChannelEnvironment,
@@ -14,7 +17,6 @@ from runtimepy.channel.event import PrimitiveEvent
14
17
  from runtimepy.channel.registry import ParsedEvent
15
18
  from runtimepy.mapping import DEFAULT_PATTERN
16
19
  from runtimepy.metrics.channel import ChannelMetrics
17
- from runtimepy.util import name_search
18
20
 
19
21
 
20
22
  class TelemetryChannelEnvironment(_BaseChannelEnvironment):
@@ -42,6 +42,7 @@
42
42
 
43
43
  .table-container {
44
44
  overflow-x: scroll;
45
+ min-height: fit-content;
45
46
  }
46
47
 
47
48
  .channel-column {
@@ -76,19 +77,17 @@ textarea.text-logs {
76
77
  padding-bottom: 0 !important;
77
78
 
78
79
  border-top: 0;
79
- background-color: var(--bs-secondary-bg-subtle);
80
80
  }
81
81
 
82
82
  .vertical-divider {
83
83
  flex-basis: 0.75em;
84
84
  flex-grow: 0;
85
85
  flex-shrink: 0;
86
- background-color: var(--bs-secondary-bg-subtle);
87
86
  }
88
87
 
89
88
  .vertical-divider:hover {
90
89
  cursor: col-resize;
91
- background-color: var(--bs-secondary-bg);
90
+ background-color: var(--bs-highlight-bg) !important;
92
91
  }
93
92
 
94
93
  button:hover {
@@ -98,3 +97,14 @@ button:hover {
98
97
  .channel-value-input {
99
98
  width: 6em;
100
99
  }
100
+
101
+ /*
102
+ * Should probably build the bootstrap stuff from source and set custom Sass:
103
+ * https://getbootstrap.com/docs/5.3/customize/sass/
104
+ */
105
+
106
+ :root {
107
+ /* Prefer 'Arial' and 'Consolas' at the highest priority. */
108
+ --bs-font-sans-serif: Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
109
+ --bs-font-monospace: Consolas, "Liberation Mono", "Courier New", monospace;
110
+ }
@@ -17,6 +17,10 @@ body > :first-child {
17
17
  height: 100%;
18
18
  }
19
19
 
20
+ #runtimepy-tabs {
21
+ width: min-content;
22
+ }
23
+
20
24
  #runtimepy-splash {
21
25
  position: fixed;
22
26
  top: 0;
@@ -24,7 +28,6 @@ body > :first-child {
24
28
  width: 100vw;
25
29
  height: 100vh;
26
30
  opacity: 1.0;
27
- background-color: var(--bs-secondary-bg-subtle);
28
31
  }
29
32
 
30
33
  .click-plot {
@@ -9,7 +9,19 @@ tasks:
9
9
  # Sinusoids.
10
10
  - {name: wave1, factory: sinusoid, period_s: 0.01}
11
11
  - {name: wave2, factory: sinusoid, period_s: 0.02}
12
- - {name: wave3, factory: sinusoid, period_s: 0.03}
12
+ - name: wave3
13
+ factory: sinusoid
14
+ period_s: 0.03
15
+ markdown: |
16
+ # Markdown for wave3
17
+
18
+ * list element 1
19
+ * list element 2
20
+ * list element 3
21
+
22
+ To be continued.
23
+
24
+ `peace`
13
25
 
14
26
  # Drive interactions with runtime entities that won't otherwise be polled.
15
27
  - {name: app, factory: SampleApp, period_s: 0.25}
@@ -21,6 +33,11 @@ clients:
21
33
  defer: true
22
34
  kwargs:
23
35
  remote_addr: [localhost, "$udp_json"]
36
+ markdown: |
37
+ # `udp_json_client`
38
+
39
+ Connects to `udp_json_server`.
40
+
24
41
  - factory: udp_json
25
42
  name: udp_json_server
26
43
  kwargs:
@@ -36,8 +53,19 @@ structs:
36
53
  b: 2
37
54
  c: 3
38
55
 
56
+ markdown: |
57
+ # Docs for `example.struct1`
58
+
59
+ Should be shown for peer process as well?
60
+
39
61
  - name: struct2
40
62
  factory: sample_struct
63
+ config:
64
+ markdown: |
65
+ # `struct2`
66
+
67
+ One of the structs of all time.
68
+
41
69
  - name: struct3
42
70
  factory: sample_struct
43
71
 
@@ -46,6 +74,11 @@ processes:
46
74
  - name: proc1
47
75
  factory: sample_peer
48
76
 
77
+ markdown: |
78
+ # Markdown for `proc1`
79
+
80
+ A process that
81
+
49
82
  # The peer itself runs an arbiter process.
50
83
  config:
51
84
  includes:
@@ -7,6 +7,7 @@ class WindowHashManager {
7
7
  this.tabFilter = "";
8
8
  this.tabsShown = true;
9
9
  this.channelsShown = true;
10
+ this.lightMode = false;
10
11
  this.plotChannels = {};
11
12
  this.filters = {};
12
13
  this.minTxPeriod = 0.0;
@@ -17,6 +18,15 @@ class WindowHashManager {
17
18
  this.update();
18
19
  }
19
20
 
21
+ lightDarkClick(event) {
22
+ this.lightMode = !this.lightMode;
23
+
24
+ document.getElementById("runtimepy")
25
+ .setAttribute("data-bs-theme", this.lightMode ? "light" : "dark");
26
+
27
+ this.update();
28
+ }
29
+
20
30
  channelClick(event) {
21
31
  this.channelsShown = !this.channelsShown;
22
32
 
@@ -106,6 +116,12 @@ class WindowHashManager {
106
116
  channelsButton.addEventListener("click", this.channelClick.bind(this));
107
117
  }
108
118
 
119
+ /* Click handler for light/dark toggle. */
120
+ let lightDarkButton = document.getElementById("theme-button");
121
+ if (lightDarkButton) {
122
+ lightDarkButton.addEventListener("click", this.lightDarkClick.bind(this));
123
+ }
124
+
109
125
  /* Click handlers for new window buttons. */
110
126
  for (const button of document.querySelectorAll(".window-button")) {
111
127
  button.onclick = () => {
@@ -150,13 +166,6 @@ class WindowHashManager {
150
166
  }
151
167
  }
152
168
 
153
- if (split.includes("hide-tabs")) {
154
- tabButton.click();
155
- }
156
- if (split.includes("hide-channels")) {
157
- channelsButton.click();
158
- }
159
-
160
169
  /* Check for tab filter. */
161
170
  for (let item of split) {
162
171
  if (item.includes("=")) {
@@ -171,6 +180,16 @@ class WindowHashManager {
171
180
  }
172
181
  }
173
182
  }
183
+
184
+ if (split.includes("hide-tabs")) {
185
+ tabButton.click();
186
+ }
187
+ if (split.includes("hide-channels")) {
188
+ channelsButton.click();
189
+ }
190
+ if (split.includes("light-mode")) {
191
+ lightDarkButton.click();
192
+ }
174
193
  }
175
194
  }
176
195
 
@@ -199,6 +218,9 @@ class WindowHashManager {
199
218
  if (!this.channelsShown) {
200
219
  hash += ",hide-channels"
201
220
  }
221
+ if (this.lightMode) {
222
+ hash += ",light-mode";
223
+ }
202
224
 
203
225
  if (this.minTxPeriod != 0.0) {
204
226
  hash += `,min-tx-period-ms=${this.minTxPeriod}`;
@@ -0,0 +1,3 @@
1
+ # Connections
2
+
3
+ To be continued.
@@ -0,0 +1,3 @@
1
+ # Periodic Tasks
2
+
3
+ To be continued.
@@ -0,0 +1,3 @@
1
+ # Runtime Structures
2
+
3
+ To be continued.
@@ -0,0 +1,3 @@
1
+ # Peer Programs
2
+
3
+ To be continued.
@@ -0,0 +1,20 @@
1
+ # Sinusoid Tasks
2
+
3
+ ## Intent
4
+
5
+ These tasks compute
6
+ [`math.sin`](https://docs.python.org/3/library/math.html#math.sin) and
7
+ [`math.cos`](https://docs.python.org/3/library/math.html#math.cos) on every
8
+ iteration, which advances one "step" per dispatch where the "step angle"
9
+ advanced depends on the `steps` control.
10
+
11
+ Once the current "step angle" is computed, controls `amplitude` and phase
12
+ angles are considered for final `sin` and `cos` channel values.
13
+
14
+ ## Discussion
15
+
16
+ * Is it worth adding a `tan` channel that computes
17
+ [`math.tan`](https://docs.python.org/3/library/math.html#math.tan) and/or other
18
+ trigonometric functions?
19
+ * Is it worth adding a "number of steps" control, such that one task iteration
20
+ could advance multiple waveform steps?
@@ -2,6 +2,7 @@
2
2
  includes:
3
3
  - has_factory.yaml
4
4
  - has_name.yaml
5
+ - has_markdown.yaml
5
6
 
6
7
  properties:
7
8
  defer:
@@ -3,6 +3,7 @@ includes:
3
3
  - has_factory.yaml
4
4
  - has_name.yaml
5
5
  - has_config.yaml
6
+ - has_markdown.yaml
6
7
 
7
8
  required: [program]
8
9
 
@@ -2,6 +2,7 @@
2
2
  includes:
3
3
  - has_factory.yaml
4
4
  - has_name.yaml
5
+ - has_markdown.yaml
5
6
 
6
7
  properties:
7
8
  period_s:
@@ -0,0 +1,4 @@
1
+ ---
2
+ properties:
3
+ markdown:
4
+ type: string
@@ -13,10 +13,10 @@ from typing import cast as _cast
13
13
 
14
14
  # third-party
15
15
  from vcorelib.logging import LoggerMixin
16
+ from vcorelib.names import name_search
16
17
 
17
18
  # internal
18
19
  from runtimepy.mixins.regex import RegexMixin as _RegexMixin
19
- from runtimepy.util import name_search
20
20
 
21
21
  # This determines types that are valid as keys.
22
22
  T = _TypeVar("T", int, bool)
@@ -11,7 +11,7 @@ from typing import Any, Optional, Union
11
11
 
12
12
  # third-party
13
13
  from vcorelib.dict.codec import JsonCodec
14
- from vcorelib.logging import LoggerType
14
+ from vcorelib.logging import ListLogger, LoggerType
15
15
  from vcorelib.target.resolver import TargetResolver
16
16
 
17
17
  # internal
@@ -39,7 +39,7 @@ from runtimepy.message.types import (
39
39
  T,
40
40
  TypedHandler,
41
41
  )
42
- from runtimepy.util import Identifier, ListLogger
42
+ from runtimepy.util import Identifier
43
43
 
44
44
 
45
45
  class JsonMessageInterface:
@@ -30,11 +30,14 @@ class ChannelEnvironmentMixin:
30
30
  return id(self.env)
31
31
 
32
32
  def register_task_metrics(
33
- self, metrics: PeriodicTaskMetrics, namespace: str = METRICS_NAME
33
+ self,
34
+ metrics: PeriodicTaskMetrics,
35
+ *names: str,
36
+ namespace: str = METRICS_NAME,
34
37
  ) -> None:
35
38
  """Register periodic task metrics."""
36
39
 
37
- with self.env.names_pushed(namespace):
40
+ with self.env.names_pushed(namespace, *names):
38
41
  self.env.channel(
39
42
  "dispatches",
40
43
  metrics.dispatches,
@@ -104,11 +107,14 @@ class ChannelEnvironmentMixin:
104
107
  )
105
108
 
106
109
  def register_connection_metrics(
107
- self, metrics: ConnectionMetrics, namespace: str = METRICS_NAME
110
+ self,
111
+ metrics: ConnectionMetrics,
112
+ *names: str,
113
+ namespace: str = METRICS_NAME,
108
114
  ) -> None:
109
115
  """Register connection metrics."""
110
116
 
111
- with self.env.names_pushed(namespace):
117
+ with self.env.names_pushed(namespace, *names):
112
118
  for name, direction, verb in [
113
119
  ("tx", metrics.tx, "transmitted"),
114
120
  ("rx", metrics.rx, "received"),
@@ -0,0 +1,110 @@
1
+ """
2
+ A module implementing a logger-mixin extension.
3
+ """
4
+
5
+ # built-in
6
+ from contextlib import AsyncExitStack
7
+ import io
8
+ import logging
9
+ from typing import Any, Iterable
10
+
11
+ # third-party
12
+ import aiofiles
13
+ from vcorelib.logging import LoggerMixin, LoggerType
14
+ from vcorelib.paths import Pathlike, normalize
15
+
16
+ # internal
17
+ from runtimepy.channel.environment import ChannelEnvironment
18
+ from runtimepy.enum.registry import RuntimeIntEnum
19
+
20
+
21
+ class LogLevel(RuntimeIntEnum):
22
+ """A runtime enumeration for log level."""
23
+
24
+ DEBUG = logging.DEBUG
25
+ INFO = logging.INFO
26
+ WARNING = logging.WARNING
27
+ ERROR = logging.ERROR
28
+ CRITICAL = logging.CRITICAL
29
+
30
+
31
+ LogLevellike = LogLevel | int | str
32
+
33
+
34
+ class LoggerMixinLevelControl(LoggerMixin):
35
+ """A logger mixin that exposes a runtime-controllable level."""
36
+
37
+ def _log_level_changed(self, _: int, new_value: int) -> None:
38
+ """Handle a change in log level."""
39
+
40
+ self.logger.setLevel(new_value)
41
+ self.logger.log(new_value, "Log level updated to %d.", new_value)
42
+
43
+ def setup_level_channel(
44
+ self,
45
+ env: ChannelEnvironment,
46
+ name: str = "log_level",
47
+ initial: str = "info",
48
+ description: str = "Text-log level filter for this environment.",
49
+ ) -> None:
50
+ """Add a commandable log-level channel to the environment."""
51
+
52
+ chan = env.int_channel(
53
+ name,
54
+ enum=LogLevel.register_enum(env.enums),
55
+ commandable=True,
56
+ description=description,
57
+ )
58
+
59
+ # Set up change handler.
60
+ chan[0].raw.register_callback(self._log_level_changed)
61
+
62
+ # Set the initial log level.
63
+ env.set(name, initial)
64
+
65
+ del chan
66
+
67
+
68
+ LogPaths = Iterable[tuple[LogLevellike, Pathlike]]
69
+
70
+
71
+ class LogCaptureMixin:
72
+ """A simple async file-reading interface."""
73
+
74
+ logger: LoggerType
75
+
76
+ # Open aiofiles handles.
77
+ streams: list[tuple[int, Any]]
78
+
79
+ ext_log_extra = {"external": True}
80
+
81
+ async def init_log_capture(
82
+ self, stack: AsyncExitStack, log_paths: LogPaths
83
+ ) -> None:
84
+ """Initialize this task with application information."""
85
+
86
+ self.streams = [
87
+ (
88
+ LogLevel.normalize(level),
89
+ await stack.enter_async_context(aiofiles.open(path, mode="r")),
90
+ )
91
+ for level, path in log_paths
92
+ if normalize(path).is_file()
93
+ ]
94
+
95
+ # Don't handle any kind of backhaul.
96
+ for stream in self.streams:
97
+ await stream[1].seek(0, io.SEEK_END)
98
+
99
+ def log_line(self, level: int, data: str) -> None:
100
+ """Log a line for output."""
101
+ self.logger.log(level, data, extra=self.ext_log_extra)
102
+
103
+ async def dispatch_log_capture(self) -> None:
104
+ """Get the next line from this log stream."""
105
+
106
+ for level, stream in self.streams:
107
+ line = (await stream.readline()).rstrip()
108
+ while line:
109
+ self.log_line(level, line)
110
+ line = (await stream.readline()).rstrip()
@@ -48,7 +48,9 @@ from runtimepy.subprocess.peer import RuntimepyPeer as _RuntimepyPeer
48
48
  from runtimepy.tui.mixin import CursesWindow, TuiMixin
49
49
 
50
50
  ServerTask = _Awaitable[None]
51
- RuntimeProcessTask = tuple[type[_RuntimepyPeer], str, _JsonObject, str]
51
+ RuntimeProcessTask = tuple[
52
+ type[_RuntimepyPeer], str, _JsonObject, str, Optional[str]
53
+ ]
52
54
 
53
55
 
54
56
  async def init_only(app: AppInfo) -> int:
@@ -226,9 +228,17 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
226
228
  async def _start_processes(self, stack: _AsyncExitStack) -> None:
227
229
  """Start processes."""
228
230
 
229
- for name, (peer, name, config, import_str) in self._peers.items():
231
+ for name, (
232
+ peer,
233
+ name,
234
+ config,
235
+ import_str,
236
+ markdown,
237
+ ) in self._peers.items():
230
238
  self._runtime_peers[name] = await stack.enter_async_context(
231
- peer.running_program(name, config, import_str)
239
+ peer.running_program(
240
+ name, config, import_str, markdown=markdown
241
+ )
232
242
  )
233
243
  self.logger.info("Started process '%s'.", name)
234
244
 
@@ -17,6 +17,7 @@ from vcorelib.dict.env import dict_resolve_env_vars, list_resolve_env_vars
17
17
  from vcorelib.io import ARBITER as _ARBITER
18
18
  from vcorelib.io.types import JsonObject as _JsonObject
19
19
  from vcorelib.logging import LoggerMixin as _LoggerMixin
20
+ from vcorelib.names import import_str_and_item
20
21
  from vcorelib.paths import Pathlike as _Pathlike
21
22
  from vcorelib.paths import find_file
22
23
  from vcorelib.paths import normalize as _normalize
@@ -29,7 +30,6 @@ from runtimepy.net.arbiter.imports import (
29
30
  ImportConnectionArbiter as _ImportConnectionArbiter,
30
31
  )
31
32
  from runtimepy.net.arbiter.imports.util import get_apps
32
- from runtimepy.util import import_str_and_item
33
33
 
34
34
  ConfigObject = dict[str, _Any]
35
35
  ConfigBuilder = _Callable[[ConfigObject], None]
@@ -168,6 +168,7 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
168
168
  kwargs = dict_resolve_env_vars(
169
169
  client.get("kwargs", {}), env=config.ports # type: ignore
170
170
  )
171
+ kwargs.setdefault("markdown", client.get("markdown"))
171
172
 
172
173
  assert await self.factory_client(
173
174
  factory,
@@ -201,6 +202,7 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
201
202
  name,
202
203
  period_s=task["period_s"],
203
204
  average_depth=task["average_depth"],
205
+ markdown=task.get("markdown"),
204
206
  ), f"Couldn't register task '{name}' ({factory})!"
205
207
 
206
208
  # Register structs.
@@ -216,7 +218,9 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
216
218
  name = process["name"]
217
219
  factory = process["factory"]
218
220
  assert self.factory_process(
219
- factory, name, process.get("config", {}), process["program"]
221
+ factory,
222
+ name,
223
+ process,
220
224
  ), f"Couldn't register process '{name}' ({factory})!"
221
225
 
222
226
  # Load initialization methods.