webapp-shell 0.1__tar.gz → 0.2__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.
- webapp_shell-0.2/CHANGE_LOG.md +3 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/PKG-INFO +24 -10
- {webapp_shell-0.1 → webapp_shell-0.2}/README.md +23 -9
- webapp_shell-0.1/CHANGE_LOG.md → webapp_shell-0.2/change_logs/0.1.md +1 -1
- {webapp_shell-0.1 → webapp_shell-0.2}/pyproject.toml +1 -1
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_guides.py +6 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/.gitignore +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/CONTRIBUTING.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/LICENSE +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/change_logs/README.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/API.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/CONFIGURATION.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/CONTRACT.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/FREEZING.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/NATIVE_FUNCTIONS.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/REMAINING.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/TRANSLATING.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/docs/TROUBLESHOOTING.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/README.md +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/acme_backend/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/acme_backend/__main__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/acme_backend/spec.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/app.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/freeze_plan.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/app.js +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/index.html +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/webapp-shell-bridge.d.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/webapp-shell-bridge.js +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/.prettierignore +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/.prettierrc.json +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/app.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/__main__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/crash.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/describe.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/job.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/list_folder.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/messages.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/save_note.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/spec.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/frontend/dist/assets/index-DPVhUfoU.js +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/frontend/dist/assets/index-UmDhVWJw.css +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/frontend/dist/index.html +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/index.html +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/native_functions.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/package-lock.json +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/package.json +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/App.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/bridge/webapp-shell-bridge.d.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/bridge/webapp-shell-bridge.js +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/bridgeContext.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/browserNative.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/CodeBlock.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/CodeTabs.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/Demo.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/FeaturePage.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/Flow.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/Guide.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/bootColors.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/health.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/job.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/messages.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/openLink.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/ownFunction.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/pickFile.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/pickFolder.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/reveal.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/saveAs.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/stopping.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/zoom.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/main.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/BackendJob.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/BackendStopping.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/BootColors.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/ChooseFile.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/ChooseFolder.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/ForFrontend.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/GettingStarted.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/OpenLink.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Overview.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/OwnFunction.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Reveal.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/SaveAs.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Security.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/StartUp.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/TokenAndHealth.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Zoom.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/guides.tsx +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/styles.css +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/theme.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/vite-env.d.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/tsconfig.json +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/vite.config.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/__main__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/backend.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/backend_process.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/bridge/webapp-shell-bridge.d.ts +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/bridge/webapp-shell-bridge.js +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/cli.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/config.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/guard.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/launch.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/tokens.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/enums.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/app.spec +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/builder.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/entry.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/plan.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/profile.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/spec.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/verify.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/identity.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/installation.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/json_types.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/library_check.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/messages.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/arguments.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/errors.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/filters.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/os_actions.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/qt_bridge.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/qt_window.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/registry.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/standard.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/start_location.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_background.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_bridge.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_icon.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_window.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/window.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/zoom.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/zoom_range.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/preferences.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/protocol.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/py.typed +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/qt_shell.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/registry.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/settings.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/shell.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/smoke.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/splash.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/watchdog.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/webview2.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/webview_shell.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/conftest.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/fake_backend/__init__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/fake_backend/__main__.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_api_listing.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_backend_command.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_backend_process.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_boot_look.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_bridge_js.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_change_log.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_cli.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_config.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_contract.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_example_minimal.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_example_site.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_freezing.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_installation.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_library_is_independent.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_messages.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_native.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_native_arguments.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_native_registry.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_start_location.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_watchdog.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_webview2.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_window_title.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_zoom.py +0 -0
- {webapp_shell-0.1 → webapp_shell-0.2}/tools/api_listing.py +0 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# 0.2
|
|
2
|
+
|
|
3
|
+
- **README:** every link in it is now absolute (to the repository on GitHub), so the links work on the PyPI page, where a relative link led to a 404. The backend example is complete, and freezing and the `freeze` extra are mentioned. A test keeps relative links out of the README.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: webapp-shell
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2
|
|
4
4
|
Summary: A desktop window for a web app made of a Python backend and a compiled frontend.
|
|
5
5
|
Project-URL: Homepage, https://github.com/prmpsmart/webapp_shell
|
|
6
6
|
Project-URL: Documentation, https://prmpsmart.github.io/webapp_shell
|
|
@@ -44,7 +44,7 @@ Description-Content-Type: text/markdown
|
|
|
44
44
|
[](https://github.com/prmpsmart/webapp_shell/actions/workflows/ci.yml)
|
|
45
45
|
[](https://pypi.org/project/webapp-shell/)
|
|
46
46
|
[](https://pypi.org/project/webapp-shell/)
|
|
47
|
-
[](LICENSE)
|
|
47
|
+
[](https://github.com/prmpsmart/webapp_shell/blob/main/LICENSE)
|
|
48
48
|
[](https://prmpsmart.github.io/webapp_shell)
|
|
49
49
|
|
|
50
50
|
A desktop window for a web app made of a **Python backend** and a **compiled frontend**. Your project describes itself
|
|
@@ -82,9 +82,19 @@ if __name__ == "__main__":
|
|
|
82
82
|
The backend reads the same contract with the library's helpers (Starlette or FastAPI):
|
|
83
83
|
|
|
84
84
|
```python
|
|
85
|
+
import argparse
|
|
86
|
+
|
|
87
|
+
from starlette.applications import Starlette
|
|
88
|
+
from webapp_shell.contract import TokenValidator, add_launch_arguments, read_launch_arguments
|
|
89
|
+
from webapp_shell.contract.guard import TokenGuard
|
|
90
|
+
|
|
91
|
+
wire = config.backend.wire # the same names the shell uses
|
|
92
|
+
|
|
85
93
|
parser = argparse.ArgumentParser()
|
|
86
94
|
add_launch_arguments(parser, config.backend) # --port, --frontend, --preferences-file, --token
|
|
87
|
-
launch = read_launch_arguments(parser, parser.parse_args(),
|
|
95
|
+
launch = read_launch_arguments(parser, parser.parse_args(), wire)
|
|
96
|
+
|
|
97
|
+
app = Starlette(...)
|
|
88
98
|
app.add_middleware(TokenGuard, validator=TokenValidator(launch.token, wire), wire=wire)
|
|
89
99
|
```
|
|
90
100
|
|
|
@@ -117,16 +127,20 @@ const path = await bridge.pickFile([{ name: "Excel", extensions: ["xlsx"] }]);
|
|
|
117
127
|
const hello = await bridge.call("greet", "Ada");
|
|
118
128
|
```
|
|
119
129
|
|
|
120
|
-
Install: `pip install webapp-shell` (pywebview is included);
|
|
121
|
-
`pip install "webapp-shell[backend]"
|
|
130
|
+
Install: `pip install webapp-shell` (pywebview is included); the extras are `qt` (the Qt window), `backend` (Starlette,
|
|
131
|
+
for the token guard) and `freeze` (PyInstaller, for the next step), for example `pip install "webapp-shell[qt,backend]"`.
|
|
132
|
+
|
|
133
|
+
Freezing: describe the program in a `FreezePlan` and run `python -m webapp_shell freeze plan:PLAN qt webview`. The
|
|
134
|
+
library writes the entry file and the PyInstaller spec, keeps the other window toolkit out of each build and checks the
|
|
135
|
+
finished folder (see [freezing](https://github.com/prmpsmart/webapp_shell/blob/main/docs/FREEZING.md)).
|
|
122
136
|
|
|
123
137
|
On Windows the pywebview window needs the WebView2 runtime (present on Windows 11); `pythonnet` is installed by pywebview.
|
|
124
138
|
|
|
125
139
|
A runnable minimal program is in `examples/minimal/`, and `examples/site/` is the documentation website, opened by the
|
|
126
140
|
library's own shell, with a live demonstration of every feature.
|
|
127
141
|
|
|
128
|
-
Guides (`docs/`): [the contract](docs/CONTRACT.md), [configuration](docs/CONFIGURATION.md),
|
|
129
|
-
[native functions](docs/NATIVE_FUNCTIONS.md), [freezing with PyInstaller](docs/FREEZING.md),
|
|
130
|
-
[translating](docs/TRANSLATING.md), [troubleshooting](docs/TROUBLESHOOTING.md), and the generated
|
|
131
|
-
[API listing](docs/API.md) (the public API: nothing that is not listed there is promised). The same guides are pages of
|
|
132
|
-
the documentation site. To work on the library, read [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
142
|
+
Guides (`docs/`): [the contract](https://github.com/prmpsmart/webapp_shell/blob/main/docs/CONTRACT.md), [configuration](https://github.com/prmpsmart/webapp_shell/blob/main/docs/CONFIGURATION.md),
|
|
143
|
+
[native functions](https://github.com/prmpsmart/webapp_shell/blob/main/docs/NATIVE_FUNCTIONS.md), [freezing with PyInstaller](https://github.com/prmpsmart/webapp_shell/blob/main/docs/FREEZING.md),
|
|
144
|
+
[translating](https://github.com/prmpsmart/webapp_shell/blob/main/docs/TRANSLATING.md), [troubleshooting](https://github.com/prmpsmart/webapp_shell/blob/main/docs/TROUBLESHOOTING.md), and the generated
|
|
145
|
+
[API listing](https://github.com/prmpsmart/webapp_shell/blob/main/docs/API.md) (the public API: nothing that is not listed there is promised). The same guides are pages of
|
|
146
|
+
the documentation site. To work on the library, read [CONTRIBUTING.md](https://github.com/prmpsmart/webapp_shell/blob/main/CONTRIBUTING.md).
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://github.com/prmpsmart/webapp_shell/actions/workflows/ci.yml)
|
|
4
4
|
[](https://pypi.org/project/webapp-shell/)
|
|
5
5
|
[](https://pypi.org/project/webapp-shell/)
|
|
6
|
-
[](LICENSE)
|
|
6
|
+
[](https://github.com/prmpsmart/webapp_shell/blob/main/LICENSE)
|
|
7
7
|
[](https://prmpsmart.github.io/webapp_shell)
|
|
8
8
|
|
|
9
9
|
A desktop window for a web app made of a **Python backend** and a **compiled frontend**. Your project describes itself
|
|
@@ -41,9 +41,19 @@ if __name__ == "__main__":
|
|
|
41
41
|
The backend reads the same contract with the library's helpers (Starlette or FastAPI):
|
|
42
42
|
|
|
43
43
|
```python
|
|
44
|
+
import argparse
|
|
45
|
+
|
|
46
|
+
from starlette.applications import Starlette
|
|
47
|
+
from webapp_shell.contract import TokenValidator, add_launch_arguments, read_launch_arguments
|
|
48
|
+
from webapp_shell.contract.guard import TokenGuard
|
|
49
|
+
|
|
50
|
+
wire = config.backend.wire # the same names the shell uses
|
|
51
|
+
|
|
44
52
|
parser = argparse.ArgumentParser()
|
|
45
53
|
add_launch_arguments(parser, config.backend) # --port, --frontend, --preferences-file, --token
|
|
46
|
-
launch = read_launch_arguments(parser, parser.parse_args(),
|
|
54
|
+
launch = read_launch_arguments(parser, parser.parse_args(), wire)
|
|
55
|
+
|
|
56
|
+
app = Starlette(...)
|
|
47
57
|
app.add_middleware(TokenGuard, validator=TokenValidator(launch.token, wire), wire=wire)
|
|
48
58
|
```
|
|
49
59
|
|
|
@@ -76,16 +86,20 @@ const path = await bridge.pickFile([{ name: "Excel", extensions: ["xlsx"] }]);
|
|
|
76
86
|
const hello = await bridge.call("greet", "Ada");
|
|
77
87
|
```
|
|
78
88
|
|
|
79
|
-
Install: `pip install webapp-shell` (pywebview is included);
|
|
80
|
-
`pip install "webapp-shell[backend]"
|
|
89
|
+
Install: `pip install webapp-shell` (pywebview is included); the extras are `qt` (the Qt window), `backend` (Starlette,
|
|
90
|
+
for the token guard) and `freeze` (PyInstaller, for the next step), for example `pip install "webapp-shell[qt,backend]"`.
|
|
91
|
+
|
|
92
|
+
Freezing: describe the program in a `FreezePlan` and run `python -m webapp_shell freeze plan:PLAN qt webview`. The
|
|
93
|
+
library writes the entry file and the PyInstaller spec, keeps the other window toolkit out of each build and checks the
|
|
94
|
+
finished folder (see [freezing](https://github.com/prmpsmart/webapp_shell/blob/main/docs/FREEZING.md)).
|
|
81
95
|
|
|
82
96
|
On Windows the pywebview window needs the WebView2 runtime (present on Windows 11); `pythonnet` is installed by pywebview.
|
|
83
97
|
|
|
84
98
|
A runnable minimal program is in `examples/minimal/`, and `examples/site/` is the documentation website, opened by the
|
|
85
99
|
library's own shell, with a live demonstration of every feature.
|
|
86
100
|
|
|
87
|
-
Guides (`docs/`): [the contract](docs/CONTRACT.md), [configuration](docs/CONFIGURATION.md),
|
|
88
|
-
[native functions](docs/NATIVE_FUNCTIONS.md), [freezing with PyInstaller](docs/FREEZING.md),
|
|
89
|
-
[translating](docs/TRANSLATING.md), [troubleshooting](docs/TROUBLESHOOTING.md), and the generated
|
|
90
|
-
[API listing](docs/API.md) (the public API: nothing that is not listed there is promised). The same guides are pages of
|
|
91
|
-
the documentation site. To work on the library, read [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
101
|
+
Guides (`docs/`): [the contract](https://github.com/prmpsmart/webapp_shell/blob/main/docs/CONTRACT.md), [configuration](https://github.com/prmpsmart/webapp_shell/blob/main/docs/CONFIGURATION.md),
|
|
102
|
+
[native functions](https://github.com/prmpsmart/webapp_shell/blob/main/docs/NATIVE_FUNCTIONS.md), [freezing with PyInstaller](https://github.com/prmpsmart/webapp_shell/blob/main/docs/FREEZING.md),
|
|
103
|
+
[translating](https://github.com/prmpsmart/webapp_shell/blob/main/docs/TRANSLATING.md), [troubleshooting](https://github.com/prmpsmart/webapp_shell/blob/main/docs/TROUBLESHOOTING.md), and the generated
|
|
104
|
+
[API listing](https://github.com/prmpsmart/webapp_shell/blob/main/docs/API.md) (the public API: nothing that is not listed there is promised). The same guides are pages of
|
|
105
|
+
the documentation site. To work on the library, read [CONTRIBUTING.md](https://github.com/prmpsmart/webapp_shell/blob/main/CONTRIBUTING.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 0.1
|
|
2
2
|
|
|
3
|
-
The first version (
|
|
3
|
+
The first version (published on PyPI on 1 November 2026). What it holds:
|
|
4
4
|
|
|
5
5
|
- **The shell as a library:** `run(config)` gives a program its command line; the backend is started, watched and restarted by the shell (`BackendProcess`, `BackendWatchdog`), with a splash and a first-run library check.
|
|
6
6
|
- **Config objects:** `AppIdentity`, `BackendSpec`, `WireProtocol`, `CliFlag` and `ShellConfig`; no program's name is built into the library.
|
|
@@ -57,3 +57,9 @@ def test_the_examples_use_only_the_public_modules(path):
|
|
|
57
57
|
return
|
|
58
58
|
for module in library_imports(path.read_text(encoding="utf-8")):
|
|
59
59
|
assert module in PUBLIC, f"{path.name} imports {module}, which is not public"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_the_readme_has_no_relative_links():
|
|
63
|
+
"""PyPI shows the README away from the repository: a relative link there leads to a 404."""
|
|
64
|
+
links = re.findall(r"\]\(([^)]+)\)", (ROOT / "README.md").read_text(encoding="utf-8"))
|
|
65
|
+
assert [link for link in links if not link.startswith(("https://", "http://", "#"))] == []
|
|
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
|
{webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/webapp-shell-bridge.d.ts
RENAMED
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|