oe-python-template 0.3.5__tar.gz → 0.3.6__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 (153) hide show
  1. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.copier-answers.yml +1 -1
  2. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.pre-commit-config.yaml +1 -0
  3. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.secrets.baseline +1 -1
  4. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/CHANGELOG.md +18 -0
  5. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/PKG-INFO +2 -1
  6. oe_python_template-0.3.6/RELEASE_NOTES.md +16 -0
  7. oe_python_template-0.3.6/VERSION +1 -0
  8. oe_python_template-0.3.6/docs/source/_static/openapi.json +185 -0
  9. oe_python_template-0.3.6/docs/source/_static/openapi.yaml +131 -0
  10. oe_python_template-0.3.6/docs/source/api.rst +5 -0
  11. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/conf.py +2 -1
  12. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/index.rst +1 -0
  13. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/noxfile.py +6 -0
  14. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/pyproject.toml +8 -6
  15. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/sonar-project.properties +1 -1
  16. oe_python_template-0.3.6/src/oe_python_template/api.py +87 -0
  17. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/src/oe_python_template/cli.py +33 -0
  18. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.pre-commit-config.yaml.jinja +1 -0
  19. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/CONTRIBUTING.md.jinja +1 -1
  20. oe_python_template-0.3.6/template/docs/source/api.rst.jinja +5 -0
  21. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/conf.py.jinja +1 -0
  22. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/index.rst.jinja +1 -0
  23. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/noxfile.py.jinja +6 -0
  24. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/pyproject.toml.jinja +6 -4
  25. oe_python_template-0.3.6/template/src/{{ project_name_snake_case }}/api.py.jinja +87 -0
  26. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/src/{{ project_name_snake_case }}/cli.py.jinja +33 -0
  27. oe_python_template-0.3.6/template/tests/api_test.py.jinja +48 -0
  28. oe_python_template-0.3.6/template/tests/cli_test.py.jinja +74 -0
  29. oe_python_template-0.3.6/tests/api_test.py +48 -0
  30. oe_python_template-0.3.6/tests/cli_test.py +75 -0
  31. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/uv.lock +296 -1
  32. oe_python_template-0.3.5/RELEASE_NOTES.md +0 -1
  33. oe_python_template-0.3.5/VERSION +0 -1
  34. oe_python_template-0.3.5/template/tests/cli_test.py.jinja +0 -39
  35. oe_python_template-0.3.5/tests/cli_test.py +0 -39
  36. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.act-env +0 -0
  37. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.act-secret +0 -0
  38. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.devcontainer/Dockerfile +0 -0
  39. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.devcontainer/devcontainer.json +0 -0
  40. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.devcontainer/onCreateCommand +0 -0
  41. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.devcontainer/postAttachCommand +0 -0
  42. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.devcontainer/postCreateCommand +0 -0
  43. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.env.example +0 -0
  44. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.github/workflows/docker-image-build-publish.yml +0 -0
  45. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.github/workflows/package-build-publish-release.yml +0 -0
  46. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.github/workflows/test-and-report.yml +0 -0
  47. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.gitignore +0 -0
  48. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.python-version +0 -0
  49. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.readthedocs.yml +0 -0
  50. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.vscode/extensions.json +0 -0
  51. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/.vscode/settings.json +0 -0
  52. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/CODEOWNERS +0 -0
  53. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/CONTRIBUTING.md +0 -0
  54. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/Dockerfile +0 -0
  55. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/LICENSE +0 -0
  56. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/README.md +0 -0
  57. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/SERVICE_CONNECTIONS.md +0 -0
  58. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/_readme_footer.md +0 -0
  59. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/_readme_header.md +0 -0
  60. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/_readme_main.md +0 -0
  61. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/bin/git-cliff +0 -0
  62. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/bump +0 -0
  63. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/codecov.yml +0 -0
  64. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/compose.yaml +0 -0
  65. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/copier.yml +0 -0
  66. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/Makefile +0 -0
  67. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/make.bat +0 -0
  68. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/_static/.keep +0 -0
  69. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/contributing.rst +0 -0
  70. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/latexmkrc +0 -0
  71. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/main.rst +0 -0
  72. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/reference.rst +0 -0
  73. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/docs/source/release-notes.rst +0 -0
  74. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/examples/__init__.py +0 -0
  75. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/examples/jupyter.ipynb +0 -0
  76. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/examples/notebook.ipynb +0 -0
  77. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/examples/notebook.py +0 -0
  78. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/examples/script.py +0 -0
  79. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/examples/streamlit.py +0 -0
  80. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/CHANGELOG.md +0 -0
  81. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/LICENSE-APACHE +0 -0
  82. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/LICENSE-MIT +0 -0
  83. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/README.md +0 -0
  84. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/completions/_git-cliff +0 -0
  85. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/completions/_git-cliff.ps1 +0 -0
  86. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/completions/git-cliff.bash +0 -0
  87. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/completions/git-cliff.elv +0 -0
  88. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/completions/git-cliff.fish +0 -0
  89. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/git-cliff-completions +0 -0
  90. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/git-cliff-mangen +0 -0
  91. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0/man/git-cliff.1 +0 -0
  92. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/git-cliff-2.7.0-x86_64-unknown-linux-gnu.tar.gz +0 -0
  93. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/github-action-run +0 -0
  94. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/latexmkrc +0 -0
  95. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/logo.png +0 -0
  96. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/renovate.json +0 -0
  97. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/reports/mypy.xml +0 -0
  98. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/src/oe_python_template/__init__.py +0 -0
  99. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/src/oe_python_template/constants.py +0 -0
  100. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/src/oe_python_template/service.py +0 -0
  101. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.act-env.jinja +0 -0
  102. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.act-secret.jinja +0 -0
  103. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.devcontainer/Dockerfile.jinja +0 -0
  104. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.devcontainer/devcontainer.json.jinja +0 -0
  105. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.devcontainer/onCreateCommand.jinja +0 -0
  106. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.devcontainer/postAttachCommand.jinja +0 -0
  107. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.devcontainer/postCreateCommand.jinja +0 -0
  108. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.env.example.jinja +0 -0
  109. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.github/workflows/docker-image-build-publish.yml.jinja +0 -0
  110. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.github/workflows/package-build-publish-release.yml.jinja +0 -0
  111. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.github/workflows/test-and-report.yml.jinja +0 -0
  112. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.gitignore.jinja +0 -0
  113. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.python-version +0 -0
  114. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.readthedocs.yml.jinja +0 -0
  115. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.vscode/extensions.json +0 -0
  116. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/.vscode/settings.json.jinja +0 -0
  117. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/CHANGELOG.md +0 -0
  118. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/CODEOWNERS.jinja +0 -0
  119. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/Dockerfile.jinja +0 -0
  120. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/LICENSE.jinja +0 -0
  121. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/SERVICE_CONNECTIONS.md.jinja +0 -0
  122. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/VERSION +0 -0
  123. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/_readme_footer.md.jinja +0 -0
  124. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/_readme_header.md.jinja +0 -0
  125. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/_readme_main.md.jinja +0 -0
  126. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/bump.jinja +0 -0
  127. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/codecov.yml.jinja +0 -0
  128. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/compose.yaml.jinja +0 -0
  129. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/Makefile.jinja +0 -0
  130. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/make.bat.jinja +0 -0
  131. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/_static/.keep +0 -0
  132. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/contributing.rst.jinja +0 -0
  133. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/latexmkrc.jinja +0 -0
  134. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/main.rst.jinja +0 -0
  135. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/reference.rst.jinja +0 -0
  136. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/docs/source/release-notes.rst.jinja +0 -0
  137. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/examples/__init__.py.jinja +0 -0
  138. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/examples/notebook.ipynb.jinja +0 -0
  139. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/examples/notebook.py.jinja +0 -0
  140. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/examples/script.py.jinja +0 -0
  141. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/examples/streamlit.py.jinja +0 -0
  142. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/github-action-run.jinja +0 -0
  143. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/latexmkrc.jinja +0 -0
  144. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/logo.png +0 -0
  145. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/sonar-project.properties.jinja +0 -0
  146. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/src/{{ project_name_snake_case }}/__init__.py.jinja +0 -0
  147. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/src/{{ project_name_snake_case }}/constants.py.jinja +0 -0
  148. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/src/{{ project_name_snake_case }}/service.py.jinja +0 -0
  149. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/tests/__init__.py.jinja +0 -0
  150. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/tests/fixtures/.keep +0 -0
  151. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/template/{{_copier_conf.answers_file}}.jinja +0 -0
  152. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/tests/__init__.py +0 -0
  153. {oe_python_template-0.3.5 → oe_python_template-0.3.6}/tests/fixtures/.keep +0 -0
