fastapi-templatekit 0.1.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 (54) hide show
  1. fastapi_templatekit-0.1.0/LICENSE +21 -0
  2. fastapi_templatekit-0.1.0/PKG-INFO +163 -0
  3. fastapi_templatekit-0.1.0/README.md +154 -0
  4. fastapi_templatekit-0.1.0/fastapi_templatekit/__init__.py +1 -0
  5. fastapi_templatekit-0.1.0/fastapi_templatekit/cli.py +33 -0
  6. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/__init__.py +1 -0
  7. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/addhealthprobes.py +68 -0
  8. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/help.py +70 -0
  9. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/project.py +22 -0
  10. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/rendering.py +15 -0
  11. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/startapp.py +170 -0
  12. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/startproject.py +82 -0
  13. fastapi_templatekit-0.1.0/fastapi_templatekit/commands/validation.py +17 -0
  14. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/__init__.py +1 -0
  15. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/__init__.py.tpl +1 -0
  16. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/endpoints/__init__.py.tpl +1 -0
  17. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/endpoints/api.py.tpl +14 -0
  18. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/models/__init__.py.tpl +1 -0
  19. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/router.py.tpl +9 -0
  20. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/schemas/__init__.py.tpl +1 -0
  21. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/schemas/validator.py.tpl +7 -0
  22. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/service/__init__.py.tpl +1 -0
  23. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/service/app_service.py.tpl +5 -0
  24. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/websocket/__init__.py.tpl +1 -0
  25. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/app/websocket/router.py.tpl +25 -0
  26. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/__init__.py.tpl +1 -0
  27. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/endpoints/__init__.py.tpl +1 -0
  28. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/endpoints/api.py.tpl +19 -0
  29. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/models/__init__.py.tpl +1 -0
  30. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/router.py.tpl +9 -0
  31. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/schemas/__init__.py.tpl +1 -0
  32. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/schemas/validator.py.tpl +7 -0
  33. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/service/__init__.py.tpl +1 -0
  34. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/healthprobes/service/healthprobes_service.py.tpl +5 -0
  35. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/README.md.tpl +12 -0
  36. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/env.example.tpl +4 -0
  37. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/fastapi_templatekit.toml.tpl +5 -0
  38. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/gitignore.tpl +9 -0
  39. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/package/__init__.py.tpl +1 -0
  40. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/package/cli.py.tpl +88 -0
  41. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/package/config.py.tpl +15 -0
  42. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/package/main.py.tpl +15 -0
  43. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/package/router.py.tpl +6 -0
  44. fastapi_templatekit-0.1.0/fastapi_templatekit/templates/project/pyproject.toml.tpl +26 -0
  45. fastapi_templatekit-0.1.0/fastapi_templatekit.egg-info/PKG-INFO +163 -0
  46. fastapi_templatekit-0.1.0/fastapi_templatekit.egg-info/SOURCES.txt +52 -0
  47. fastapi_templatekit-0.1.0/fastapi_templatekit.egg-info/dependency_links.txt +1 -0
  48. fastapi_templatekit-0.1.0/fastapi_templatekit.egg-info/entry_points.txt +2 -0
  49. fastapi_templatekit-0.1.0/fastapi_templatekit.egg-info/top_level.txt +1 -0
  50. fastapi_templatekit-0.1.0/pyproject.toml +74 -0
  51. fastapi_templatekit-0.1.0/setup.cfg +4 -0
  52. fastapi_templatekit-0.1.0/tests/test_commands.py +155 -0
  53. fastapi_templatekit-0.1.0/tests/test_startapp.py +232 -0
  54. fastapi_templatekit-0.1.0/tests/test_startproject.py +23 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Amogha Hegde
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-templatekit
3
+ Version: 0.1.0
4
+ Summary: FastAPI project generator with a root-level, Django-style app layout
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Dynamic: license-file
9
+
10
+ # fastapi-templatekit
11
+
12
+ [![Tests](https://github.com/Amogha-Hegde/fastapi-templatekit/actions/workflows/ci.yml/badge.svg)](https://github.com/Amogha-Hegde/fastapi-templatekit/actions/workflows/ci.yml)
13
+ [![Coverage](https://codecov.io/gh/Amogha-Hegde/fastapi-templatekit/branch/main/graph/badge.svg)](https://codecov.io/gh/Amogha-Hegde/fastapi-templatekit)
14
+ [![PyPI version](https://img.shields.io/pypi/v/fastapi-templatekit.svg)](https://pypi.org/project/fastapi-templatekit/)
15
+ [![Python versions](https://img.shields.io/pypi/pyversions/fastapi-templatekit.svg)](https://pypi.org/project/fastapi-templatekit/)
16
+ [![PyPI downloads](https://static.pepy.tech/badge/fastapi-templatekit)](https://pepy.tech/project/fastapi-templatekit)
17
+
18
+ A FastAPI TemplateKit with a root-level, Django-style app layout.
19
+
20
+ ## CLI
21
+
22
+ Create a new project without installing this template into that project's
23
+ environment:
24
+
25
+ ```bash
26
+ uvx fastapi-templatekit startproject myproject
27
+ cd myproject
28
+ uvx fastapi-templatekit startapp users
29
+ ```
30
+
31
+ Create the project files directly in the current directory:
32
+
33
+ ```bash
34
+ uvx fastapi-templatekit startproject myproject .
35
+ ```
36
+
37
+ If generated files already exist, the CLI asks before overwriting them. Use
38
+ `--force` to overwrite without a prompt:
39
+
40
+ ```bash
41
+ uvx fastapi-templatekit startproject myproject . --force
42
+ ```
43
+
44
+ Create the project at a custom path:
45
+
46
+ ```bash
47
+ uvx fastapi-templatekit startproject myproject ../services/myproject
48
+ ```
49
+
50
+ For local development from this repository:
51
+
52
+ ```bash
53
+ uvx --from . fastapi-templatekit startproject myproject
54
+ ```
55
+
56
+ Generated projects include a Typer management command to discover registered
57
+ HTTP and websocket routes:
58
+
59
+ ```bash
60
+ uv run myproject urls
61
+ ```
62
+
63
+ Show available commands and details:
64
+
65
+ ```bash
66
+ uvx fastapi-templatekit help
67
+ ```
68
+
69
+ Add health probes to an existing generated project:
70
+
71
+ ```bash
72
+ uvx fastapi-templatekit addhealthprobes
73
+ ```
74
+
75
+ Create an app with optional websocket and database scaffolding:
76
+
77
+ ```bash
78
+ uvx fastapi-templatekit startapp users
79
+ uvx fastapi-templatekit startapp users --with-websockets --with-database
80
+ ```
81
+
82
+ Generated projects keep the main router beside `main.py`:
83
+
84
+ ```text
85
+ myproject/
86
+ ├── pyproject.toml
87
+ ├── fastapi_templatekit.toml
88
+ ├── myproject/
89
+ │ ├── __init__.py
90
+ │ ├── main.py
91
+ │ ├── config.py
92
+ │ └── router.py
93
+ └── users/
94
+ ├── __init__.py
95
+ ├── router.py
96
+ ├── endpoints/
97
+ │ ├── __init__.py
98
+ │ └── api.py
99
+ ├── schemas/
100
+ │ ├── __init__.py
101
+ │ └── validator.py
102
+ ├── service/
103
+ │ ├── __init__.py
104
+ │ └── users_service.py
105
+ ├── models/ # created only with database/tables enabled
106
+ │ └── __init__.py
107
+ └── websocket/ # created only with websockets enabled
108
+ ├── __init__.py
109
+ └── router.py
110
+ ```
111
+
112
+ ## Structure
113
+
114
+ ```text
115
+ .
116
+ ├── api/ # top-level router registration
117
+ ├── health/ # example domain app at project root
118
+ ├── main/
119
+ │ ├── config.py # settings and config live here
120
+ │ └── app.py # FastAPI declaration lives here
121
+ └── pyproject.toml
122
+ ```
123
+
124
+ This follows the same domain-first idea from `fastapi-best-practices`, but without a `src/` directory.
125
+ Feature apps and the shared API router live directly under the project root, similar to Django apps.
126
+
127
+ ## Run
128
+
129
+ ```bash
130
+ uv run uvicorn main.app:app --reload
131
+ ```
132
+
133
+ ## WebSockets
134
+
135
+ WebSocket routes are mounted under the same API prefix, so the default endpoint is:
136
+
137
+ ```text
138
+ /api/v1/ws/{room_name}
139
+ ```
140
+
141
+ There is also a built-in browser test page at:
142
+
143
+ ```text
144
+ /api/v1/ws/test
145
+ ```
146
+
147
+ This app uses `fastapi-websockets` with the package's environment-based channel-layer loader.
148
+ For websocket-related environment configuration, refer to https://github.com/Amogha-Hegde/fastapi-websockets.
149
+
150
+ Tests force `FASTAPI_WEBSOCKETS_BACKEND=inmemory` so they do not depend on a running database.
151
+
152
+ Example session:
153
+
154
+ ```text
155
+ connect ws://127.0.0.1:8000/api/v1/ws/demo
156
+ receive {"event":"connected","room":"demo",...}
157
+ send {"sender":"alice","message":"hello"}
158
+ receive {"event":"message","room":"demo","sender":"alice","message":"hello"}
159
+ ```
160
+
161
+ ## Add a new app
162
+
163
+ Create a root-level package such as `users/` or `orders/`, define its router there, and include it from your project's main `router.py`.
@@ -0,0 +1,154 @@
1
+ # fastapi-templatekit
2
+
3
+ [![Tests](https://github.com/Amogha-Hegde/fastapi-templatekit/actions/workflows/ci.yml/badge.svg)](https://github.com/Amogha-Hegde/fastapi-templatekit/actions/workflows/ci.yml)
4
+ [![Coverage](https://codecov.io/gh/Amogha-Hegde/fastapi-templatekit/branch/main/graph/badge.svg)](https://codecov.io/gh/Amogha-Hegde/fastapi-templatekit)
5
+ [![PyPI version](https://img.shields.io/pypi/v/fastapi-templatekit.svg)](https://pypi.org/project/fastapi-templatekit/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/fastapi-templatekit.svg)](https://pypi.org/project/fastapi-templatekit/)
7
+ [![PyPI downloads](https://static.pepy.tech/badge/fastapi-templatekit)](https://pepy.tech/project/fastapi-templatekit)
8
+
9
+ A FastAPI TemplateKit with a root-level, Django-style app layout.
10
+
11
+ ## CLI
12
+
13
+ Create a new project without installing this template into that project's
14
+ environment:
15
+
16
+ ```bash
17
+ uvx fastapi-templatekit startproject myproject
18
+ cd myproject
19
+ uvx fastapi-templatekit startapp users
20
+ ```
21
+
22
+ Create the project files directly in the current directory:
23
+
24
+ ```bash
25
+ uvx fastapi-templatekit startproject myproject .
26
+ ```
27
+
28
+ If generated files already exist, the CLI asks before overwriting them. Use
29
+ `--force` to overwrite without a prompt:
30
+
31
+ ```bash
32
+ uvx fastapi-templatekit startproject myproject . --force
33
+ ```
34
+
35
+ Create the project at a custom path:
36
+
37
+ ```bash
38
+ uvx fastapi-templatekit startproject myproject ../services/myproject
39
+ ```
40
+
41
+ For local development from this repository:
42
+
43
+ ```bash
44
+ uvx --from . fastapi-templatekit startproject myproject
45
+ ```
46
+
47
+ Generated projects include a Typer management command to discover registered
48
+ HTTP and websocket routes:
49
+
50
+ ```bash
51
+ uv run myproject urls
52
+ ```
53
+
54
+ Show available commands and details:
55
+
56
+ ```bash
57
+ uvx fastapi-templatekit help
58
+ ```
59
+
60
+ Add health probes to an existing generated project:
61
+
62
+ ```bash
63
+ uvx fastapi-templatekit addhealthprobes
64
+ ```
65
+
66
+ Create an app with optional websocket and database scaffolding:
67
+
68
+ ```bash
69
+ uvx fastapi-templatekit startapp users
70
+ uvx fastapi-templatekit startapp users --with-websockets --with-database
71
+ ```
72
+
73
+ Generated projects keep the main router beside `main.py`:
74
+
75
+ ```text
76
+ myproject/
77
+ ├── pyproject.toml
78
+ ├── fastapi_templatekit.toml
79
+ ├── myproject/
80
+ │ ├── __init__.py
81
+ │ ├── main.py
82
+ │ ├── config.py
83
+ │ └── router.py
84
+ └── users/
85
+ ├── __init__.py
86
+ ├── router.py
87
+ ├── endpoints/
88
+ │ ├── __init__.py
89
+ │ └── api.py
90
+ ├── schemas/
91
+ │ ├── __init__.py
92
+ │ └── validator.py
93
+ ├── service/
94
+ │ ├── __init__.py
95
+ │ └── users_service.py
96
+ ├── models/ # created only with database/tables enabled
97
+ │ └── __init__.py
98
+ └── websocket/ # created only with websockets enabled
99
+ ├── __init__.py
100
+ └── router.py
101
+ ```
102
+
103
+ ## Structure
104
+
105
+ ```text
106
+ .
107
+ ├── api/ # top-level router registration
108
+ ├── health/ # example domain app at project root
109
+ ├── main/
110
+ │ ├── config.py # settings and config live here
111
+ │ └── app.py # FastAPI declaration lives here
112
+ └── pyproject.toml
113
+ ```
114
+
115
+ This follows the same domain-first idea from `fastapi-best-practices`, but without a `src/` directory.
116
+ Feature apps and the shared API router live directly under the project root, similar to Django apps.
117
+
118
+ ## Run
119
+
120
+ ```bash
121
+ uv run uvicorn main.app:app --reload
122
+ ```
123
+
124
+ ## WebSockets
125
+
126
+ WebSocket routes are mounted under the same API prefix, so the default endpoint is:
127
+
128
+ ```text
129
+ /api/v1/ws/{room_name}
130
+ ```
131
+
132
+ There is also a built-in browser test page at:
133
+
134
+ ```text
135
+ /api/v1/ws/test
136
+ ```
137
+
138
+ This app uses `fastapi-websockets` with the package's environment-based channel-layer loader.
139
+ For websocket-related environment configuration, refer to https://github.com/Amogha-Hegde/fastapi-websockets.
140
+
141
+ Tests force `FASTAPI_WEBSOCKETS_BACKEND=inmemory` so they do not depend on a running database.
142
+
143
+ Example session:
144
+
145
+ ```text
146
+ connect ws://127.0.0.1:8000/api/v1/ws/demo
147
+ receive {"event":"connected","room":"demo",...}
148
+ send {"sender":"alice","message":"hello"}
149
+ receive {"event":"message","room":"demo","sender":"alice","message":"hello"}
150
+ ```
151
+
152
+ ## Add a new app
153
+
154
+ Create a root-level package such as `users/` or `orders/`, define its router there, and include it from your project's main `router.py`.
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,33 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+
5
+ from fastapi_templatekit.commands.addhealthprobes import add_addhealthprobes_parser
6
+ from fastapi_templatekit.commands.help import add_help_parser
7
+ from fastapi_templatekit.commands.startapp import add_startapp_parser
8
+ from fastapi_templatekit.commands.startproject import add_startproject_parser
9
+
10
+
11
+ def build_parser() -> argparse.ArgumentParser:
12
+ parser = argparse.ArgumentParser(
13
+ prog="fastapi-templatekit",
14
+ description="Create FastAPI projects and apps.",
15
+ )
16
+ subparsers = parser.add_subparsers(dest="command", required=True)
17
+
18
+ add_startproject_parser(subparsers)
19
+ add_startapp_parser(subparsers)
20
+ add_addhealthprobes_parser(subparsers)
21
+ add_help_parser(subparsers)
22
+
23
+ return parser
24
+
25
+
26
+ def main() -> None:
27
+ parser = build_parser()
28
+ args = parser.parse_args()
29
+ args.handler(args)
30
+
31
+
32
+ if __name__ == "__main__":
33
+ main()
@@ -0,0 +1,68 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from pathlib import Path
5
+
6
+ from fastapi_templatekit.commands.project import load_project_config
7
+ from fastapi_templatekit.commands.rendering import render_template
8
+
9
+
10
+ HEALTHPROBES_APP_NAME = "healthprobes"
11
+
12
+ HEALTHPROBES_TEMPLATES = (
13
+ ("healthprobes/__init__.py.tpl", "healthprobes/__init__.py"),
14
+ ("healthprobes/router.py.tpl", "healthprobes/router.py"),
15
+ ("healthprobes/endpoints/__init__.py.tpl", "healthprobes/endpoints/__init__.py"),
16
+ ("healthprobes/endpoints/api.py.tpl", "healthprobes/endpoints/api.py"),
17
+ ("healthprobes/schemas/__init__.py.tpl", "healthprobes/schemas/__init__.py"),
18
+ ("healthprobes/schemas/validator.py.tpl", "healthprobes/schemas/validator.py"),
19
+ ("healthprobes/service/__init__.py.tpl", "healthprobes/service/__init__.py"),
20
+ ("healthprobes/service/healthprobes_service.py.tpl", "healthprobes/service/healthprobes_service.py"),
21
+ ("healthprobes/models/__init__.py.tpl", "healthprobes/models/__init__.py"),
22
+ )
23
+
24
+
25
+ def add_addhealthprobes_parser(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
26
+ parser = subparsers.add_parser(
27
+ "addhealthprobes",
28
+ help="Add healthz and livez endpoints to an existing generated project.",
29
+ )
30
+ parser.add_argument(
31
+ "--force",
32
+ action="store_true",
33
+ help="Overwrite existing healthprobes files without prompting.",
34
+ )
35
+ parser.set_defaults(handler=handle_addhealthprobes)
36
+
37
+
38
+ def handle_addhealthprobes(args: argparse.Namespace) -> None:
39
+ project_root = Path.cwd()
40
+ project = load_project_config(project_root)
41
+ apps_dir = project_root / project.get("apps_dir", ".")
42
+ app_dir = apps_dir / HEALTHPROBES_APP_NAME
43
+
44
+ context = {
45
+ "app_name": HEALTHPROBES_APP_NAME,
46
+ "route_prefix": HEALTHPROBES_APP_NAME,
47
+ }
48
+ destinations = [
49
+ apps_dir / destination_pattern.format(**context)
50
+ for _, destination_pattern in HEALTHPROBES_TEMPLATES
51
+ ]
52
+ existing_paths = [destination for destination in destinations if destination.exists()]
53
+
54
+ if existing_paths and not args.force:
55
+ conflicts = "\n".join(f" {path}" for path in existing_paths)
56
+ print(f"Healthprobes files already exist:\n{conflicts}")
57
+ answer = input("Overwrite these files? [y/N]: ").strip().lower()
58
+ if answer not in {"y", "yes"}:
59
+ raise SystemExit("Aborted.")
60
+
61
+ for template_path, destination_pattern in HEALTHPROBES_TEMPLATES:
62
+ destination = apps_dir / destination_pattern.format(**context)
63
+ render_template(template_path, destination, context)
64
+
65
+ print(f"Created health probes app at {app_dir}")
66
+ print("Register the router in your project router:")
67
+ print(" from healthprobes.router import router as healthprobes_router")
68
+ print(" api_router.include_router(healthprobes_router, tags=[\"healthprobes\"])")
@@ -0,0 +1,70 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+
5
+
6
+ HELP_TEXT = """fastapi-templatekit
7
+
8
+ Available commands:
9
+
10
+ startproject <name> [directory]
11
+ Create a new FastAPI project.
12
+
13
+ Examples:
14
+ fastapi-templatekit startproject myproject
15
+ fastapi-templatekit startproject myproject .
16
+ fastapi-templatekit startproject myproject ../services/myproject
17
+
18
+ Details:
19
+ - Without directory, creates ./<name>/.
20
+ - With '.', creates project files in the current directory.
21
+ - With a custom directory, creates project files at that path.
22
+ - If generated files already exist, asks before overwriting.
23
+ - Use --force to overwrite generated files without prompting.
24
+
25
+ startapp <name>
26
+ Create a root-level app inside an existing generated project.
27
+
28
+ Example:
29
+ fastapi-templatekit startapp users
30
+ fastapi-templatekit startapp users --with-websockets --with-database
31
+
32
+ Details:
33
+ - Must be run from a directory containing fastapi_templatekit.toml.
34
+ - Creates endpoints, schemas, service, and router.py.
35
+ - Includes a hello-world GET endpoint.
36
+ - Asks whether to include websockets.
37
+ - Asks whether to include database/tables.
38
+ - Use --with-websockets to add websocket scaffolding without prompting for it.
39
+ - Use --with-database to add the models folder without prompting for it.
40
+ - Prints the router registration lines for your project router.py.
41
+
42
+ addhealthprobes
43
+ Create a root-level healthprobes app inside an existing generated project.
44
+
45
+ Example:
46
+ fastapi-templatekit addhealthprobes
47
+
48
+ Details:
49
+ - Must be run from a directory containing fastapi_templatekit.toml.
50
+ - Creates /healthz and /livez GET endpoints.
51
+ - Prints the router registration lines for your project router.py.
52
+ - Use --force to overwrite generated healthprobes files without prompting.
53
+
54
+ help
55
+ Show this command summary.
56
+
57
+ Use 'fastapi-templatekit <command> --help' for argparse usage details.
58
+ """
59
+
60
+
61
+ def add_help_parser(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
62
+ parser = subparsers.add_parser(
63
+ "help",
64
+ help="Show available commands and details.",
65
+ )
66
+ parser.set_defaults(handler=handle_help)
67
+
68
+
69
+ def handle_help(_: argparse.Namespace) -> None:
70
+ print(HELP_TEXT)
@@ -0,0 +1,22 @@
1
+ from __future__ import annotations
2
+
3
+ import tomllib
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+
8
+ def load_project_config(project_root: Path) -> dict[str, Any]:
9
+ marker_path = project_root / "fastapi_templatekit.toml"
10
+
11
+ if not marker_path.exists():
12
+ raise SystemExit(
13
+ "Error: command must be run inside a fastapi-templatekit project.\n"
14
+ "Run: fastapi-templatekit startproject <project_name>"
15
+ )
16
+
17
+ marker = tomllib.loads(marker_path.read_text(encoding="utf-8"))
18
+ project = marker.get("project", {})
19
+ if not isinstance(project, dict):
20
+ raise SystemExit(f"Error: invalid project config: {marker_path}")
21
+
22
+ return project
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from importlib import resources
4
+ from pathlib import Path
5
+ from string import Template
6
+
7
+
8
+ TEMPLATE_ROOT = "fastapi_templatekit.templates"
9
+
10
+
11
+ def render_template(template_path: str, destination: Path, context: dict[str, str]) -> None:
12
+ template = resources.files(TEMPLATE_ROOT).joinpath(template_path)
13
+ content = Template(template.read_text(encoding="utf-8")).safe_substitute(context)
14
+ destination.parent.mkdir(parents=True, exist_ok=True)
15
+ destination.write_text(content, encoding="utf-8")