runtimepy 5.13.0__tar.gz → 5.13.2__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 (319) hide show
  1. {runtimepy-5.13.0/runtimepy.egg-info → runtimepy-5.13.2}/PKG-INFO +6 -6
  2. {runtimepy-5.13.0 → runtimepy-5.13.2}/README.md +3 -3
  3. {runtimepy-5.13.0 → runtimepy-5.13.2}/pyproject.toml +1 -1
  4. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/__init__.py +3 -3
  5. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/__main__.py +1 -1
  6. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/app.py +1 -1
  7. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/all.py +1 -1
  8. runtimepy-5.13.2/runtimepy/data/base.yaml +19 -0
  9. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/css/main.css +1 -1
  10. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/server_base.yaml +1 -17
  11. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/entry.py +1 -1
  12. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/html/__init__.py +3 -1
  13. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/__init__.py +31 -5
  14. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/__init__.py +2 -0
  15. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/tab/html.py +1 -0
  16. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/widgets.py +2 -0
  17. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/html.py +33 -3
  18. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/markdown.py +16 -15
  19. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/http/__init__.py +9 -2
  20. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/requirements.txt +2 -2
  21. {runtimepy-5.13.0 → runtimepy-5.13.2/runtimepy.egg-info}/PKG-INFO +6 -6
  22. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy.egg-info/SOURCES.txt +1 -0
  23. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy.egg-info/requires.txt +2 -2
  24. {runtimepy-5.13.0 → runtimepy-5.13.2}/setup.py +1 -1
  25. {runtimepy-5.13.0 → runtimepy-5.13.2}/LICENSE +0 -0
  26. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/__init__.py +0 -0
  27. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/__init__.py +0 -0
  28. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/array.py +0 -0
  29. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/base.py +0 -0
  30. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/command/__init__.py +0 -0
  31. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/command/parser.py +0 -0
  32. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/command/processor.py +0 -0
  33. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/command/result.py +0 -0
  34. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/create.py +0 -0
  35. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/file.py +0 -0
  36. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/sample.py +0 -0
  37. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/environment/telemetry.py +0 -0
  38. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/event/__init__.py +0 -0
  39. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/event/header.py +0 -0
  40. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/channel/registry.py +0 -0
  41. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/codec/__init__.py +0 -0
  42. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/codec/protocol/__init__.py +0 -0
  43. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/codec/protocol/base.py +0 -0
  44. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/codec/protocol/json.py +0 -0
  45. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/codec/system/__init__.py +0 -0
  46. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/__init__.py +0 -0
  47. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/arbiter.py +0 -0
  48. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/common.py +0 -0
  49. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/mtu.py +0 -0
  50. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/server.py +0 -0
  51. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/task.py +0 -0
  52. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/tftp.py +0 -0
  53. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/commands/tui.py +0 -0
  54. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/control/__init__.py +0 -0
  55. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/control/env/__init__.py +0 -0
  56. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/control/source.py +0 -0
  57. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/control/step.py +0 -0
  58. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/404.html +0 -0
  59. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/browser.yaml +0 -0
  60. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/css/bootstrap_extra.css +0 -0
  61. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/css/font.css +0 -0
  62. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/dummy_load.yaml +0 -0
  63. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/factories.yaml +0 -0
  64. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/favicon.ico +0 -0
  65. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/DataConnection.js +0 -0
  66. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/JsonConnection.js +0 -0
  67. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/audio.js +0 -0
  68. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/App.js +0 -0
  69. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/ChannelTable.js +0 -0
  70. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/DataConnection.js +0 -0
  71. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/JsonConnection.js +0 -0
  72. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/OverlayManager.js +0 -0
  73. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/Plot.js +0 -0
  74. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
  75. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/PlotManager.js +0 -0
  76. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
  77. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/PointBuffer.js +0 -0
  78. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/PointManager.js +0 -0
  79. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/TabFilter.js +0 -0
  80. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/TabInterface.js +0 -0
  81. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/UnitSystem.js +0 -0
  82. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/WindowHashManager.js +0 -0
  83. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/classes/WorkerInterface.js +0 -0
  84. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/events.js +0 -0
  85. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/init.js +0 -0
  86. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/main.js +0 -0
  87. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/markdown_page.js +0 -0
  88. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/tab/env.js +0 -0
  89. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/tab/sound.js +0 -0
  90. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
  91. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/unused/pyodide.js +0 -0
  92. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/util.js +0 -0
  93. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/js/worker.js +0 -0
  94. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/md/Connection.md +0 -0
  95. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/md/PeriodicTask.md +0 -0
  96. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/md/RuntimeStruct.md +0 -0
  97. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/md/RuntimepyPeer.md +0 -0
  98. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/md/SinusoidTask.md +0 -0
  99. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/sample_telemetry.yaml +0 -0
  100. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/BitFields.yaml +0 -0
  101. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/Channel.yaml +0 -0
  102. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
  103. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
  104. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/ClientConnectionConfig.yaml +0 -0
  105. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +0 -0
  106. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
  107. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/FindFile.yaml +0 -0
  108. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/PeerProcessConfig.yaml +0 -0
  109. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
  110. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
  111. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/StructConfig.yaml +0 -0
  112. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/TaskConfig.yaml +0 -0
  113. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/channel_controls.yaml +0 -0
  114. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/has_config.yaml +0 -0
  115. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/has_factory.yaml +0 -0
  116. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/has_markdown.yaml +0 -0
  117. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/has_name.yaml +0 -0
  118. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
  119. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/server.yaml +0 -0
  120. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/server_dev.yaml +0 -0
  121. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/css/bootstrap-icons.min.css +0 -0
  122. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/css/bootstrap.min.css +0 -0
  123. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/css/fonts/bootstrap-icons.woff +0 -0
  124. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/css/fonts/bootstrap-icons.woff2 +0 -0
  125. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/js/bootstrap.bundle.min.js +0 -0
  126. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/js/webglplot.umd.min.js +0 -0
  127. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/1024x1024.png +0 -0
  128. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/128x128.png +0 -0
  129. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/16x16.png +0 -0
  130. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/1920x1920.png +0 -0
  131. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/24x24.png +0 -0
  132. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/256x256.png +0 -0
  133. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/32x32.png +0 -0
  134. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/512x512.png +0 -0
  135. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/png/chip-circle-bootstrap/64x64.png +0 -0
  136. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/svg/chip-circle-bootstrap.svg +0 -0
  137. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaCode-Bold.woff2 +0 -0
  138. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaCode-BoldItalic.woff2 +0 -0
  139. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaCode-Italic.woff2 +0 -0
  140. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaCode-Regular.woff2 +0 -0
  141. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaMono-Bold.woff2 +0 -0
  142. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaMono-BoldItalic.woff2 +0 -0
  143. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaMono-Italic.woff2 +0 -0
  144. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/CascadiaMono-Regular.woff2 +0 -0
  145. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/static/woff2/README.md +0 -0
  146. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/data/tftp_server.yaml +0 -0
  147. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/dev_requirements.txt +0 -0
  148. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/enum/__init__.py +0 -0
  149. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/enum/registry.py +0 -0
  150. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/enum/types.py +0 -0
  151. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mapping.py +0 -0
  152. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/message/__init__.py +0 -0
  153. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/message/handlers.py +0 -0
  154. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/message/interface.py +0 -0
  155. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/message/types.py +0 -0
  156. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/metrics/__init__.py +0 -0
  157. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/metrics/channel.py +0 -0
  158. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/metrics/connection.py +0 -0
  159. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/metrics/task.py +0 -0
  160. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/__init__.py +0 -0
  161. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/async_command.py +0 -0
  162. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/enum.py +0 -0
  163. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/environment.py +0 -0
  164. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/finalize.py +0 -0
  165. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/logging.py +0 -0
  166. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/psutil.py +0 -0
  167. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/regex.py +0 -0
  168. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/mixins/trig.py +0 -0
  169. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/__init__.py +0 -0
  170. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/apps/__init__.py +0 -0
  171. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/__init__.py +0 -0
  172. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/base.py +0 -0
  173. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/config/__init__.py +0 -0
  174. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/config/codec.py +0 -0
  175. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/config/util.py +0 -0
  176. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/factory/__init__.py +0 -0
  177. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/factory/connection.py +0 -0
  178. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/factory/task.py +0 -0
  179. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
  180. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/imports/__init__.py +0 -0
  181. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/imports/util.py +0 -0
  182. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/info.py +0 -0
  183. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/result.py +0 -0
  184. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/struct/__init__.py +0 -0
  185. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/task.py +0 -0
  186. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
  187. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/tcp/json.py +0 -0
  188. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/udp.py +0 -0
  189. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/arbiter/websocket.py +0 -0
  190. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/backoff.py +0 -0
  191. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/connection.py +0 -0
  192. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/factories/__init__.py +0 -0
  193. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/html/arbiter.py +0 -0
  194. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/html/bootstrap/__init__.py +0 -0
  195. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/html/bootstrap/elements.py +0 -0
  196. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/html/bootstrap/tabs.py +0 -0
  197. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/http/__init__.py +0 -0
  198. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/http/common.py +0 -0
  199. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/http/header.py +0 -0
  200. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/http/request_target.py +0 -0
  201. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/http/response.py +0 -0
  202. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/http/state.py +0 -0
  203. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/http/version.py +0 -0
  204. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/manager.py +0 -0
  205. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/mixin.py +0 -0
  206. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/mtu.py +0 -0
  207. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/base.py +0 -0
  208. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/create.py +0 -0
  209. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/elements.py +0 -0
  210. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/__init__.py +0 -0
  211. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/modal.py +0 -0
  212. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/settings.py +0 -0
  213. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
  214. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/tab/base.py +0 -0
  215. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/tab/controls.py +0 -0
  216. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/env/tab/message.py +0 -0
  217. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/files.py +0 -0
  218. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/landing_page.py +0 -0
  219. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/placeholder.py +0 -0
  220. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/pyodide.py +0 -0
  221. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/sound.py +0 -0
  222. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/app/tab.py +0 -0
  223. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/json.py +0 -0
  224. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/struct/__init__.py +0 -0
  225. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/websocket/__init__.py +0 -0
  226. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/server/websocket/state.py +0 -0
  227. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/ssl.py +0 -0
  228. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/stream/__init__.py +0 -0
  229. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/stream/base.py +0 -0
  230. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/stream/json/__init__.py +0 -0
  231. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/stream/string.py +0 -0
  232. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/__init__.py +0 -0
  233. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/connection.py +0 -0
  234. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/create.py +0 -0
  235. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/protocol.py +0 -0
  236. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/scpi/__init__.py +0 -0
  237. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/telnet/__init__.py +0 -0
  238. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/telnet/codes.py +0 -0
  239. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
  240. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/__init__.py +0 -0
  241. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/connection.py +0 -0
  242. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/create.py +0 -0
  243. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/protocol.py +0 -0
  244. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/queue.py +0 -0
  245. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/tftp/__init__.py +0 -0
  246. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/tftp/base.py +0 -0
  247. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/tftp/endpoint.py +0 -0
  248. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/tftp/enums.py +0 -0
  249. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/udp/tftp/io.py +0 -0
  250. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/util.py +0 -0
  251. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/websocket/__init__.py +0 -0
  252. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/net/websocket/connection.py +0 -0
  253. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/noise/__init__.py +0 -0
  254. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/__init__.py +0 -0
  255. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/array/__init__.py +0 -0
  256. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/base.py +0 -0
  257. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/bool.py +0 -0
  258. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/byte_order.py +0 -0
  259. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/evaluation.py +0 -0
  260. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/field/__init__.py +0 -0
  261. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/field/fields.py +0 -0
  262. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/field/manager/__init__.py +0 -0
  263. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/field/manager/base.py +0 -0
  264. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/float.py +0 -0
  265. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/int.py +0 -0
  266. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/scaling.py +0 -0
  267. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/serializable/__init__.py +0 -0
  268. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/serializable/base.py +0 -0
  269. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/serializable/fixed.py +0 -0
  270. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/serializable/framer.py +0 -0
  271. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/serializable/prefixed.py +0 -0
  272. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/string.py +0 -0
  273. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/types/__init__.py +0 -0
  274. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/types/base.py +0 -0
  275. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/types/bool.py +0 -0
  276. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/types/bounds.py +0 -0
  277. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/types/float.py +0 -0
  278. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/primitives/types/int.py +0 -0
  279. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/py.typed +0 -0
  280. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/registry/__init__.py +0 -0
  281. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/registry/bool.py +0 -0
  282. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/registry/item.py +0 -0
  283. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/registry/name.py +0 -0
  284. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/sample/__init__.py +0 -0
  285. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/sample/peer.py +0 -0
  286. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/sample/program.py +0 -0
  287. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/schemas.py +0 -0
  288. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/struct/__init__.py +0 -0
  289. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/subprocess/__init__.py +0 -0
  290. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/subprocess/interface.py +0 -0
  291. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/subprocess/peer.py +0 -0
  292. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/subprocess/program.py +0 -0
  293. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/subprocess/protocol.py +0 -0
  294. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/task/__init__.py +0 -0
  295. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/task/asynchronous.py +0 -0
  296. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/task/basic/__init__.py +0 -0
  297. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/task/basic/manager.py +0 -0
  298. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/task/basic/periodic.py +0 -0
  299. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/task/sample.py +0 -0
  300. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/task/trig/__init__.py +0 -0
  301. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/telemetry/__init__.py +0 -0
  302. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/telemetry/sample.py +0 -0
  303. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/tui/__init__.py +0 -0
  304. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/tui/channels/__init__.py +0 -0
  305. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/tui/cursor.py +0 -0
  306. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/tui/mixin.py +0 -0
  307. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/tui/mock.py +0 -0
  308. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/tui/task.py +0 -0
  309. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/ui/__init__.py +0 -0
  310. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/ui/controls.py +0 -0
  311. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy/util.py +0 -0
  312. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy.egg-info/dependency_links.txt +0 -0
  313. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy.egg-info/entry_points.txt +0 -0
  314. {runtimepy-5.13.0 → runtimepy-5.13.2}/runtimepy.egg-info/top_level.txt +0 -0
  315. {runtimepy-5.13.0 → runtimepy-5.13.2}/setup.cfg +0 -0
  316. {runtimepy-5.13.0 → runtimepy-5.13.2}/tests/test_entry.py +0 -0
  317. {runtimepy-5.13.0 → runtimepy-5.13.2}/tests/test_mapping.py +0 -0
  318. {runtimepy-5.13.0 → runtimepy-5.13.2}/tests/test_resources.py +0 -0
  319. {runtimepy-5.13.0 → runtimepy-5.13.2}/tests/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runtimepy