@@ -1,4 +1,4 @@
1
- _commit: v0.3.4-1-gd342382
1
+ _commit: v0.3.5-3-gc123fae
2
2
  _src_path: .
3
3
  author_email: helmuthva@gmail.com
4
4
  author_github_username: helmut-hoffer-von-ankershoffen
@@ -53,6 +53,7 @@ repos:
53
53
  - id: name-tests-test
54
54
  - id: requirements-txt-fixer
55
55
  - id: trailing-whitespace
56
+ exclude: "docs/source/_static"
56
57
  - repo: https://github.com/Yelp/detect-secrets
57
58
  rev: v1.5.0
58
59
  hooks:
@@ -123,5 +123,5 @@
123
123
  }
124
124
  ],
125
125
  "results": {},
126
- "generated_at": "2025-03-08T19:00:27Z"
126
+ "generated_at": "2025-03-11T07:50:30Z"
127
127
  }
@@ -1,5 +1,23 @@
1
1
  [🧠 OE Python Template](https://oe-python-template.readthedocs.io/en/latest/)
2
2
 
3
+ ## [0.3.6](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/compare/v0.3.5..0.3.6) - 2025-03-11
4
+
5
+ ### ⛰️ Features
6
+
7
+ - Api incl. swagger within sphinx - ([69138f1](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/commit/69138f132f5492cea5c6d61bcc700fd483cf582a))
8
+
9
+ ### 📚 Documentation
10
+
11
+ - Placing of openapi specs for sphinx - ([da85ba0](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/commit/da85ba0300e388de25d2feb820d2600f74f22612))
12
+
13
+ ### 🧪 Testing
14
+
15
+ - Tests for serve and openapi commands - ([fee2798](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/commit/fee2798c4e93223f062bd108f476728f617b8461))
16
+
17
+ ## New Contributors ❤️
18
+
19
+ * @helmut-hoffer-von-ankershoffen made their first contribution
20
+
3
21
  ## [0.3.4](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/compare/v0.3.3..v0.3.4) - 2025-03-08
4
22
 
5
23
  ### 📚 Documentation
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oe-python-template
3
- Version: 0.3.5
3
+ Version: 0.3.6
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/
@@ -48,6 +48,7 @@ Classifier: Programming Language :: Python :: 3.12
48
48
  Classifier: Programming Language :: Python :: 3.13
49
49
  Classifier: Typing :: Typed
50
50
  Requires-Python: <4.0,>=3.11
51
+ Requires-Dist: fastapi[all,standard]>=0.115.11
51
52
  Requires-Dist: pydantic>=2.10.6
52
53
  Requires-Dist: python-dotenv>=1.0.1
53
54
  Requires-Dist: typer>=0.15.1
@@ -0,0 +1,16 @@
1
+ ## [0.3.6](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/compare/v0.3.5..v0.3.6) - 2025-03-11
2
+
3
+ ### ⛰️ Features
4
+
5
+ - Api incl. swagger within sphinx - ([69138f1](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/commit/69138f132f5492cea5c6d61bcc700fd483cf582a))
6
+
7
+ ### 📚 Documentation
8
+
9
+ - Placing of openapi specs for sphinx - ([da85ba0](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/commit/da85ba0300e388de25d2feb820d2600f74f22612))
10
+
11
+ ### 🧪 Testing
12
+
13
+ - Tests for serve and openapi commands - ([fee2798](https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template/commit/fee2798c4e93223f062bd108f476728f617b8461))
14
+
15
+
16
+
@@ -0,0 +1 @@
1
+ 0.3.6
@@ -0,0 +1,185 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "OE Python Template",
5
+ "termsOfService": "https://oe-python-template.readthedocs.io/en/latest/",
6
+ "contact": {
7
+ "name": "Helmut Hoffer von Ankershoffen",
8
+ "url": "https://github.com/helmut-hoffer-von-ankershoffen",
9
+ "email": "helmuthva@gmail.com"
10
+ },
11
+ "version": "1.0.0"
12
+ },
13
+ "paths": {
14
+ "/hello-world": {
15
+ "get": {
16
+ "tags": [
17
+ "Basics"
18
+ ],
19
+ "summary": "Hello World",
20
+ "description": "Return a hello world message.\n\nReturns:\n HelloWorldResponse: A response containing the hello world message.",
21
+ "operationId": "hello_world_hello_world_get",
22
+ "responses": {
23
+ "200": {
24
+ "description": "Successful Response",
25
+ "content": {
26
+ "application/json": {
27
+ "schema": {
28
+ "$ref": "#/components/schemas/HelloWorldResponse"
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ },
36
+ "/echo": {
37
+ "post": {
38
+ "tags": [
39
+ "Basics"
40
+ ],
41
+ "summary": "Echo",
42
+ "description": "Echo back the provided text.\n\nArgs:\n request (EchoRequest): The request containing the text to echo back.\n\nReturns:\n EchoResponse: A response containing the echoed text.\n\nRaises:\n 422 Unprocessable Entity: If text is not provided or empty.",
43
+ "operationId": "echo_echo_post",
44
+ "requestBody": {
45
+ "content": {
46
+ "application/json": {
47
+ "schema": {
48
+ "$ref": "#/components/schemas/EchoRequest"
49
+ }
50
+ }
51
+ },
52
+ "required": true
53
+ },
54
+ "responses": {
55
+ "200": {
56
+ "description": "Successful Response",
57
+ "content": {
58
+ "application/json": {
59
+ "schema": {
60
+ "$ref": "#/components/schemas/EchoResponse"
61
+ }
62
+ }
63
+ }
64
+ },
65
+ "422": {
66
+ "description": "Validation Error",
67
+ "content": {
68
+ "application/json": {
69
+ "schema": {
70
+ "$ref": "#/components/schemas/HTTPValidationError"
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ },
79
+ "components": {
80
+ "schemas": {
81
+ "EchoRequest": {
82
+ "properties": {
83
+ "text": {
84
+ "type": "string",
85
+ "minLength": 1,
86
+ "title": "Text",
87
+ "description": "The text to echo back",
88
+ "examples": [
89
+ "Hello, world!"
90
+ ]
91
+ }
92
+ },
93
+ "type": "object",
94
+ "required": [
95
+ "text"
96
+ ],
97
+ "title": "EchoRequest",
98
+ "description": "Request model for echo endpoint."
99
+ },
100
+ "EchoResponse": {
101
+ "properties": {
102
+ "message": {
103
+ "type": "string",
104
+ "minLength": 1,
105
+ "title": "Message",
106
+ "description": "The message content",
107
+ "examples": [
108
+ "Hello, world!"
109
+ ]
110
+ }
111
+ },
112
+ "type": "object",
113
+ "required": [
114
+ "message"
115
+ ],
116
+ "title": "EchoResponse",
117
+ "description": "Response model for echo endpoint."
118
+ },
119
+ "HTTPValidationError": {
120
+ "properties": {
121
+ "detail": {
122
+ "items": {
123
+ "$ref": "#/components/schemas/ValidationError"
124
+ },
125
+ "type": "array",
126
+ "title": "Detail"
127
+ }
128
+ },
129
+ "type": "object",
130
+ "title": "HTTPValidationError"
131
+ },
132
+ "HelloWorldResponse": {
133
+ "properties": {
134
+ "message": {
135
+ "type": "string",
136
+ "title": "Message",
137
+ "description": "The hello world message",
138
+ "examples": [
139
+ "Hello, world!"
140
+ ]
141
+ }
142
+ },
143
+ "type": "object",
144
+ "required": [
145
+ "message"
146
+ ],
147
+ "title": "HelloWorldResponse",
148
+ "description": "Response model for hello-world endpoint."
149
+ },
150
+ "ValidationError": {
151
+ "properties": {
152
+ "loc": {
153
+ "items": {
154
+ "anyOf": [
155
+ {
156
+ "type": "string"
157
+ },
158
+ {
159
+ "type": "integer"
160
+ }
161
+ ]
162
+ },
163
+ "type": "array",
164
+ "title": "Location"
165
+ },
166
+ "msg": {
167
+ "type": "string",
168
+ "title": "Message"
169
+ },
170
+ "type": {
171
+ "type": "string",
172
+ "title": "Error Type"
173
+ }
174
+ },
175
+ "type": "object",
176
+ "required": [
177
+ "loc",
178
+ "msg",
179
+ "type"
180
+ ],
181
+ "title": "ValidationError"
182
+ }
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,131 @@
1
+ components:
2
+ schemas:
3
+ EchoRequest:
4
+ description: Request model for echo endpoint.
5
+ properties:
6
+ text:
7
+ description: The text to echo back
8
+ examples:
9
+ - Hello, world!
10
+ minLength: 1
11
+ title: Text
12
+ type: string
13
+ required:
14
+ - text
15
+ title: EchoRequest
16
+ type: object
17
+ EchoResponse:
18
+ description: Response model for echo endpoint.
19
+ properties:
20
+ message:
21
+ description: The message content
22
+ examples:
23
+ - Hello, world!
24
+ minLength: 1
25
+ title: Message
26
+ type: string
27
+ required:
28
+ - message
29
+ title: EchoResponse
30
+ type: object
31
+ HTTPValidationError:
32
+ properties:
33
+ detail:
34
+ items:
35
+ $ref: '#/components/schemas/ValidationError'
36
+ title: Detail
37
+ type: array
38
+ title: HTTPValidationError
39
+ type: object
40
+ HelloWorldResponse:
41
+ description: Response model for hello-world endpoint.
42
+ properties:
43
+ message:
44
+ description: The hello world message
45
+ examples:
46
+ - Hello, world!
47
+ title: Message
48
+ type: string
49
+ required:
50
+ - message
51
+ title: HelloWorldResponse
52
+ type: object
53
+ ValidationError:
54
+ properties:
55
+ loc:
56
+ items:
57
+ anyOf:
58
+ - type: string
59
+ - type: integer
60
+ title: Location
61
+ type: array
62
+ msg:
63
+ title: Message
64
+ type: string
65
+ type:
66
+ title: Error Type
67
+ type: string
68
+ required:
69
+ - loc
70
+ - msg
71
+ - type
72
+ title: ValidationError
73
+ type: object
74
+ info:
75
+ contact:
76
+ email: helmuthva@gmail.com
77
+ name: Helmut Hoffer von Ankershoffen
78
+ url: https://github.com/helmut-hoffer-von-ankershoffen
79
+ termsOfService: https://oe-python-template.readthedocs.io/en/latest/
80
+ title: OE Python Template
81
+ version: 1.0.0
82
+ openapi: 3.1.0
83
+ paths:
84
+ /echo:
85
+ post:
86
+ description: "Echo back the provided text.\n\nArgs:\n request
87
+ (EchoRequest):\
88
+ \ The request containing the text to echo back.\n\nReturns:\n
89
+ EchoResponse:\
90
+ \ A response containing the echoed text.\n\nRaises:\n 422
91
+ Unprocessable\
92
+ \ Entity: If text is not provided or empty."
93
+ operationId: echo_echo_post
94
+ requestBody:
95
+ content:
96
+ application/json:
97
+ schema:
98
+ $ref: '#/components/schemas/EchoRequest'
99
+ required: true
100
+ responses:
101
+ '200':
102
+ content:
103
+ application/json:
104
+ schema:
105
+ $ref: '#/components/schemas/EchoResponse'
106
+ description: Successful Response
107
+ '422':
108
+ content:
109
+ application/json:
110
+ schema:
111
+ $ref: '#/components/schemas/HTTPValidationError'
112
+ description: Validation Error
113
+ summary: Echo
114
+ tags:
115
+ - Basics
116
+ /hello-world:
117
+ get:
118
+ description: "Return a hello world message.\n\nReturns:\n
119
+ HelloWorldResponse:\
120
+ \ A response containing the hello world message."
121
+ operationId: hello_world_hello_world_get
122
+ responses:
123
+ '200':
124
+ content:
125
+ application/json:
126
+ schema:
127
+ $ref: '#/components/schemas/HelloWorldResponse'
128
+ description: Successful Response
129
+ summary: Hello World
130
+ tags:
131
+ - Basics
@@ -0,0 +1,5 @@
1
+ API
2
+ ===
3
+
4
+ .. swagger-plugin:: _static/openapi.yaml
5
+ :full-page:
@@ -20,12 +20,13 @@ extensions = [
20
20
  "sphinx_inline_tabs",
21
21
  "sphinx_mdinclude",
22
22
  "sphinxext.opengraph",
23
+ "swagger_plugin_for_sphinx", # https://github.com/SAP/swagger-plugin-for-sphinx?tab=readme-ov-file
23
24
  ]
24
25
 
25
26
  project = "oe-python-template"
26
27
  author = "Helmut Hoffer von Ankershoffen"
27
28
  copyright = f" (c) 2025-{datetime.now(UTC).year}, {author}" # noqa: A001
28
- version = "0.3.5"
29
+ version = "0.3.6"
29
30
  release = version
30
31
  github_username = "helmut-hoffer-von-ankershoffen"
31
32
  github_repository = "oe-python-template"
@@ -11,6 +11,7 @@
11
11
  :maxdepth: 2
12
12
 
13
13
  main
14
+ api
14
15
  reference
15
16
  release-notes
16
17
  contributing
@@ -59,7 +59,13 @@ def docs(session: nox.Session) -> None:
59
59
  footer = Path("_readme_footer.md").read_text(encoding="utf-8")
60
60
  readme_content = f"{header}\n\n{main}\n\n{footer}"
61
61
  Path("README.md").write_text(readme_content, encoding="utf-8")
62
+ # Dump openapi schema to file
63
+ with Path("docs/source/_static/openapi.yaml").open("w", encoding="utf-8") as f:
64
+ session.run("oe-python-template", "openapi", stdout=f, external=True)
65
+ with Path("docs/source/_static/openapi.json").open("w", encoding="utf-8") as f:
66
+ session.run("oe-python-template", "openapi", "--output-format=json", stdout=f, external=True)
62
67
  # Build docs
68
+ session.run("make", "-C", "docs", "clean", external=True)
63
69
  session.run("make", "-C", "docs", "html", external=True)
64
70
 
65
71
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oe-python-template"
3
- version = "0.3.5"
3
+ version = "0.3.6"
4
4
  description = "🧠 Copier template to scaffold Python projects compliant with best practices and modern tooling."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -62,6 +62,7 @@ classifiers = [
62
62
  requires-python = ">=3.11, <4.0"
63
63
 
64
64
  dependencies = [
65
+ "fastapi[standard,all]>=0.115.11",
65
66
  "pydantic>=2.10.6",
66
67
  "python-dotenv>=1.0.1",
67
68
  "typer>=0.15.1",
@@ -98,6 +99,7 @@ dev = [
98
99
  "enum-tools>=0.12.0",
99
100
  "furo>=2024.8.6",
100
101
  "git-cliff>=2.8.0",
102
+ "matplotlib>=3.10.1",
101
103
  "mypy>=1.5.0",
102
104
  "nox[uv]>=2025.2.9",
103
105
  "pip-audit>=2.8.0",
@@ -109,6 +111,7 @@ dev = [
109
111
  "pytest-cov>=6.0.0",
110
112
  "pytest-docker>=3.2.0",
111
113
  "pytest-env>=1.1.5",
114
+ "pytest-regressions>=2.7.0",
112
115
  "pytest-xdist[psutil]>=3.6.1",
113
116
  "ruff>=0.9.10",
114
117
  "sphinx>=8.2.3",
@@ -116,14 +119,13 @@ dev = [
116
119
  "sphinx-copybutton>=0.5.2",
117
120
  "sphinx-inline-tabs>=2023.4.21",
118
121
  "sphinx-mdinclude>=0.6.2",
119
- "sphinxext.opengraph>=0.9.1",
120
122
  "sphinx-pydantic>=0.1.1",
121
123
  "sphinx-rtd-theme>=3.0.2",
122
124
  "sphinx-toolbox>=3.9.0",
123
- "sphinxext-opengraph>=0.9.1",
125
+ "sphinxext.opengraph>=0.9.1",
126
+ "swagger-plugin-for-sphinx>=5.1.0",
124
127
  "tomli>=2.1.0",
125
- "matplotlib>=3.10.1",
126
- "pytest-regressions>=2.7.0",
128
+ "types-pyyaml>=6.0.12.20241230",
127
129
  ]
128
130
 
129
131
  [tool.ruff]
@@ -242,7 +244,7 @@ source = ["src/"]
242
244
 
243
245
 
244
246
  [tool.bumpversion]
245
- current_version = "0.3.5"
247
+ current_version = "0.3.6"
246
248
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
247
249
  serialize = ["{major}.{minor}.{patch}"]
248
250
  search = "{current_version}"
@@ -1,6 +1,6 @@
1
1
  sonar.projectKey=helmut-hoffer-von-ankershoffen_oe-python-template
2
2
  sonar.organization=helmut-hoffer-von-ankershoffen
3
- sonar.projectVersion=0.3.5
3
+ sonar.projectVersion=0.3.6
4
4
  sonar.projectDescription=🧠 Copier template to scaffold Python projects compliant with best practices and modern tooling.
5
5
  sonar.links.homepage=https://oe-python-template.readthedocs.io/en/latest/
6
6
  sonar.links.scm=https://github.com/helmut-hoffer-von-ankershoffen/oe-python-template
@@ -0,0 +1,87 @@
1
+ """FastAPI application with REST API endpoints.
2
+
3
+ This module provides a FastAPI application with several endpoints:
4
+ - A hello-world endpoint that returns a greeting message
5
+ - An echo endpoint that echoes back the provided text
6
+
7
+ The endpoints use Pydantic models for request and response validation.
8
+ """
9
+
10
+ from fastapi import FastAPI
11
+ from pydantic import BaseModel, Field
12
+
13
+ from oe_python_template import Service
14
+
15
+ HELLO_WORLD_EXAMPLE = "Hello, world!"
16
+
17
+
18
+ app = FastAPI(
19
+ version="1.0.0",
20
+ title="OE Python Template",
21
+ contact={
22
+ "name": "Helmut Hoffer von Ankershoffen",
23
+ "email": "helmuthva@gmail.com",
24
+ "url": "https://github.com/helmut-hoffer-von-ankershoffen",
25
+ },
26
+ terms_of_service="https://oe-python-template.readthedocs.io/en/latest/",
27
+ )
28
+
29
+
30
+ class HelloWorldResponse(BaseModel):
31
+ """Response model for hello-world endpoint."""
32
+
33
+ message: str = Field(
34
+ ...,
35
+ description="The hello world message",
36
+ examples=[HELLO_WORLD_EXAMPLE],
37
+ )
38
+
39
+
40
+ class EchoResponse(BaseModel):
41
+ """Response model for echo endpoint."""
42
+
43
+ message: str = Field(
44
+ ...,
45
+ min_length=1,
46
+ description="The message content",
47
+ examples=[HELLO_WORLD_EXAMPLE],
48
+ )
49
+
50
+
51
+ class EchoRequest(BaseModel):
52
+ """Request model for echo endpoint."""
53
+
54
+ text: str = Field(
55
+ ...,
56
+ min_length=1,
57
+ description="The text to echo back",
58
+ examples=[HELLO_WORLD_EXAMPLE],
59
+ )
60
+
61
+
62
+ @app.get("/hello-world", tags=["Basics"])
63
+ async def hello_world() -> HelloWorldResponse:
64
+ """
65
+ Return a hello world message.
66
+
67
+ Returns:
68
+ HelloWorldResponse: A response containing the hello world message.
69
+ """
70
+ return HelloWorldResponse(message=Service.get_hello_world())
71
+
72
+
73
+ @app.post("/echo", tags=["Basics"])
74
+ async def echo(request: EchoRequest) -> EchoResponse:
75
+ """
76
+ Echo back the provided text.
77
+
78
+ Args:
79
+ request (EchoRequest): The request containing the text to echo back.
80
+
81
+ Returns:
82
+ EchoResponse: A response containing the echoed text.
83
+
84
+ Raises:
85
+ 422 Unprocessable Entity: If text is not provided or empty.
86
+ """
87
+ return EchoResponse(message=request.text)
@@ -3,9 +3,12 @@
3
3
  from typing import Annotated
4
4
 
5
5
  import typer
6
+ import uvicorn
7
+ import yaml
6
8
  from rich.console import Console
7
9
 
8
10
  from oe_python_template import Service, __version__
11
+ from oe_python_template.api import app as api
9
12
 
10
13
  console = Console()
11
14
 
@@ -37,6 +40,36 @@ def hello_world() -> None:
37
40
  console.print(Service.get_hello_world())
38
41
 
39
42
 
43
+ @cli.command()
44
+ def serve(
45
+ host: Annotated[str, typer.Option(help="Host to bind the server to")] = "127.0.0.1",
46
+ port: Annotated[int, typer.Option(help="Port to bind the server to")] = 8000,
47
+ reload: Annotated[bool, typer.Option(help="Enable auto-reload")] = True,
48
+ ) -> None:
49
+ """Start the API server."""
50
+ console.print(f"Starting API server at http://{host}:{port}")
51
+ uvicorn.run(
52
+ "oe_python_template.api:app",
53
+ host=host,
54
+ port=port,
55
+ reload=reload,
56
+ )
57
+
58
+
59
+ @cli.command()
60
+ def openapi(
61
+ output_format: Annotated[
62
+ str, typer.Option(help="Output format (yaml or json), defaults to yaml", case_sensitive=False)
63
+ ] = "yaml",
64
+ ) -> None:
65
+ """Dump the OpenAPI specification to stdout (YAML by default)."""
66
+ schema = api.openapi()
67
+ if output_format.lower() == "json":
68
+ console.print_json(data=schema)
69
+ else:
70
+ console.print(yaml.dump(schema, default_flow_style=False), end="")
71
+
72
+
40
73
  def _apply_cli_settings(cli: typer.Typer, epilog: str) -> None:
41
74
  """Add epilog to all typers in the tree and configure default behavior."""
42
75
  cli.info.epilog = epilog
@@ -53,6 +53,7 @@ repos:
53
53
  - id: name-tests-test
54
54
  - id: requirements-txt-fixer
55
55
  - id: trailing-whitespace
56
+ exclude: "docs/source/_static"
56
57
  - repo: https://github.com/Yelp/detect-secrets
57
58
  rev: v1.5.0
58
59
  hooks:
@@ -119,7 +119,7 @@ Update scaffold from template
119
119
  copier update --trust --skip-tasks --skip-answered
120
120
  ```
121
121
 
122
- ### Updating demo application contained within oe-python-template
122
+ ### Updating demo application contained within {{ project_name_kebab_case }}
123
123
 
124
124
  ```shell
125
125
  copier copy -r HEAD . . --force --trust
@@ -0,0 +1,5 @@
1
+ API
2
+ ===
3
+
4
+ .. swagger-plugin:: _static/openapi.yaml
5
+ :full-page: