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.
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/.gitignore +7 -1
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/PKG-INFO +51 -29
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/README.md +45 -24
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/pyproject.toml +37 -31
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/api.py +2 -2
- oe_python_template_example-0.4.3/src/oe_python_template_example/cli.py +55 -0
- oe_python_template_example-0.4.3/src/oe_python_template_example/constants.py +13 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/__init__.py +11 -0
- oe_python_template_example-0.4.3/src/oe_python_template_example/hello/_gui.py +44 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/__init__.py +12 -1
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_cli.py +64 -23
- oe_python_template_example-0.4.3/src/oe_python_template_example/system/_gui.py +20 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_service.py +1 -0
- oe_python_template_example-0.4.3/src/oe_python_template_example/utils/.vendored/bottle.py +4563 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/__init__.py +14 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_constants.py +27 -8
- oe_python_template_example-0.4.3/src/oe_python_template_example/utils/_gui.py +174 -0
- oe_python_template_example-0.4.3/src/oe_python_template_example/utils/_notebook.py +61 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/boot.py +6 -0
- oe_python_template_example-0.4.1/src/oe_python_template_example/cli.py +0 -22
- oe_python_template_example-0.4.1/src/oe_python_template_example/constants.py +0 -7
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/LICENSE +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/__init__.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_api.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_cli.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_constants.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_models.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_service.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/hello/_settings.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_api.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/system/_settings.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_api.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_cli.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_console.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_di.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_health.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_log.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_logfire.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_process.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_sentry.py +0 -0
- {oe_python_template_example-0.4.1 → oe_python_template_example-0.4.3}/src/oe_python_template_example/utils/_service.py +0 -0
- {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
|
-
|
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.
|
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.
|
63
|
-
Requires-Dist:
|
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.
|
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.
|
155
|
-
21.
|
156
|
-
22.
|
157
|
-
23.
|
158
|
-
24.
|
159
|
-
25.
|
160
|
-
26.
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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.
|
174
|
-
9.
|
175
|
-
10.
|
176
|
-
11.
|
177
|
-
12.
|
178
|
-
13.
|
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
|
246
|
-
uvx oe-python-template-example
|
247
|
-
uvx oe-python-template-example
|
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
|
261
|
-
uvx oe-python-template-example echo --help
|
262
|
-
uvx oe-python-template-example
|
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.
|
82
|
-
21.
|
83
|
-
22.
|
84
|
-
23.
|
85
|
-
24.
|
86
|
-
25.
|
87
|
-
26.
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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.
|
101
|
-
9.
|
102
|
-
10.
|
103
|
-
11.
|
104
|
-
12.
|
105
|
-
13.
|
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
|
173
|
-
uvx oe-python-template-example
|
174
|
-
uvx oe-python-template-example
|
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
|
188
|
-
uvx oe-python-template-example echo --help
|
189
|
-
uvx oe-python-template-example
|
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.
|
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.
|
78
|
-
"
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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"
|
@@ -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
|
-
"""
|
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}"
|