runtimepy 5.7.4__tar.gz → 5.7.6__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 (301) hide show
  1. {runtimepy-5.7.4/runtimepy.egg-info → runtimepy-5.7.6}/PKG-INFO +6 -6
  2. {runtimepy-5.7.4 → runtimepy-5.7.6}/README.md +2 -2
  3. {runtimepy-5.7.4 → runtimepy-5.7.6}/pyproject.toml +1 -1
  4. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/__init__.py +2 -2
  5. runtimepy-5.7.6/runtimepy/data/404.html +3 -0
  6. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/server_base.yaml +15 -3
  7. runtimepy-5.7.6/runtimepy/net/html/arbiter.py +32 -0
  8. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/__init__.py +47 -23
  9. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/__init__.py +4 -3
  10. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/html.py +3 -1
  11. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/connection.py +12 -10
  12. {runtimepy-5.7.4 → runtimepy-5.7.6/runtimepy.egg-info}/PKG-INFO +6 -6
  13. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy.egg-info/SOURCES.txt +2 -0
  14. {runtimepy-5.7.4 → runtimepy-5.7.6}/LICENSE +0 -0
  15. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/__main__.py +0 -0
  16. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/app.py +0 -0
  17. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/__init__.py +0 -0
  18. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/__init__.py +0 -0
  19. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/array.py +0 -0
  20. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/base.py +0 -0
  21. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/command/__init__.py +0 -0
  22. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/command/parser.py +0 -0
  23. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/command/processor.py +0 -0
  24. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/command/result.py +0 -0
  25. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/create.py +0 -0
  26. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/file.py +0 -0
  27. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/sample.py +0 -0
  28. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/environment/telemetry.py +0 -0
  29. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/event/__init__.py +0 -0
  30. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/event/header.py +0 -0
  31. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/channel/registry.py +0 -0
  32. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/codec/__init__.py +0 -0
  33. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/codec/protocol/__init__.py +0 -0
  34. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/codec/protocol/base.py +0 -0
  35. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/codec/protocol/json.py +0 -0
  36. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/codec/system/__init__.py +0 -0
  37. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/__init__.py +0 -0
  38. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/all.py +0 -0
  39. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/arbiter.py +0 -0
  40. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/common.py +0 -0
  41. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/mtu.py +0 -0
  42. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/server.py +0 -0
  43. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/task.py +0 -0
  44. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/tftp.py +0 -0
  45. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/commands/tui.py +0 -0
  46. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/control/__init__.py +0 -0
  47. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/control/env/__init__.py +0 -0
  48. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/control/source.py +0 -0
  49. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/control/step.py +0 -0
  50. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/browser.yaml +0 -0
  51. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/css/bootstrap_extra.css +0 -0
  52. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/css/font.css +0 -0
  53. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/css/main.css +0 -0
  54. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/dummy_load.yaml +0 -0
  55. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/factories.yaml +0 -0
  56. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/favicon.ico +0 -0
  57. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/DataConnection.js +0 -0
  58. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/JsonConnection.js +0 -0
  59. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/audio.js +0 -0
  60. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/App.js +0 -0
  61. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/ChannelTable.js +0 -0
  62. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/DataConnection.js +0 -0
  63. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/JsonConnection.js +0 -0
  64. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/OverlayManager.js +0 -0
  65. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/Plot.js +0 -0
  66. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
  67. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/PlotManager.js +0 -0
  68. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
  69. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/PointBuffer.js +0 -0
  70. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/PointManager.js +0 -0
  71. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/TabFilter.js +0 -0
  72. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/TabInterface.js +0 -0
  73. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/UnitSystem.js +0 -0
  74. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/WindowHashManager.js +0 -0
  75. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/classes/WorkerInterface.js +0 -0
  76. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/events.js +0 -0
  77. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/init.js +0 -0
  78. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/main.js +0 -0
  79. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/markdown_page.js +0 -0
  80. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/tab/env.js +0 -0
  81. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/tab/sound.js +0 -0
  82. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
  83. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/unused/pyodide.js +0 -0
  84. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/util.js +0 -0
  85. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/js/worker.js +0 -0
  86. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/md/Connection.md +0 -0
  87. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/md/PeriodicTask.md +0 -0
  88. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/md/RuntimeStruct.md +0 -0
  89. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/md/RuntimepyPeer.md +0 -0
  90. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/md/SinusoidTask.md +0 -0
  91. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/sample_telemetry.yaml +0 -0
  92. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/BitFields.yaml +0 -0
  93. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/Channel.yaml +0 -0
  94. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
  95. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
  96. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/ClientConnectionConfig.yaml +0 -0
  97. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +0 -0
  98. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
  99. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/FindFile.yaml +0 -0
  100. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/PeerProcessConfig.yaml +0 -0
  101. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
  102. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
  103. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/StructConfig.yaml +0 -0
  104. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/TaskConfig.yaml +0 -0
  105. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/channel_controls.yaml +0 -0
  106. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/has_config.yaml +0 -0
  107. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/has_factory.yaml +0 -0
  108. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/has_markdown.yaml +0 -0
  109. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/has_name.yaml +0 -0
  110. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
  111. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/server.yaml +0 -0
  112. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/server_dev.yaml +0 -0
  113. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/svg/chip-circle-bootstrap.svg +0 -0
  114. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaCode-Bold.woff2 +0 -0
  115. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaCode-BoldItalic.woff2 +0 -0
  116. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaCode-Italic.woff2 +0 -0
  117. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaCode-Regular.woff2 +0 -0
  118. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaMono-Bold.woff2 +0 -0
  119. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaMono-BoldItalic.woff2 +0 -0
  120. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaMono-Italic.woff2 +0 -0
  121. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/CascadiaMono-Regular.woff2 +0 -0
  122. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/static/woff2/README.md +0 -0
  123. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/data/tftp_server.yaml +0 -0
  124. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/dev_requirements.txt +0 -0
  125. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/entry.py +0 -0
  126. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/enum/__init__.py +0 -0
  127. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/enum/registry.py +0 -0
  128. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/enum/types.py +0 -0
  129. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mapping.py +0 -0
  130. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/message/__init__.py +0 -0
  131. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/message/handlers.py +0 -0
  132. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/message/interface.py +0 -0
  133. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/message/types.py +0 -0
  134. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/metrics/__init__.py +0 -0
  135. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/metrics/channel.py +0 -0
  136. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/metrics/connection.py +0 -0
  137. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/metrics/task.py +0 -0
  138. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/__init__.py +0 -0
  139. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/async_command.py +0 -0
  140. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/enum.py +0 -0
  141. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/environment.py +0 -0
  142. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/finalize.py +0 -0
  143. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/logging.py +0 -0
  144. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/psutil.py +0 -0
  145. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/regex.py +0 -0
  146. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/mixins/trig.py +0 -0
  147. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/__init__.py +0 -0
  148. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/apps/__init__.py +0 -0
  149. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/__init__.py +0 -0
  150. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/base.py +0 -0
  151. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/config/__init__.py +0 -0
  152. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/config/codec.py +0 -0
  153. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/config/util.py +0 -0
  154. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/factory/__init__.py +0 -0
  155. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/factory/connection.py +0 -0
  156. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/factory/task.py +0 -0
  157. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
  158. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/imports/__init__.py +0 -0
  159. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/imports/util.py +0 -0
  160. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/info.py +0 -0
  161. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/result.py +0 -0
  162. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/struct/__init__.py +0 -0
  163. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/task.py +0 -0
  164. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
  165. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/tcp/json.py +0 -0
  166. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/udp.py +0 -0
  167. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/arbiter/websocket.py +0 -0
  168. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/backoff.py +0 -0
  169. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/connection.py +0 -0
  170. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/factories/__init__.py +0 -0
  171. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/html/__init__.py +0 -0
  172. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/html/bootstrap/__init__.py +0 -0
  173. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/html/bootstrap/elements.py +0 -0
  174. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/html/bootstrap/tabs.py +0 -0
  175. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/http/__init__.py +0 -0
  176. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/http/common.py +0 -0
  177. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/http/header.py +0 -0
  178. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/http/request_target.py +0 -0
  179. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/http/response.py +0 -0
  180. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/http/state.py +0 -0
  181. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/http/version.py +0 -0
  182. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/manager.py +0 -0
  183. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/mixin.py +0 -0
  184. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/mtu.py +0 -0
  185. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/base.py +0 -0
  186. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/create.py +0 -0
  187. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/elements.py +0 -0
  188. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/__init__.py +0 -0
  189. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/modal.py +0 -0
  190. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/settings.py +0 -0
  191. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
  192. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/tab/base.py +0 -0
  193. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/tab/controls.py +0 -0
  194. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/tab/html.py +0 -0
  195. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/tab/message.py +0 -0
  196. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/env/widgets.py +0 -0
  197. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/files.py +0 -0
  198. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/landing_page.py +0 -0
  199. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/placeholder.py +0 -0
  200. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/pyodide.py +0 -0
  201. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/sound.py +0 -0
  202. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/app/tab.py +0 -0
  203. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/json.py +0 -0
  204. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/struct/__init__.py +0 -0
  205. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/websocket/__init__.py +0 -0
  206. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/server/websocket/state.py +0 -0
  207. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/ssl.py +0 -0
  208. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/stream/__init__.py +0 -0
  209. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/stream/base.py +0 -0
  210. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/stream/json/__init__.py +0 -0
  211. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/stream/string.py +0 -0
  212. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/__init__.py +0 -0
  213. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/create.py +0 -0
  214. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/http/__init__.py +0 -0
  215. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/protocol.py +0 -0
  216. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/scpi/__init__.py +0 -0
  217. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/telnet/__init__.py +0 -0
  218. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/telnet/codes.py +0 -0
  219. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
  220. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/__init__.py +0 -0
  221. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/connection.py +0 -0
  222. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/create.py +0 -0
  223. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/protocol.py +0 -0
  224. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/queue.py +0 -0
  225. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/tftp/__init__.py +0 -0
  226. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/tftp/base.py +0 -0
  227. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/tftp/endpoint.py +0 -0
  228. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/tftp/enums.py +0 -0
  229. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/udp/tftp/io.py +0 -0
  230. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/util.py +0 -0
  231. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/websocket/__init__.py +0 -0
  232. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/net/websocket/connection.py +0 -0
  233. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/noise/__init__.py +0 -0
  234. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/__init__.py +0 -0
  235. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/array/__init__.py +0 -0
  236. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/base.py +0 -0
  237. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/bool.py +0 -0
  238. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/byte_order.py +0 -0
  239. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/evaluation.py +0 -0
  240. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/field/__init__.py +0 -0
  241. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/field/fields.py +0 -0
  242. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/field/manager/__init__.py +0 -0
  243. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/field/manager/base.py +0 -0
  244. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/float.py +0 -0
  245. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/int.py +0 -0
  246. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/scaling.py +0 -0
  247. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/serializable/__init__.py +0 -0
  248. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/serializable/base.py +0 -0
  249. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/serializable/fixed.py +0 -0
  250. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/serializable/framer.py +0 -0
  251. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/serializable/prefixed.py +0 -0
  252. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/string.py +0 -0
  253. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/types/__init__.py +0 -0
  254. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/types/base.py +0 -0
  255. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/types/bool.py +0 -0
  256. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/types/bounds.py +0 -0
  257. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/types/float.py +0 -0
  258. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/primitives/types/int.py +0 -0
  259. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/py.typed +0 -0
  260. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/registry/__init__.py +0 -0
  261. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/registry/bool.py +0 -0
  262. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/registry/item.py +0 -0
  263. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/registry/name.py +0 -0
  264. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/requirements.txt +0 -0
  265. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/sample/__init__.py +0 -0
  266. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/sample/peer.py +0 -0
  267. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/sample/program.py +0 -0
  268. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/schemas.py +0 -0
  269. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/struct/__init__.py +0 -0
  270. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/subprocess/__init__.py +0 -0
  271. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/subprocess/interface.py +0 -0
  272. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/subprocess/peer.py +0 -0
  273. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/subprocess/program.py +0 -0
  274. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/subprocess/protocol.py +0 -0
  275. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/task/__init__.py +0 -0
  276. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/task/asynchronous.py +0 -0
  277. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/task/basic/__init__.py +0 -0
  278. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/task/basic/manager.py +0 -0
  279. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/task/basic/periodic.py +0 -0
  280. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/task/sample.py +0 -0
  281. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/task/trig/__init__.py +0 -0
  282. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/telemetry/__init__.py +0 -0
  283. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/telemetry/sample.py +0 -0
  284. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/tui/__init__.py +0 -0
  285. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/tui/channels/__init__.py +0 -0
  286. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/tui/cursor.py +0 -0
  287. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/tui/mixin.py +0 -0
  288. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/tui/mock.py +0 -0
  289. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/tui/task.py +0 -0
  290. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/ui/__init__.py +0 -0
  291. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/ui/controls.py +0 -0
  292. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy/util.py +0 -0
  293. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy.egg-info/dependency_links.txt +0 -0
  294. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy.egg-info/entry_points.txt +0 -0
  295. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy.egg-info/requires.txt +3 -3
  296. {runtimepy-5.7.4 → runtimepy-5.7.6}/runtimepy.egg-info/top_level.txt +0 -0
  297. {runtimepy-5.7.4 → runtimepy-5.7.6}/setup.cfg +0 -0
  298. {runtimepy-5.7.4 → runtimepy-5.7.6}/setup.py +0 -0
  299. {runtimepy-5.7.4 → runtimepy-5.7.6}/tests/test_entry.py +0 -0
  300. {runtimepy-5.7.4 → runtimepy-5.7.6}/tests/test_mapping.py +0 -0
  301. {runtimepy-5.7.4 → runtimepy-5.7.6}/tests/test_resources.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runtimepy
