oe-python-template 0.9.6__tar.gz → 0.10.0__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 (40) hide show
  1. {oe_python_template-0.9.6 → oe_python_template-0.10.0}/PKG-INFO +77 -51
  2. {oe_python_template-0.9.6 → oe_python_template-0.10.0}/README.md +63 -48
  3. {oe_python_template-0.9.6 → oe_python_template-0.10.0}/pyproject.toml +22 -11
  4. oe_python_template-0.10.0/src/oe_python_template/__init__.py +6 -0
  5. oe_python_template-0.10.0/src/oe_python_template/api.py +75 -0
  6. oe_python_template-0.10.0/src/oe_python_template/cli.py +22 -0
  7. oe_python_template-0.10.0/src/oe_python_template/constants.py +7 -0
  8. oe_python_template-0.10.0/src/oe_python_template/hello/__init__.py +17 -0
  9. oe_python_template-0.10.0/src/oe_python_template/hello/_api.py +94 -0
  10. oe_python_template-0.10.0/src/oe_python_template/hello/_cli.py +47 -0
  11. oe_python_template-0.10.0/src/oe_python_template/hello/_constants.py +4 -0
  12. oe_python_template-0.10.0/src/oe_python_template/hello/_models.py +28 -0
  13. oe_python_template-0.10.0/src/oe_python_template/hello/_service.py +96 -0
  14. oe_python_template-0.9.6/src/oe_python_template/settings.py → oe_python_template-0.10.0/src/oe_python_template/hello/_settings.py +6 -4
  15. oe_python_template-0.10.0/src/oe_python_template/system/__init__.py +17 -0
  16. oe_python_template-0.10.0/src/oe_python_template/system/_api.py +78 -0
  17. oe_python_template-0.10.0/src/oe_python_template/system/_cli.py +165 -0
  18. oe_python_template-0.10.0/src/oe_python_template/system/_service.py +163 -0
  19. oe_python_template-0.10.0/src/oe_python_template/utils/__init__.py +57 -0
  20. oe_python_template-0.10.0/src/oe_python_template/utils/_api.py +18 -0
  21. oe_python_template-0.10.0/src/oe_python_template/utils/_cli.py +68 -0
  22. oe_python_template-0.10.0/src/oe_python_template/utils/_console.py +14 -0
  23. oe_python_template-0.10.0/src/oe_python_template/utils/_constants.py +48 -0
  24. oe_python_template-0.10.0/src/oe_python_template/utils/_di.py +70 -0
  25. oe_python_template-0.10.0/src/oe_python_template/utils/_health.py +107 -0
  26. oe_python_template-0.10.0/src/oe_python_template/utils/_log.py +122 -0
  27. oe_python_template-0.10.0/src/oe_python_template/utils/_logfire.py +67 -0
  28. oe_python_template-0.10.0/src/oe_python_template/utils/_process.py +41 -0
  29. oe_python_template-0.10.0/src/oe_python_template/utils/_sentry.py +96 -0
  30. oe_python_template-0.10.0/src/oe_python_template/utils/_service.py +39 -0
  31. oe_python_template-0.10.0/src/oe_python_template/utils/_settings.py +68 -0
  32. oe_python_template-0.10.0/src/oe_python_template/utils/boot.py +86 -0
  33. oe_python_template-0.9.6/src/oe_python_template/__init__.py +0 -20
  34. oe_python_template-0.9.6/src/oe_python_template/api.py +0 -181
  35. oe_python_template-0.9.6/src/oe_python_template/cli.py +0 -150
  36. oe_python_template-0.9.6/src/oe_python_template/constants.py +0 -10
  37. oe_python_template-0.9.6/src/oe_python_template/models.py +0 -44
  38. oe_python_template-0.9.6/src/oe_python_template/service.py +0 -68
  39. {oe_python_template-0.9.6 → oe_python_template-0.10.0}/.gitignore +0 -0
  40. {oe_python_template-0.9.6 → oe_python_template-0.10.0}/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oe-python-template
3
- Version: 0.9.6
3
+ Version: 0.10.0
4
4
  Summary: 🧠 Copier template to scaffold Python projects compliant with best practices and modern tooling.
