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

|
|
@@ -114,12 +114,14 @@ runtimepy/data/schemas/RuntimeEnum.yaml
|
|
|
114
114
|
runtimepy/data/schemas/ServerConnectionConfig.yaml
|
|
115
115
|
runtimepy/data/schemas/StructConfig.yaml
|
|
116
116
|
runtimepy/data/schemas/TaskConfig.yaml
|
|
117
|
+
runtimepy/data/schemas/TwoTupleArray.yaml
|
|
117
118
|
runtimepy/data/schemas/channel_controls.yaml
|
|
118
119
|
runtimepy/data/schemas/has_config.yaml
|
|
119
120
|
runtimepy/data/schemas/has_factory.yaml
|
|
120
121
|
runtimepy/data/schemas/has_markdown.yaml
|
|
121
122
|
runtimepy/data/schemas/has_name.yaml
|
|
122
123
|
runtimepy/data/schemas/has_request_flag.yaml
|
|
124
|
+
runtimepy/data/schemas/has_views.yaml
|
|
123
125
|
runtimepy/data/static/css/bootstrap-icons.min.css
|
|
124
126
|
runtimepy/data/static/css/bootstrap.min.css
|
|
125
127
|
runtimepy/data/static/css/fonts/bootstrap-icons.woff
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|