3
- Version: 5.7.4
3
+ Version: 5.7.6
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/vkottler/runtimepy
6
6
  Author: Vaughn Kottler
@@ -17,11 +17,11 @@ Classifier: License :: OSI Approved :: MIT License
17
17
  Requires-Python: >=3.11
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: vcorelib>=3.4.2
21
- Requires-Dist: svgen>=0.6.8
22
- Requires-Dist: websockets
23
20
  Requires-Dist: aiofiles
21
+ Requires-Dist: websockets
24
22
  Requires-Dist: psutil
23
+ Requires-Dist: vcorelib>=3.4.2
24
+ Requires-Dist: svgen>=0.6.8
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint; extra == "test"
27
27
  Requires-Dist: flake8; extra == "test"
@@ -45,11 +45,11 @@ Requires-Dist: uvloop; (sys_platform != "win32" and sys_platform != "cygwin") an
45
45
  =====================================
46
46
  generator=datazen
47
47
  version=3.1.4
48
- hash=fbb71900eae64b008d2a2df1b7dde92b
48
+ hash=41ff8742602f69f2831092a4b666cddc
49
49
  =====================================
50
50
  -->
51
51
 
52
- # runtimepy ([5.7.4](https://pypi.org/project/runtimepy/))
52
+ # runtimepy ([5.7.6](https://pypi.org/project/runtimepy/))
53
53
 