5
5
  Project-URL: Homepage, https://oe-python-template.readthedocs.io/en/latest/
6
6
  Project-URL: Documentation, https://oe-python-template.readthedocs.io/en/latest/
@@ -49,13 +49,24 @@ 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
55
66
  Provides-Extra: examples
56
67
  Requires-Dist: jinja2>=3.1.6; extra == 'examples'
57
68
  Requires-Dist: jupyter>=1.1.1; extra == 'examples'
58
- Requires-Dist: marimo>=0.12.2; extra == 'examples'
69
+ Requires-Dist: marimo>=0.12.8; extra == 'examples'
59
70
  Requires-Dist: streamlit>=1.44.1; extra == 'examples'
60
71
  Description-Content-Type: text/markdown
61
72
 
@@ -89,6 +100,8 @@ Description-Content-Type: text/markdown
89
100
  [![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
101
  [![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)
91
102
  [![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)
103
+ [![Vercel Deploy](https://deploy-badge.vercel.app/vercel/oe-python-template?root=docs)](https://oe-python-template.vercel.app/docs)
104
+ [![Better Stack Uptime](https://uptime.betterstack.com/status-badges/v1/monitor/1vze5.svg)](https://helmut-hoffer-von-ankershoffen.betteruptime.com/)
92
105
 
93
106
  <!---
94
107
  [![ghcr.io - Version](https://ghcr-badge.egpl.dev/helmut-hoffer-von-ankershoffen/oe-python-template/tags?color=%2344cc11&ignore=0.0%2C0%2Clatest&n=3&label=ghcr.io&trim=)](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/pkgs/container/oe-python-template)
@@ -124,33 +137,40 @@ Projects generated with this template come with a comprehensive development tool
124
137
  8. CI/CD pipeline can be run locally with [act](https://github.com/nektos/act)
125
138
  9. Code quality and security checks with [SonarQube](https://www.sonarsource.com/products/sonarcloud) and [GitHub CodeQL](https://codeql.github.com/)
126
139
  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)
127
- 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
128
- 12. Generation of attributions from extracted licenses
129
- 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
130
- 14. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
131
- 15. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
132
- 16. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
133
- 17. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
134
- 18. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
135
- 19. Python package published to [PyPI](https://pypi.org/)
136
- 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)
137
- 21. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
138
- 22. Settings for use with [VSCode](https://code.visualstudio.com/)
139
- 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)
140
+ 11. Error monitoring and profiling with [Sentry](https://sentry.io/) (optional)
141
+ 12. Logging and metrics with [Logfire](https://logfire.dev/) (optional)
142
+ 13. Prepared for uptime monitoring with [betterstack](https://betterstack.com/) or alternatives
143
+ 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
144
+ 14. Generation of attributions from extracted licenses
145
+ 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
146
+ 16. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
147
+ 17. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
148
+ 18. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
149
+ 19. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
150
+ 20. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
151
+ 21. Python package published to [PyPI](https://pypi.org/)
152
+ 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)
153
+ 23. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
154
+ 24. Settings for use with [VSCode](https://code.visualstudio.com/)
155
+ 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)
156
+ 26. API deployed as serverless function to [Vercel](https://vercel.com/) (optional)
140
157
 
141
158
  ### Application Features
142
159
 
143
- 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:
144
-
145
- 1. Service architecture suitable for use as shared library
146
- 2. Validation with [pydantic](https://docs.pydantic.dev/)
147
- 3. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
148
- 4. Versioned Web API with [FastAPI](https://fastapi.tiangolo.com/)
149
- 5. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
150
- 6. Simple Web UI with [Streamlit](https://streamlit.io/)
151
- 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/)
152
- 8. Documentation including badges, setup instructions, contribution guide and security policy
153
- 9. Preparation to deploy API as serverless function to Vercel
160
+ 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:
161
+
162
+ 1. Usable as library with "Hello" module exposing a simple service
163
+ 2. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
164
+ 3. Versioned webservice API with [FastAPI](https://fastapi.tiangolo.com/)
165
+ 4. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
166
+ 5. Simple Web UI with [Streamlit](https://streamlit.io/)
167
+ 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/)
168
+ 7. Validation and settings management with [pydantic](https://docs.pydantic.dev/)
169
+ 8. Info command enabling to inspect the runtime, compiled settings, and further info provided dynamically by modules
170
+ 9. Health endpoint exposing system health dynamically aggregated from all modules and dependencies
171
+ 10. Flexible logging and instrumentation, including support for [Sentry](https://sentry.io/) and [Logfire](https://logfire.dev/)
172
+ 11. Modular architecture including auto-registration of services, CLI commands and API routes exposed by modules
173
+ 12. Documentation including dynamic badges, setup instructions, contribution guide and security policy
154
174
 
155
175
  Explore [here](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example) for what's generated out of the box.
156
176
 
@@ -273,7 +293,7 @@ The following examples run from source - clone this repository using
273
293
  from dotenv import load_dotenv
274
294
  from rich.console import Console
275
295
 
276
- from oe_python_template import Service
296
+ from oe_python_template.hello import Service
277
297
 
278
298
  console = Console()
279
299
 
@@ -355,13 +375,15 @@ uvx oe-python-template --help
355
375
  Execute commands:
356
376
 
357
377
  ```shell
358
- uvx oe-python-template hello-world
359
- uvx oe-python-template echo --help
360
- uvx oe-python-template echo "Lorem"
361
- uvx oe-python-template echo "Lorem" --json
362
- uvx oe-python-template openapi
363
- uvx oe-python-template openapi --output-format=json
364
- uvx oe-python-template serve
378
+ uvx oe-python-template hello world
379
+ uvx oe-python-template hello echo --help
380
+ uvx oe-python-template hello echo "Lorem"
381
+ uvx oe-python-template hello echo "Lorem" --json
382
+ uvx oe-python-template system info
383
+ uvx oe-python-template system health
384
+ uvx oe-python-template system openapi
385
+ uvx oe-python-template system openapi --output-format=json
386
+ uvx oe-python-template system serve
365
387
  ```
366
388
 
367
389
  See the [reference documentation of the CLI](https://oe-python-template.readthedocs.io/en/latest/cli_reference.html) for detailed documentation of all CLI commands and options.
@@ -384,19 +406,21 @@ You can as well run the CLI within Docker.
384
406
 
385
407
  ```shell
386
408
  docker run helmuthva/oe-python-template --help
387
- docker run helmuthva/oe-python-template hello-world
388
- docker run helmuthva/oe-python-template echo --help
389
- docker run helmuthva/oe-python-template echo "Lorem"
390
- docker run helmuthva/oe-python-template echo "Lorem" --json
391
- docker run helmuthva/oe-python-template openapi
392
- docker run helmuthva/oe-python-template openapi --output-format=json
393
- docker run helmuthva/oe-python-template serve
409
+ docker run helmuthva/oe-python-template hello world
410
+ docker run helmuthva/oe-python-template hello echo --help
411
+ docker run helmuthva/oe-python-template hello echo "Lorem"
412
+ docker run helmuthva/oe-python-template hello echo "Lorem" --json
413
+ docker run helmuthva/oe-python-template system info
414
+ docker run helmuthva/oe-python-template system health
415
+ docker run helmuthva/oe-python-template system openapi
416
+ docker run helmuthva/oe-python-template system openapi --output-format=json
417
+ docker run helmuthva/oe-python-template system serve
394
418
  ```
395
419
 
396
420
  Execute command:
397
421
 
398
422
  ```shell
399
- docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template echo "Lorem Ipsum"
423
+ docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template hello echo "Lorem Ipsum"
400
424
  ```
401
425
 
402
426
  Or use docker compose
@@ -405,12 +429,14 @@ The .env is passed through from the host to the Docker container.
405
429
 
406
430
  ```shell
407
431
  docker compose run --remove-orphans oe-python-template --help
408
- docker compose run --remove-orphans oe-python-template hello-world
409
- docker compose run --remove-orphans oe-python-template echo --help
410
- docker compose run --remove-orphans oe-python-template echo "Lorem"
411
- docker compose run --remove-orphans oe-python-template echo "Lorem" --json
412
- docker compose run --remove-orphans oe-python-template openapi
413
- docker compose run --remove-orphans oe-python-template openapi --output-format=json
432
+ docker compose run --remove-orphans oe-python-template hello world
433
+ docker compose run --remove-orphans oe-python-template hello echo --help
434
+ docker compose run --remove-orphans oe-python-template hello echo "Lorem"
435
+ docker compose run --remove-orphans oe-python-template hello echo "Lorem" --json
436
+ docker compose run --remove-orphans oe-python-template system info
437
+ docker compose run --remove-orphans oe-python-template system health
438
+ docker compose run --remove-orphans oe-python-template system openapi
439
+ docker compose run --remove-orphans oe-python-template system openapi --output-format=json
414
440
  echo "Running OE Python Template's API container as a daemon ..."
415
441
  docker compose up -d
416
442
  echo "Waiting for the API server to start ..."
@@ -419,7 +445,7 @@ echo "Checking health of v1 API ..."
419
445
  curl http://127.0.0.1:8000/api/v1/healthz
420
446
  echo ""
421
447
  echo "Saying hello world with v1 API ..."
422
- curl http://127.0.0.1:8000/api/v1/hello-world
448
+ curl http://127.0.0.1:8000/api/v1/hello/world
423
449
  echo ""
424
450
  echo "Swagger docs of v1 API ..."
425
451
  curl http://127.0.0.1:8000/api/v1/docs
@@ -428,7 +454,7 @@ echo "Checking health of v2 API ..."
428
454
  curl http://127.0.0.1:8000/api/v2/healthz
429
455
  echo ""
430
456
  echo "Saying hello world with v1 API ..."
431
- curl http://127.0.0.1:8000/api/v2/hello-world
457
+ curl http://127.0.0.1:8000/api/v2/hello/world
432
458
  echo ""
433
459
  echo "Swagger docs of v2 API ..."
434
460
  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)
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)
31
+ [![Vercel Deploy](https://deploy-badge.vercel.app/vercel/oe-python-template?root=docs)](https://oe-python-template.vercel.app/docs)
32
+ [![Better Stack Uptime](https://uptime.betterstack.com/status-badges/v1/monitor/1vze5.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/tags?color=%2344cc11&ignore=0.0%2C0%2Clatest&n=3&label=ghcr.io&trim=)](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/pkgs/container/oe-python-template)
@@ -63,33 +65,40 @@ Projects generated with this template come with a comprehensive development tool
63
65
  8. CI/CD pipeline can be run locally with [act](https://github.com/nektos/act)
64
66
  9. Code quality and security checks with [SonarQube](https://www.sonarsource.com/products/sonarcloud) and [GitHub CodeQL](https://codeql.github.com/)
65
67
  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)
66
- 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
67
- 12. Generation of attributions from extracted licenses
68
- 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
69
- 14. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
70
- 15. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
71
- 16. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
72
- 17. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
73
- 18. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
74
- 19. Python package published to [PyPI](https://pypi.org/)
75
- 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)
76
- 21. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
77
- 22. Settings for use with [VSCode](https://code.visualstudio.com/)
78
- 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)
68
+ 11. Error monitoring and profiling with [Sentry](https://sentry.io/) (optional)
69
+ 12. Logging and metrics with [Logfire](https://logfire.dev/) (optional)
70
+ 13. Prepared for uptime monitoring with [betterstack](https://betterstack.com/) or alternatives
71
+ 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
72
+ 14. Generation of attributions from extracted licenses
73
+ 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
74
+ 16. Version and release management with [bump-my-version](https://callowayproject.github.io/bump-my-version/)
75
+ 17. Changelog and release notes generated with [git-cliff](https://git-cliff.org/)
76
+ 18. Documentation generated with [Sphinx](https://www.sphinx-doc.org/en/master/) including reference documentation for the library, CLI, and API
77
+ 19. Documentation published to [Read The Docs](https://readthedocs.org/) including generation of PDF and single page HTML versions
78
+ 20. Interactive OpenAPI specification with [Swagger](https://swagger.io/)
79
+ 21. Python package published to [PyPI](https://pypi.org/)
80
+ 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)
81
+ 23. One-click development environments with [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) and [GitHub Codespaces](https://github.com/features/codespaces)
82
+ 24. Settings for use with [VSCode](https://code.visualstudio.com/)
83
+ 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)
84
+ 26. API deployed as serverless function to [Vercel](https://vercel.com/) (optional)
79
85
 
80
86
  ### Application Features
81
87
 
82
- 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:
83
-
84
- 1. Service architecture suitable for use as shared library
85
- 2. Validation with [pydantic](https://docs.pydantic.dev/)
86
- 3. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
87
- 4. Versioned Web API with [FastAPI](https://fastapi.tiangolo.com/)
88
- 5. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
89
- 6. Simple Web UI with [Streamlit](https://streamlit.io/)
90
- 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/)
91
- 8. Documentation including badges, setup instructions, contribution guide and security policy
92
- 9. Preparation to deploy API as serverless function to Vercel
88
+ 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:
89
+
90
+ 1. Usable as library with "Hello" module exposing a simple service
91
+ 2. Command-line interface (CLI) with [Typer](https://typer.tiangolo.com/)
92
+ 3. Versioned webservice API with [FastAPI](https://fastapi.tiangolo.com/)
93
+ 4. [Interactive Jupyter notebook](https://jupyter.org/) and [reactive Marimo notebook](https://marimo.io/)
94
+ 5. Simple Web UI with [Streamlit](https://streamlit.io/)
95
+ 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/)
96
+ 7. Validation and settings management with [pydantic](https://docs.pydantic.dev/)
97
+ 8. Info command enabling to inspect the runtime, compiled settings, and further info provided dynamically by modules
98
+ 9. Health endpoint exposing system health dynamically aggregated from all modules and dependencies
99
+ 10. Flexible logging and instrumentation, including support for [Sentry](https://sentry.io/) and [Logfire](https://logfire.dev/)
100
+ 11. Modular architecture including auto-registration of services, CLI commands and API routes exposed by modules
101
+ 12. Documentation including dynamic badges, setup instructions, contribution guide and security policy
93
102
 
94
103
  Explore [here](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template-example) for what's generated out of the box.
95
104
 
@@ -212,7 +221,7 @@ The following examples run from source - clone this repository using
212
221
  from dotenv import load_dotenv
213
222
  from rich.console import Console
214
223
 
215
- from oe_python_template import Service
224
+ from oe_python_template.hello import Service
216
225
 
217
226
  console = Console()
218
227
 
@@ -294,13 +303,15 @@ uvx oe-python-template --help
294
303
  Execute commands:
295
304
 
296
305
  ```shell
297
- uvx oe-python-template hello-world
298
- uvx oe-python-template echo --help
299
- uvx oe-python-template echo "Lorem"
300
- uvx oe-python-template echo "Lorem" --json
301
- uvx oe-python-template openapi
302
- uvx oe-python-template openapi --output-format=json
303
- uvx oe-python-template serve
306
+ uvx oe-python-template hello world
307
+ uvx oe-python-template hello echo --help
308
+ uvx oe-python-template hello echo "Lorem"
309
+ uvx oe-python-template hello echo "Lorem" --json
310
+ uvx oe-python-template system info
311
+ uvx oe-python-template system health
312
+ uvx oe-python-template system openapi
313
+ uvx oe-python-template system openapi --output-format=json
314
+ uvx oe-python-template system serve
304
315
  ```
305
316
 
306
317
  See the [reference documentation of the CLI](https://oe-python-template.readthedocs.io/en/latest/cli_reference.html) for detailed documentation of all CLI commands and options.
@@ -323,19 +334,21 @@ You can as well run the CLI within Docker.
323
334
 
324
335
  ```shell
325
336
  docker run helmuthva/oe-python-template --help
326
- docker run helmuthva/oe-python-template hello-world
327
- docker run helmuthva/oe-python-template echo --help
328
- docker run helmuthva/oe-python-template echo "Lorem"
329
- docker run helmuthva/oe-python-template echo "Lorem" --json
330
- docker run helmuthva/oe-python-template openapi
331
- docker run helmuthva/oe-python-template openapi --output-format=json
332
- docker run helmuthva/oe-python-template serve
337
+ docker run helmuthva/oe-python-template hello world
338
+ docker run helmuthva/oe-python-template hello echo --help
339
+ docker run helmuthva/oe-python-template hello echo "Lorem"
340
+ docker run helmuthva/oe-python-template hello echo "Lorem" --json
341
+ docker run helmuthva/oe-python-template system info
342
+ docker run helmuthva/oe-python-template system health
343
+ docker run helmuthva/oe-python-template system openapi
344
+ docker run helmuthva/oe-python-template system openapi --output-format=json
345
+ docker run helmuthva/oe-python-template system serve
333
346
  ```
334
347
 
335
348
  Execute command:
336
349
 
337
350
  ```shell
338
- docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template echo "Lorem Ipsum"
351
+ docker run --env THE_VAR=MY_VALUE helmuthva/oe-python-template hello echo "Lorem Ipsum"
339
352
  ```
340
353
 
341
354
  Or use docker compose
@@ -344,12 +357,14 @@ The .env is passed through from the host to the Docker container.
344
357
 
345
358
  ```shell
346
359
  docker compose run --remove-orphans oe-python-template --help
347
- docker compose run --remove-orphans oe-python-template hello-world
348
- docker compose run --remove-orphans oe-python-template echo --help
349
- docker compose run --remove-orphans oe-python-template echo "Lorem"
350
- docker compose run --remove-orphans oe-python-template echo "Lorem" --json
351
- docker compose run --remove-orphans oe-python-template openapi
352
- docker compose run --remove-orphans oe-python-template openapi --output-format=json
360
+ docker compose run --remove-orphans oe-python-template hello world
361
+ docker compose run --remove-orphans oe-python-template hello echo --help
362
+ docker compose run --remove-orphans oe-python-template hello echo "Lorem"
363
+ docker compose run --remove-orphans oe-python-template hello echo "Lorem" --json
364
+ docker compose run --remove-orphans oe-python-template system info
365
+ docker compose run --remove-orphans oe-python-template system health
366
+ docker compose run --remove-orphans oe-python-template system openapi
367
+ docker compose run --remove-orphans oe-python-template system openapi --output-format=json
353
368
  echo "Running OE Python Template's API container as a daemon ..."
354
369
  docker compose up -d
355
370
  echo "Waiting for the API server to start ..."
@@ -358,7 +373,7 @@ echo "Checking health of v1 API ..."
358
373
  curl http://127.0.0.1:8000/api/v1/healthz
359
374
  echo ""
360
375
  echo "Saying hello world with v1 API ..."
361
- curl http://127.0.0.1:8000/api/v1/hello-world
376
+ curl http://127.0.0.1:8000/api/v1/hello/world
362
377
  echo ""
363
378
  echo "Swagger docs of v1 API ..."
364
379
  curl http://127.0.0.1:8000/api/v1/docs
@@ -367,7 +382,7 @@ echo "Checking health of v2 API ..."
367
382
  curl http://127.0.0.1:8000/api/v2/healthz
368
383
  echo ""
369
384
  echo "Saying hello world with v1 API ..."
370
- curl http://127.0.0.1:8000/api/v2/hello-world
385
+ curl http://127.0.0.1:8000/api/v2/hello/world
371
386
  echo ""
372
387
  echo "Swagger docs of v2 API ..."
373
388
  curl http://127.0.0.1:8000/api/v2/docs
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oe-python-template"
3
- version = "0.9.6"
3
+ version = "0.10.0"
4
4
  description = "🧠 Copier template to scaffold Python projects compliant with best practices and modern tooling."
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Helmut Hoffer von Ankershoffen", email = "helmuthva@gmail.com" }]
@@ -62,8 +62,19 @@ requires-python = ">=3.11, <4.0"
62
62
  dependencies = [
63
63
  # From Template
64
64
  "fastapi[standard,all]>=0.115.12",
65
- "pydantic>=2.11.1",
65
+ "logfire[system-metrics]>=3.13.1",
66
+ "opentelemetry-instrumentation-fastapi>=0.53b0",
67
+ "opentelemetry-instrumentation-httpx>=0.53b0",
68
+ "opentelemetry-instrumentation-jinja2>=0.53b0",
69
+ "opentelemetry-instrumentation-requests>=0.53b0",
70
+ "opentelemetry-instrumentation-sqlite3>=0.53b0",
71
+ "opentelemetry-instrumentation-tornado>=0.53b0",
72
+ "opentelemetry-instrumentation-urllib>=0.53b0",
73
+ "opentelemetry-instrumentation-urllib3>=0.53b0",
74
+ "psutil>=7.0.0",
75
+ "pydantic>=2.11.3",
66
76
  "pydantic-settings>=2.8.1",
77
+ "sentry-sdk>=2.25.1",
67
78
  "typer>=0.15.1",
68
79
  # Custom
69
80
  # Nothing yet
@@ -92,7 +103,7 @@ packages = ["src/oe_python_template"]
92
103
  [project.optional-dependencies]
93
104
  examples = [
94
105
  "streamlit>=1.44.1",
95
- "marimo>=0.12.2",
106
+ "marimo>=0.12.8",
96
107
  "jupyter>=1.1.1",
97
108
  "jinja2>=3.1.6",
98
109
  ]
@@ -109,20 +120,20 @@ dev = [
109
120
  "matplotlib>=3.10.1",
110
121
  "mypy>=1.5.0",
111
122
  "nox[uv]>=2025.2.9",
112
- "pip-audit>=2.8.0",
123
+ "pip-audit>=2.9.0",
113
124
  "pip-licenses @ git+https://github.com/neXenio/pip-licenses.git@master", # https://github.com/raimon49/pip-licenses/pull/224
114
125
  "pre-commit>=4.1.0",
115
- "pyright>=1.1.398",
126
+ "pyright>=1.1.399",
116
127
  "pytest>=8.3.5",
117
128
  "pytest-asyncio>=0.26.0",
118
- "pytest-cov>=6.1.0",
119
- "pytest-docker>=3.2.0",
129
+ "pytest-cov>=6.1.1",
130
+ "pytest-docker>=3.2.1",
120
131
  "pytest-env>=1.1.5",
121
132
  "pytest-regressions>=2.7.0",
122
133
  "pytest-subprocess>=1.5.3",
123
134
  "pytest-timeout>=2.3.1",
124
135
  "pytest-xdist[psutil]>=3.6.1",
125
- "ruff>=0.11.2",
136
+ "ruff>=0.11.5",
126
137
  "sphinx>=8.2.3",
127
138
  "sphinx-autobuild>=2024.10.3",
128
139
  "sphinx-copybutton>=0.5.2",
@@ -150,7 +161,7 @@ target-version = "py311"
150
161
  preview = true
151
162
  fix = true
152
163
  line-length = 120
153
- extend-exclude = [".fixme", "notebook.py"]
164
+ extend-exclude = [".fixme", "notebook.py", "template/*.py"]
154
165
 
155
166
  [tool.ruff.lint]
156
167
  select = ["ALL"]
@@ -176,7 +187,7 @@ ignore = [
176
187
  ]
177
188
 
178
189
  [tool.ruff.lint.per-file-ignores]
179
- "tests/**/*.py" = [
190
+ "**/tests/**/*.py" = [
180
191
  # we are more relaxed in tests, while sill applying hundreds of rules
181
192
  "S101", # asserts allowed in tests...
182
193
  "ARG", # unused function args -> fixtures nevertheless are functionally relevant...
@@ -264,7 +275,7 @@ source = ["src/"]
264
275
 
265
276
 
266
277
  [tool.bumpversion]
267
- current_version = "0.9.6"
278
+ current_version = "0.10.0"
268
279
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
269
280
  serialize = ["{major}.{minor}.{patch}"]
270
281
  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.
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"
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."""
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 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."""
2
+
3
+ API_VERSIONS = {
4
+ "v1": "1.0.0",
5
+ "v2": "2.0.0",
6
+ }
7
+ MODULES_TO_INSTRUMENT = ["oe_python_template.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
+ ]