runtimepy 5.15.4__tar.gz → 5.15.5__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.
- {runtimepy-5.15.4/runtimepy.egg-info → runtimepy-5.15.5}/PKG-INFO +7 -7
- {runtimepy-5.15.4 → runtimepy-5.15.5}/README.md +2 -2
- {runtimepy-5.15.4 → runtimepy-5.15.5}/pyproject.toml +1 -1
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/__init__.py +2 -2
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/command/processor.py +11 -1
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/css/bootstrap_extra.css +4 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/css/main.css +8 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/dummy_load.yaml +41 -21
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/WorkerInterface.js +1 -1
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/sample.js +1 -1
- runtimepy-5.15.5/runtimepy/data/schemas/Button.yaml +17 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/ClientConnectionConfig.yaml +1 -0
- runtimepy-5.15.5/runtimepy/data/schemas/has_buttons.yaml +6 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/base.py +12 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/config/__init__.py +1 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/factory/connection.py +3 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/base.py +11 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/html.py +10 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/widgets.py +11 -11
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/websocket/__init__.py +1 -1
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/requirements.txt +1 -1
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/struct/__init__.py +2 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/task/basic/periodic.py +2 -0
- runtimepy-5.15.5/runtimepy/ui/button.py +76 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5/runtimepy.egg-info}/PKG-INFO +7 -7
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy.egg-info/SOURCES.txt +3 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy.egg-info/requires.txt +4 -4
- {runtimepy-5.15.4 → runtimepy-5.15.5}/LICENSE +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/__main__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/app.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/array.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/command/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/command/parser.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/command/result.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/create.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/file.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/sample.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/environment/telemetry.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/event/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/event/header.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/channel/registry.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/codec/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/codec/protocol/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/codec/protocol/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/codec/protocol/json.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/codec/protocol/receiver.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/codec/system/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/all.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/arbiter.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/common.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/mtu.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/server.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/task.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/tftp.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/commands/tui.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/control/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/control/env/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/control/source.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/control/step.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/404.md +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/base.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/browser.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/css/font.css +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/factories.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/favicon.ico +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/DataConnection.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/JsonConnection.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/audio.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/App.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/ChannelTable.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/DataConnection.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/JsonConnection.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/OverlayManager.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/Plot.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/PlotManager.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/PointBuffer.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/PointManager.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/TabFilter.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/TabInterface.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/UnitSystem.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/classes/WindowHashManager.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/events.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/init.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/main.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/markdown_page.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/tab/env.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/tab/sound.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/unused/pyodide.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/util.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/js/worker.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/md/Connection.md +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/md/PeriodicTask.md +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/md/RuntimeStruct.md +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/md/RuntimepyPeer.md +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/md/SinusoidTask.md +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/sample_telemetry.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/BitFields.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/Channel.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/FindFile.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/PeerProcessConfig.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/StructConfig.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/TaskConfig.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/TwoTupleArray.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/channel_controls.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/has_config.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/has_factory.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/has_markdown.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/has_name.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/schemas/has_views.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/server.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/server_base.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/server_dev.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/css/bootstrap-icons.min.css +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/css/bootstrap.min.css +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/css/fonts/bootstrap-icons.woff +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/css/fonts/bootstrap-icons.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/js/bootstrap.bundle.min.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/js/webglplot.umd.min.js +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/1024x1024.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/128x128.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/16x16.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/1920x1920.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/24x24.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/256x256.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/32x32.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/512x512.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/64x64.png +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/svg/chip-circle-bootstrap.svg +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/svg/outline-dark.svg +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/svg/outline-light.svg +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-Bold.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-BoldItalic.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-Italic.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-Regular.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-Bold.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-BoldItalic.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-Italic.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-Regular.woff2 +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/static/woff2/README.md +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/data/tftp_server.yaml +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/dev_requirements.txt +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/entry.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/enum/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/enum/registry.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/enum/types.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mapping.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/message/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/message/handlers.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/message/interface.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/message/types.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/metrics/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/metrics/channel.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/metrics/connection.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/metrics/task.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/async_command.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/enum.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/environment.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/finalize.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/logging.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/psutil.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/regex.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/mixins/trig.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/apps/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/config/codec.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/config/util.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/factory/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/factory/task.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/imports/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/imports/util.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/info.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/result.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/struct/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/task.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/tcp/json.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/udp.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/arbiter/websocket.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/backoff.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/connection.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/factories/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/html/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/html/arbiter.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/html/bootstrap/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/html/bootstrap/elements.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/html/bootstrap/tabs.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/http/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/http/common.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/http/header.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/http/request_target.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/http/response.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/http/state.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/http/version.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/manager.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/mixin.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/mtu.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/create.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/elements.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/modal.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/settings.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/controls.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/message.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/files.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/landing_page.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/placeholder.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/pyodide.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/sound.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/app/tab.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/html.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/json.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/markdown.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/mux.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/struct/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/server/websocket/state.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/ssl.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/stream/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/stream/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/stream/json/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/stream/string.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/connection.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/create.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/http/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/protocol.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/scpi/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/telnet/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/telnet/codes.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/connection.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/create.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/protocol.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/queue.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/endpoint.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/enums.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/io.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/util.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/websocket/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/net/websocket/connection.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/noise/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/array/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/bool.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/byte_order.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/evaluation.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/field/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/field/fields.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/field/manager/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/field/manager/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/float.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/int.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/scaling.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/serializable/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/serializable/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/serializable/fixed.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/serializable/framer.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/serializable/prefixed.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/string.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/types/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/types/base.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/types/bool.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/types/bounds.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/types/float.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/primitives/types/int.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/py.typed +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/registry/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/registry/bool.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/registry/item.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/registry/name.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/sample/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/sample/peer.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/sample/program.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/schemas.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/subprocess/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/subprocess/interface.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/subprocess/peer.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/subprocess/program.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/subprocess/protocol.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/task/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/task/asynchronous.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/task/basic/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/task/basic/manager.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/task/sample.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/task/trig/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/telemetry/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/telemetry/sample.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/tui/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/tui/channels/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/tui/cursor.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/tui/mixin.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/tui/mock.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/tui/task.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/ui/__init__.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/ui/controls.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy/util.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy.egg-info/dependency_links.txt +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy.egg-info/entry_points.txt +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/runtimepy.egg-info/top_level.txt +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/setup.cfg +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/setup.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/tests/test_entry.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/tests/test_mapping.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/tests/test_resources.py +0 -0
- {runtimepy-5.15.4 → runtimepy-5.15.5}/tests/test_util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 5.15.
|
|
3
|
+
Version: 5.15.5
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/libre-embedded/runtimepy
|
|
6
6
|
Author: Libre Embedded
|
|
@@ -17,11 +17,11 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
17
17
|
Requires-Python: >=3.12
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
-
Requires-Dist: vcorelib>=3.6.3
|
|
21
|
-
Requires-Dist: websockets
|
|
22
|
-
Requires-Dist: svgen>=0.8.0
|
|
23
|
-
Requires-Dist: aiofiles
|
|
24
20
|
Requires-Dist: psutil
|
|
21
|
+
Requires-Dist: aiofiles
|
|
22
|
+
Requires-Dist: svgen>=0.8.0
|
|
23
|
+
Requires-Dist: websockets
|
|
24
|
+
Requires-Dist: vcorelib>=3.6.4
|
|
25
25
|
Provides-Extra: test
|
|
26
26
|
Requires-Dist: pylint; extra == "test"
|
|
27
27
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -51,11 +51,11 @@ Dynamic: requires-python
|
|
|
51
51
|
=====================================
|
|
52
52
|
generator=datazen
|
|
53
53
|
version=3.2.3
|
|
54
|
-
hash=
|
|
54
|
+
hash=fd0e57419cf9437a64c4f82cae3625f0
|
|
55
55
|
=====================================
|
|
56
56
|
-->
|
|
57
57
|
|
|
58
|
-
# runtimepy ([5.15.
|
|
58
|
+
# runtimepy ([5.15.5](https://pypi.org/project/runtimepy/))
|
|
59
59
|
|
|
60
60
|
[](https://pypi.org/project/runtimepy/)
|
|
61
61
|

|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
=====================================
|
|
3
3
|
generator=datazen
|
|
4
4
|
version=3.2.3
|
|
5
|
-
hash=
|
|
5
|
+
hash=fd0e57419cf9437a64c4f82cae3625f0
|
|
6
6
|
=====================================
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
|
-
# runtimepy ([5.15.
|
|
9
|
+
# runtimepy ([5.15.5](https://pypi.org/project/runtimepy/))
|
|
10
10
|
|
|
11
11
|
[](https://pypi.org/project/runtimepy/)
|
|
12
12
|

|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# =====================================
|
|
2
2
|
# generator=datazen
|
|
3
3
|
# version=3.2.3
|
|
4
|
-
# hash=
|
|
4
|
+
# hash=8ce7abe0f8c0e64d9afc0b5e4de6e2ad
|
|
5
5
|
# =====================================
|
|
6
6
|
|
|
7
7
|
"""
|
|
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
|
|
|
10
10
|
|
|
11
11
|
DESCRIPTION = "A framework for implementing Python services."
|
|
12
12
|
PKG_NAME = "runtimepy"
|
|
13
|
-
VERSION = "5.15.
|
|
13
|
+
VERSION = "5.15.5"
|
|
14
14
|
|
|
15
15
|
# runtimepy-specific content.
|
|
16
16
|
METRICS_NAME = "metrics"
|
|
@@ -20,6 +20,7 @@ from runtimepy.channel.environment.command.result import SUCCESS, CommandResult
|
|
|
20
20
|
from runtimepy.mixins.environment import ChannelEnvironmentMixin
|
|
21
21
|
from runtimepy.primitives.bool import Bool
|
|
22
22
|
from runtimepy.primitives.field import BitField
|
|
23
|
+
from runtimepy.ui.button import ActionButton
|
|
23
24
|
|
|
24
25
|
CommandHook = Callable[[Namespace, Optional[FieldOrChannel]], None]
|
|
25
26
|
|
|
@@ -33,7 +34,11 @@ class ChannelCommandProcessor(ChannelEnvironmentMixin):
|
|
|
33
34
|
"""A command processing interface for channel environments."""
|
|
34
35
|
|
|
35
36
|
def __init__(
|
|
36
|
-
self,
|
|
37
|
+
self,
|
|
38
|
+
env: ChannelEnvironment,
|
|
39
|
+
logger: LoggerType,
|
|
40
|
+
buttons: list[ActionButton] = None,
|
|
41
|
+
**kwargs,
|
|
37
42
|
) -> None:
|
|
38
43
|
"""Initialize this instance."""
|
|
39
44
|
|
|
@@ -49,6 +54,11 @@ class ChannelCommandProcessor(ChannelEnvironmentMixin):
|
|
|
49
54
|
|
|
50
55
|
self.parser.initialize()
|
|
51
56
|
|
|
57
|
+
# Action buttons.
|
|
58
|
+
if buttons is None:
|
|
59
|
+
buttons = []
|
|
60
|
+
self.buttons: list[ActionButton] = buttons
|
|
61
|
+
|
|
52
62
|
def register_custom_commands(
|
|
53
63
|
self, *custom_commands: CustomCommand
|
|
54
64
|
) -> None:
|
|
@@ -110,6 +110,10 @@ select:hover {
|
|
|
110
110
|
background-image: linear-gradient(to bottom, var(--bs-tertiary-bg), rgba(var(--bs-tertiary-bg-rgb), 0), var(--bs-tertiary-bg));
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
.bg-gradient-tertiary-left-right {
|
|
114
|
+
background-image: linear-gradient(to right, var(--bs-tertiary-bg), rgba(var(--bs-tertiary-bg-rgb), 0), var(--bs-tertiary-bg));
|
|
115
|
+
}
|
|
116
|
+
|
|
113
117
|
.border-start-info-subtle {
|
|
114
118
|
border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-info-border-subtle);
|
|
115
119
|
}
|
|
@@ -1,4 +1,42 @@
|
|
|
1
1
|
---
|
|
2
|
+
# UDP JSON clients.
|
|
3
|
+
clients:
|
|
4
|
+
- factory: udp_json
|
|
5
|
+
name: udp_json_client
|
|
6
|
+
defer: true
|
|
7
|
+
kwargs:
|
|
8
|
+
remote_addr: [localhost, "$udp_json"]
|
|
9
|
+
views:
|
|
10
|
+
- [metrics, metrics]
|
|
11
|
+
- [transmit, tx]
|
|
12
|
+
- [receive, rx]
|
|
13
|
+
buttons: &buttons
|
|
14
|
+
- icon: tux
|
|
15
|
+
key: test
|
|
16
|
+
payload: {}
|
|
17
|
+
- icon: tux
|
|
18
|
+
key: test
|
|
19
|
+
text: asdf
|
|
20
|
+
payload: {}
|
|
21
|
+
- icon: tux
|
|
22
|
+
key: test
|
|
23
|
+
payload: {}
|
|
24
|
+
outline: false
|
|
25
|
+
- icon: tux
|
|
26
|
+
key: test
|
|
27
|
+
text: asdf
|
|
28
|
+
payload: {}
|
|
29
|
+
outline: false
|
|
30
|
+
markdown: |
|
|
31
|
+
# `udp_json_client`
|
|
32
|
+
|
|
33
|
+
Connects to `udp_json_server`.
|
|
34
|
+
|
|
35
|
+
- factory: udp_json
|
|
36
|
+
name: udp_json_server
|
|
37
|
+
kwargs:
|
|
38
|
+
local_addr: [localhost, "$udp_json"]
|
|
39
|
+
|
|
2
40
|
# Add some sample tasks.
|
|
3
41
|
tasks:
|
|
4
42
|
# Chaos.
|
|
@@ -9,6 +47,7 @@ tasks:
|
|
|
9
47
|
a: 1
|
|
10
48
|
b: 2
|
|
11
49
|
c: 3
|
|
50
|
+
buttons: *buttons
|
|
12
51
|
views:
|
|
13
52
|
- [zero, "\\.0\\."]
|
|
14
53
|
- [one, "\\.1\\."]
|
|
@@ -49,27 +88,6 @@ tasks:
|
|
|
49
88
|
# Drive interactions with runtime entities that won't otherwise be polled.
|
|
50
89
|
- {name: app, factory: SampleApp, period_s: 0.25}
|
|
51
90
|
|
|
52
|
-
# UDP JSON clients.
|
|
53
|
-
clients:
|
|
54
|
-
- factory: udp_json
|
|
55
|
-
name: udp_json_client
|
|
56
|
-
defer: true
|
|
57
|
-
kwargs:
|
|
58
|
-
remote_addr: [localhost, "$udp_json"]
|
|
59
|
-
views:
|
|
60
|
-
- [metrics, metrics]
|
|
61
|
-
- [transmit, tx]
|
|
62
|
-
- [receive, rx]
|
|
63
|
-
markdown: |
|
|
64
|
-
# `udp_json_client`
|
|
65
|
-
|
|
66
|
-
Connects to `udp_json_server`.
|
|
67
|
-
|
|
68
|
-
- factory: udp_json
|
|
69
|
-
name: udp_json_server
|
|
70
|
-
kwargs:
|
|
71
|
-
local_addr: [localhost, "$udp_json"]
|
|
72
|
-
|
|
73
91
|
# Add some sample structs.
|
|
74
92
|
structs:
|
|
75
93
|
- name: example.struct1
|
|
@@ -80,6 +98,8 @@ structs:
|
|
|
80
98
|
b: 2
|
|
81
99
|
c: 3
|
|
82
100
|
|
|
101
|
+
buttons: *buttons
|
|
102
|
+
|
|
83
103
|
markdown: |
|
|
84
104
|
# Docs for `example.struct1`
|
|
85
105
|
|
|
@@ -10,7 +10,7 @@ class WorkerInterface {
|
|
|
10
10
|
|
|
11
11
|
command(data) { this.send({kind : "command", value : data}); }
|
|
12
12
|
|
|
13
|
-
bus(data) { this.worker.postMessage({bus : data}); }
|
|
13
|
+
bus(key, data) { this.worker.postMessage({key : key, bus : data}); }
|
|
14
14
|
|
|
15
15
|
toWorker(data, param) { return this.send({"worker" : data}, param); }
|
|
16
16
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
console.log(`sample.js included (${tab.name})`);
|
|
2
|
-
// tab.worker.bus({a: 1, b: 2, c: 3});
|
|
2
|
+
// tab.worker.bus("test", {a: 1, b: 2, c: 3});
|
|
@@ -47,6 +47,7 @@ from runtimepy.net.manager import ConnectionManager as _ConnectionManager
|
|
|
47
47
|
from runtimepy.net.server import RuntimepyServerConnection
|
|
48
48
|
from runtimepy.subprocess.peer import RuntimepyPeer as _RuntimepyPeer
|
|
49
49
|
from runtimepy.tui.mixin import CursesWindow, TuiMixin
|
|
50
|
+
from runtimepy.ui.button import ActionButton
|
|
50
51
|
|
|
51
52
|
ServerTask = _Awaitable[None]
|
|
52
53
|
RuntimeProcessTask = tuple[
|
|
@@ -148,6 +149,7 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
148
149
|
|
|
149
150
|
self._commands: list[tuple[str, str]] = []
|
|
150
151
|
self._views: dict[str, dict[str, str]] = {}
|
|
152
|
+
self._buttons: dict[str, list[ActionButton]] = {}
|
|
151
153
|
|
|
152
154
|
self._init()
|
|
153
155
|
|
|
@@ -157,9 +159,16 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
157
159
|
def _register_connection(self, connection: _Connection, name: str) -> None:
|
|
158
160
|
"""Perform connection registration."""
|
|
159
161
|
|
|
162
|
+
# Handle views.
|
|
160
163
|
if name in self._views:
|
|
161
164
|
connection.env.views.update(self._views[name])
|
|
162
165
|
del self._views[name]
|
|
166
|
+
|
|
167
|
+
# Handle buttons.
|
|
168
|
+
if name in self._buttons:
|
|
169
|
+
connection.command.buttons.extend(self._buttons[name])
|
|
170
|
+
del self._buttons[name]
|
|
171
|
+
|
|
163
172
|
self._connections[name] = connection
|
|
164
173
|
self.manager.queue.put_nowait(connection)
|
|
165
174
|
connection.logger.info("Registered as '%s'.", name)
|
|
@@ -170,6 +179,7 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
170
179
|
*names: str,
|
|
171
180
|
delim: str = None,
|
|
172
181
|
views: dict[str, str] = None,
|
|
182
|
+
buttons: list[ActionButton] = None,
|
|
173
183
|
) -> bool:
|
|
174
184
|
"""Attempt to register a connection object."""
|
|
175
185
|
|
|
@@ -180,6 +190,8 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
180
190
|
|
|
181
191
|
if views:
|
|
182
192
|
self._views[name] = views
|
|
193
|
+
if buttons:
|
|
194
|
+
self._buttons[name] = buttons
|
|
183
195
|
|
|
184
196
|
if (
|
|
185
197
|
name not in self._connections
|
|
@@ -180,6 +180,7 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
|
|
|
180
180
|
**fix_kwargs(kwargs),
|
|
181
181
|
views=client.get("views"),
|
|
182
182
|
markdown=client.get("markdown"),
|
|
183
|
+
buttons=client.get("buttons", []),
|
|
183
184
|
), f"Couldn't register client '{name}' ({factory})!"
|
|
184
185
|
|
|
185
186
|
# Register servers.
|
|
@@ -16,6 +16,7 @@ from runtimepy.net.arbiter.base import (
|
|
|
16
16
|
from runtimepy.net.arbiter.base import ServerTask as _ServerTask
|
|
17
17
|
from runtimepy.net.connection import Connection as _Connection
|
|
18
18
|
from runtimepy.net.manager import ConnectionManager as _ConnectionManager
|
|
19
|
+
from runtimepy.ui.button import ActionButton
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class ConnectionFactory:
|
|
@@ -90,6 +91,7 @@ class FactoryConnectionArbiter(_BaseConnectionArbiter):
|
|
|
90
91
|
factory_inst = self._conn_factories[factory]
|
|
91
92
|
|
|
92
93
|
views = kwargs.pop("views", {})
|
|
94
|
+
buttons = ActionButton.from_top_level(kwargs.pop("buttons", []))
|
|
93
95
|
|
|
94
96
|
conn = factory_inst.client(name, *args, **kwargs)
|
|
95
97
|
if not defer:
|
|
@@ -100,6 +102,7 @@ class FactoryConnectionArbiter(_BaseConnectionArbiter):
|
|
|
100
102
|
*self._conn_names[factory_inst],
|
|
101
103
|
name,
|
|
102
104
|
views=views,
|
|
105
|
+
buttons=buttons,
|
|
103
106
|
)
|
|
104
107
|
|
|
105
108
|
return result
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
A module implementing a channel-environment tab HTML interface.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
# built-in
|
|
6
|
+
from io import StringIO
|
|
7
|
+
|
|
5
8
|
# third-party
|
|
6
9
|
from vcorelib.io.markdown import MarkdownMixin
|
|
7
10
|
from vcorelib.logging import LoggerMixin
|
|
@@ -39,3 +42,11 @@ class ChannelEnvironmentTabBase(Tab, LoggerMixin, MarkdownMixin):
|
|
|
39
42
|
# Logging.
|
|
40
43
|
LoggerMixin.__init__(self, logger=self.command.logger)
|
|
41
44
|
self.log_limiter = RateLimiter.from_s(1.0)
|
|
45
|
+
|
|
46
|
+
def _action_markdown(self) -> str:
|
|
47
|
+
"""Get action-button markdown."""
|
|
48
|
+
|
|
49
|
+
with StringIO() as stream:
|
|
50
|
+
for button in self.command.buttons:
|
|
51
|
+
button.element().encode(stream)
|
|
52
|
+
return stream.getvalue()
|
|
@@ -289,6 +289,16 @@ class ChannelEnvironmentTabHtml(ChannelEnvironmentTabControls):
|
|
|
289
289
|
)
|
|
290
290
|
logs.booleans.add("readonly")
|
|
291
291
|
|
|
292
|
+
if self.command.buttons:
|
|
293
|
+
centered_markdown(
|
|
294
|
+
vert_container,
|
|
295
|
+
self._action_markdown(),
|
|
296
|
+
"border-start",
|
|
297
|
+
"border-bottom",
|
|
298
|
+
"border-end",
|
|
299
|
+
"bg-gradient-tertiary-left-right",
|
|
300
|
+
)
|
|
301
|
+
|
|
292
302
|
self.channel_table(vert_container)
|
|
293
303
|
|
|
294
304
|
centered_markdown(
|
|
@@ -84,15 +84,16 @@ def views_dropdown(parent: Element, command: ChannelCommandProcessor) -> None:
|
|
|
84
84
|
"""Dropdown menu for channel environment views."""
|
|
85
85
|
|
|
86
86
|
select = select_element(
|
|
87
|
-
parent=div(
|
|
87
|
+
parent=div(
|
|
88
|
+
tag="th", parent=parent, class_str="p-0 channel-views-min-width"
|
|
89
|
+
),
|
|
88
90
|
id="filter-view",
|
|
89
91
|
title="Canonical channel filters.",
|
|
90
92
|
).add_class("border-end-0", "w-100")
|
|
91
93
|
div(tag="option", value="", text="-", parent=select)
|
|
94
|
+
div(tag="option", value="^$", text="hide", parent=select)
|
|
92
95
|
for text, value in command.env.views.items():
|
|
93
96
|
div(tag="option", value=value, text=text, parent=select)
|
|
94
|
-
if not command.env.views:
|
|
95
|
-
select.booleans.add("disabled")
|
|
96
97
|
|
|
97
98
|
|
|
98
99
|
def channel_table_header(
|
|
@@ -120,7 +121,11 @@ def channel_table_header(
|
|
|
120
121
|
).add_class(*TABLE_BUTTON_CLASSES)
|
|
121
122
|
|
|
122
123
|
_, label, box = input_box(
|
|
123
|
-
div(
|
|
124
|
+
div(
|
|
125
|
+
tag="th",
|
|
126
|
+
parent=ctl_row,
|
|
127
|
+
class_str="p-0 border-end-0 channel-filter-min-width",
|
|
128
|
+
),
|
|
124
129
|
description="Channel name filter.",
|
|
125
130
|
pattern=".* ! @ $",
|
|
126
131
|
label="filter",
|
|
@@ -137,7 +142,7 @@ def channel_table_header(
|
|
|
137
142
|
parent=div(tag="th", parent=ctl_row, colspan="2", class_str="p-0")
|
|
138
143
|
)
|
|
139
144
|
|
|
140
|
-
# Add a selection menu for custom commands.
|
|
145
|
+
# Add a selection menu for custom commands.
|
|
141
146
|
select = select_element(
|
|
142
147
|
parent=cell, id="custom-commands", title="Custom command selector."
|
|
143
148
|
)
|
|
@@ -157,12 +162,7 @@ def channel_table_header(
|
|
|
157
162
|
tooltip="Send selected command (left dropdown).",
|
|
158
163
|
).add_class(*TABLE_BUTTON_CLASSES)
|
|
159
164
|
else:
|
|
160
|
-
div(
|
|
161
|
-
tag="option",
|
|
162
|
-
parent=select,
|
|
163
|
-
value="noop",
|
|
164
|
-
text="no custom commands",
|
|
165
|
-
)
|
|
165
|
+
div(tag="option", parent=select, value="noop", text="-")
|
|
166
166
|
select.booleans.add("disabled")
|
|
167
167
|
|
|
168
168
|
# Button for 'reset all defaults' if this tab has more than one channel
|
|
@@ -21,6 +21,7 @@ from runtimepy.channel.environment.command.processor import (
|
|
|
21
21
|
from runtimepy.mixins.async_command import AsyncCommandProcessingMixin
|
|
22
22
|
from runtimepy.mixins.environment import ChannelEnvironmentMixin
|
|
23
23
|
from runtimepy.mixins.logging import LoggerMixinLevelControl
|
|
24
|
+
from runtimepy.ui.button import ActionButton
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class RuntimeStructBase(
|
|
@@ -50,6 +51,7 @@ class RuntimeStructBase(
|
|
|
50
51
|
self.setup_level_channel(self.env)
|
|
51
52
|
self.command = ChannelCommandProcessor(self.env, self.logger)
|
|
52
53
|
self.config = config
|
|
54
|
+
self.command.buttons.extend(ActionButton.from_top_level(self.config))
|
|
53
55
|
|
|
54
56
|
async def poll(args: Namespace, __: Optional[FieldOrChannel]) -> None:
|
|
55
57
|
"""Handle a test command."""
|
|
@@ -33,6 +33,7 @@ from runtimepy.primitives import Bool as _Bool
|
|
|
33
33
|
from runtimepy.primitives import Double as _Double
|
|
34
34
|
from runtimepy.primitives import Float as _Float
|
|
35
35
|
from runtimepy.primitives.evaluation import EvalResult as _EvalResult
|
|
36
|
+
from runtimepy.ui.button import ActionButton
|
|
36
37
|
from runtimepy.ui.controls import Controlslike
|
|
37
38
|
|
|
38
39
|
|
|
@@ -75,6 +76,7 @@ class PeriodicTask(
|
|
|
75
76
|
self.env.views.update(self.config.get("views", {})) # type: ignore
|
|
76
77
|
self.setup_level_channel(self.env)
|
|
77
78
|
self.command = ChannelCommandProcessor(self.env, self.logger)
|
|
79
|
+
self.command.buttons.extend(ActionButton.from_top_level(self.config))
|
|
78
80
|
self.register_task_metrics(self.metrics)
|
|
79
81
|
|
|
80
82
|
# State.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A module implementing an action-button interface.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# built-in
|
|
6
|
+
from json import dumps
|
|
7
|
+
from typing import NamedTuple
|
|
8
|
+
|
|
9
|
+
# third-party
|
|
10
|
+
from svgen.element import Element
|
|
11
|
+
from svgen.element.html import div
|
|
12
|
+
from vcorelib.dict import GenericStrDict
|
|
13
|
+
|
|
14
|
+
# internal
|
|
15
|
+
from runtimepy.net.html.bootstrap import icon_str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ActionButton(NamedTuple):
|
|
19
|
+
"""A class implementing an interface for action buttons."""
|
|
20
|
+
|
|
21
|
+
key: str
|
|
22
|
+
payload: GenericStrDict
|
|
23
|
+
text: str
|
|
24
|
+
icon: str
|
|
25
|
+
variant: str
|
|
26
|
+
outline: bool
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def from_dict(data: GenericStrDict) -> "ActionButton":
|
|
30
|
+
"""Create an action button from dictionary data."""
|
|
31
|
+
|
|
32
|
+
return ActionButton(
|
|
33
|
+
data["key"],
|
|
34
|
+
data["payload"],
|
|
35
|
+
data.get("text", ""),
|
|
36
|
+
data.get("icon", ""),
|
|
37
|
+
data.get("variant", "primary"),
|
|
38
|
+
data.get("outline", True),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def from_top_level(
|
|
43
|
+
data: GenericStrDict | list[GenericStrDict],
|
|
44
|
+
) -> list["ActionButton"]:
|
|
45
|
+
"""Create an action button from dictionary data."""
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
[ActionButton.from_dict(x) for x in data.get("buttons", [])]
|
|
49
|
+
if isinstance(data, dict)
|
|
50
|
+
else [ActionButton.from_dict(x) for x in data]
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def element(self) -> Element:
|
|
54
|
+
"""Create an action button element."""
|
|
55
|
+
|
|
56
|
+
payload = dumps(self.payload).replace('"', """)
|
|
57
|
+
|
|
58
|
+
text_parts = []
|
|
59
|
+
if self.icon:
|
|
60
|
+
text_parts.append(
|
|
61
|
+
icon_str(
|
|
62
|
+
self.icon,
|
|
63
|
+
[f"text-{self.variant}-emphasis"] if self.text else [],
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
if self.text:
|
|
67
|
+
text_parts.append(self.text)
|
|
68
|
+
|
|
69
|
+
return div(
|
|
70
|
+
tag="button",
|
|
71
|
+
type="button",
|
|
72
|
+
onclick=f"tabs[shown_tab].worker.bus('{self.key}', {payload})",
|
|
73
|
+
class_str=f"btn btn{'-outline' if self.outline else ''}"
|
|
74
|
+
f"-{self.variant} m-2 ms-1 me-0",
|
|
75
|
+
text=" ".join(text_parts),
|
|
76
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 5.15.
|
|
3
|
+
Version: 5.15.5
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/libre-embedded/runtimepy
|
|
6
6
|
Author: Libre Embedded
|
|
@@ -17,11 +17,11 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
17
17
|
Requires-Python: >=3.12
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
-
Requires-Dist: vcorelib>=3.6.3
|
|
21
|
-
Requires-Dist: websockets
|
|
22
|
-
Requires-Dist: svgen>=0.8.0
|
|
23
|
-
Requires-Dist: aiofiles
|
|
24
20
|
Requires-Dist: psutil
|
|
21
|
+
Requires-Dist: aiofiles
|
|
22
|
+
Requires-Dist: svgen>=0.8.0
|
|
23
|
+
Requires-Dist: websockets
|
|
24
|
+
Requires-Dist: vcorelib>=3.6.4
|
|
25
25
|
Provides-Extra: test
|
|
26
26
|
Requires-Dist: pylint; extra == "test"
|
|
27
27
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -51,11 +51,11 @@ Dynamic: requires-python
|
|
|
51
51
|
=====================================
|
|
52
52
|
generator=datazen
|
|
53
53
|
version=3.2.3
|
|
54
|
-
hash=
|
|
54
|
+
hash=fd0e57419cf9437a64c4f82cae3625f0
|
|
55
55
|
=====================================
|
|
56
56
|
-->
|
|
57
57
|
|
|
58
|
-
# runtimepy ([5.15.
|
|
58
|
+
# runtimepy ([5.15.5](https://pypi.org/project/runtimepy/))
|
|
59
59
|
|
|
60
60
|
[](https://pypi.org/project/runtimepy/)
|
|
61
61
|

|
|
@@ -102,6 +102,7 @@ runtimepy/data/md/RuntimeStruct.md
|
|
|
102
102
|
runtimepy/data/md/RuntimepyPeer.md
|
|
103
103
|
runtimepy/data/md/SinusoidTask.md
|
|
104
104
|
runtimepy/data/schemas/BitFields.yaml
|
|
105
|
+
runtimepy/data/schemas/Button.yaml
|
|
105
106
|
runtimepy/data/schemas/Channel.yaml
|
|
106
107
|
runtimepy/data/schemas/ChannelCommand.yaml
|
|
107
108
|
runtimepy/data/schemas/ChannelRegistry.yaml
|
|
@@ -116,6 +117,7 @@ runtimepy/data/schemas/StructConfig.yaml
|
|
|
116
117
|
runtimepy/data/schemas/TaskConfig.yaml
|
|
117
118
|
runtimepy/data/schemas/TwoTupleArray.yaml
|
|
118
119
|
runtimepy/data/schemas/channel_controls.yaml
|
|
120
|
+
runtimepy/data/schemas/has_buttons.yaml
|
|
119
121
|
runtimepy/data/schemas/has_config.yaml
|
|
120
122
|
runtimepy/data/schemas/has_factory.yaml
|
|
121
123
|
runtimepy/data/schemas/has_markdown.yaml
|
|
@@ -317,6 +319,7 @@ runtimepy/tui/mock.py
|
|
|
317
319
|
runtimepy/tui/task.py
|
|
318
320
|
runtimepy/tui/channels/__init__.py
|
|
319
321
|
runtimepy/ui/__init__.py
|
|
322
|
+
runtimepy/ui/button.py
|
|
320
323
|
runtimepy/ui/controls.py
|
|
321
324
|
tests/test_entry.py
|
|
322
325
|
tests/test_mapping.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|