oe-python-template-example 0.3.5__tar.gz → 0.3.7__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 (41) hide show
  1. {oe_python_template_example-0.3.5 → oe_python_template_example-0.3.7}/PKG-INFO +78 -51
  2. {oe_python_template_example-0.3.5 → oe_python_template_example-0.3.7}/README.md +63 -48
  3. {oe_python_template_example-0.3.5 → oe_python_template_example-0.3.7}/pyproject.toml +23 -11
  4. oe_python_template_example-0.3.7/src/oe_python_template_example/__init__.py +6 -0
  5. oe_python_template_example-0.3.7/src/oe_python_template_example/api.py +75 -0
  6. oe_python_template_example-0.3.7/src/oe_python_template_example/cli.py +22 -0
  7. oe_python_template_example-0.3.7/src/oe_python_template_example/constants.py +7 -0
  8. oe_python_template_example-0.3.7/src/oe_python_template_example/hello/__init__.py +17 -0
  9. oe_python_template_example-0.3.7/src/oe_python_template_example/hello/_api.py +94 -0
  10. oe_python_template_example-0.3.7/src/oe_python_template_example/hello/_cli.py +47 -0
  11. oe_python_template_example-0.3.7/src/oe_python_template_example/hello/_constants.py +4 -0
  12. oe_python_template_example-0.3.7/src/oe_python_template_example/hello/_models.py +28 -0
  13. oe_python_template_example-0.3.7/src/oe_python_template_example/hello/_service.py +96 -0
  14. oe_python_template_example-0.3.5/src/oe_python_template_example/settings.py → oe_python_template_example-0.3.7/src/oe_python_template_example/hello/_settings.py +6 -4
  15. oe_python_template_example-0.3.7/src/oe_python_template_example/system/__init__.py +19 -0
  16. oe_python_template_example-0.3.7/src/oe_python_template_example/system/_api.py +116 -0
  17. oe_python_template_example-0.3.7/src/oe_python_template_example/system/_cli.py +165 -0
  18. oe_python_template_example-0.3.7/src/oe_python_template_example/system/_service.py +186 -0
  19. oe_python_template_example-0.3.7/src/oe_python_template_example/system/_settings.py +31 -0
  20. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/__init__.py +59 -0
  21. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_api.py +18 -0
  22. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_cli.py +68 -0
  23. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_console.py +14 -0
  24. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_constants.py +48 -0
  25. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_di.py +70 -0
  26. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_health.py +107 -0
  27. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_log.py +122 -0
  28. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_logfire.py +68 -0
  29. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_process.py +41 -0
  30. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_sentry.py +97 -0
  31. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_service.py +39 -0
  32. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/_settings.py +80 -0
  33. oe_python_template_example-0.3.7/src/oe_python_template_example/utils/boot.py +86 -0
  34. oe_python_template_example-0.3.5/src/oe_python_template_example/__init__.py +0 -20
  35. oe_python_template_example-0.3.5/src/oe_python_template_example/api.py +0 -181
  36. oe_python_template_example-0.3.5/src/oe_python_template_example/cli.py +0 -150
  37. oe_python_template_example-0.3.5/src/oe_python_template_example/constants.py +0 -10
  38. oe_python_template_example-0.3.5/src/oe_python_template_example/models.py +0 -44
  39. oe_python_template_example-0.3.5/src/oe_python_template_example/service.py +0 -68
  40. {oe_python_template_example-0.3.5 → oe_python_template_example-0.3.7}/.gitignore +0 -0
  41. {oe_python_template_example-0.3.5 → oe_python_template_example-0.3.7}/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oe-python-template-example
3
- Version: 0.3.5
3
+ Version: 0.3.7
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/
@@ -49,13 +49,25 @@ Classifier: Programming Language :: Python :: 3.13
49
49
  Classifier: Typing :: Typed
50
50
  Requires-Python: <4.0,>=3.11
51
51
  Requires-Dist: fastapi[all,standard]>=0.115.12
52
+ Requires-Dist: logfire[system-metrics]>=3.13.1
53
+ Requires-Dist: opentelemetry-instrumentation-fastapi>=0.53b0
54
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.53b0
55
+ Requires-Dist: opentelemetry-instrumentation-jinja2>=0.53b0
56
+ Requires-Dist: opentelemetry-instrumentation-requests>=0.53b0
57
+ Requires-Dist: opentelemetry-instrumentation-sqlite3>=0.53b0
58
+ Requires-Dist: opentelemetry-instrumentation-tornado>=0.53b0
59
+ Requires-Dist: opentelemetry-instrumentation-urllib3>=0.53b0
60
+ Requires-Dist: opentelemetry-instrumentation-urllib>=0.53b0
61
+ Requires-Dist: psutil>=7.0.0
52
62
  Requires-Dist: pydantic-settings>=2.8.1
53
- Requires-Dist: pydantic>=2.11.1
63
+ Requires-Dist: pydantic>=2.11.3
64
+ Requires-Dist: sentry-sdk>=2.25.1
54
65
  Requires-Dist: typer>=0.15.1
66
+ Requires-Dist: uptime>=3.0.1
55
67
  Provides-Extra: examples
56
68
  Requires-Dist: jinja2>=3.1.6; extra == 'examples'
57
69
  Requires-Dist: jupyter>=1.1.1; extra == 'examples'
58
- Requires-Dist: marimo>=0.12.2; extra == 'examples'
70
+ Requires-Dist: marimo>=0.12.8; extra == 'examples'
59
71
  Requires-Dist: streamlit>=1.44.1; extra == 'examples'
60
72
  Description-Content-Type: text/markdown
61
73
 
@@ -89,6 +101,8 @@ Description-Content-Type: text/markdown
89
101
  [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template)
90
102
  [![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE3IDE2VjdsLTYgNU0yIDlWOGwxLTFoMWw0IDMgOC04aDFsNCAyIDEgMXYxNGwtMSAxLTQgMmgtMWwtOC04LTQgM0gzbC0xLTF2LTFsMy0zIi8+PC9zdmc+)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example)
91
103
  [![Open in GitHub Codespaces](https://img.shields.io/static/v1?label=GitHub%20Codespaces&message=Open&color=blue&logo=github)](https://github.com/codespaces/new/helmut-hoffer-von-ankershoffen/oe-python-template-example)
104
+ [![Vercel Deploy](https://deploy-badge.vercel.app/vercel/oe-python-template-example?root=api%2Fv1%2Fhealthz)](https://oe-python-template-example.vercel.app/api/v1/hello/world)
105
+ [![Better Stack Badge](https://uptime.betterstack.com/status-badges/v1/monitor/1vzoq.svg)](https://helmut-hoffer-von-ankershoffen.betteruptime.com/)
92
106
 
93
107
  <!---
94
108
  [![ghcr.io - Version](https://ghcr-badge.egpl.dev/helmut-hoffer-von-ankershoffen/oe-python-template-example/tags?color=%2344cc11&ignore=0.0%2C0%2Clatest&n=3&label=ghcr.io&trim=)](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example/pkgs/container/oe-python-template-example)
@@ -127,33 +141,40 @@ Projects generated with this template come with a comprehensive development tool
127
141
  8. CI/CD pipeline can be run locally with [act](https://github.com/nektos/act)
128
142
  9. Code quality and security checks with [SonarQube](https://www.sonarsource.com/products/sonarcloud) and [GitHub CodeQL](https://codeql.github.com/)
129
143
  10. Dependency monitoring and vulnerability scanning with [pip-audit](https://pypi.org/project/pip-audit/), [trivy](https://trivy.dev/latest/), [Renovate](https://github.com/renovatebot/renovate), and [GitHub Dependabot](https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide)
130
- 11. Licenses of dependencies extracted with [pip-licenses](https://pypi.org/project/pip-licenses/), matched with allow list, and published as release artifacts in CSV and JSON format for further compliance checks
131
- 12. Generation of attributions from extracted licenses
132
- 13. Software Bill of Materials (SBOM) generated in [CycloneDX](https://cyclonedx.org/) and [SPDX](https://spdx.dev/) formats with [cyclonedx-python](https://github.com/CycloneDX/cyclonedx-python) resp. [trivy](https://trivy.dev/latest/), published as release artifacts
133
- 14. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
134
- 15. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
135
- 16. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
136
- 17. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
137
- 18. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
138
- 19. Python package published to [PyPI](https://pypi.org/)
139
- 20. 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)
140
- 21. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
141
- 22. Settings for use with [VSCode](https://code.visualstudio.com/)
142
- 23. Settings and custom instructions for use with [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot)
144
+ 11. Error monitoring and profiling with [Sentry](https://sentry.io/) (optional)
145
+ 12. Logging and metrics with [Logfire](https://logfire.dev/) (optional)
146
+ 13. Prepared for uptime monitoring with [betterstack](https://betterstack.com/) or alternatives
147
+ 13. Licenses of dependencies extracted with [pip-licenses](https://pypi.org/project/pip-licenses/), matched with allow list, and published as release artifacts in CSV and JSON format for further compliance checks
148
+ 14. Generation of attributions from extracted licenses
149
+ 15. Software Bill of Materials (SBOM) generated in [CycloneDX](https://cyclonedx.org/) and [SPDX](https://spdx.dev/) formats with [cyclonedx-python](https://github.com/CycloneDX/cyclonedx-python) resp. [trivy](https://trivy.dev/latest/), published as release artifacts
150
+ 16. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
151
+ 17. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
152
+ 18. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
153
+ 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)
143
161
 
144
162
  ### Application Features
145
163
 
146
- Beyond development tooling, projects generated with this template include the code, documentation, and configuration of a fully functioning demo application and service. This reference implementation serves as a starting point for your own business logic with modern patterns and practices already in place:
147
-
148
- 1. Service architecture suitable for use as shared library
149
- 2. Validation with [pydantic](https://docs.pydantic.dev/)
150
- 3. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
151
- 4. Versioned Web API with [FastAPI](https://fastapi.tiangolo.com/)
152
- 5. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
153
- 6. Simple Web UI with [Streamlit](https://streamlit.io/)
154
- 7. 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/)
155
- 8. Documentation including badges, setup instructions, contribution guide and security policy
156
- 9. Preparation to deploy API as serverless function to Vercel
164
+ Beyond development tooling, projects generated with this template include the code, documentation, and configuration of a fully functioning application and service. This reference implementation serves as a starting point for your own business logic with modern patterns and enterprise practices already in place:
165
+
166
+ 1. Usable as library with "Hello" module exposing a simple service
167
+ 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/)
172
+ 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. Modular architecture including auto-registration of services, CLI commands and API routes exposed by modules
177
+ 12. Documentation including dynamic badges, setup instructions, contribution guide and security policy
157
178
 
158
179
  Explore [here](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example) for what's generated out of the box.
159
180
 
@@ -276,7 +297,7 @@ The following examples run from source - clone this repository using
276
297
  from dotenv import load_dotenv
277
298
  from rich.console import Console
278
299
 
279
- from oe_python_template_example import Service
300
+ from oe_python_template_example.hello import Service
280
301
 
281
302
  console = Console()
282
303
 
@@ -362,13 +383,15 @@ uvx oe-python-template-example --help
362
383
  Execute commands:
363
384
 
364
385
  ```shell
365
- uvx oe-python-template-example hello-world
366
- uvx oe-python-template-example echo --help
367
- uvx oe-python-template-example echo "Lorem"
368
- uvx oe-python-template-example echo "Lorem" --json
369
- uvx oe-python-template-example openapi
370
- uvx oe-python-template-example openapi --output-format=json
371
- uvx oe-python-template-example serve
386
+ uvx oe-python-template-example hello world
387
+ uvx oe-python-template-example hello echo --help
388
+ uvx oe-python-template-example hello echo "Lorem"
389
+ uvx oe-python-template-example hello echo "Lorem" --json
390
+ uvx oe-python-template-example system info
391
+ uvx oe-python-template-example system health
392
+ uvx oe-python-template-example system openapi
393
+ uvx oe-python-template-example system openapi --output-format=json
394
+ uvx oe-python-template-example system serve
372
395
  ```
373
396
 
374
397
  See the [reference documentation of the CLI](https://oe-python-template-example.readthedocs.io/en/latest/cli_reference.html) for detailed documentation of all CLI commands and options.
@@ -391,19 +414,21 @@ You can as well run the CLI within Docker.
391
414
 
392
415
  ```shell
393
416
  docker run helmuthva/oe-python-template-example --help
394
- docker run helmuthva/oe-python-template-example hello-world
395
- docker run helmuthva/oe-python-template-example echo --help
396
- docker run helmuthva/oe-python-template-example echo "Lorem"
397
- docker run helmuthva/oe-python-template-example echo "Lorem" --json
398
- docker run helmuthva/oe-python-template-example openapi
399
- docker run helmuthva/oe-python-template-example openapi --output-format=json
400
- docker run helmuthva/oe-python-template-example serve
417
+ docker run helmuthva/oe-python-template-example hello world
418
+ docker run helmuthva/oe-python-template-example hello echo --help
419
+ docker run helmuthva/oe-python-template-example hello echo "Lorem"
420
+ docker run helmuthva/oe-python-template-example hello echo "Lorem" --json
421
+ docker run helmuthva/oe-python-template-example system info
422
+ docker run helmuthva/oe-python-template-example system health
423
+ docker run helmuthva/oe-python-template-example system openapi
424
+ docker run helmuthva/oe-python-template-example system openapi --output-format=json
425
+ docker run helmuthva/oe-python-template-example system serve
401
426
  ```
402
427
 
403
428
  Execute command:
404
429
 
405
430
  ```shell
406
- docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template-example echo "Lorem Ipsum"
431
+ docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template-example hello echo "Lorem Ipsum"
407
432
  ```
408
433
 
409
434
  Or use docker compose
@@ -412,12 +437,14 @@ The .env is passed through from the host to the Docker container.
412
437
 
413
438
  ```shell
414
439
  docker compose run --remove-orphans oe-python-template-example --help
415
- docker compose run --remove-orphans oe-python-template-example hello-world
416
- docker compose run --remove-orphans oe-python-template-example echo --help
417
- docker compose run --remove-orphans oe-python-template-example echo "Lorem"
418
- docker compose run --remove-orphans oe-python-template-example echo "Lorem" --json
419
- docker compose run --remove-orphans oe-python-template-example openapi
420
- docker compose run --remove-orphans oe-python-template-example openapi --output-format=json
440
+ docker compose run --remove-orphans oe-python-template-example hello world
441
+ docker compose run --remove-orphans oe-python-template-example hello echo --help
442
+ docker compose run --remove-orphans oe-python-template-example hello echo "Lorem"
443
+ docker compose run --remove-orphans oe-python-template-example hello echo "Lorem" --json
444
+ docker compose run --remove-orphans oe-python-template-example system info
445
+ docker compose run --remove-orphans oe-python-template-example system health
446
+ docker compose run --remove-orphans oe-python-template-example system openapi
447
+ docker compose run --remove-orphans oe-python-template-example system openapi --output-format=json
421
448
  echo "Running OE Python Template Example's API container as a daemon ..."
422
449
  docker compose up -d
423
450
  echo "Waiting for the API server to start ..."
@@ -426,7 +453,7 @@ echo "Checking health of v1 API ..."
426
453
  curl http://127.0.0.1:8000/api/v1/healthz
427
454
  echo ""
428
455
  echo "Saying hello world with v1 API ..."
429
- curl http://127.0.0.1:8000/api/v1/hello-world
456
+ curl http://127.0.0.1:8000/api/v1/hello/world
430
457
  echo ""
431
458
  echo "Swagger docs of v1 API ..."
432
459
  curl http://127.0.0.1:8000/api/v1/docs
@@ -435,7 +462,7 @@ echo "Checking health of v2 API ..."
435
462
  curl http://127.0.0.1:8000/api/v2/healthz
436
463
  echo ""
437
464
  echo "Saying hello world with v1 API ..."
438
- curl http://127.0.0.1:8000/api/v2/hello-world
465
+ curl http://127.0.0.1:8000/api/v2/hello/world
439
466
  echo ""
440
467
  echo "Swagger docs of v2 API ..."
441
468
  curl http://127.0.0.1:8000/api/v2/docs
@@ -28,6 +28,8 @@
28
28
  [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template)
29
29
  [![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE3IDE2VjdsLTYgNU0yIDlWOGwxLTFoMWw0IDMgOC04aDFsNCAyIDEgMXYxNGwtMSAxLTQgMmgtMWwtOC04LTQgM0gzbC0xLTF2LTFsMy0zIi8+PC9zdmc+)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example)
30
30
  [![Open in GitHub Codespaces](https://img.shields.io/static/v1?label=GitHub%20Codespaces&message=Open&color=blue&logo=github)](https://github.com/codespaces/new/helmut-hoffer-von-ankershoffen/oe-python-template-example)
31
+ [![Vercel Deploy](https://deploy-badge.vercel.app/vercel/oe-python-template-example?root=api%2Fv1%2Fhealthz)](https://oe-python-template-example.vercel.app/api/v1/hello/world)
32
+ [![Better Stack Badge](https://uptime.betterstack.com/status-badges/v1/monitor/1vzoq.svg)](https://helmut-hoffer-von-ankershoffen.betteruptime.com/)
31
33
 
32
34
  <!---
33
35
  [![ghcr.io - Version](https://ghcr-badge.egpl.dev/helmut-hoffer-von-ankershoffen/oe-python-template-example/tags?color=%2344cc11&ignore=0.0%2C0%2Clatest&n=3&label=ghcr.io&trim=)](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example/pkgs/container/oe-python-template-example)
@@ -66,33 +68,40 @@ Projects generated with this template come with a comprehensive development tool
66
68
  8. CI/CD pipeline can be run locally with [act](https://github.com/nektos/act)
67
69
  9. Code quality and security checks with [SonarQube](https://www.sonarsource.com/products/sonarcloud) and [GitHub CodeQL](https://codeql.github.com/)
68
70
  10. Dependency monitoring and vulnerability scanning with [pip-audit](https://pypi.org/project/pip-audit/), [trivy](https://trivy.dev/latest/), [Renovate](https://github.com/renovatebot/renovate), and [GitHub Dependabot](https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide)
69
- 11. Licenses of dependencies extracted with [pip-licenses](https://pypi.org/project/pip-licenses/), matched with allow list, and published as release artifacts in CSV and JSON format for further compliance checks
70
- 12. Generation of attributions from extracted licenses
71
- 13. Software Bill of Materials (SBOM) generated in [CycloneDX](https://cyclonedx.org/) and [SPDX](https://spdx.dev/) formats with [cyclonedx-python](https://github.com/CycloneDX/cyclonedx-python) resp. [trivy](https://trivy.dev/latest/), published as release artifacts
72
- 14. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
73
- 15. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
74
- 16. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
75
- 17. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
76
- 18. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
77
- 19. Python package published to [PyPI](https://pypi.org/)
78
- 20. 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)
79
- 21. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
80
- 22. Settings for use with [VSCode](https://code.visualstudio.com/)
81
- 23. Settings and custom instructions for use with [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot)
71
+ 11. Error monitoring and profiling with [Sentry](https://sentry.io/) (optional)
72
+ 12. Logging and metrics with [Logfire](https://logfire.dev/) (optional)
73
+ 13. Prepared for uptime monitoring with [betterstack](https://betterstack.com/) or alternatives
74
+ 13. Licenses of dependencies extracted with [pip-licenses](https://pypi.org/project/pip-licenses/), matched with allow list, and published as release artifacts in CSV and JSON format for further compliance checks
75
+ 14. Generation of attributions from extracted licenses
76
+ 15. Software Bill of Materials (SBOM) generated in [CycloneDX](https://cyclonedx.org/) and [SPDX](https://spdx.dev/) formats with [cyclonedx-python](https://github.com/CycloneDX/cyclonedx-python) resp. [trivy](https://trivy.dev/latest/), published as release artifacts
77
+ 16. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
78
+ 17. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
79
+ 18. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
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)
82
88
 
83
89
  ### Application Features
84
90
 
85
- Beyond development tooling, projects generated with this template include the code, documentation, and configuration of a fully functioning demo application and service. This reference implementation serves as a starting point for your own business logic with modern patterns and practices already in place:
86
-
87
- 1. Service architecture suitable for use as shared library
88
- 2. Validation with [pydantic](https://docs.pydantic.dev/)
89
- 3. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
90
- 4. Versioned Web API with [FastAPI](https://fastapi.tiangolo.com/)
91
- 5. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
92
- 6. Simple Web UI with [Streamlit](https://streamlit.io/)
93
- 7. 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/)
94
- 8. Documentation including badges, setup instructions, contribution guide and security policy
95
- 9. Preparation to deploy API as serverless function to Vercel
91
+ Beyond development tooling, projects generated with this template include the code, documentation, and configuration of a fully functioning application and service. This reference implementation serves as a starting point for your own business logic with modern patterns and enterprise practices already in place:
92
+
93
+ 1. Usable as library with "Hello" module exposing a simple service
94
+ 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/)
99
+ 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. Modular architecture including auto-registration of services, CLI commands and API routes exposed by modules
104
+ 12. Documentation including dynamic badges, setup instructions, contribution guide and security policy
96
105
 
97
106
  Explore [here](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example) for what's generated out of the box.
98
107
 
@@ -215,7 +224,7 @@ The following examples run from source - clone this repository using
215
224
  from dotenv import load_dotenv
216
225
  from rich.console import Console
217
226
 
218
- from oe_python_template_example import Service
227
+ from oe_python_template_example.hello import Service
219
228
 
220
229
  console = Console()
221
230
 
@@ -301,13 +310,15 @@ uvx oe-python-template-example --help
301
310
  Execute commands:
302
311
 
303
312
  ```shell
304
- uvx oe-python-template-example hello-world
305
- uvx oe-python-template-example echo --help
306
- uvx oe-python-template-example echo "Lorem"
307
- uvx oe-python-template-example echo "Lorem" --json
308
- uvx oe-python-template-example openapi
309
- uvx oe-python-template-example openapi --output-format=json
310
- uvx oe-python-template-example serve
313
+ uvx oe-python-template-example hello world
314
+ uvx oe-python-template-example hello echo --help
315
+ uvx oe-python-template-example hello echo "Lorem"
316
+ uvx oe-python-template-example hello echo "Lorem" --json
317
+ uvx oe-python-template-example system info
318
+ uvx oe-python-template-example system health
319
+ uvx oe-python-template-example system openapi
320
+ uvx oe-python-template-example system openapi --output-format=json
321
+ uvx oe-python-template-example system serve
311
322
  ```
312
323
 
313
324
  See the [reference documentation of the CLI](https://oe-python-template-example.readthedocs.io/en/latest/cli_reference.html) for detailed documentation of all CLI commands and options.
@@ -330,19 +341,21 @@ You can as well run the CLI within Docker.
330
341
 
331
342
  ```shell
332
343
  docker run helmuthva/oe-python-template-example --help
333
- docker run helmuthva/oe-python-template-example hello-world
334
- docker run helmuthva/oe-python-template-example echo --help
335
- docker run helmuthva/oe-python-template-example echo "Lorem"
336
- docker run helmuthva/oe-python-template-example echo "Lorem" --json
337
- docker run helmuthva/oe-python-template-example openapi
338
- docker run helmuthva/oe-python-template-example openapi --output-format=json
339
- docker run helmuthva/oe-python-template-example serve
344
+ docker run helmuthva/oe-python-template-example hello world
345
+ docker run helmuthva/oe-python-template-example hello echo --help
346
+ docker run helmuthva/oe-python-template-example hello echo "Lorem"
347
+ docker run helmuthva/oe-python-template-example hello echo "Lorem" --json
348
+ docker run helmuthva/oe-python-template-example system info
349
+ docker run helmuthva/oe-python-template-example system health
350
+ docker run helmuthva/oe-python-template-example system openapi
351
+ docker run helmuthva/oe-python-template-example system openapi --output-format=json
352
+ docker run helmuthva/oe-python-template-example system serve
340
353
  ```
341
354
 
342
355
  Execute command:
343
356
 
344
357
  ```shell
345
- docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template-example echo "Lorem Ipsum"
358
+ docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template-example hello echo "Lorem Ipsum"
346
359
  ```
347
360
 
348
361
  Or use docker compose
@@ -351,12 +364,14 @@ The .env is passed through from the host to the Docker container.
351
364
 
352
365
  ```shell
353
366
  docker compose run --remove-orphans oe-python-template-example --help
354
- docker compose run --remove-orphans oe-python-template-example hello-world
355
- docker compose run --remove-orphans oe-python-template-example echo --help
356
- docker compose run --remove-orphans oe-python-template-example echo "Lorem"
357
- docker compose run --remove-orphans oe-python-template-example echo "Lorem" --json
358
- docker compose run --remove-orphans oe-python-template-example openapi
359
- docker compose run --remove-orphans oe-python-template-example openapi --output-format=json
367
+ docker compose run --remove-orphans oe-python-template-example hello world
368
+ docker compose run --remove-orphans oe-python-template-example hello echo --help
369
+ docker compose run --remove-orphans oe-python-template-example hello echo "Lorem"
370
+ docker compose run --remove-orphans oe-python-template-example hello echo "Lorem" --json
371
+ docker compose run --remove-orphans oe-python-template-example system info
372
+ docker compose run --remove-orphans oe-python-template-example system health
373
+ docker compose run --remove-orphans oe-python-template-example system openapi
374
+ docker compose run --remove-orphans oe-python-template-example system openapi --output-format=json
360
375
  echo "Running OE Python Template Example's API container as a daemon ..."
361
376
  docker compose up -d
362
377
  echo "Waiting for the API server to start ..."
@@ -365,7 +380,7 @@ echo "Checking health of v1 API ..."
365
380
  curl http://127.0.0.1:8000/api/v1/healthz
366
381
  echo ""
367
382
  echo "Saying hello world with v1 API ..."
368
- curl http://127.0.0.1:8000/api/v1/hello-world
383
+ curl http://127.0.0.1:8000/api/v1/hello/world
369
384
  echo ""
370
385
  echo "Swagger docs of v1 API ..."
371
386
  curl http://127.0.0.1:8000/api/v1/docs
@@ -374,7 +389,7 @@ echo "Checking health of v2 API ..."
374
389
  curl http://127.0.0.1:8000/api/v2/healthz
375
390
  echo ""
376
391
  echo "Saying hello world with v1 API ..."
377
- curl http://127.0.0.1:8000/api/v2/hello-world
392
+ curl http://127.0.0.1:8000/api/v2/hello/world
378
393
  echo ""
379
394
  echo "Swagger docs of v2 API ..."
380
395
  curl http://127.0.0.1:8000/api/v2/docs
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oe-python-template-example"
3
- version = "0.3.5"
3
+ version = "0.3.7"
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 = [
@@ -64,9 +64,21 @@ requires-python = ">=3.11, <4.0"
64
64
  dependencies = [
65
65
  # From Template
66
66
  "fastapi[standard,all]>=0.115.12",
67
- "pydantic>=2.11.1",
67
+ "logfire[system-metrics]>=3.13.1",
68
+ "opentelemetry-instrumentation-fastapi>=0.53b0",
69
+ "opentelemetry-instrumentation-httpx>=0.53b0",
70
+ "opentelemetry-instrumentation-jinja2>=0.53b0",
71
+ "opentelemetry-instrumentation-requests>=0.53b0",
72
+ "opentelemetry-instrumentation-sqlite3>=0.53b0",
73
+ "opentelemetry-instrumentation-tornado>=0.53b0",
74
+ "opentelemetry-instrumentation-urllib>=0.53b0",
75
+ "opentelemetry-instrumentation-urllib3>=0.53b0",
76
+ "psutil>=7.0.0",
77
+ "pydantic>=2.11.3",
68
78
  "pydantic-settings>=2.8.1",
79
+ "sentry-sdk>=2.25.1",
69
80
  "typer>=0.15.1",
81
+ "uptime>=3.0.1",
70
82
  # Custom
71
83
  # Nothing yet
72
84
  ]
@@ -94,7 +106,7 @@ packages = ["src/oe_python_template_example"]
94
106
  [project.optional-dependencies]
95
107
  examples = [
96
108
  "streamlit>=1.44.1",
97
- "marimo>=0.12.2",
109
+ "marimo>=0.12.8",
98
110
  "jupyter>=1.1.1",
99
111
  "jinja2>=3.1.6",
100
112
  ]
@@ -111,20 +123,20 @@ dev = [
111
123
  "matplotlib>=3.10.1",
112
124
  "mypy>=1.5.0",
113
125
  "nox[uv]>=2025.2.9",
114
- "pip-audit>=2.8.0",
126
+ "pip-audit>=2.9.0",
115
127
  "pip-licenses @ git+https://github.com/neXenio/pip-licenses.git@master", # https://github.com/raimon49/pip-licenses/pull/224
116
128
  "pre-commit>=4.1.0",
117
- "pyright>=1.1.398",
129
+ "pyright>=1.1.399",
118
130
  "pytest>=8.3.5",
119
131
  "pytest-asyncio>=0.26.0",
120
- "pytest-cov>=6.1.0",
121
- "pytest-docker>=3.2.0",
132
+ "pytest-cov>=6.1.1",
133
+ "pytest-docker>=3.2.1",
122
134
  "pytest-env>=1.1.5",
123
135
  "pytest-regressions>=2.7.0",
124
136
  "pytest-subprocess>=1.5.3",
125
137
  "pytest-timeout>=2.3.1",
126
138
  "pytest-xdist[psutil]>=3.6.1",
127
- "ruff>=0.11.2",
139
+ "ruff>=0.11.5",
128
140
  "sphinx>=8.2.3",
129
141
  "sphinx-autobuild>=2024.10.3",
130
142
  "sphinx-copybutton>=0.5.2",
@@ -152,7 +164,7 @@ target-version = "py311"
152
164
  preview = true
153
165
  fix = true
154
166
  line-length = 120
155
- extend-exclude = [".fixme", "notebook.py"]
167
+ extend-exclude = [".fixme", "notebook.py", "template/*.py"]
156
168
 
157
169
  [tool.ruff.lint]
158
170
  select = ["ALL"]
@@ -178,7 +190,7 @@ ignore = [
178
190
  ]
179
191
 
180
192
  [tool.ruff.lint.per-file-ignores]
181
- "tests/**/*.py" = [
193
+ "**/tests/**/*.py" = [
182
194
  # we are more relaxed in tests, while sill applying hundreds of rules
183
195
  "S101", # asserts allowed in tests...
184
196
  "ARG", # unused function args -> fixtures nevertheless are functionally relevant...
@@ -266,7 +278,7 @@ source = ["src/"]
266
278
 
267
279
 
268
280
  [tool.bumpversion]
269
- current_version = "0.3.5"
281
+ current_version = "0.3.7"
270
282
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
271
283
  serialize = ["{major}.{minor}.{patch}"]
272
284
  search = "{current_version}"
@@ -0,0 +1,6 @@
1
+ """Copier template to scaffold Python projects compliant with best practices and modern tooling."""
2
+
3
+ from .constants import MODULES_TO_INSTRUMENT
4
+ from .utils.boot import boot
5
+
6
+ boot(modules_to_instrument=MODULES_TO_INSTRUMENT)
@@ -0,0 +1,75 @@
1
+ """Webservice API of OE Python Template Example.
2
+
3
+ - Provides a versioned API
4
+ - Automatically registers APIs of modules and mounts them to the main API.
5
+ """
6
+
7
+ import os
8
+
9
+ from fastapi import FastAPI
10
+
11
+ from .constants import API_VERSIONS
12
+ from .utils import (
13
+ VersionedAPIRouter,
14
+ __author_email__,
15
+ __author_name__,
16
+ __documentation__url__,
17
+ __repository_url__,
18
+ locate_implementations,
19
+ )
20
+
21
+ TITLE = "OE Python Template Example"
22
+ UVICORN_HOST = os.environ.get("UVICORN_HOST", "127.0.0.1")
23
+ UVICORN_PORT = os.environ.get("UVICORN_PORT", "8000")
24
+ CONTACT_NAME = __author_name__
25
+ CONTACT_EMAIL = __author_email__
26
+ CONTACT_URL = __repository_url__
27
+ TERMS_OF_SERVICE_URL = __documentation__url__
28
+
29
+
30
+ app = FastAPI(
31
+ root_path="/api",
32
+ title=TITLE,
33
+ contact={
34
+ "name": CONTACT_NAME,
35
+ "email": CONTACT_EMAIL,
36
+ "url": CONTACT_URL,
37
+ },
38
+ terms_of_service=TERMS_OF_SERVICE_URL,
39
+ openapi_tags=[
40
+ {
41
+ "name": version,
42
+ "description": f"API version {version.lstrip('v')}, check link on the right",
43
+ "externalDocs": {
44
+ "description": "sub-docs",
45
+ "url": f"http://{UVICORN_HOST}:{UVICORN_PORT}/api/{version}/docs",
46
+ },
47
+ }
48
+ for version, _ in API_VERSIONS.items()
49
+ ],
50
+ )
51
+
52
+ # Create API instances for each version
53
+ api_instances: dict["str", FastAPI] = {}
54
+ for version, semver in API_VERSIONS.items():
55
+ api_instances[version] = FastAPI(
56
+ version=semver,
57
+ title=TITLE,
58
+ contact={
59
+ "name": CONTACT_NAME,
60
+ "email": CONTACT_EMAIL,
61
+ "url": CONTACT_URL,
62
+ },
63
+ terms_of_service=TERMS_OF_SERVICE_URL,
64
+ )
65
+
66
+ # Register routers with appropriate API versions
67
+ for router in locate_implementations(VersionedAPIRouter):
68
+ router_instance: VersionedAPIRouter = router
69
+ version = router_instance.version
70
+ if version in API_VERSIONS:
71
+ api_instances[version].include_router(router_instance)
72
+
73
+ # Mount all API versions to the main app
74
+ for version in API_VERSIONS:
75
+ app.mount(f"/{version}", api_instances[version])
@@ -0,0 +1,22 @@
1
+ """CLI (Command Line Interface) of OE Python Template Example."""
2
+
3
+ import sys
4
+
5
+ import typer
6
+
7
+ from .constants import MODULES_TO_INSTRUMENT
8
+ from .utils import __version__, boot, console, get_logger, prepare_cli
9
+
10
+ boot(MODULES_TO_INSTRUMENT)
11
+ logger = get_logger(__name__)
12
+
13
+ cli = typer.Typer(help="Command Line Interface of ")
14
+ prepare_cli(cli, f"🧠 OE Python Template Example v{__version__} - built with love in Berlin 🐻")
15
+
16
+ if __name__ == "__main__": # pragma: no cover
17
+ try:
18
+ cli()
19
+ except Exception as e: # noqa: BLE001
20
+ logger.critical("Fatal error occurred: %s", e)
21
+ console.print(f"Fatal error occurred: {e}", style="error")
22
+ sys.exit(1)
@@ -0,0 +1,7 @@
1
+ """Constants for the OE Python Template Example."""
2
+
3
+ API_VERSIONS = {
4
+ "v1": "1.0.0",
5
+ "v2": "2.0.0",
6
+ }
7
+ MODULES_TO_INSTRUMENT = ["oe_python_template_example.hello"]
@@ -0,0 +1,17 @@
1
+ """Hello module."""
2
+
3
+ from ._api import api_v1, api_v2
4
+ from ._cli import cli
5
+ from ._models import Echo, Utterance
6
+ from ._service import Service
7
+ from ._settings import Settings
8
+
9
+ __all__ = [
10
+ "Echo",
11
+ "Service",
12
+ "Settings",
13
+ "Utterance",
14
+ "api_v1",
15
+ "api_v2",
16
+ "cli",
17
+ ]