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

|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
=====================================
|
|
3
3
|
generator=datazen
|
|
4
|
-
version=3.2.
|
|
5
|
-
hash=
|
|
4
|
+
version=3.2.3
|
|
5
|
+
hash=69775d79c8c13f44e0ac000acdeb93e2
|
|
6
6
|
=====================================
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
|
-
# runtimepy ([5.
|
|
9
|
+
# runtimepy ([5.13.1](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
|
-
# version=3.2.
|
|
4
|
-
# hash=
|
|
3
|
+
# version=3.2.3
|
|
4
|
+
# hash=25280d90363095aa6b5717f2105ff685
|
|
5
5
|
# =====================================
|
|
6
6
|
|
|
7
7
|
"""
|
|
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
|
|
|
10
10
|
|
|
11
11
|
DESCRIPTION = "A framework for implementing Python services."
|
|
12
12
|
PKG_NAME = "runtimepy"
|
|
13
|
-
VERSION = "5.
|
|
13
|
+
VERSION = "5.13.1"
|
|
14
14
|
|
|
15
15
|
# runtimepy-specific content.
|
|
16
16
|
METRICS_NAME = "metrics"
|
|
@@ -51,9 +51,10 @@ def create_app_shell(
|
|
|
51
51
|
# Dark/light theme switch button.
|
|
52
52
|
bootstrap_button(
|
|
53
53
|
icon_str("lightbulb"),
|
|
54
|
-
tooltip="
|
|
54
|
+
tooltip="Toggle light/dark.",
|
|
55
55
|
id="theme-button",
|
|
56
56
|
parent=button_column,
|
|
57
|
+
title="change theme button",
|
|
57
58
|
)
|
|
58
59
|
|
|
59
60
|
return container, button_column
|
|
@@ -112,6 +113,7 @@ def full_markdown_page(
|
|
|
112
113
|
icon_str("printer"),
|
|
113
114
|
tooltip="Printer-friendly view.",
|
|
114
115
|
id="print-button",
|
|
116
|
+
title="print-view button",
|
|
115
117
|
parent=div(tag="a", href="?print=true", parent=button_column),
|
|
116
118
|
)
|
|
117
119
|
|
|
@@ -6,8 +6,12 @@ A module implementing HTTP-response interfaces.
|
|
|
6
6
|
import http
|
|
7
7
|
from io import StringIO
|
|
8
8
|
import logging
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import AsyncIterator, cast
|
|
9
11
|
|
|
10
12
|
# third-party
|
|
13
|
+
import aiofiles
|
|
14
|
+
import aiofiles.os
|
|
11
15
|
from vcorelib.logging import LoggerType
|
|
12
16
|
|
|
13
17
|
# internal
|
|
@@ -83,3 +87,31 @@ class ResponseHeader(HeadersMixin):
|
|
|
83
87
|
self.status_line,
|
|
84
88
|
self.headers,
|
|
85
89
|
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class AsyncResponse:
|
|
93
|
+
"""
|
|
94
|
+
A class facilitating asynchronous server responses for e.g.
|
|
95
|
+
file-system files.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
def __init__(self, path: Path, chunk_size: int = 1024) -> None:
|
|
99
|
+
"""Initialize this instance."""
|
|
100
|
+
|
|
101
|
+
self.path = path
|
|
102
|
+
self.chunk_size = chunk_size
|
|
103
|
+
|
|
104
|
+
async def size(self) -> int:
|
|
105
|
+
"""Get this response's size."""
|
|
106
|
+
return cast(int, await aiofiles.os.path.getsize(self.path))
|
|
107
|
+
|
|
108
|
+
async def process(self) -> AsyncIterator[bytes]:
|
|
109
|
+
"""Yield chunks to write asynchronously."""
|
|
110
|
+
|
|
111
|
+
async with aiofiles.open(self.path, mode="rb") as path_fd:
|
|
112
|
+
while True:
|
|
113
|
+
data = await path_fd.read(self.chunk_size)
|
|
114
|
+
if data:
|
|
115
|
+
yield data
|
|
116
|
+
else:
|
|
117
|
+
break
|
|
@@ -21,11 +21,11 @@ from runtimepy.channel.environment.command import GLOBAL
|
|
|
21
21
|
from runtimepy.net.html import full_markdown_page
|
|
22
22
|
from runtimepy.net.http.header import RequestHeader
|
|
23
23
|
from runtimepy.net.http.request_target import PathMaybeQuery
|
|
24
|
-
from runtimepy.net.http.response import ResponseHeader
|
|
24
|
+
from runtimepy.net.http.response import AsyncResponse, ResponseHeader
|
|
25
25
|
from runtimepy.net.server.html import HtmlApp, HtmlApps, get_html, html_handler
|
|
26
26
|
from runtimepy.net.server.json import encode_json, json_handler
|
|
27
27
|
from runtimepy.net.server.markdown import markdown_for_dir
|
|
28
|
-
from runtimepy.net.tcp.http import HttpConnection
|
|
28
|
+
from runtimepy.net.tcp.http import HttpConnection, HttpResult
|
|
29
29
|
from runtimepy.util import normalize_root, path_has_part, read_binary
|
|
30
30
|
|
|
31
31
|
MIMETYPES_INIT = False
|
|
@@ -156,7 +156,9 @@ class RuntimepyServerConnection(HttpConnection):
|
|
|
156
156
|
|
|
157
157
|
response["Content-Type"] = f"text/html; charset={DEFAULT_ENCODING}"
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
with StringIO() as stream:
|
|
160
|
+
document.render(stream)
|
|
161
|
+
return stream.getvalue().encode()
|
|
160
162
|
|
|
161
163
|
async def render_markdown_file(
|
|
162
164
|
self,
|
|
@@ -173,20 +175,20 @@ class RuntimepyServerConnection(HttpConnection):
|
|
|
173
175
|
|
|
174
176
|
async def try_file(
|
|
175
177
|
self, path: PathMaybeQuery, response: ResponseHeader
|
|
176
|
-
) ->
|
|
178
|
+
) -> HttpResult:
|
|
177
179
|
"""Try serving this path as a file directly from the file-system."""
|
|
178
180
|
|
|
179
|
-
result = None
|
|
181
|
+
result: HttpResult = None
|
|
180
182
|
|
|
181
183
|
# Keep track of directories encountered.
|
|
182
|
-
directories: list[Path] = []
|
|
184
|
+
directories: list[tuple[Path, Path]] = []
|
|
183
185
|
|
|
184
186
|
# Build a list of all candidate files to check.
|
|
185
187
|
candidates: list[Path] = []
|
|
186
188
|
for search in self.paths:
|
|
187
189
|
candidate = search.joinpath(path[0][1:])
|
|
188
190
|
if candidate.is_dir():
|
|
189
|
-
directories.append(candidate)
|
|
191
|
+
directories.append((candidate, search))
|
|
190
192
|
candidates.append(candidate.joinpath("index.html"))
|
|
191
193
|
else:
|
|
192
194
|
candidates.append(candidate)
|
|
@@ -206,6 +208,13 @@ class RuntimepyServerConnection(HttpConnection):
|
|
|
206
208
|
|
|
207
209
|
# Set MIME type if it can be determined.
|
|
208
210
|
if mime:
|
|
211
|
+
# webhint suggestion
|
|
212
|
+
if (
|
|
213
|
+
mime.startswith("text")
|
|
214
|
+
and DEFAULT_ENCODING not in mime
|
|
215
|
+
):
|
|
216
|
+
mime += f"; charset={DEFAULT_ENCODING}"
|
|
217
|
+
|
|
209
218
|
response["Content-Type"] = mime
|
|
210
219
|
|
|
211
220
|
# We don't handle this yet.
|
|
@@ -214,14 +223,15 @@ class RuntimepyServerConnection(HttpConnection):
|
|
|
214
223
|
self.logger.info("Serving '%s' (MIME: %s)", candidate, mime)
|
|
215
224
|
|
|
216
225
|
# Return the file data.
|
|
217
|
-
result =
|
|
226
|
+
result = AsyncResponse(candidate)
|
|
218
227
|
break
|
|
219
228
|
|
|
220
229
|
# Handle a directory as a last resort.
|
|
221
230
|
if not result and directories:
|
|
231
|
+
candidate, search = directories[0]
|
|
222
232
|
result = self.render_markdown(
|
|
223
233
|
markdown_for_dir(
|
|
224
|
-
|
|
234
|
+
candidate, search, {"applications": self.apps.keys()}
|
|
225
235
|
),
|
|
226
236
|
response,
|
|
227
237
|
path[1],
|
|
@@ -259,7 +269,7 @@ class RuntimepyServerConnection(HttpConnection):
|
|
|
259
269
|
response: ResponseHeader,
|
|
260
270
|
request: RequestHeader,
|
|
261
271
|
request_data: Optional[bytes],
|
|
262
|
-
) ->
|
|
272
|
+
) -> HttpResult:
|
|
263
273
|
"""Handle POST requests."""
|
|
264
274
|
|
|
265
275
|
request.log(self.logger, False, level=logging.INFO)
|
|
@@ -281,7 +291,7 @@ class RuntimepyServerConnection(HttpConnection):
|
|
|
281
291
|
response: ResponseHeader,
|
|
282
292
|
request: RequestHeader,
|
|
283
293
|
request_data: Optional[bytes],
|
|
284
|
-
) ->
|
|
294
|
+
) -> HttpResult:
|
|
285
295
|
"""Handle GET requests."""
|
|
286
296
|
|
|
287
297
|
request.log(self.logger, False, level=logging.INFO)
|
|
@@ -110,6 +110,7 @@ def channel_table_header(
|
|
|
110
110
|
tooltip="Clear plotted channels.",
|
|
111
111
|
icon="x-lg",
|
|
112
112
|
id="clear-plotted-channels",
|
|
113
|
+
title="button for clearing plotted channels",
|
|
113
114
|
).add_class("pb-2")
|
|
114
115
|
|
|
115
116
|
input_box(
|
|
@@ -124,6 +125,7 @@ def channel_table_header(
|
|
|
124
125
|
icon="trash",
|
|
125
126
|
tooltip="Clear all plot points.",
|
|
126
127
|
id="clear-plotted-points",
|
|
128
|
+
title="button for clearing plot point data",
|
|
127
129
|
).add_class("pb-2")
|
|
128
130
|
|
|
129
131
|
cell = flex(tag="th", parent=ctl_row)
|
|
@@ -6,6 +6,7 @@ A module implementing HTML interfaces for web applications.
|
|
|
6
6
|
from typing import Awaitable, Callable, Optional, TextIO
|
|
7
7
|
|
|
8
8
|
# third-party
|
|
9
|
+
from svgen.element import Element
|
|
9
10
|
from svgen.element.html import Html
|
|
10
11
|
from vcorelib import DEFAULT_ENCODING
|
|
11
12
|
|
|
@@ -20,10 +21,23 @@ HtmlApp = Callable[
|
|
|
20
21
|
HtmlApps = dict[str, HtmlApp]
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
def get_html(
|
|
24
|
+
def get_html(
|
|
25
|
+
title: str = HttpConnection.identity,
|
|
26
|
+
cache_control: str = "public",
|
|
27
|
+
**kwargs,
|
|
28
|
+
) -> Html:
|
|
24
29
|
"""Get a default HTML document."""
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
elem = Html(title, **kwargs)
|
|
32
|
+
|
|
33
|
+
elem.children.append(
|
|
34
|
+
Element(
|
|
35
|
+
tag="meta",
|
|
36
|
+
attrib={"http-equiv": "Cache-Control", "content": cache_control},
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return elem
|
|
27
41
|
|
|
28
42
|
|
|
29
43
|
async def html_handler(
|
|
@@ -11,14 +11,11 @@ from typing import Iterable, cast
|
|
|
11
11
|
from vcorelib.io.file_writer import IndentedFileWriter
|
|
12
12
|
from vcorelib.paths import rel
|
|
13
13
|
|
|
14
|
-
LOGO_MARKDOWN = (
|
|
15
|
-
"[](https://libre-embedded.com)"
|
|
17
|
-
)
|
|
14
|
+
LOGO_MARKDOWN = "[](/)"
|
|
18
15
|
|
|
19
16
|
|
|
20
17
|
def markdown_for_dir(
|
|
21
|
-
path: Path, extra_links: dict[str, Iterable[str]] = None
|
|
18
|
+
path: Path, base: Path, extra_links: dict[str, Iterable[str]] = None
|
|
22
19
|
) -> str:
|
|
23
20
|
"""Get markdown data for a directory."""
|
|
24
21
|
|
|
@@ -29,24 +26,28 @@ def markdown_for_dir(
|
|
|
29
26
|
|
|
30
27
|
if extra_links:
|
|
31
28
|
for category, apps in extra_links.items():
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
if apps:
|
|
30
|
+
writer.write(f"## {category}")
|
|
31
|
+
with writer.padding():
|
|
32
|
+
for app in apps:
|
|
33
|
+
writer.write(f"* [{app}]({app})")
|
|
34
|
+
|
|
35
|
+
curr_dir = rel(path, base=base)
|
|
36
|
+
writer.write(f"## `{curr_dir}`")
|
|
38
37
|
writer.empty()
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
# Link to go up a directory.
|
|
40
|
+
if curr_dir != Path():
|
|
41
|
+
writer.write(f"* [..](/{curr_dir.parent})")
|
|
41
42
|
|
|
42
43
|
for item in path.iterdir():
|
|
43
|
-
curr = rel(item, base=
|
|
44
|
+
curr = rel(item, base=base)
|
|
44
45
|
|
|
45
|
-
name = f"`{curr}`"
|
|
46
|
+
name = f"`{curr.name}`"
|
|
46
47
|
if item.is_dir():
|
|
47
48
|
name = f"**{name}**"
|
|
48
49
|
|
|
49
|
-
writer.write(f"* [{name}]({curr})")
|
|
50
|
+
writer.write(f"* [{name}](/{curr})")
|
|
50
51
|
|
|
51
52
|
result: str = cast(StringIO, writer.stream).getvalue()
|
|
52
53
|
|
|
@@ -16,22 +16,24 @@ from vcorelib import DEFAULT_ENCODING
|
|
|
16
16
|
from runtimepy import PKG_NAME, VERSION
|
|
17
17
|
from runtimepy.net.http import HttpMessageProcessor
|
|
18
18
|
from runtimepy.net.http.header import RequestHeader
|
|
19
|
-
from runtimepy.net.http.response import ResponseHeader
|
|
19
|
+
from runtimepy.net.http.response import AsyncResponse, ResponseHeader
|
|
20
20
|
from runtimepy.net.tcp.connection import TcpConnection as _TcpConnection
|
|
21
21
|
|
|
22
|
+
HttpResult = Optional[bytes | AsyncResponse]
|
|
23
|
+
|
|
22
24
|
#
|
|
23
25
|
# async def handler(
|
|
24
26
|
# response: ResponseHeader,
|
|
25
27
|
# request: RequestHeader,
|
|
26
28
|
# request_data: Optional[bytes],
|
|
27
|
-
# ) ->
|
|
29
|
+
# ) -> HttpResult:
|
|
28
30
|
# """Sample handler."""
|
|
29
31
|
#
|
|
30
32
|
HttpRequestHandler = Callable[
|
|
31
33
|
[ResponseHeader, RequestHeader, Optional[bytes]],
|
|
32
|
-
Awaitable[
|
|
34
|
+
Awaitable[HttpResult],
|
|
33
35
|
]
|
|
34
|
-
HttpResponse = Tuple[ResponseHeader,
|
|
36
|
+
HttpResponse = Tuple[ResponseHeader, HttpResult]
|
|
35
37
|
|
|
36
38
|
HttpRequestHandlers = dict[http.HTTPMethod, HttpRequestHandler]
|
|
37
39
|
|
|
@@ -89,7 +91,7 @@ class HttpConnection(_TcpConnection):
|
|
|
89
91
|
response: ResponseHeader,
|
|
90
92
|
request: RequestHeader,
|
|
91
93
|
request_data: Optional[bytes],
|
|
92
|
-
) ->
|
|
94
|
+
) -> HttpResult:
|
|
93
95
|
"""Sample handler."""
|
|
94
96
|
|
|
95
97
|
async def post_handler(
|
|
@@ -97,7 +99,7 @@ class HttpConnection(_TcpConnection):
|
|
|
97
99
|
response: ResponseHeader,
|
|
98
100
|
request: RequestHeader,
|
|
99
101
|
request_data: Optional[bytes],
|
|
100
|
-
) ->
|
|
102
|
+
) -> HttpResult:
|
|
101
103
|
"""Sample handler."""
|
|
102
104
|
|
|
103
105
|
async def _process_request(
|
|
@@ -105,7 +107,7 @@ class HttpConnection(_TcpConnection):
|
|
|
105
107
|
response: ResponseHeader,
|
|
106
108
|
request_header: RequestHeader,
|
|
107
109
|
request_data: Optional[bytes] = None,
|
|
108
|
-
) ->
|
|
110
|
+
) -> HttpResult:
|
|
109
111
|
"""Process an individual request."""
|
|
110
112
|
|
|
111
113
|
result = None
|
|
@@ -124,7 +126,11 @@ class HttpConnection(_TcpConnection):
|
|
|
124
126
|
)
|
|
125
127
|
|
|
126
128
|
# Set boilerplate header data.
|
|
127
|
-
|
|
129
|
+
|
|
130
|
+
# webhint suggestions
|
|
131
|
+
# response["server"] = self.identity
|
|
132
|
+
response["server"] = PKG_NAME
|
|
133
|
+
response["X-Content-Type-Options"] = "nosniff"
|
|
128
134
|
|
|
129
135
|
return result
|
|
130
136
|
|
|
@@ -137,7 +143,7 @@ class HttpConnection(_TcpConnection):
|
|
|
137
143
|
# Set boilerplate header data.
|
|
138
144
|
request["user-agent"] = self.identity
|
|
139
145
|
|
|
140
|
-
self._send(request, data)
|
|
146
|
+
await self._send(request, data)
|
|
141
147
|
self.expecting_response = True
|
|
142
148
|
result = await self.responses.get()
|
|
143
149
|
self.expecting_response = False
|
|
@@ -153,21 +159,29 @@ class HttpConnection(_TcpConnection):
|
|
|
153
159
|
"""
|
|
154
160
|
return to_json(await self.request(request, data))
|
|
155
161
|
|
|
156
|
-
def _send(
|
|
162
|
+
async def _send(
|
|
157
163
|
self,
|
|
158
164
|
header: Union[ResponseHeader, RequestHeader],
|
|
159
|
-
data:
|
|
165
|
+
data: HttpResult = None,
|
|
160
166
|
) -> None:
|
|
161
167
|
"""Send a request or response to a request."""
|
|
162
168
|
|
|
163
169
|
# Set content length.
|
|
164
170
|
header["content-length"] = "0"
|
|
165
|
-
|
|
171
|
+
|
|
172
|
+
if isinstance(data, AsyncResponse):
|
|
173
|
+
header["content-length"] = str(await data.size())
|
|
174
|
+
elif data is not None:
|
|
166
175
|
header["content-length"] = str(len(data))
|
|
167
176
|
|
|
168
177
|
self.send_binary(bytes(header))
|
|
169
|
-
|
|
170
|
-
|
|
178
|
+
|
|
179
|
+
if data is not None:
|
|
180
|
+
if isinstance(data, AsyncResponse):
|
|
181
|
+
async for chunk in data.process():
|
|
182
|
+
self.send_binary(chunk)
|
|
183
|
+
else:
|
|
184
|
+
self.send_binary(data)
|
|
171
185
|
|
|
172
186
|
header.log(self.logger, True)
|
|
173
187
|
|
|
@@ -183,7 +197,7 @@ class HttpConnection(_TcpConnection):
|
|
|
183
197
|
if not self.expecting_response:
|
|
184
198
|
# Process request.
|
|
185
199
|
response = ResponseHeader()
|
|
186
|
-
self._send(
|
|
200
|
+
await self._send(
|
|
187
201
|
response,
|
|
188
202
|
await self._process_request(
|
|
189
203
|
response, cast(RequestHeader, header), payload
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.13.1
|
|
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: aiofiles
|
|
21
20
|
Requires-Dist: psutil
|
|
21
|
+
Requires-Dist: aiofiles
|
|
22
|
+
Requires-Dist: svgen>=0.7.12
|
|
22
23
|
Requires-Dist: websockets
|
|
23
24
|
Requires-Dist: vcorelib>=3.5.1
|
|
24
|
-
Requires-Dist: svgen>=0.7.4
|
|
25
25
|
Provides-Extra: test
|
|
26
26
|
Requires-Dist: pylint; extra == "test"
|
|
27
27
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -50,12 +50,12 @@ Dynamic: requires-python
|
|
|
50
50
|
<!--
|
|
51
51
|
=====================================
|
|
52
52
|
generator=datazen
|
|
53
|
-
version=3.2.
|
|
54
|
-
hash=
|
|
53
|
+
version=3.2.3
|
|
54
|
+
hash=69775d79c8c13f44e0ac000acdeb93e2
|
|
55
55
|
=====================================
|
|
56
56
|
-->
|
|
57
57
|
|
|
58
|
-
# runtimepy ([5.
|
|
58
|
+
# runtimepy ([5.13.1](https://pypi.org/project/runtimepy/))
|
|
59
59
|
|
|
60
60
|
[](https://pypi.org/project/runtimepy/)
|
|
61
61
|

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