3
- Version: 5.13.0
3
+ Version: 5.13.2
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,10 +17,10 @@ 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.5.8
20
21
  Requires-Dist: psutil
22
+ Requires-Dist: svgen>=0.7.12
21
23
  Requires-Dist: aiofiles
22
- Requires-Dist: vcorelib>=3.5.1
23
- Requires-Dist: svgen>=0.7.4
24
24
  Requires-Dist: websockets
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint; extra == "test"
@@ -50,12 +50,12 @@ Dynamic: requires-python
50
50
  <!--
51
51
  =====================================
52
52
  generator=datazen
53
- version=3.2.1
54
- hash=4f0e82dc45d3ea9c4ccf5b262413c206
53
+ version=3.2.3
54
+ hash=f3bcab8765e649f1b80ad504e5debde9
55
55
  =====================================
56
56
  -->
57
57
 
58
- # runtimepy ([5.13.0](https://pypi.org/project/runtimepy/))
58
+ # runtimepy ([5.13.2](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)
@@ -1,12 +1,12 @@
1
1
  <!--
2
2
  =====================================
3
3
  generator=datazen
4
- version=3.2.1
5
- hash=4f0e82dc45d3ea9c4ccf5b262413c206
4
+ version=3.2.3
5
+ hash=f3bcab8765e649f1b80ad504e5debde9
6
6
  =====================================
