runtimepy 4.2.2__tar.gz → 4.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {runtimepy-4.2.2/runtimepy.egg-info → runtimepy-4.3.0}/PKG-INFO +5 -5
- {runtimepy-4.2.2 → runtimepy-4.3.0}/README.md +2 -2
- {runtimepy-4.2.2 → runtimepy-4.3.0}/pyproject.toml +1 -1
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/__init__.py +2 -2
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/dummy_load.yaml +9 -1
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/message/interface.py +18 -6
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/env/__init__.py +19 -1
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/sample/peer.py +17 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/sample/program.py +36 -25
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/subprocess/interface.py +37 -1
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/subprocess/peer.py +12 -4
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/subprocess/program.py +33 -1
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/task/sample.py +1 -1
- {runtimepy-4.2.2 → runtimepy-4.3.0/runtimepy.egg-info}/PKG-INFO +5 -5
- {runtimepy-4.2.2 → runtimepy-4.3.0}/LICENSE +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/__main__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/app.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/array.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/command/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/command/parser.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/command/processor.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/command/result.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/create.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/file.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/sample.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/environment/telemetry.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/event/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/event/header.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/channel/registry.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/codec/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/codec/protocol/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/codec/protocol/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/codec/protocol/json.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/codec/system/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/commands/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/commands/all.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/commands/arbiter.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/commands/common.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/commands/server.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/commands/task.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/commands/tui.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/css/bootstrap_extra.css +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/css/main.css +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/factories.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/favicon.ico +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/DataConnection.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/JsonConnection.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/audio.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/App.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/ChannelTable.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/DataConnection.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/JsonConnection.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/Plot.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/PlotManager.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/TabFilter.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/TabInterface.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/WindowHashManager.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/classes/WorkerInterface.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/init.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/main.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/tab/env.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/tab/sound.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/unused/pyodide.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/util.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/js/worker.js +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/BitFields.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/Channel.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/ClientConnectionConfig.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/FindFile.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/PeerProcessConfig.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/StructConfig.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/TaskConfig.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/has_config.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/has_factory.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/has_name.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/server.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/server_base.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/data/server_dev.yaml +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/dev_requirements.txt +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/entry.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/enum/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/enum/registry.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/enum/types.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mapping.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/message/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/message/handlers.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/message/types.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/metrics/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/metrics/channel.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/metrics/connection.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/metrics/task.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/async_command.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/enum.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/environment.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/finalize.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/logging.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/psutil.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/mixins/regex.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/apps/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/config/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/config/codec.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/config/util.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/factory/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/factory/connection.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/factory/task.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/imports/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/imports/util.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/info.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/result.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/task.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/tcp/json.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/udp.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/arbiter/websocket.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/backoff.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/connection.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/factories/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/http/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/http/common.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/http/header.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/http/request_target.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/http/response.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/http/state.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/http/version.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/manager.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/mixin.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/bootstrap/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/bootstrap/elements.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/bootstrap/tabs.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/create.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/elements.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/env/modal.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/env/tab/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/env/tab/html.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/env/tab/message.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/env/widgets.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/files.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/placeholder.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/pyodide.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/sound.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/app/tab.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/html.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/json.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/struct/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/websocket/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/server/websocket/state.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/stream/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/stream/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/stream/json/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/stream/string.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/tcp/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/tcp/connection.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/tcp/create.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/tcp/http/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/tcp/protocol.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/tcp/telnet/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/tcp/telnet/codes.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/udp/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/udp/connection.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/udp/create.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/udp/protocol.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/util.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/websocket/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/net/websocket/connection.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/array/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/bool.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/byte_order.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/field/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/field/fields.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/field/manager/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/field/manager/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/float.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/int.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/scaling.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/serializable/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/serializable/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/serializable/fixed.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/serializable/prefixed.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/string.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/types/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/types/base.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/types/bool.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/types/bounds.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/types/float.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/primitives/types/int.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/py.typed +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/registry/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/registry/bool.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/registry/item.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/registry/name.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/requirements.txt +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/sample/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/schemas.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/struct/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/subprocess/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/subprocess/protocol.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/task/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/task/asynchronous.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/task/basic/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/task/basic/manager.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/task/basic/periodic.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/task/trig/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/telemetry/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/tui/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/tui/channels/__init__.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/tui/cursor.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/tui/mixin.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/tui/mock.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/tui/task.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy/util.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy.egg-info/SOURCES.txt +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy.egg-info/dependency_links.txt +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy.egg-info/entry_points.txt +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy.egg-info/requires.txt +2 -2
- {runtimepy-4.2.2 → runtimepy-4.3.0}/runtimepy.egg-info/top_level.txt +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/setup.cfg +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/setup.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/tests/test_entry.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/tests/test_mapping.py +0 -0
- {runtimepy-4.2.2 → runtimepy-4.3.0}/tests/test_resources.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/vkottler/runtimepy
|
|
6
6
|
Author: Vaughn Kottler
|
|
@@ -17,10 +17,10 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
17
17
|
Requires-Python: >=3.11
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
-
Requires-Dist:
|
|
20
|
+
Requires-Dist: websockets
|
|
21
21
|
Requires-Dist: vcorelib>=3.2.4
|
|
22
22
|
Requires-Dist: svgen>=0.6.6
|
|
23
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: psutil
|
|
24
24
|
Provides-Extra: test
|
|
25
25
|
Requires-Dist: pylint; extra == "test"
|
|
26
26
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -44,11 +44,11 @@ Requires-Dist: uvloop; (sys_platform != "win32" and sys_platform != "cygwin") an
|
|
|
44
44
|
=====================================
|
|
45
45
|
generator=datazen
|
|
46
46
|
version=3.1.4
|
|
47
|
-
hash=
|
|
47
|
+
hash=2adcb8a8e9a6b4dffec41ec316de0fee
|
|
48
48
|
=====================================
|
|
49
49
|
-->
|
|
50
50
|
|
|
51
|
-
# runtimepy ([4.
|
|
51
|
+
# runtimepy ([4.3.0](https://pypi.org/project/runtimepy/))
|
|
52
52
|
|
|
53
53
|
[](https://pypi.org/project/runtimepy/)
|
|
54
54
|

|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
=====================================
|
|
3
3
|
generator=datazen
|
|
4
4
|
version=3.1.4
|
|
5
|
-
hash=
|
|
5
|
+
hash=2adcb8a8e9a6b4dffec41ec316de0fee
|
|
6
6
|
=====================================
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
|
-
# runtimepy ([4.
|
|
9
|
+
# runtimepy ([4.3.0](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.1.4
|
|
4
|
-
# hash=
|
|
4
|
+
# hash=1bcf34402e57d84b3694f43c457d2a50
|
|
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 = "4.
|
|
13
|
+
VERSION = "4.3.0"
|
|
14
14
|
|
|
15
15
|
# runtimepy-specific content.
|
|
16
16
|
METRICS_NAME = "metrics"
|
|
@@ -45,5 +45,13 @@ structs:
|
|
|
45
45
|
processes:
|
|
46
46
|
- name: proc1
|
|
47
47
|
factory: sample_peer
|
|
48
|
-
|
|
48
|
+
|
|
49
|
+
# The peer itself runs an arbiter process.
|
|
50
|
+
config:
|
|
51
|
+
includes:
|
|
52
|
+
- package://runtimepy/server.yaml
|
|
53
|
+
|
|
54
|
+
app: runtimepy.sample.program.run
|
|
55
|
+
config: *cfg
|
|
56
|
+
|
|
49
57
|
program: runtimepy.sample.program.SampleProgram
|
|
@@ -108,6 +108,13 @@ class JsonMessageInterface:
|
|
|
108
108
|
async def poll_handler(self) -> None:
|
|
109
109
|
"""Poll this instance."""
|
|
110
110
|
|
|
111
|
+
def send_poll(self, loopback: int = 1) -> None:
|
|
112
|
+
"""
|
|
113
|
+
Send a poll message with a default loopback of 1, so that this instance
|
|
114
|
+
will also be polled.
|
|
115
|
+
"""
|
|
116
|
+
self.send_json({"poll": {"loopback": loopback}})
|
|
117
|
+
|
|
111
118
|
async def _poll_handler(
|
|
112
119
|
self, outbox: JsonMessage, inbox: JsonMessage
|
|
113
120
|
) -> None:
|
|
@@ -193,6 +200,16 @@ class JsonMessageInterface:
|
|
|
193
200
|
self.processor.encode_json(stream, data)
|
|
194
201
|
self.write(stream.getvalue(), addr=addr)
|
|
195
202
|
|
|
203
|
+
def handle_log_message(self, message: JsonMessage) -> None:
|
|
204
|
+
"""Handle a log message."""
|
|
205
|
+
|
|
206
|
+
if "msg" in message and message["msg"]:
|
|
207
|
+
self.logger.log(
|
|
208
|
+
message.get("level", logging.INFO),
|
|
209
|
+
"remote: " + message["msg"],
|
|
210
|
+
*message.get("args", []),
|
|
211
|
+
)
|
|
212
|
+
|
|
196
213
|
def _handle_reserved(
|
|
197
214
|
self, data: JsonMessage, response: JsonMessage
|
|
198
215
|
) -> bool:
|
|
@@ -218,12 +235,7 @@ class JsonMessageInterface:
|
|
|
218
235
|
# Log messages sent by the peer.
|
|
219
236
|
if "__log_messages__" in data:
|
|
220
237
|
for message in data["__log_messages__"]:
|
|
221
|
-
|
|
222
|
-
self.logger.log(
|
|
223
|
-
message.get("level", logging.INFO),
|
|
224
|
-
"remote: " + message["msg"],
|
|
225
|
-
*message.get("args", []),
|
|
226
|
-
)
|
|
238
|
+
self.handle_log_message(message)
|
|
227
239
|
del data["__log_messages__"]
|
|
228
240
|
|
|
229
241
|
return should_respond
|
|
@@ -14,6 +14,7 @@ from runtimepy.net.server.app.env.modal import Modal
|
|
|
14
14
|
from runtimepy.net.server.app.env.tab import ChannelEnvironmentTab
|
|
15
15
|
from runtimepy.net.server.app.placeholder import dummy_tabs, under_construction
|
|
16
16
|
from runtimepy.net.server.app.sound import SoundTab
|
|
17
|
+
from runtimepy.subprocess.program import PROGRAM
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
def channel_environments(app: AppInfo, tabs: TabbedContent) -> None:
|
|
@@ -44,7 +45,7 @@ def channel_environments(app: AppInfo, tabs: TabbedContent) -> None:
|
|
|
44
45
|
).entry()
|
|
45
46
|
|
|
46
47
|
# Subprocess tabs.
|
|
47
|
-
for
|
|
48
|
+
for peer in app.peers.values():
|
|
48
49
|
# Host side.
|
|
49
50
|
ChannelEnvironmentTab(
|
|
50
51
|
peer.struct.name, peer.struct.command, app, tabs, icon="cpu-fill"
|
|
@@ -56,6 +57,23 @@ def channel_environments(app: AppInfo, tabs: TabbedContent) -> None:
|
|
|
56
57
|
peer.peer_name, peer.peer, app, tabs, icon="cpu"
|
|
57
58
|
).entry()
|
|
58
59
|
|
|
60
|
+
# If we are a peer program, load environments.
|
|
61
|
+
if PROGRAM is not None:
|
|
62
|
+
# Host side.
|
|
63
|
+
ChannelEnvironmentTab(
|
|
64
|
+
PROGRAM.struct.name,
|
|
65
|
+
PROGRAM.struct.command,
|
|
66
|
+
app,
|
|
67
|
+
tabs,
|
|
68
|
+
icon="cpu-fill",
|
|
69
|
+
).entry()
|
|
70
|
+
|
|
71
|
+
# Remote side.
|
|
72
|
+
assert PROGRAM.peer is not None
|
|
73
|
+
ChannelEnvironmentTab(
|
|
74
|
+
PROGRAM.peer_name, PROGRAM.peer, app, tabs, icon="cpu"
|
|
75
|
+
).entry()
|
|
76
|
+
|
|
59
77
|
# Toggle channel-table button.
|
|
60
78
|
tabs.add_button(
|
|
61
79
|
"Toggle channel table",
|
|
@@ -6,6 +6,8 @@ A sample peer program interface.
|
|
|
6
6
|
import asyncio
|
|
7
7
|
|
|
8
8
|
# internal
|
|
9
|
+
from runtimepy.net.http.header import RequestHeader
|
|
10
|
+
from runtimepy.net.tcp.http import HttpConnection
|
|
9
11
|
from runtimepy.subprocess.peer import RuntimepyPeer
|
|
10
12
|
|
|
11
13
|
|
|
@@ -35,3 +37,18 @@ class SamplePeer(RuntimepyPeer):
|
|
|
35
37
|
await asyncio.sleep(0)
|
|
36
38
|
|
|
37
39
|
self.struct.poll()
|
|
40
|
+
|
|
41
|
+
# Query UI.
|
|
42
|
+
if self.peer_config is not None and "servers" in self.peer_config:
|
|
43
|
+
for server in self.peer_config["servers"]:
|
|
44
|
+
if server["factory"] == "runtimepy_http":
|
|
45
|
+
port = server["kwargs"]["port"]
|
|
46
|
+
|
|
47
|
+
conn = await HttpConnection.create_connection(
|
|
48
|
+
host="localhost", port=port
|
|
49
|
+
)
|
|
50
|
+
sig = asyncio.Event()
|
|
51
|
+
task = asyncio.create_task(conn.process(stop_sig=sig))
|
|
52
|
+
await conn.request(RequestHeader(target="/index.html"))
|
|
53
|
+
sig.set()
|
|
54
|
+
await task
|
|
@@ -6,6 +6,7 @@ A module implementing a sample peer-program interface.
|
|
|
6
6
|
import asyncio
|
|
7
7
|
|
|
8
8
|
# internal
|
|
9
|
+
from runtimepy.net.arbiter.info import AppInfo
|
|
9
10
|
from runtimepy.subprocess.program import PeerProgram
|
|
10
11
|
|
|
11
12
|
|
|
@@ -35,36 +36,46 @@ class SampleProgram(PeerProgram):
|
|
|
35
36
|
with self.streaming_events():
|
|
36
37
|
self.struct.poll()
|
|
37
38
|
|
|
38
|
-
async def
|
|
39
|
-
"""
|
|
39
|
+
async def cleanup(self) -> None:
|
|
40
|
+
"""Runs when program 'running' context exits."""
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
# Cancel stderr task.
|
|
43
|
+
if hasattr(self, "stderr_task"):
|
|
44
|
+
self.stderr_task.cancel()
|
|
45
|
+
await self.stderr_task
|
|
42
46
|
|
|
43
|
-
self.struct.poll()
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
for cmd in [
|
|
48
|
-
"set a.0.really_really_long_enum very_long_member_name_2",
|
|
49
|
-
"set -f a.0.enum one",
|
|
50
|
-
]:
|
|
51
|
-
self.peer.command(cmd)
|
|
52
|
-
await self.process_command_queue()
|
|
48
|
+
async def run(app: AppInfo) -> int:
|
|
49
|
+
"""A network application that doesn't do anything."""
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
did_write = asyncio.Event()
|
|
56
|
-
self.stderr_task = asyncio.create_task(
|
|
57
|
-
self.log_message_sender(0.1, did_write)
|
|
58
|
-
)
|
|
59
|
-
await did_write.wait()
|
|
51
|
+
await app.all_finalized()
|
|
60
52
|
|
|
61
|
-
|
|
53
|
+
prog = SampleProgram.singleton()
|
|
62
54
|
|
|
63
|
-
|
|
55
|
+
await prog.share_config({"config": app.original_config()})
|
|
64
56
|
|
|
65
|
-
|
|
66
|
-
"""Runs when program 'running' context exits."""
|
|
57
|
+
assert prog is not None
|
|
67
58
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
59
|
+
prog.struct.poll()
|
|
60
|
+
|
|
61
|
+
# Send remote commands.
|
|
62
|
+
assert prog.peer is not None
|
|
63
|
+
for cmd in [
|
|
64
|
+
"set a.0.really_really_long_enum very_long_member_name_2",
|
|
65
|
+
"set -f a.0.enum one",
|
|
66
|
+
]:
|
|
67
|
+
prog.peer.command(cmd)
|
|
68
|
+
await prog.process_command_queue()
|
|
69
|
+
|
|
70
|
+
# Register other async tasks.
|
|
71
|
+
did_write = asyncio.Event()
|
|
72
|
+
prog.stderr_task = asyncio.create_task(
|
|
73
|
+
prog.log_message_sender(0.1, did_write)
|
|
74
|
+
)
|
|
75
|
+
await did_write.wait()
|
|
76
|
+
|
|
77
|
+
prog.struct.poll()
|
|
78
|
+
|
|
79
|
+
await prog.wait_json({"a": 1, "b": 2, "c": 3})
|
|
80
|
+
|
|
81
|
+
return 0
|
|
@@ -6,7 +6,8 @@ A module implementing a runtimepy peer interface.
|
|
|
6
6
|
from argparse import Namespace
|
|
7
7
|
import asyncio
|
|
8
8
|
from io import BytesIO
|
|
9
|
-
from
|
|
9
|
+
from json import dumps
|
|
10
|
+
from logging import INFO, getLogger
|
|
10
11
|
from typing import Optional
|
|
11
12
|
|
|
12
13
|
# third-party
|
|
@@ -48,6 +49,8 @@ class RuntimepyPeerInterface(
|
|
|
48
49
|
self.struct = self.struct_type(self.basename + HOST_SUFFIX, config)
|
|
49
50
|
|
|
50
51
|
self.peer: Optional[RemoteCommandProcessor] = None
|
|
52
|
+
self.peer_config: Optional[JsonMessage] = None
|
|
53
|
+
self.peer_config_event = asyncio.Event()
|
|
51
54
|
self._peer_env_event = asyncio.Event()
|
|
52
55
|
|
|
53
56
|
# Set these for JsonMessageInterface.
|
|
@@ -63,6 +66,18 @@ class RuntimepyPeerInterface(
|
|
|
63
66
|
def struct_pre_finalize(self) -> None:
|
|
64
67
|
"""Configure struct before finalization."""
|
|
65
68
|
|
|
69
|
+
def handle_log_message(self, message: JsonMessage) -> None:
|
|
70
|
+
"""Handle a log message."""
|
|
71
|
+
|
|
72
|
+
logger = self.logger
|
|
73
|
+
msg = "remote: " + message["msg"]
|
|
74
|
+
|
|
75
|
+
if self.peer is not None:
|
|
76
|
+
logger = self.peer.logger
|
|
77
|
+
msg = message["msg"]
|
|
78
|
+
|
|
79
|
+
logger.log(message.get("level", INFO), msg, *message.get("args", []))
|
|
80
|
+
|
|
66
81
|
@property
|
|
67
82
|
def peer_name(self) -> str:
|
|
68
83
|
"""Get the name of the peer's environment."""
|
|
@@ -131,6 +146,27 @@ class RuntimepyPeerInterface(
|
|
|
131
146
|
|
|
132
147
|
self.basic_handler("env", env_handler)
|
|
133
148
|
|
|
149
|
+
async def config_handler(
|
|
150
|
+
outbox: JsonMessage, inbox: JsonMessage
|
|
151
|
+
) -> None:
|
|
152
|
+
"""Store peer's configuration."""
|
|
153
|
+
|
|
154
|
+
if self.peer_config is None:
|
|
155
|
+
self.peer_config = inbox["config"]
|
|
156
|
+
outbox["config"] = self.struct.config
|
|
157
|
+
self.logger.info(
|
|
158
|
+
"Peer's configuration: '%s'.",
|
|
159
|
+
dumps(self.peer_config, indent=4),
|
|
160
|
+
)
|
|
161
|
+
self.peer_config_event.set()
|
|
162
|
+
|
|
163
|
+
self.basic_handler("config", config_handler)
|
|
164
|
+
|
|
165
|
+
async def share_config(self, data: JsonMessage) -> None:
|
|
166
|
+
"""Exchange configuration data."""
|
|
167
|
+
|
|
168
|
+
await self.wait_json({"config": data})
|
|
169
|
+
|
|
134
170
|
async def share_environment(self) -> None:
|
|
135
171
|
"""Exchange channel environments."""
|
|
136
172
|
|
|
@@ -10,7 +10,7 @@ from sys import executable
|
|
|
10
10
|
from typing import AsyncIterator, Type, TypeVar
|
|
11
11
|
|
|
12
12
|
# third-party
|
|
13
|
-
from vcorelib.io import ARBITER
|
|
13
|
+
from vcorelib.io import ARBITER, DEFAULT_INCLUDES_KEY
|
|
14
14
|
from vcorelib.io.file_writer import IndentedFileWriter
|
|
15
15
|
from vcorelib.io.types import JsonObject
|
|
16
16
|
from vcorelib.paths.context import tempfile
|
|
@@ -73,7 +73,6 @@ class RuntimepyPeer(RuntimepyPeerInterface):
|
|
|
73
73
|
with suppress(AssertionError):
|
|
74
74
|
if await self.loopback():
|
|
75
75
|
await self.wait_json({"meta": self.meta})
|
|
76
|
-
|
|
77
76
|
await self.share_environment()
|
|
78
77
|
|
|
79
78
|
yield self
|
|
@@ -122,7 +121,7 @@ class RuntimepyPeer(RuntimepyPeerInterface):
|
|
|
122
121
|
|
|
123
122
|
writer.write("import sys")
|
|
124
123
|
writer.write("from vcorelib.asyncio import run_handle_interrupt")
|
|
125
|
-
writer.write("from vcorelib.io import ARBITER")
|
|
124
|
+
writer.write("from vcorelib.io import ARBITER, DEFAULT_INCLUDES_KEY")
|
|
126
125
|
|
|
127
126
|
from_str, to_import = import_str_and_item(import_str)
|
|
128
127
|
writer.write(f"from {from_str} import {to_import}")
|
|
@@ -135,7 +134,8 @@ class RuntimepyPeer(RuntimepyPeerInterface):
|
|
|
135
134
|
writer.write(
|
|
136
135
|
f'run_handle_interrupt({to_import}.run("{name}", '
|
|
137
136
|
"ARBITER.decode(CONFIG_PATH, "
|
|
138
|
-
"require_success=True
|
|
137
|
+
"require_success=True, includes_key=DEFAULT_INCLUDES_KEY"
|
|
138
|
+
").data, sys.argv))"
|
|
139
139
|
)
|
|
140
140
|
writer.write("sys.exit(0)")
|
|
141
141
|
|
|
@@ -155,6 +155,14 @@ class RuntimepyPeer(RuntimepyPeerInterface):
|
|
|
155
155
|
# Encode configuration data.
|
|
156
156
|
assert ARBITER.encode(config_path, config)[0]
|
|
157
157
|
|
|
158
|
+
# Decode to load includes.
|
|
159
|
+
config = ARBITER.decode(
|
|
160
|
+
config_path,
|
|
161
|
+
require_success=True,
|
|
162
|
+
includes_key=DEFAULT_INCLUDES_KEY,
|
|
163
|
+
).data
|
|
164
|
+
assert ARBITER.encode(config_path, config)[0]
|
|
165
|
+
|
|
158
166
|
with tempfile(suffix=".py") as path:
|
|
159
167
|
# Write file contents.
|
|
160
168
|
with IndentedFileWriter.from_path(
|
|
@@ -9,18 +9,22 @@ import logging
|
|
|
9
9
|
import os
|
|
10
10
|
import signal
|
|
11
11
|
import sys
|
|
12
|
-
from typing import AsyncIterator, BinaryIO, Iterator, Type, TypeVar
|
|
12
|
+
from typing import AsyncIterator, BinaryIO, Iterator, Optional, Type, TypeVar
|
|
13
13
|
|
|
14
14
|
# third-party
|
|
15
|
+
from vcorelib.io import ARBITER
|
|
15
16
|
from vcorelib.io.types import JsonObject
|
|
17
|
+
from vcorelib.paths.context import tempfile
|
|
16
18
|
|
|
17
19
|
# internal
|
|
18
20
|
from runtimepy.metrics.channel import ChannelMetrics
|
|
19
21
|
from runtimepy.mixins.psutil import PsutilMixin
|
|
22
|
+
from runtimepy.net.arbiter import ConnectionArbiter
|
|
20
23
|
from runtimepy.net.arbiter.info import RuntimeStruct, SampleStruct
|
|
21
24
|
from runtimepy.subprocess.interface import RuntimepyPeerInterface
|
|
22
25
|
|
|
23
26
|
T = TypeVar("T", bound="PeerProgram")
|
|
27
|
+
PROGRAM: Optional["PeerProgram"] = None
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
class PeerProgram(RuntimepyPeerInterface, PsutilMixin):
|
|
@@ -32,6 +36,16 @@ class PeerProgram(RuntimepyPeerInterface, PsutilMixin):
|
|
|
32
36
|
|
|
33
37
|
struct_type: Type[RuntimeStruct] = SampleStruct
|
|
34
38
|
|
|
39
|
+
got_eof: asyncio.Event
|
|
40
|
+
|
|
41
|
+
_singleton: Optional["PeerProgram"] = None
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def singleton(cls: type[T]) -> T:
|
|
45
|
+
"""Get a shared single instance of a protocol for this class."""
|
|
46
|
+
assert cls._singleton is not None
|
|
47
|
+
return cls._singleton # type: ignore
|
|
48
|
+
|
|
35
49
|
@contextmanager
|
|
36
50
|
def streaming_events(self) -> Iterator[None]:
|
|
37
51
|
"""Stream events to the stream output."""
|
|
@@ -104,6 +118,9 @@ class PeerProgram(RuntimepyPeerInterface, PsutilMixin):
|
|
|
104
118
|
self.stdin_metrics.increment(accumulator)
|
|
105
119
|
accumulator = 0
|
|
106
120
|
|
|
121
|
+
# Signal the end of input processing.
|
|
122
|
+
self.got_eof.set()
|
|
123
|
+
|
|
107
124
|
@classmethod
|
|
108
125
|
def run_standard(
|
|
109
126
|
cls: Type[T], name: str, config: JsonObject
|
|
@@ -113,13 +130,28 @@ class PeerProgram(RuntimepyPeerInterface, PsutilMixin):
|
|
|
113
130
|
peer = cls(name, config)
|
|
114
131
|
peer.json_output = sys.stdout.buffer
|
|
115
132
|
peer.stream_output = sys.stderr.buffer
|
|
133
|
+
peer.got_eof = asyncio.Event()
|
|
116
134
|
peer.stream_metrics = ChannelMetrics()
|
|
117
135
|
|
|
136
|
+
global PROGRAM # pylint: disable=global-statement
|
|
137
|
+
PROGRAM = peer
|
|
138
|
+
assert cls._singleton is None
|
|
139
|
+
cls._singleton = peer
|
|
140
|
+
|
|
118
141
|
return asyncio.create_task(peer.io_task(sys.stdin.buffer)), peer
|
|
119
142
|
|
|
120
143
|
async def main(self, argv: list[str]) -> None:
|
|
121
144
|
"""Program entry."""
|
|
122
145
|
|
|
146
|
+
del argv
|
|
147
|
+
|
|
148
|
+
with tempfile(suffix=".json") as config_path:
|
|
149
|
+
arbiter = ConnectionArbiter(stop_sig=self.got_eof)
|
|
150
|
+
ARBITER.encode(config_path, self.struct.config)
|
|
151
|
+
await arbiter.load_configs([config_path], wait_for_stop=True)
|
|
152
|
+
|
|
153
|
+
await arbiter.app()
|
|
154
|
+
|
|
123
155
|
async def cleanup(self) -> None:
|
|
124
156
|
"""Runs when program 'running' context exits."""
|
|
125
157
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/vkottler/runtimepy
|
|
6
6
|
Author: Vaughn Kottler
|
|
@@ -17,10 +17,10 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
17
17
|
Requires-Python: >=3.11
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
-
Requires-Dist:
|
|
20
|
+
Requires-Dist: websockets
|
|
21
21
|
Requires-Dist: vcorelib>=3.2.4
|
|
22
22
|
Requires-Dist: svgen>=0.6.6
|
|
23
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: psutil
|
|
24
24
|
Provides-Extra: test
|
|
25
25
|
Requires-Dist: pylint; extra == "test"
|
|
26
26
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -44,11 +44,11 @@ Requires-Dist: uvloop; (sys_platform != "win32" and sys_platform != "cygwin") an
|
|
|
44
44
|
=====================================
|
|
45
45
|
generator=datazen
|
|
46
46
|
version=3.1.4
|
|
47
|
-
hash=
|
|
47
|
+
hash=2adcb8a8e9a6b4dffec41ec316de0fee
|
|
48
48
|
=====================================
|
|
49
49
|
-->
|
|
50
50
|
|
|
51
|
-
# runtimepy ([4.
|
|
51
|
+
# runtimepy ([4.3.0](https://pypi.org/project/runtimepy/))
|
|
52
52
|
|
|
53
53
|
[](https://pypi.org/project/runtimepy/)
|
|
54
54
|

|
|
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
|
|
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
|