54
54
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
55
55
  ![Build Status](https://github.com/vkottler/runtimepy/workflows/Python%20Package/badge.svg)
@@ -2,11 +2,11 @@
2
2
  =====================================
3
3
  generator=datazen
4
4
  version=3.1.4
5
- hash=fbb71900eae64b008d2a2df1b7dde92b
5
+ hash=41ff8742602f69f2831092a4b666cddc
6
6
  =====================================
7
7
  -->
8
8
 
9
- # runtimepy ([5.7.4](https://pypi.org/project/runtimepy/))
9
+ # runtimepy ([5.7.6](https://pypi.org/project/runtimepy/))
10
10
 
11
11
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
12
12
  ![Build Status](https://github.com/vkottler/runtimepy/workflows/Python%20Package/badge.svg)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta:__legacy__"
4
4
 
5
5
  [project]
6
6
  name = "runtimepy"
7
- version = "5.7.4"
7
+ version = "5.7.6"
8
8
  description = "A framework for implementing Python services."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,7 +1,7 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
3
  # version=3.1.4
4
- # hash=cb3ed2d01203d78ad794d39500d706f9
4
+ # hash=cab7cff2cb194a61178fa386b80eae85
5
5
  # =====================================
6
6
 
7
7
  """
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
10
10
 
11
11
  DESCRIPTION = "A framework for implementing Python services."
12
12
  PKG_NAME = "runtimepy"
13
- VERSION = "5.7.4"
13
+ VERSION = "5.7.6"
14
14
 
15
15
  # runtimepy-specific content.
16
16
  METRICS_NAME = "metrics"
@@ -0,0 +1,3 @@
1
+ <html lang=en><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>runtimepy/5.7.6</title><style>@font-face{font-family:CascadiaCode;src:url(/static/woff2/CascadiaCode-Regular.woff2)}@font-face{font-family:CascadiaCode;src:url(/static/woff2/CascadiaCode-Bold.woff2);font-weight:700}@font-face{font-family:CascadiaCode;src:url(/static/woff2/CascadiaCode-BoldItalic.woff2);font-weight:700;font-style:italic}@font-face{font-family:CascadiaCode;src:url(/static/woff2/CascadiaCode-Italic.woff2);font-style:italic}@font-face{font-family:CascadiaMono;src:url(/static/woff2/CascadiaMono-Regular.woff2)}@font-face{font-family:CascadiaMono;src:url(/static/woff2/CascadiaMono-Bold.woff2);font-weight:700}@font-face{font-family:CascadiaMono;src:url(/static/woff2/CascadiaMono-BoldItalic.woff2);font-weight:700;font-style:italic}@font-face{font-family:CascadiaMono;src:url(/static/woff2/CascadiaMono-Italic.woff2);font-style:italic}</style><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css></link>
2
+ <link href=https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css rel=stylesheet crossorigin=anonymous></link><style>html{height:100%}body{height:100%;margin:0;overflow:hidden}body>:first-child{height:100%}#runtimepy{height:100%}#runtimepy-tabs{width:min-content}#runtimepy-splash{position:fixed;top:0;left:0;width:100vw;height:100vh;opacity:1}.click-plot{cursor:pointer}.stale{color:var(--bs-warning-text-emphasis)!important}.slider{min-width:8em}.toggle-value{}.window-button{border-right:var(--bs-border-width)var(--bs-border-style)var(--bs-link-hover-color)!important}canvas:focus{outline:none}.flex-column-scroll-bodge{height:100%;flex-wrap:nowrap;overflow-y:scroll;flex-shrink:0}.scroll{overflow:scroll}.tab-content-bodge{width:100%;height:100%}.button-bodge{text-align:left}.collapsing{transition:none!important}.tab-pane.fade{transition:none!important}.modal.fade{transition:none!important}.modal-dialog{width:80%;max-width:80%}.table{margin-bottom:0;width:auto}.table-container{overflow-x:scroll;min-height:fit-content}.channel-column{overflow-y:scroll;overflow-x:hidden;flex-grow:0;flex-shrink:0}.channel-value{min-width:10em}.table>tbody>tr>td{vertical-align:middle}.collapse:not(.show){display:none!important}select.form-select{width:min-content}select.form-select:hover{cursor:pointer}textarea.text-logs{min-height:10em!important;padding-top:0!important;padding-bottom:0!important;border-top:0}.vertical-divider{flex-basis:.75em;flex-grow:0;flex-shrink:0}.vertical-divider:hover{cursor:col-resize;background-color:var(--bs-highlight-bg)!important}button:hover{background-color:var(--bs-tertiary-bg)}.channel-value-input{width:6em}:root,[data-bs-theme=dark],[data-bs-theme=light]{--bs-font-sans-serif:CascadiaCode, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace:CascadiaMono, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}</style><div id=runtimepy class="align-items-start bg-body d-flex" data-bs-theme=dark><div class="bg-dark-subtle h-100 d-flex flex-column"><button type=button id=theme-button class="btn btn-secondary rounded-0 font-monospace button-bodge text-nowrap has-tooltip" data-bs-title=" Toggle light/dark." data-bs-placement=right>
3
+ <i class="bi bi-lightbulb"></i></button></div><div class="overflow-y-auto d-flex flex-grow-1 h-100 flex-column justify-content-between text-body"><div></div><div class="d-flex flex-row justify-content-between"><div></div><div class="text-body p-3 pb-0"><h1><a href=https://libre-embedded.com><img alt=logo src=https://libre-embedded.com/static/png/chip-circle-bootstrap/128x128.png></a> Resource Not Found (404) <a href=https://libre-embedded.com><img alt=logo src=https://libre-embedded.com/static/png/chip-circle-bootstrap/128x128.png></a></h1><p>(<a href=https://libre-embedded.com>home</a>)</div><div></div></div><div></div></div></div><script>let lightMode=!1;function lightDarkClick(){lightMode=!lightMode,document.getElementById("runtimepy").setAttribute("data-bs-theme",lightMode?"light":"dark"),window.location.hash=lightMode?"#light-mode":""}let lightDarkButton=document.getElementById("theme-button");if(lightDarkButton&&lightDarkButton.addEventListener("click",lightDarkClick),window.location.hash){let e=window.location.hash.slice(1).split(",");e.includes("light-mode")&&lightDarkButton.click()}</script><script src=https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js crossorigin=anonymous></script>
@@ -13,11 +13,23 @@ structs:
13
13
  init:
14
14
  - runtimepy.net.arbiter.housekeeping.init
15
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
+
16
29
  servers:
17
30
  - factory: runtimepy_http
18
31
  kwargs: {port: "$runtimepy_http_server"}
19
-
20
32
  - factory: runtimepy_websocket_json
21
- kwargs: {host: "0.0.0.0", port: "$runtimepy_websocket_json_server"}
33
+ kwargs: {port: "$runtimepy_websocket_json_server"}
22
34
  - factory: runtimepy_websocket_data
23
- kwargs: {host: "0.0.0.0", port: "$runtimepy_websocket_data_server"}
35
+ kwargs: {port: "$runtimepy_websocket_data_server"}
@@ -0,0 +1,32 @@
1
+ """
2
+ A module implementing connection-arbiter related utilities.
3
+ """
4
+
5
+ # internal
6
+ from runtimepy.net.arbiter.config import ConfigObject
7
+
8
+
9
+ def web_app_paths(config: ConfigObject) -> None:
10
+ """
11
+ Register boilerplate path handling for additional application-serving URIs.
12
+ """
13
+
14
+ config.setdefault("config", {})
15
+ redirects = config["config"].setdefault("http_redirects", {})
16
+ app_paths = config["config"].setdefault("http_app_paths", [])
17
+
18
+ for prefix in config["config"].get("http_app_prefixes", []):
19
+ if not prefix.startswith("/"):
20
+ prefix = "/" + prefix
21
+
22
+ assert not prefix.endswith("/"), prefix
23
+
24
+ # Add re-directs.
25
+ index_path = f"{prefix}/index.html"
26
+ app_path = f"{prefix}/app.html"
27
+ redirects.setdefault(prefix, index_path)
28
+ redirects.setdefault(index_path, app_path)
29
+
30
+ # Add app path.
31
+ if app_path not in app_paths:
32
+ app_paths.append(app_path)
@@ -109,6 +109,18 @@ class RuntimepyServerConnection(HttpConnection):
109
109
  with favicon.open("rb") as favicon_fd:
110
110
  type(self).favicon_data = favicon_fd.read()
111
111
 
112
+ def redirect_to(
113
+ self,
114
+ path: str,
115
+ response: ResponseHeader,
116
+ status: http.HTTPStatus = http.HTTPStatus.TEMPORARY_REDIRECT,
117
+ ) -> bytes:
118
+ """Handle responding with redirection status."""
119
+
120
+ response["Location"] = path
121
+ response.status = status
122
+ return bytes()
123
+
112
124
  async def try_redirect(
113
125
  self, path: PathMaybeQuery, response: ResponseHeader
114
126
  ) -> Optional[bytes]:
@@ -118,33 +130,39 @@ class RuntimepyServerConnection(HttpConnection):
118
130
 
119
131
  curr = Path(path[0])
120
132
  if curr in self.class_redirect_paths:
121
- response["Location"] = str(self.class_redirect_paths[curr])
122
- response.status = http.HTTPStatus.TEMPORARY_REDIRECT
123
-
124
- # No data payload, but signal to caller that a response is ready.
125
- result = bytes()
133
+ result = self.redirect_to(
134
+ str(self.class_redirect_paths[curr]), response
135
+ )
126
136
 
127
137
  return result
128
138
 
129
- async def render_markdown(
130
- self, path: Path, response: ResponseHeader, **kwargs
139
+ def render_markdown(
140
+ self, content: str, response: ResponseHeader, **kwargs
131
141
  ) -> bytes:
132
- """Render a markdown file as HTML and return the result."""
142
+ """Return rendered markdown content."""
133
143
 
134
144
  document = get_html()
135
-
136
- async with aiofiles.open(path, mode="r") as path_fd:
137
- with IndentedFileWriter.string() as writer:
138
- writer.write_markdown(await path_fd.read(), **kwargs)
139
- full_markdown_page(
140
- document,
141
- writer.stream.getvalue(), # type: ignore
142
- )
145
+ with IndentedFileWriter.string() as writer:
146
+ writer.write_markdown(content, **kwargs)
147
+ full_markdown_page(
148
+ document,
149
+ writer.stream.getvalue(), # type: ignore
150
+ )
143
151
 
144
152
  response["Content-Type"] = f"text/html; charset={DEFAULT_ENCODING}"
145
153
 
146
154
  return document.encode_str().encode()
147
155
 
156
+ async def render_markdown_file(
157
+ self, path: Path, response: ResponseHeader, **kwargs
158
+ ) -> bytes:
159
+ """Render a markdown file as HTML and return the result."""
160
+
161
+ async with aiofiles.open(path, mode="r") as path_fd:
162
+ return self.render_markdown(
163
+ await path_fd.read(), response, **kwargs
164
+ )
165
+
148
166
  async def try_file(
149
167
  self, path: PathMaybeQuery, response: ResponseHeader
150
168
  ) -> Optional[bytes]:
@@ -157,9 +175,12 @@ class RuntimepyServerConnection(HttpConnection):
157
175
  candidate = search.joinpath(path[0][1:])
158
176
 
159
177
  # Handle markdown sources.
160
- md_candidate = candidate.with_suffix(".md")
161
- if md_candidate.is_file():
162
- return await self.render_markdown(md_candidate, response)
178
+ if candidate.name:
179
+ md_candidate = candidate.with_suffix(".md")
180
+ if md_candidate.is_file():
181
+ return await self.render_markdown_file(
182
+ md_candidate, response
183
+ )
163
184
 
164
185
  if candidate.is_file():
165
186
  mime, encoding = mimetypes.guess_type(candidate, strict=False)
@@ -239,6 +260,7 @@ class RuntimepyServerConnection(HttpConnection):
239
260
  request.log(self.logger, False, level=logging.INFO)
240
261
 
241
262
  result = None
263
+ populated = False
242
264
 
243
265
  with StringIO() as stream:
244
266
  if request.target.origin_form:
@@ -250,7 +272,7 @@ class RuntimepyServerConnection(HttpConnection):
250
272
  return self.favicon_data
251
273
 
252
274
  # Try serving a file and handling redirects.
253
- for handler in [self.try_redirect, self.try_file]:
275
+ for handler in [self.try_file, self.try_redirect]:
254
276
  result = await handler(
255
277
  request.target.origin_form, response
256
278
  )
@@ -266,10 +288,11 @@ class RuntimepyServerConnection(HttpConnection):
266
288
  request_data,
267
289
  self.json_data,
268
290
  )
291
+ populated = True
269
292
 
270
293
  # Serve the application.
271
294
  else:
272
- await html_handler(
295
+ populated = await html_handler(
273
296
  type(self).apps,
274
297
  stream,
275
298
  request,
@@ -278,6 +301,7 @@ class RuntimepyServerConnection(HttpConnection):
278
301
  default_app=type(self).default_app,
279
302
  )
280
303
 
281
- result = stream.getvalue().encode()
304
+ if populated:
305
+ result = stream.getvalue().encode()
282
306
 
283
- return result
307
+ return result or self.redirect_to("/404.html", response)
@@ -69,9 +69,10 @@ async def setup(app: AppInfo) -> int:
69
69
  )
70
70
 
71
71
  # Default application (environment tabs).
72
- web_app = create_app(app, getattr(_import_module(module), method))
73
- RuntimepyServerConnection.apps["/app.html"] = web_app
74
- RuntimepyServerConnection.default_app = web_app
72
+ html_app = create_app(app, getattr(_import_module(module), method))
73
+ target: str
74
+ for target in app.config_param("http_app_paths", []):
75
+ RuntimepyServerConnection.apps[target] = html_app
75
76
 
76
77
  # Register redirects.
77
78
  redirects: dict[str, str] = app.config_param("http_redirects", {})
@@ -33,7 +33,7 @@ async def html_handler(
33
33
  response: ResponseHeader,
34
34
  request_data: Optional[bytes],
35
35
  default_app: HtmlApp = None,
36
- ) -> None:
36
+ ) -> bool:
37
37
  """Render an HTML document in response to an HTTP request."""
38
38
 
39
39
  # Set response headers.
@@ -43,3 +43,5 @@ async def html_handler(
43
43
  app = apps.get(request.target.path, default_app)
44
44
  if app is not None:
45
45
  (await app(get_html(), request, response, request_data)).render(stream)
46
+
47
+ return app is not None
@@ -10,7 +10,6 @@ from asyncio import get_event_loop as _get_event_loop
10
10
  from contextlib import AsyncExitStack as _AsyncExitStack
11
11
  from contextlib import asynccontextmanager as _asynccontextmanager
12
12
  from logging import getLogger as _getLogger
13
- import socket as _socket
14
13
  from typing import Any as _Any
15
14
  from typing import AsyncIterator as _AsyncIterator
16
15
  from typing import Callable as _Callable
@@ -170,11 +169,7 @@ class TcpConnection(_Connection, _TransportMixin):
170
169
 
171
170
  server_kwargs = handle_possible_ssl(client=False, **kwargs)
172
171
  is_ssl = "ssl" in server_kwargs
173
- server = await eloop.create_server(
174
- CallbackProtocol,
175
- family=_socket.AF_INET,
176
- **server_kwargs,
177
- )
172
+ server = await eloop.create_server(CallbackProtocol, **server_kwargs)
178
173
  async with server:
179
174
  for socket in server.sockets:
180
175
  LOG.info(
@@ -224,6 +219,7 @@ class TcpConnection(_Connection, _TransportMixin):
224
219
  peer: type[V] = None,
225
220
  serve_kwargs: dict[str, _Any] = None,
226
221
  connect_kwargs: dict[str, _Any] = None,
222
+ host: str = "127.0.0.1",
227
223
  ) -> _AsyncIterator[tuple[V, T]]:
228
224
  """Create a connection pair."""
229
225
 
@@ -246,16 +242,22 @@ class TcpConnection(_Connection, _TransportMixin):
246
242
  serve_kwargs = {}
247
243
 
248
244
  server = await stack.enter_async_context(
249
- peer.serve(callback, port=0, backlog=1, **serve_kwargs)
245
+ peer.serve(
246
+ callback,
247
+ host=host,
248
+ port=0,
249
+ backlog=1,
250
+ **serve_kwargs,
251
+ )
250
252
  )
251
253
 
252
- host = server.sockets[0].getsockname()
253
-
254
254
  if connect_kwargs is None:
255
255
  connect_kwargs = {}
256
256
 
257
257
  client = await cls.create_connection(
258
- host="localhost", port=host[1], **connect_kwargs
258
+ host=host,
259
+ port=server.sockets[0].getsockname()[1],
260
+ **connect_kwargs,
259
261
  )
260
262
  await cond.acquire()
261
263
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runtimepy
3
- Version: 5.7.4
3
+ Version: 5.7.6
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/vkottler/runtimepy
6
6
  Author: Vaughn Kottler
@@ -17,11 +17,11 @@ Classifier: License :: OSI Approved :: MIT License
17
17
  Requires-Python: >=3.11
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: vcorelib>=3.4.2
21
- Requires-Dist: svgen>=0.6.8
22
- Requires-Dist: websockets
23
20
  Requires-Dist: aiofiles
21
+ Requires-Dist: websockets
24
22
  Requires-Dist: psutil
23
+ Requires-Dist: vcorelib>=3.4.2
24
+ Requires-Dist: svgen>=0.6.8
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint; extra == "test"
27
27
  Requires-Dist: flake8; extra == "test"
@@ -45,11 +45,11 @@ Requires-Dist: uvloop; (sys_platform != "win32" and sys_platform != "cygwin") an
45
45
  =====================================
46
46
  generator=datazen
47
47
  version=3.1.4
48
- hash=fbb71900eae64b008d2a2df1b7dde92b
48
+ hash=41ff8742602f69f2831092a4b666cddc
49
49
  =====================================
50
50
  -->
51
51
 
52
- # runtimepy ([5.7.4](https://pypi.org/project/runtimepy/))
52
+ # runtimepy ([5.7.6](https://pypi.org/project/runtimepy/))
53
53
 
54
54
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
55
55
  ![Build Status](https://github.com/vkottler/runtimepy/workflows/Python%20Package/badge.svg)
@@ -51,6 +51,7 @@ runtimepy/control/__init__.py
51
51
  runtimepy/control/source.py
52
52
  runtimepy/control/step.py
53
53
  runtimepy/control/env/__init__.py
54
+ runtimepy/data/404.html
54
55
  runtimepy/data/browser.yaml
55
56
  runtimepy/data/dummy_load.yaml
56
57
  runtimepy/data/factories.yaml
@@ -176,6 +177,7 @@ runtimepy/net/arbiter/tcp/__init__.py
176
177
  runtimepy/net/arbiter/tcp/json.py
177
178
  runtimepy/net/factories/__init__.py
178
179
  runtimepy/net/html/__init__.py
180
+ runtimepy/net/html/arbiter.py
179
181
  runtimepy/net/html/bootstrap/__init__.py
180
182
  runtimepy/net/html/bootstrap/elements.py
181
183
  runtimepy/net/html/bootstrap/tabs.py
File without changes
File without changes