oe-python-template-example 0.4.1__tar.gz → 0.4.3__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 (42) hide show
  1. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/.gitignore +7 -1
  2. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/PKG-INFO +51 -29
  3. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/README.md +45 -24
  4. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/pyproject.toml +37 -31
  5. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/api.py +2 -2
  6. oe_python_template_example-0.4.3/src/oe_python_template_example/cli.py +55 -0
  7. oe_python_template_example-0.4.3/src/oe_python_template_example/constants.py +13 -0
  8. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/__init__.py +11 -0
  9. oe_python_template_example-0.4.3/src/oe_python_template_example/hello/_gui.py +44 -0
  10. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/__init__.py +12 -1
  11. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_cli.py +64 -23
  12. oe_python_template_example-0.4.3/src/oe_python_template_example/system/_gui.py +20 -0
  13. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_service.py +1 -0
  14. oe_python_template_example-0.4.3/src/oe_python_template_example/utils/.vendored/bottle.py +4563 -0
  15. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/__init__.py +14 -0
  16. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_constants.py +27 -8
  17. oe_python_template_example-0.4.3/src/oe_python_template_example/utils/_gui.py +174 -0
  18. oe_python_template_example-0.4.3/src/oe_python_template_example/utils/_notebook.py +61 -0
  19. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/boot.py +6 -0
  20. oe_python_template_example-0.4.1/src/oe_python_template_example/cli.py +0 -22
  21. oe_python_template_example-0.4.1/src/oe_python_template_example/constants.py +0 -7
  22. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/LICENSE +0 -0
  23. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/__init__.py +0 -0
  24. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_api.py +0 -0
  25. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_cli.py +0 -0
  26. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_constants.py +0 -0
  27. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_models.py +0 -0
  28. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_service.py +0 -0
  29. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_settings.py +0 -0
  30. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_api.py +0 -0
  31. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_settings.py +0 -0
  32. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_api.py +0 -0
  33. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_cli.py +0 -0
  34. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_console.py +0 -0
  35. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_di.py +0 -0
  36. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_health.py +0 -0
  37. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_log.py +0 -0
  38. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_logfire.py +0 -0
  39. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_process.py +0 -0
  40. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_sentry.py +0 -0
  41. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_service.py +0 -0
  42. {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_settings.py +0 -0
@@ -17,6 +17,10 @@ env/
17
17
  .secrets.json
18
18
  .act-env-secret
19
19
 
20
+ # More secrets
21
+ .ssh
22
+ .aws
23
+
20
24
  # Python virtual environment
21
25
  venv/
22
26
  .venv/
@@ -69,6 +73,7 @@ tmp/
69
73
  # Node temps
70
74
  node_modules/
71
75
 
76
+
72
77
  # AI workflow
73
78
  .fixme
74
79
 
@@ -80,4 +85,5 @@ node_modules/
80
85
  .vercel
81
86
 
82
87
 
83
- # Application specific
88
+
89
+ # Application specific
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oe-python-template-example
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: 🧠 Example project scaffolded and kept up to date with OE Python Template (oe-python-template).
5
5
  Project-URL: Homepage, https://oe-python-template-example.readthedocs.io/en/latest/
6
6
  Project-URL: Documentation, https://oe-python-template-example.readthedocs.io/en/latest/
@@ -50,6 +50,7 @@ Classifier: Typing :: Typed
50
50
  Requires-Python: <4.0,>=3.11
51
51
  Requires-Dist: fastapi[all,standard]>=0.115.12
52
52
  Requires-Dist: logfire[system-metrics]>=3.13.1
53
+ Requires-Dist: nicegui[native]>=2.15.0
53
54
  Requires-Dist: opentelemetry-instrumentation-fastapi>=0.53b0
54
55
  Requires-Dist: opentelemetry-instrumentation-httpx>=0.53b0
55
56
  Requires-Dist: opentelemetry-instrumentation-jinja2>=0.53b0
@@ -59,15 +60,15 @@ Requires-Dist: opentelemetry-instrumentation-tornado>=0.53b0
59
60
  Requires-Dist: opentelemetry-instrumentation-urllib3>=0.53b0
60
61
  Requires-Dist: opentelemetry-instrumentation-urllib>=0.53b0
61
62
  Requires-Dist: psutil>=7.0.0
62
- Requires-Dist: pydantic-settings>=2.8.1
63
- Requires-Dist: pydantic>=2.11.3
64
- Requires-Dist: sentry-sdk>=2.25.1
63
+ Requires-Dist: pydantic-settings>=2.9.1
64
+ Requires-Dist: sentry-sdk>=2.26.1
65
65
  Requires-Dist: typer>=0.15.1
66
66
  Requires-Dist: uptime>=3.0.1
67
67
  Provides-Extra: examples
68
68
  Requires-Dist: jinja2>=3.1.6; extra == 'examples'
69
69
  Requires-Dist: jupyter>=1.1.1; extra == 'examples'
70
- Requires-Dist: marimo>=0.12.8; extra == 'examples'
70
+ Requires-Dist: marimo>=0.13.0; extra == 'examples'
71
+ Requires-Dist: matplotlib>=3.10.1; extra == 'examples'
71
72
  Requires-Dist: streamlit>=1.44.1; extra == 'examples'
72
73
  Description-Content-Type: text/markdown
73
74
 
@@ -151,13 +152,15 @@ Projects generated with this template come with a comprehensive development tool
151
152
  17. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
152
153
  18. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
153
154
  19. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
154
- 20. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
155
- 21. Python package published to [PyPI](https://pypi.org/)
156
- 22. Docker images published to [Docker.io](https://hub.docker.com/) and [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) with [artifact attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds)
157
- 23. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
158
- 24. Settings for use with [VSCode](https://code.visualstudio.com/)
159
- 25. Settings and custom instructions for use with [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot)
160
- 26. API deployed as serverless function to [Vercel](https://vercel.com/) (optional)
155
+ 20. Documentation including dynamic badges, setup instructions, contribution guide and security policy
156
+ 21. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
157
+ 22. Python package published to [PyPI](https://pypi.org/)
158
+ 23. Multi-stage build of fat and slim (no-extras) Docker images, app running nonroot
159
+ 24. Mult-arch Docker images published to [Docker.io](https://hub.docker.com/) and [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) with [artifact attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds)
160
+ 25. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
161
+ 26. Settings for use with [VSCode](https://code.visualstudio.com/)
162
+ 27. Settings and custom instructions for use with [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot)
163
+ 28. API deployed as serverless function to [Vercel](https://vercel.com/) (optional)
161
164
 
162
165
  ### Application Features
163
166
 
@@ -165,17 +168,20 @@ Beyond development tooling, projects generated with this template include the co
165
168
 
166
169
  1. Usable as library with "Hello" module exposing a simple service that can say "Hello, world!" and echo utterances.
167
170
  2. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
168
- 3. Versioned webservice API with [FastAPI](https://fastapi.tiangolo.com/)
169
- 4. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
170
- 5. Simple Web UI with [Streamlit](https://streamlit.io/)
171
- 6. Configuration to run the CLI and API in a Docker container including setup for [Docker Compose](https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-docker-compose/)
171
+ 2. Versioned webservice API with [FastAPI](https://fastapi.tiangolo.com/)
172
+ 3. Comfortable command-line interface (CLI) with
173
+ [Typer](https://typer.tiangolo.com/)
174
+ 4. Cross-platform Graphical User Interface (GUI) with
175
+ [NiceGUI](https://nicegui.io/) running in native window
176
+ 5. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
177
+ 6. Simple Web UI with [Streamlit](https://streamlit.io/)
172
178
  7. Validation and settings management with [pydantic](https://docs.pydantic.dev/)
173
- 8. Info command enabling to inspect the runtime, compiled settings, and further info provided dynamically by modules
174
- 9. Health endpoint exposing system health dynamically aggregated from all modules and dependencies
175
- 10. Flexible logging and instrumentation, including support for [Sentry](https://sentry.io/) and [Logfire](https://logfire.dev/)
176
- 11. Hello service demonstrates use of custom real time metrics collected via Logfire
177
- 12. Modular architecture including auto-registration of services, CLI commands and API routes exposed by modules
178
- 13. Documentation including dynamic badges, setup instructions, contribution guide and security policy
179
+ 8. Flexible logging and instrumentation, including support for [Sentry](https://sentry.io/) and [Logfire](https://logfire.dev/)
180
+ 9. Modular architecture including auto-registration of services, CLI commands, API routes and GUI pages exposed by domain modules
181
+ 10. System module providing aggregate health and info to the runtime, compiled settings, and further info provided by domain modules
182
+ 11. Health and Info available via command, webservice API (info passsword protected) and GUI
183
+ 12. Hello service demonstrates use of custom real time metrics collected via Logfire
184
+ 13. Configuration to run the CLI and API in a Docker container including setup for [Docker Compose](https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-docker-compose/)
179
185
 
180
186
  Explore [here](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example) for what's generated out of the box.
181
187
 
@@ -242,9 +248,13 @@ pip install oe-python-template-example # add dependency to your project
242
248
  Executing the command line interface (CLI) in an isolated Python environment is just as easy:
243
249
 
244
250
  ```shell
245
- uvx oe-python-template-example hello-world # prints "Hello, world! [..]"
246
- uvx oe-python-template-example serve # serves web API
247
- uvx oe-python-template-example serve --port=4711 # serves web API on port 4711
251
+ uvx oe-python-template-example hello world # prints "Hello, world! [..]"
252
+ uvx oe-python-template-example hello echo "Lorem Ipsum" # echos "Lorem Ipsum"
253
+ uvx oe-python-template-example gui # opens the graphical user interface (GUI)
254
+ uvx --with "oe-python-template-example[examples]" oe-python-template-example gui # opens the graphical user interface (GUI) with support for scientific computing
255
+ uvx oe-python-template-example system serve # serves web API
256
+ uvx oe-python-template-example system serve --port=4711 # serves web API on port 4711
257
+ uvx oe-python-template-example system openapi # serves web API on port 4711
248
258
  ```
249
259
 
250
260
  Notes:
@@ -257,10 +267,11 @@ The CLI provides extensive help:
257
267
 
258
268
  ```shell
259
269
  uvx oe-python-template-example --help # all CLI commands
260
- uvx oe-python-template-example hello-world --help # help for specific command
261
- uvx oe-python-template-example echo --help
262
- uvx oe-python-template-example openapi --help
263
- uvx oe-python-template-example serve --help
270
+ uvx oe-python-template-example hello world --help # help for specific command
271
+ uvx oe-python-template-example hello echo --help
272
+ uvx oe-python-template-example gui --help
273
+ uvx oe-python-template-example system serve --help
274
+ uvx oe-python-template-example system openapi --help
264
275
  ```
265
276
 
266
277
 
@@ -388,6 +399,8 @@ uvx oe-python-template-example hello world
388
399
  uvx oe-python-template-example hello echo --help
389
400
  uvx oe-python-template-example hello echo "Lorem"
390
401
  uvx oe-python-template-example hello echo "Lorem" --json
402
+ uvx oe-python-template-example gui
403
+ uvx --with "oe-python-template-example[examples]" oe-python-template-example gui # opens the graphical user interface (GUI) with support for scientific computing
391
404
  uvx oe-python-template-example system info
392
405
  uvx oe-python-template-example system health
393
406
  uvx oe-python-template-example system openapi
@@ -472,6 +485,15 @@ echo "Shutting down the API container ..."
472
485
  docker compose down
473
486
  ```
474
487
 
488
+ #### Slim
489
+
490
+ The default Docker image includes all extras. Additionally a slim image is provided, with no extras. Run as follows
491
+
492
+ ```shell
493
+ docker compose run --remove-orphans oe-python-template-example-slim --help
494
+ ```
495
+
496
+
475
497
  * See the [reference documentation of the API](https://oe-python-template-example.readthedocs.io/en/latest/api_reference_v1.html) for detailed documentation of all API operations and parameters.
476
498
 
477
499
 
@@ -78,13 +78,15 @@ Projects generated with this template come with a comprehensive development tool
78
78
  17. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
79
79
  18. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
80
80
  19. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
81
- 20. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
82
- 21. Python package published to [PyPI](https://pypi.org/)
83
- 22. Docker images published to [Docker.io](https://hub.docker.com/) and [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) with [artifact attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds)
84
- 23. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
85
- 24. Settings for use with [VSCode](https://code.visualstudio.com/)
86
- 25. Settings and custom instructions for use with [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot)
87
- 26. API deployed as serverless function to [Vercel](https://vercel.com/) (optional)
81
+ 20. Documentation including dynamic badges, setup instructions, contribution guide and security policy
82
+ 21. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
83
+ 22. Python package published to [PyPI](https://pypi.org/)
84
+ 23. Multi-stage build of fat and slim (no-extras) Docker images, app running nonroot
85
+ 24. Mult-arch Docker images published to [Docker.io](https://hub.docker.com/) and [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) with [artifact attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds)
86
+ 25. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
87
+ 26. Settings for use with [VSCode](https://code.visualstudio.com/)
88
+ 27. Settings and custom instructions for use with [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot)
89
+ 28. API deployed as serverless function to [Vercel](https://vercel.com/) (optional)
88
90
 
89
91
  ### Application Features
90
92
 
@@ -92,17 +94,20 @@ Beyond development tooling, projects generated with this template include the co
92
94
 
93
95
  1. Usable as library with "Hello" module exposing a simple service that can say "Hello, world!" and echo utterances.
94
96
  2. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
95
- 3. Versioned webservice API with [FastAPI](https://fastapi.tiangolo.com/)
96
- 4. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
97
- 5. Simple Web UI with [Streamlit](https://streamlit.io/)
98
- 6. Configuration to run the CLI and API in a Docker container including setup for [Docker Compose](https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-docker-compose/)
97
+ 2. Versioned webservice API with [FastAPI](https://fastapi.tiangolo.com/)
98
+ 3. Comfortable command-line interface (CLI) with
99
+ [Typer](https://typer.tiangolo.com/)
100
+ 4. Cross-platform Graphical User Interface (GUI) with
101
+ [NiceGUI](https://nicegui.io/) running in native window
102
+ 5. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
103
+ 6. Simple Web UI with [Streamlit](https://streamlit.io/)
99
104
  7. Validation and settings management with [pydantic](https://docs.pydantic.dev/)
100
- 8. Info command enabling to inspect the runtime, compiled settings, and further info provided dynamically by modules
101
- 9. Health endpoint exposing system health dynamically aggregated from all modules and dependencies
102
- 10. Flexible logging and instrumentation, including support for [Sentry](https://sentry.io/) and [Logfire](https://logfire.dev/)
103
- 11. Hello service demonstrates use of custom real time metrics collected via Logfire
104
- 12. Modular architecture including auto-registration of services, CLI commands and API routes exposed by modules
105
- 13. Documentation including dynamic badges, setup instructions, contribution guide and security policy
105
+ 8. Flexible logging and instrumentation, including support for [Sentry](https://sentry.io/) and [Logfire](https://logfire.dev/)
106
+ 9. Modular architecture including auto-registration of services, CLI commands, API routes and GUI pages exposed by domain modules
107
+ 10. System module providing aggregate health and info to the runtime, compiled settings, and further info provided by domain modules
108
+ 11. Health and Info available via command, webservice API (info passsword protected) and GUI
109
+ 12. Hello service demonstrates use of custom real time metrics collected via Logfire
110
+ 13. Configuration to run the CLI and API in a Docker container including setup for [Docker Compose](https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-docker-compose/)
106
111
 
107
112
  Explore [here](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example) for what's generated out of the box.
108
113
 
@@ -169,9 +174,13 @@ pip install oe-python-template-example # add dependency to your project
169
174
  Executing the command line interface (CLI) in an isolated Python environment is just as easy:
170
175
 
171
176
  ```shell
172
- uvx oe-python-template-example hello-world # prints "Hello, world! [..]"
173
- uvx oe-python-template-example serve # serves web API
174
- uvx oe-python-template-example serve --port=4711 # serves web API on port 4711
177
+ uvx oe-python-template-example hello world # prints "Hello, world! [..]"
178
+ uvx oe-python-template-example hello echo "Lorem Ipsum" # echos "Lorem Ipsum"
179
+ uvx oe-python-template-example gui # opens the graphical user interface (GUI)
180
+ uvx --with "oe-python-template-example[examples]" oe-python-template-example gui # opens the graphical user interface (GUI) with support for scientific computing
181
+ uvx oe-python-template-example system serve # serves web API
182
+ uvx oe-python-template-example system serve --port=4711 # serves web API on port 4711
183
+ uvx oe-python-template-example system openapi # serves web API on port 4711
175
184
  ```
176
185
 
177
186
  Notes:
@@ -184,10 +193,11 @@ The CLI provides extensive help:
184
193
 
185
194
  ```shell
186
195
  uvx oe-python-template-example --help # all CLI commands
187
- uvx oe-python-template-example hello-world --help # help for specific command
188
- uvx oe-python-template-example echo --help
189
- uvx oe-python-template-example openapi --help
190
- uvx oe-python-template-example serve --help
196
+ uvx oe-python-template-example hello world --help # help for specific command
197
+ uvx oe-python-template-example hello echo --help
198
+ uvx oe-python-template-example gui --help
199
+ uvx oe-python-template-example system serve --help
200
+ uvx oe-python-template-example system openapi --help
191
201
  ```
192
202
 
193
203
 
@@ -315,6 +325,8 @@ uvx oe-python-template-example hello world
315
325
  uvx oe-python-template-example hello echo --help
316
326
  uvx oe-python-template-example hello echo "Lorem"
317
327
  uvx oe-python-template-example hello echo "Lorem" --json
328
+ uvx oe-python-template-example gui
329
+ uvx --with "oe-python-template-example[examples]" oe-python-template-example gui # opens the graphical user interface (GUI) with support for scientific computing
318
330
  uvx oe-python-template-example system info
319
331
  uvx oe-python-template-example system health
320
332
  uvx oe-python-template-example system openapi
@@ -399,6 +411,15 @@ echo "Shutting down the API container ..."
399
411
  docker compose down
400
412
  ```
401
413
 
414
+ #### Slim
415
+
416
+ The default Docker image includes all extras. Additionally a slim image is provided, with no extras. Run as follows
417
+
418
+ ```shell
419
+ docker compose run --remove-orphans oe-python-template-example-slim --help
420
+ ```
421
+
422
+
402
423
  * See the [reference documentation of the API](https://oe-python-template-example.readthedocs.io/en/latest/api_reference_v1.html) for detailed documentation of all API operations and parameters.
403
424
 
404
425
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oe-python-template-example"
3
- version = "0.4.1"
3
+ version = "0.4.3"
4
4
  description = "🧠 Example project scaffolded and kept up to date with OE Python Template (oe-python-template)."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -65,6 +65,7 @@ dependencies = [
65
65
  # From Template
66
66
  "fastapi[standard,all]>=0.115.12",
67
67
  "logfire[system-metrics]>=3.13.1",
68
+ "nicegui[native]>=2.15.0",
68
69
  "opentelemetry-instrumentation-fastapi>=0.53b0",
69
70
  "opentelemetry-instrumentation-httpx>=0.53b0",
70
71
  "opentelemetry-instrumentation-jinja2>=0.53b0",
@@ -74,50 +75,30 @@ dependencies = [
74
75
  "opentelemetry-instrumentation-urllib>=0.53b0",
75
76
  "opentelemetry-instrumentation-urllib3>=0.53b0",
76
77
  "psutil>=7.0.0",
77
- "pydantic>=2.11.3",
78
- "pydantic-settings>=2.8.1",
79
- "sentry-sdk>=2.25.1",
78
+ "pydantic-settings>=2.9.1",
79
+ "sentry-sdk>=2.26.1",
80
80
  "typer>=0.15.1",
81
81
  "uptime>=3.0.1",
82
82
  # Custom
83
83
  # Nothing yet
84
84
  ]
85
85
 
86
- [project.scripts]
87
- oe-python-template-example = "oe_python_template_example.cli:cli"
88
-
89
- [project.urls]
90
- Homepage = "https://oe-python-template-example.readthedocs.io/en/latest/"
91
- Documentation = "https://oe-python-template-example.readthedocs.io/en/latest/"
92
- Source = "https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example"
93
- Changelog = "https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example/releases"
94
- Issues = "https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example/issues"
95
-
96
- [build-system]
97
- requires = ["hatchling==1.27.0"]
98
- build-backend = "hatchling.build"
99
-
100
- [tool.hatch.build]
101
- include = ["src/*"]
102
-
103
- [tool.hatch.build.targets.wheel]
104
- packages = ["src/oe_python_template_example"]
105
-
106
86
  [project.optional-dependencies]
107
87
  examples = [
108
88
  "streamlit>=1.44.1",
109
- "marimo>=0.12.8",
89
+ "marimo>=0.13.0",
110
90
  "jupyter>=1.1.1",
111
91
  "jinja2>=3.1.6",
92
+ "matplotlib>=3.10.1",
112
93
  ]
113
94
 
114
95
  [dependency-groups]
115
96
  dev = [
116
97
  "autodoc-pydantic>=2.2.0",
117
- "bump-my-version>=1.1.1",
98
+ "bump-my-version>=1.1.2",
118
99
  "cyclonedx-py>=1.0.1",
119
100
  "detect-secrets>=1.5.0",
120
- "enum-tools>=0.12.0",
101
+ "enum-tools>=0.13.0",
121
102
  "furo>=2024.8.6",
122
103
  "git-cliff>=2.8.0",
123
104
  "matplotlib>=3.10.1",
@@ -133,10 +114,12 @@ dev = [
133
114
  "pytest-docker>=3.2.1",
134
115
  "pytest-env>=1.1.5",
135
116
  "pytest-regressions>=2.7.0",
117
+ "pytest-selenium>=4.1.0",
136
118
  "pytest-subprocess>=1.5.3",
137
119
  "pytest-timeout>=2.3.1",
120
+ "pytest-watcher>=0.4.3",
138
121
  "pytest-xdist[psutil]>=3.6.1",
139
- "ruff>=0.11.5",
122
+ "ruff>=0.11.6",
140
123
  "sphinx>=8.2.3",
141
124
  "sphinx-autobuild>=2024.10.3",
142
125
  "sphinx-copybutton>=0.5.2",
@@ -153,18 +136,37 @@ dev = [
153
136
  "watchdog>=6.0.0",
154
137
  ]
155
138
 
139
+ [project.scripts]
140
+ oe-python-template-example = "oe_python_template_example.cli:cli"
141
+
142
+ [project.urls]
143
+ Homepage = "https://oe-python-template-example.readthedocs.io/en/latest/"
144
+ Documentation = "https://oe-python-template-example.readthedocs.io/en/latest/"
145
+ Source = "https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example"
146
+ Changelog = "https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example/releases"
147
+ Issues = "https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example/issues"
148
+
149
+ [build-system]
150
+ requires = ["hatchling==1.27.0"]
151
+ build-backend = "hatchling.build"
152
+
153
+ [tool.hatch.build]
154
+ include = ["src/*"]
155
+
156
+ [tool.hatch.build.targets.wheel]
157
+ packages = ["src/oe_python_template_example"]
158
+
156
159
  [tool.uv]
157
160
  override-dependencies = [ # https://github.com/astral-sh/uv/issues/4422
158
161
  "rfc3987; sys_platform == 'never'", # GPLv3
159
162
  ]
160
163
 
161
-
162
164
  [tool.ruff]
163
165
  target-version = "py311"
164
166
  preview = true
165
167
  fix = true
166
168
  line-length = 120
167
- extend-exclude = [".fixme", "notebook.py", "template/*.py"]
169
+ extend-exclude = [".fixme", "notebook.py", "template/*.py", "bottle.py"]
168
170
 
169
171
  [tool.ruff.lint]
170
172
  select = ["ALL"]
@@ -227,6 +229,7 @@ docstring-code-format = true
227
229
  convention = "google"
228
230
 
229
231
  [tool.mypy] # https://mypy.readthedocs.io/en/latest/config_file.html
232
+ exclude = ["bottle.py"]
230
233
  junit_xml = "reports/mypy_junit.xml"
231
234
  plugins = "pydantic.mypy"
232
235
  strict = true
@@ -278,7 +281,7 @@ source = ["src/"]
278
281
 
279
282
 
280
283
  [tool.bumpversion]
281
- current_version = "0.4.1"
284
+ current_version = "0.4.3"
282
285
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
283
286
  serialize = ["{major}.{minor}.{patch}"]
284
287
  search = "{current_version}"
@@ -316,6 +319,9 @@ filename = "sonar-project.properties"
316
319
  [[tool.bumpversion.files]]
317
320
  filename = "docs/source/conf.py"
318
321
 
322
+ [[tool.bumpversion.files]]
323
+ filename = "examples/notebook.py"
324
+
319
325
  [tool.git-cliff.remote.github]
320
326
  owner = "helmut-hoffer-von-ankershoffen"
321
327
  repo = "oe-python-template-example"
@@ -31,7 +31,7 @@ API_BASE_URL = __base__url__
31
31
  if not API_BASE_URL:
32
32
  API_BASE_URL = f"http://{UVICORN_HOST}:{UVICORN_PORT}"
33
33
 
34
- app = FastAPI(
34
+ api = FastAPI(
35
35
  root_path="/api",
36
36
  title=TITLE,
37
37
  contact={
@@ -76,4 +76,4 @@ for router in locate_implementations(VersionedAPIRouter):
76
76
 
77
77
  # Mount all API versions to the main app
78
78
  for version in API_VERSIONS:
79
- app.mount(f"/{version}", api_instances[version])
79
+ api.mount(f"/{version}", api_instances[version])
@@ -0,0 +1,55 @@
1
+ """CLI (Command Line Interface) of OE Python Template Example."""
2
+
3
+ import sys
4
+ from importlib.util import find_spec
5
+
6
+ import typer
7
+
8
+ from .constants import MODULES_TO_INSTRUMENT
9
+ from .utils import __version__, boot, console, get_logger, prepare_cli
10
+
11
+ boot(MODULES_TO_INSTRUMENT)
12
+ logger = get_logger(__name__)
13
+
14
+ cli = typer.Typer(help="Command Line Interface of OE Python Template Example")
15
+ prepare_cli(cli, f"🧠 OE Python Template Example v{__version__} - built with love in Berlin 🐻")
16
+
17
+
18
+ if find_spec("nicegui") and find_spec("webview"):
19
+
20
+ @cli.command()
21
+ def gui() -> None:
22
+ """Start graphical user interface (GUI) in native window."""
23
+ from .utils import gui_run # noqa: PLC0415
24
+
25
+ gui_run(native=True, with_api=False, title="OE Python Template Example", icon="🧠")
26
+
27
+
28
+ if find_spec("marimo"):
29
+ from typing import Annotated
30
+
31
+ import uvicorn
32
+
33
+ from .utils import create_marimo_app
34
+
35
+ @cli.command()
36
+ def notebook(
37
+ host: Annotated[str, typer.Option(help="Host to bind the server to")] = "127.0.0.1",
38
+ port: Annotated[int, typer.Option(help="Port to bind the server to")] = 8001,
39
+ ) -> None:
40
+ """Start notebook in web browser."""
41
+ console.print(f"Starting marimo notebook server at http://{host}:{port}")
42
+ uvicorn.run(
43
+ create_marimo_app(),
44
+ host=host,
45
+ port=port,
46
+ )
47
+
48
+
49
+ if __name__ == "__main__": # pragma: no cover
50
+ try:
51
+ cli()
52
+ except Exception as e: # noqa: BLE001
53
+ logger.critical("Fatal error occurred: %s", e)
54
+ console.print(f"Fatal error occurred: {e}", style="error")
55
+ sys.exit(1)
@@ -0,0 +1,13 @@
1
+ """Constants for the OE Python Template Example."""
2
+
3
+ from pathlib import Path
4
+
5
+ MODULES_TO_INSTRUMENT = ["oe_python_template_example.hello"]
6
+
7
+ API_VERSIONS = {
8
+ "v1": "1.0.0",
9
+ "v2": "2.0.0",
10
+ }
11
+
12
+ NOTEBOOK_FOLDER = Path(__file__).parent.parent.parent / "examples"
13
+ NOTEBOOK_APP = Path(__file__).parent.parent.parent / "examples" / "notebook.py"
@@ -15,3 +15,14 @@ __all__ = [
15
15
  "api_v2",
16
16
  "cli",
17
17
  ]
18
+
19
+
20
+ from importlib.util import find_spec
21
+
22
+ # advertise PageBuuilder to enable auto-discovery
23
+ if find_spec("nicegui"):
24
+ from ._gui import PageBuilder
25
+
26
+ __all__ += [
27
+ "PageBuilder",
28
+ ]
@@ -0,0 +1,44 @@
1
+ """Homepage (index) of GUI."""
2
+
3
+ from pathlib import Path
4
+
5
+ from nicegui import ui
6
+
7
+ from oe_python_template_example.utils import BasePageBuilder, GUILocalFilePicker
8
+
9
+ from ._service import Service
10
+
11
+
12
+ async def pick_file() -> None:
13
+ """Open a file picker dialog and show notifier when closed again."""
14
+ result = await GUILocalFilePicker(str(Path.cwd() / "examples"), multiple=True)
15
+ ui.notify(f"You chose {result}")
16
+
17
+
18
+ class PageBuilder(BasePageBuilder):
19
+ @staticmethod
20
+ def register_pages() -> None:
21
+ @ui.page("/")
22
+ def page_index() -> None:
23
+ """Homepage of GUI."""
24
+ service = Service()
25
+
26
+ ui.button("Choose file", on_click=pick_file, icon="folder").mark("BUTTON_CHOOSE_FILE")
27
+
28
+ ui.button("Click me", on_click=lambda: ui.notify(service.get_hello_world()), icon="check").mark(
29
+ "BUTTON_CLICK_ME"
30
+ )
31
+
32
+ from importlib.util import find_spec # noqa: PLC0415
33
+
34
+ if find_spec("matplotlib") and find_spec("numpy"):
35
+ import numpy as np # noqa: PLC0415
36
+
37
+ with ui.card().tight().mark("CARD_PLOT"): # noqa: SIM117
38
+ with ui.matplotlib(figsize=(4, 3)).figure as fig:
39
+ x = np.linspace(0.0, 5.0)
40
+ y = np.cos(2 * np.pi * x) * np.exp(-x)
41
+ ax = fig.gca()
42
+ ax.plot(x, y, "-")
43
+
44
+ ui.link("Info", "/info").mark("LINK_INFO")
@@ -1,4 +1,4 @@
1
- """Hello module."""
1
+ """System module."""
2
2
 
3
3
  from ._api import api_routers
4
4
  from ._cli import cli
@@ -12,6 +12,17 @@ __all__ = [
12
12
  "cli",
13
13
  ]
14
14
 
15
+
16
+ from importlib.util import find_spec
17
+
18
+ # advertise PageBuuilder to enable auto-discovery
19
+ if find_spec("nicegui"):
20
+ from ._gui import PageBuilder
21
+
22
+ __all__ += [
23
+ "PageBuilder",
24
+ ]
25
+
15
26
  # Export all individual API routers so they are picked up by depdency injection (DI)
16
27
  for version, router in api_routers.items():
17
28
  router_name = f"api_{version}"