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.
Files changed (177) hide show
  1. webapp_shell-0.2/CHANGE_LOG.md +3 -0
  2. {webapp_shell-0.1 → webapp_shell-0.2}/PKG-INFO +24 -10
  3. {webapp_shell-0.1 → webapp_shell-0.2}/README.md +23 -9
  4. webapp_shell-0.1/CHANGE_LOG.md → webapp_shell-0.2/change_logs/0.1.md +1 -1
  5. {webapp_shell-0.1 → webapp_shell-0.2}/pyproject.toml +1 -1
  6. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_guides.py +6 -0
  7. {webapp_shell-0.1 → webapp_shell-0.2}/.gitignore +0 -0
  8. {webapp_shell-0.1 → webapp_shell-0.2}/CONTRIBUTING.md +0 -0
  9. {webapp_shell-0.1 → webapp_shell-0.2}/LICENSE +0 -0
  10. {webapp_shell-0.1 → webapp_shell-0.2}/change_logs/README.md +0 -0
  11. {webapp_shell-0.1 → webapp_shell-0.2}/docs/API.md +0 -0
  12. {webapp_shell-0.1 → webapp_shell-0.2}/docs/CONFIGURATION.md +0 -0
  13. {webapp_shell-0.1 → webapp_shell-0.2}/docs/CONTRACT.md +0 -0
  14. {webapp_shell-0.1 → webapp_shell-0.2}/docs/FREEZING.md +0 -0
  15. {webapp_shell-0.1 → webapp_shell-0.2}/docs/NATIVE_FUNCTIONS.md +0 -0
  16. {webapp_shell-0.1 → webapp_shell-0.2}/docs/REMAINING.md +0 -0
  17. {webapp_shell-0.1 → webapp_shell-0.2}/docs/TRANSLATING.md +0 -0
  18. {webapp_shell-0.1 → webapp_shell-0.2}/docs/TROUBLESHOOTING.md +0 -0
  19. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/README.md +0 -0
  20. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/acme_backend/__init__.py +0 -0
  21. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/acme_backend/__main__.py +0 -0
  22. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/acme_backend/spec.py +0 -0
  23. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/app.py +0 -0
  24. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/freeze_plan.py +0 -0
  25. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/app.js +0 -0
  26. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/index.html +0 -0
  27. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/webapp-shell-bridge.d.ts +0 -0
  28. {webapp_shell-0.1 → webapp_shell-0.2}/examples/minimal/frontend/dist/webapp-shell-bridge.js +0 -0
  29. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/.prettierignore +0 -0
  30. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/.prettierrc.json +0 -0
  31. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/app.py +0 -0
  32. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/__init__.py +0 -0
  33. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/__main__.py +0 -0
  34. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/crash.py +0 -0
  35. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/describe.py +0 -0
  36. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/job.py +0 -0
  37. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/list_folder.py +0 -0
  38. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/messages.py +0 -0
  39. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/save_note.py +0 -0
  40. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/docs_backend/spec.py +0 -0
  41. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/frontend/dist/assets/index-DPVhUfoU.js +0 -0
  42. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/frontend/dist/assets/index-UmDhVWJw.css +0 -0
  43. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/frontend/dist/index.html +0 -0
  44. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/index.html +0 -0
  45. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/native_functions.py +0 -0
  46. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/package-lock.json +0 -0
  47. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/package.json +0 -0
  48. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/App.tsx +0 -0
  49. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/bridge/webapp-shell-bridge.d.ts +0 -0
  50. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/bridge/webapp-shell-bridge.js +0 -0
  51. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/bridgeContext.tsx +0 -0
  52. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/browserNative.ts +0 -0
  53. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/CodeBlock.tsx +0 -0
  54. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/CodeTabs.tsx +0 -0
  55. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/Demo.tsx +0 -0
  56. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/FeaturePage.tsx +0 -0
  57. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/Flow.tsx +0 -0
  58. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/components/Guide.tsx +0 -0
  59. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/bootColors.ts +0 -0
  60. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/health.ts +0 -0
  61. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/job.ts +0 -0
  62. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/messages.ts +0 -0
  63. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/openLink.ts +0 -0
  64. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/ownFunction.ts +0 -0
  65. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/pickFile.ts +0 -0
  66. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/pickFolder.ts +0 -0
  67. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/reveal.ts +0 -0
  68. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/saveAs.ts +0 -0
  69. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/stopping.ts +0 -0
  70. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/demos/zoom.ts +0 -0
  71. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/main.tsx +0 -0
  72. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/BackendJob.tsx +0 -0
  73. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/BackendStopping.tsx +0 -0
  74. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/BootColors.tsx +0 -0
  75. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/ChooseFile.tsx +0 -0
  76. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/ChooseFolder.tsx +0 -0
  77. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/ForFrontend.tsx +0 -0
  78. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/GettingStarted.tsx +0 -0
  79. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/OpenLink.tsx +0 -0
  80. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Overview.tsx +0 -0
  81. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/OwnFunction.tsx +0 -0
  82. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Reveal.tsx +0 -0
  83. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/SaveAs.tsx +0 -0
  84. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Security.tsx +0 -0
  85. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/StartUp.tsx +0 -0
  86. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/TokenAndHealth.tsx +0 -0
  87. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/Zoom.tsx +0 -0
  88. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages/guides.tsx +0 -0
  89. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/pages.ts +0 -0
  90. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/styles.css +0 -0
  91. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/theme.ts +0 -0
  92. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/src/vite-env.d.ts +0 -0
  93. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/tsconfig.json +0 -0
  94. {webapp_shell-0.1 → webapp_shell-0.2}/examples/site/vite.config.ts +0 -0
  95. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/__init__.py +0 -0
  96. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/__main__.py +0 -0
  97. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/backend.py +0 -0
  98. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/backend_process.py +0 -0
  99. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/bridge/webapp-shell-bridge.d.ts +0 -0
  100. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/bridge/webapp-shell-bridge.js +0 -0
  101. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/cli.py +0 -0
  102. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/config.py +0 -0
  103. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/__init__.py +0 -0
  104. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/guard.py +0 -0
  105. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/launch.py +0 -0
  106. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/contract/tokens.py +0 -0
  107. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/enums.py +0 -0
  108. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/__init__.py +0 -0
  109. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/app.spec +0 -0
  110. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/builder.py +0 -0
  111. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/entry.py +0 -0
  112. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/plan.py +0 -0
  113. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/profile.py +0 -0
  114. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/spec.py +0 -0
  115. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/freezing/verify.py +0 -0
  116. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/identity.py +0 -0
  117. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/installation.py +0 -0
  118. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/json_types.py +0 -0
  119. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/library_check.py +0 -0
  120. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/messages.py +0 -0
  121. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/__init__.py +0 -0
  122. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/arguments.py +0 -0
  123. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/errors.py +0 -0
  124. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/filters.py +0 -0
  125. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/os_actions.py +0 -0
  126. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/qt_bridge.py +0 -0
  127. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/qt_window.py +0 -0
  128. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/registry.py +0 -0
  129. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/standard.py +0 -0
  130. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/start_location.py +0 -0
  131. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_background.py +0 -0
  132. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_bridge.py +0 -0
  133. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_icon.py +0 -0
  134. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/webview_window.py +0 -0
  135. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/window.py +0 -0
  136. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/zoom.py +0 -0
  137. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/native/zoom_range.py +0 -0
  138. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/preferences.py +0 -0
  139. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/protocol.py +0 -0
  140. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/py.typed +0 -0
  141. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/qt_shell.py +0 -0
  142. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/registry.py +0 -0
  143. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/settings.py +0 -0
  144. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/shell.py +0 -0
  145. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/smoke.py +0 -0
  146. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/splash.py +0 -0
  147. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/watchdog.py +0 -0
  148. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/webview2.py +0 -0
  149. {webapp_shell-0.1 → webapp_shell-0.2}/src/webapp_shell/webview_shell.py +0 -0
  150. {webapp_shell-0.1 → webapp_shell-0.2}/tests/__init__.py +0 -0
  151. {webapp_shell-0.1 → webapp_shell-0.2}/tests/conftest.py +0 -0
  152. {webapp_shell-0.1 → webapp_shell-0.2}/tests/fake_backend/__init__.py +0 -0
  153. {webapp_shell-0.1 → webapp_shell-0.2}/tests/fake_backend/__main__.py +0 -0
  154. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_api_listing.py +0 -0
  155. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_backend_command.py +0 -0
  156. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_backend_process.py +0 -0
  157. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_boot_look.py +0 -0
  158. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_bridge_js.py +0 -0
  159. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_change_log.py +0 -0
  160. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_cli.py +0 -0
  161. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_config.py +0 -0
  162. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_contract.py +0 -0
  163. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_example_minimal.py +0 -0
  164. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_example_site.py +0 -0
  165. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_freezing.py +0 -0
  166. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_installation.py +0 -0
  167. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_library_is_independent.py +0 -0
  168. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_messages.py +0 -0
  169. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_native.py +0 -0
  170. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_native_arguments.py +0 -0
  171. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_native_registry.py +0 -0
  172. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_start_location.py +0 -0
  173. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_watchdog.py +0 -0
  174. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_webview2.py +0 -0
  175. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_window_title.py +0 -0
  176. {webapp_shell-0.1 → webapp_shell-0.2}/tests/test_zoom.py +0 -0
  177. {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.1
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
  [![CI](https://github.com/prmpsmart/webapp_shell/actions/workflows/ci.yml/badge.svg)](https://github.com/prmpsmart/webapp_shell/actions/workflows/ci.yml)
45
45
  [![PyPI](https://img.shields.io/pypi/v/webapp-shell)](https://pypi.org/project/webapp-shell/)
46
46
  [![Python](https://img.shields.io/pypi/pyversions/webapp-shell)](https://pypi.org/project/webapp-shell/)
47
- [![Licence: MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](LICENSE)
47
+ [![Licence: MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](https://github.com/prmpsmart/webapp_shell/blob/main/LICENSE)
48
48
  [![Docs](https://img.shields.io/badge/docs-site-3556d6)](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(), config.backend.wire)
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); `pip install "webapp-shell[qt]"` adds Qt, and
121
- `pip install "webapp-shell[backend]"` adds Starlette for the token guard.
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
  [![CI](https://github.com/prmpsmart/webapp_shell/actions/workflows/ci.yml/badge.svg)](https://github.com/prmpsmart/webapp_shell/actions/workflows/ci.yml)
4
4
  [![PyPI](https://img.shields.io/pypi/v/webapp-shell)](https://pypi.org/project/webapp-shell/)
5
5
  [![Python](https://img.shields.io/pypi/pyversions/webapp-shell)](https://pypi.org/project/webapp-shell/)
6
- [![Licence: MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](LICENSE)
6
+ [![Licence: MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](https://github.com/prmpsmart/webapp_shell/blob/main/LICENSE)
7
7
  [![Docs](https://img.shields.io/badge/docs-site-3556d6)](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(), config.backend.wire)
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); `pip install "webapp-shell[qt]"` adds Qt, and
80
- `pip install "webapp-shell[backend]"` adds Starlette for the token guard.
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 (not yet published). What it holds:
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.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "webapp-shell"
7
- version = "0.1"
7
+ version = "0.2"
8
8
  description = "A desktop window for a web app made of a Python backend and a compiled frontend."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -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