7
7
  -->
8
8
 
9
- # runtimepy ([5.13.0](https://pypi.org/project/runtimepy/))
9
+ # runtimepy ([5.13.2](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.13.0"
7
+ version = "5.13.2"
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
- # version=3.2.1
4
- # hash=35e5555173fdfd064e5047172de9b6a4
3
+ # version=3.2.3
4
+ # hash=6693eae62108cbcdfbccdb9de6b57fa8
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.13.0"
13
+ VERSION = "5.13.2"
14
14
 
15
15
  # runtimepy-specific content.
16
16
  METRICS_NAME = "metrics"
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=b28a8111bcc727e854c1f6474a3c4232
5
5
  # =====================================
6
6
  """
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=a4deafb4ebcc179d8d85f9376d22dc92
5
5
  # =====================================
6
6
 
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=1814b7f7fae3556a0dbeec37141e4182
5
5
  # =====================================
6
6
 
@@ -0,0 +1,19 @@
1
+ ---
2
+ includes:
3
+ - package://runtimepy/factories.yaml
4
+
5
+ init:
6
+ - runtimepy.net.arbiter.housekeeping.init
7
+
8
+ config:
9
+ # Default redirects.
10
+ http_redirects:
11
+ "/": "/index.html"
12
+ "/index.html": "/app.html"
13
+
14
+ # Serve these applications by default at these paths.
15
+ http_app_paths: ["/app.html"]
16
+
17
+ # Handles config["http_app_prefixes"].
18
+ config_builders:
19
+ - runtimepy.net.html.arbiter.web_app_paths
@@ -52,6 +52,6 @@ body > :first-child {
52
52
  border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-link-hover-color) !important;
53
53
  }
54
54
 
55
- canvas:focus {
55
+ :focus {
56
56
  outline: none;
57
57
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  includes:
3
- - package://runtimepy/factories.yaml
3
+ - package://runtimepy/base.yaml
4
4
 
5
5
  ports:
6
6
  - {name: runtimepy_http_server, type: tcp}
@@ -10,22 +10,6 @@ ports:
10
10
  structs:
11
11
  - {name: ui, factory: ui_state}
12
12
 
13
- init:
14
- - runtimepy.net.arbiter.housekeeping.init
15
-
16
- config:
17
- # Default redirects.
18
- http_redirects:
19
- "/": "/index.html"
20
- "/index.html": "/app.html"
21
-
22
- # Serve these applications by default at these paths.
23
- http_app_paths: ["/app.html"]
24
-
25
- # Handles config["http_app_prefixes"].
26
- config_builders:
27
- - runtimepy.net.html.arbiter.web_app_paths
28
-
29
13
  servers:
30
14
  - factory: runtimepy_http
31
15
  kwargs: {port: "$runtimepy_http_server"}
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=79c31d1280a6e97b5d326aecb758c597
5
5
  # =====================================
6
6
 
@@ -51,9 +51,10 @@ def create_app_shell(
51
51
  # Dark/light theme switch button.
52
52
  bootstrap_button(
53
53
  icon_str("lightbulb"),
54
- tooltip=" Toggle light/dark.",
54
+ tooltip="Toggle light/dark.",
55
55
  id="theme-button",
56
56
  parent=button_column,
57
+ title="change theme button",
57
58
  )
58
59
 
59
60
  return container, button_column
@@ -112,6 +113,7 @@ def full_markdown_page(
112
113
  icon_str("printer"),
113
114
  tooltip="Printer-friendly view.",
114
115
  id="print-button",
116
+ title="print-view button",
115
117
  parent=div(tag="a", href="?print=true", parent=button_column),
116
118
  )
117
119
 
@@ -55,6 +55,12 @@ class RuntimepyServerConnection(HttpConnection):
55
55
  class_paths: list[Pathlike] = [Path(), package_data_dir()]
56
56
  class_redirect_paths: dict[Path, Union[str, Path]] = {}
57
57
 
58
+ # Set these to control meta attributes.
59
+ metadata: dict[str, Optional[str]] = {
60
+ "title": HttpConnection.identity,
61
+ "description": None,
62
+ }
63
+
58
64
  def add_path(self, path: Pathlike, front: bool = False) -> None:
59
65
  """Add a path."""
60
66
 
@@ -145,7 +151,16 @@ class RuntimepyServerConnection(HttpConnection):
145
151
  ) -> bytes:
146
152
  """Return rendered markdown content."""
147
153
 
148
- document = get_html()
154
+ meta: dict[str, str] = type(self).metadata.copy() # type: ignore
155
+
156
+ meta.setdefault("description", "")
157
+ meta["description"] += (
158
+ " This page was rendered from "
159
+ f"Markdown by {HttpConnection.identity}."
160
+ )
161
+
162
+ document = get_html(**meta)
163
+
149
164
  with IndentedFileWriter.string() as writer:
150
165
  writer.write_markdown(content, **kwargs)
151
166
  full_markdown_page(
@@ -156,7 +171,9 @@ class RuntimepyServerConnection(HttpConnection):
156
171
 
157
172
  response["Content-Type"] = f"text/html; charset={DEFAULT_ENCODING}"
158
173
 
159
- return document.encode_str().encode()
174
+ with StringIO() as stream:
175
+ document.render(stream)
176
+ return stream.getvalue().encode()
160
177
 
161
178
  async def render_markdown_file(
162
179
  self,
@@ -179,14 +196,14 @@ class RuntimepyServerConnection(HttpConnection):
179
196
  result: HttpResult = None
180
197
 
181
198
  # Keep track of directories encountered.
182
- directories: list[Path] = []
199
+ directories: list[tuple[Path, Path]] = []
183
200
 
184
201
  # Build a list of all candidate files to check.
185
202
  candidates: list[Path] = []
186
203
  for search in self.paths:
187
204
  candidate = search.joinpath(path[0][1:])
188
205
  if candidate.is_dir():
189
- directories.append(candidate)
206
+ directories.append((candidate, search))
190
207
  candidates.append(candidate.joinpath("index.html"))
191
208
  else:
192
209
  candidates.append(candidate)
@@ -206,6 +223,13 @@ class RuntimepyServerConnection(HttpConnection):
206
223
 
207
224
  # Set MIME type if it can be determined.
208
225
  if mime:
226
+ # webhint suggestion
227
+ if (
228
+ mime.startswith("text")
229
+ and DEFAULT_ENCODING not in mime
230
+ ):
231
+ mime += f"; charset={DEFAULT_ENCODING}"
232
+
209
233
  response["Content-Type"] = mime
210
234
 
211
235
  # We don't handle this yet.
@@ -219,9 +243,10 @@ class RuntimepyServerConnection(HttpConnection):
219
243
 
220
244
  # Handle a directory as a last resort.
221
245
  if not result and directories:
246
+ candidate, search = directories[0]
222
247
  result = self.render_markdown(
223
248
  markdown_for_dir(
224
- directories[0], {"applications": self.apps.keys()}
249
+ candidate, search, {"applications": self.apps.keys()}
225
250
  ),
226
251
  response,
227
252
  path[1],
@@ -326,6 +351,7 @@ class RuntimepyServerConnection(HttpConnection):
326
351
  response,
327
352
  request_data,
328
353
  default_app=type(self).default_app,
354
+ **type(self).metadata,
329
355
  )
330
356
 
331
357
  if populated:
@@ -68,6 +68,8 @@ async def setup(app: AppInfo) -> int:
68
68
  )
69
69
  )
70
70
 
71
+ RuntimepyServerConnection.metadata.update(app.config_param("html", {}))
72
+
71
73
  # Default application (environment tabs).
72
74
  html_app = create_app(app, getattr(_import_module(module), method))
73
75
  target: str
@@ -226,6 +226,7 @@ class ChannelEnvironmentTabHtml(ChannelEnvironmentTabControls):
226
226
  vert_container = flex(
227
227
  parent=container,
228
228
  kind="column",
229
+ tag="form",
229
230
  )
230
231
  vert_container.add_class("channel-column", "collapse", "show")
231
232
 
@@ -110,6 +110,7 @@ def channel_table_header(
110
110
  tooltip="Clear plotted channels.",
111
111
  icon="x-lg",
112
112
  id="clear-plotted-channels",
113
+ title="button for clearing plotted channels",
113
114
  ).add_class("pb-2")
114
115
 
115
116
  input_box(
@@ -124,6 +125,7 @@ def channel_table_header(
124
125
  icon="trash",
125
126
  tooltip="Clear all plot points.",
126
127
  id="clear-plotted-points",
128
+ title="button for clearing plot point data",
127
129
  ).add_class("pb-2")
128
130
 
129
131
  cell = flex(tag="th", parent=ctl_row)
@@ -6,6 +6,7 @@ A module implementing HTML interfaces for web applications.
6
6
  from typing import Awaitable, Callable, Optional, TextIO
7
7
 
8
8
  # third-party
9
+ from svgen.element import Element
9
10
  from svgen.element.html import Html
10
11
  from vcorelib import DEFAULT_ENCODING
11
12
 
@@ -20,10 +21,36 @@ HtmlApp = Callable[
20
21
  HtmlApps = dict[str, HtmlApp]
21
22
 
22
23
 
23
- def get_html() -> Html:
24
+ def get_html(
25
+ title: str = HttpConnection.identity,
26
+ cache_control: str = "public",
27
+ description: str = None,
28
+ **kwargs,
29
+ ) -> Html:
24
30
  """Get a default HTML document."""
25
31
 
26
- return Html(HttpConnection.identity)
32
+ elem = Html(title, **kwargs)
33
+
34
+ elem.head.children.append(
35
+ Element(
36
+ tag="meta",
37
+ attrib={"http-equiv": "Cache-Control", "content": cache_control},
38
+ )
39
+ )
40
+
41
+ elem.head.children.append(
42
+ Element(tag="link", rel="icon", href="/favicon.ico")
43
+ )
44
+
45
+ if description:
46
+ elem.head.children.append(
47
+ Element(
48
+ tag="meta",
49
+ attrib={"name": "description", "content": description},
50
+ )
51
+ )
52
+
53
+ return elem
27
54
 
28
55
 
29
56
  async def html_handler(
@@ -33,6 +60,7 @@ async def html_handler(
33
60
  response: ResponseHeader,
34
61
  request_data: Optional[bytes],
35
62
  default_app: HtmlApp = None,
63
+ **kwargs,
36
64
  ) -> bool:
37
65
  """Render an HTML document in response to an HTTP request."""
38
66
 
@@ -42,6 +70,8 @@ async def html_handler(
42
70
  # Create the application.
43
71
  app = apps.get(request.target.path, default_app)
44
72
  if app is not None:
45
- (await app(get_html(), request, response, request_data)).render(stream)
73
+ (
74
+ await app(get_html(**kwargs), request, response, request_data)
75
+ ).render(stream)
46
76
 
47
77
  return app is not None
@@ -11,14 +11,11 @@ from typing import Iterable, cast
11
11
  from vcorelib.io.file_writer import IndentedFileWriter
12
12
  from vcorelib.paths import rel
13
13
 
14
- LOGO_MARKDOWN = (
15
- "[![logo](https://libre-embedded.com/static/"
16
- "png/chip-circle-bootstrap/128x128.png)](https://libre-embedded.com)"
17
- )
14
+ LOGO_MARKDOWN = "[![logo](/static/png/chip-circle-bootstrap/128x128.png)](/)"
18
15
 
19
16
 
20
17
  def markdown_for_dir(
21
- path: Path, extra_links: dict[str, Iterable[str]] = None
18
+ path: Path, base: Path, extra_links: dict[str, Iterable[str]] = None
22
19
  ) -> str:
23
20
  """Get markdown data for a directory."""
24
21
 
@@ -29,24 +26,28 @@ def markdown_for_dir(
29
26
 
30
27
  if extra_links:
31
28
  for category, apps in extra_links.items():
32
- writer.write(f"## {category}")
33
- with writer.padding():
34
- for app in apps:
35
- writer.write(f"* [{app}]({app})")
36
-
37
- writer.write(f"## `{path}`")
29
+ if apps:
30
+ writer.write(f"## {category}")
31
+ with writer.padding():
32
+ for app in apps:
33
+ writer.write(f"* [{app}]({app})")
34
+
35
+ curr_dir = rel(path, base=base)
36
+ writer.write(f"## `{curr_dir}`")
38
37
  writer.empty()
39
38
 
40
- writer.write("* [..](..)")
39
+ # Link to go up a directory.
40
+ if curr_dir != Path():
41
+ writer.write(f"* [..](/{curr_dir.parent})")
41
42
 
42
43
  for item in path.iterdir():
43
- curr = rel(item, base=path)
44
+ curr = rel(item, base=base)
44
45
 
45
- name = f"`{curr}`"
46
+ name = f"`{curr.name}`"
46
47
  if item.is_dir():
47
48
  name = f"**{name}**"
48
49
 
49
- writer.write(f"* [{name}]({curr})")
50
+ writer.write(f"* [{name}](/{curr})")
50
51
 
51
52
  result: str = cast(StringIO, writer.stream).getvalue()
52
53
 
@@ -52,10 +52,13 @@ def to_json(response: HttpResponse) -> Any:
52
52
  )
53
53
 
54
54
 
55
+ IDENTITY = f"{PKG_NAME}/{VERSION}"
56
+
57
+
55
58
  class HttpConnection(_TcpConnection):
56
59
  """A class implementing a basic HTTP interface."""
57
60
 
58
- identity = f"{PKG_NAME}/{VERSION}"
61
+ identity = IDENTITY
59
62
 
60
63
  expecting_response: bool
61
64
 
@@ -126,7 +129,11 @@ class HttpConnection(_TcpConnection):
126
129
  )
127
130
 
128
131
  # Set boilerplate header data.
129
- response["server"] = self.identity
132
+
133
+ # webhint suggestions
134
+ # response["server"] = self.identity
135
+ response["server"] = PKG_NAME
136
+ response["X-Content-Type-Options"] = "nosniff"
130
137
 
131
138
  return result
132
139
 
@@ -1,6 +1,6 @@
1
1
  aiofiles
2
- vcorelib>=3.5.1
3
- svgen>=0.7.4
2
+ vcorelib>=3.5.8
3
+ svgen>=0.7.12
4
4
  websockets
5
5
  psutil
6
6
  windows-curses; sys_platform == 'win32' and python_version < '3.12'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runtimepy
3
- Version: 5.13.0
3
+ Version: 5.13.2
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,10 +17,10 @@ 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.5.8
20
21
  Requires-Dist: psutil
22
+ Requires-Dist: svgen>=0.7.12
21
23
  Requires-Dist: aiofiles
22
- Requires-Dist: vcorelib>=3.5.1
23
- Requires-Dist: svgen>=0.7.4
24
24
  Requires-Dist: websockets
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint; extra == "test"
@@ -50,12 +50,12 @@ Dynamic: requires-python
50
50
  <!--
51
51
  =====================================
52
52
  generator=datazen
53
- version=3.2.1
54
- hash=4f0e82dc45d3ea9c4ccf5b262413c206
53
+ version=3.2.3
54
+ hash=f3bcab8765e649f1b80ad504e5debde9
55
55
  =====================================
56
56
  -->
57
57
 
58
- # runtimepy ([5.13.0](https://pypi.org/project/runtimepy/))
58
+ # runtimepy ([5.13.2](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)
@@ -52,6 +52,7 @@ runtimepy/control/source.py
52
52
  runtimepy/control/step.py
53
53
  runtimepy/control/env/__init__.py
54
54
  runtimepy/data/404.html
55
+ runtimepy/data/base.yaml
55
56
  runtimepy/data/browser.yaml
56
57
  runtimepy/data/dummy_load.yaml
57
58
  runtimepy/data/factories.yaml
@@ -1,7 +1,7 @@
1
+ vcorelib>=3.5.8
1
2
  psutil
3
+ svgen>=0.7.12
2
4
  aiofiles
3
- vcorelib>=3.5.1
4
- svgen>=0.7.4
5
5
  websockets
6
6
 
7
7
  [test]
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=23791ff25e92caf639fdcfe48ce010bf
5
5
  # =====================================
6
6
 
File without changes