pytemplate-uv 0.1.0__py3-none-any.whl

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 (53) hide show
  1. pytemplate/__init__.py +1 -0
  2. pytemplate/main.py +142 -0
  3. pytemplate_uv-0.1.0.dist-info/LICENSE +21 -0
  4. pytemplate_uv-0.1.0.dist-info/METADATA +142 -0
  5. pytemplate_uv-0.1.0.dist-info/RECORD +53 -0
  6. pytemplate_uv-0.1.0.dist-info/WHEEL +5 -0
  7. pytemplate_uv-0.1.0.dist-info/entry_points.txt +3 -0
  8. pytemplate_uv-0.1.0.dist-info/top_level.txt +1 -0
  9. templates/fastapi-template/cookiecutter.json +23 -0
  10. templates/fastapi-template/{{cookiecutter.project_name}}/Dockerfile +38 -0
  11. templates/fastapi-template/{{cookiecutter.project_name}}/Makefile +145 -0
  12. templates/fastapi-template/{{cookiecutter.project_name}}/README.md +99 -0
  13. templates/fastapi-template/{{cookiecutter.project_name}}/pyproject.toml +115 -0
  14. templates/fastapi-template/{{cookiecutter.project_name}}/tests/__init__.py +0 -0
  15. templates/fastapi-template/{{cookiecutter.project_name}}/tests/conftest.py +85 -0
  16. templates/fastapi-template/{{cookiecutter.project_name}}/tests/test_cli.py +33 -0
  17. templates/fastapi-template/{{cookiecutter.project_name}}/tests/test_example.py +104 -0
  18. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.envfile}} +40 -0
  19. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__init__.py +0 -0
  20. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/__init__.cpython-311.pyc +0 -0
  21. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/db.cpython-311.pyc +0 -0
  22. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/main.cpython-311.pyc +0 -0
  23. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/models.cpython-311.pyc +0 -0
  24. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/cli.py +61 -0
  25. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/__pycache__/config.cpython-311.pyc +0 -0
  26. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/__pycache__/exceptions.cpython-311.pyc +0 -0
  27. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/__pycache__/middleware.cpython-311.pyc +0 -0
  28. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/config.py +48 -0
  29. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/exceptions.py +73 -0
  30. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/middleware.py +100 -0
  31. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/db.py +12 -0
  32. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/main.py +62 -0
  33. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/models.py +7 -0
  34. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/__init__.py +0 -0
  35. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/__pycache__/__init__.cpython-311.pyc +0 -0
  36. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/__pycache__/example.cpython-311.pyc +0 -0
  37. templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/example.py +102 -0
  38. templates/pyproject-template/cookiecutter.json +24 -0
  39. templates/pyproject-template/{{cookiecutter.project_name}}/Dockerfile +35 -0
  40. templates/pyproject-template/{{cookiecutter.project_name}}/Makefile +145 -0
  41. templates/pyproject-template/{{cookiecutter.project_name}}/README.md +80 -0
  42. templates/pyproject-template/{{cookiecutter.project_name}}/pyproject.toml +106 -0
  43. templates/pyproject-template/{{cookiecutter.project_name}}/tests/__init__.py +0 -0
  44. templates/pyproject-template/{{cookiecutter.project_name}}/tests/test_cli.py +33 -0
  45. templates/pyproject-template/{{cookiecutter.project_name}}/tests/test_main.py +2 -0
  46. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.envfile}} +41 -0
  47. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__init__.py +0 -0
  48. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/__init__.cpython-311.pyc +0 -0
  49. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/example_module.cpython-311.pyc +0 -0
  50. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/main.cpython-311.pyc +0 -0
  51. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/cli.py +61 -0
  52. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/example_module.py +1 -0
  53. templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/main.py +5 -0
pytemplate/__init__.py ADDED
@@ -0,0 +1 @@
1
+ # Pytemplate package initialization
pytemplate/main.py ADDED
@@ -0,0 +1,142 @@
1
+ """Command-line interface for creating Python projects from templates."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import subprocess
7
+ from pathlib import Path
8
+
9
+ import typer
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.text import Text
13
+
14
+ app = typer.Typer(
15
+ name="pytemplate-uv",
16
+ help="Create Python projects from templates using uv package manager",
17
+ add_completion=True,
18
+ rich_help_panel=True,
19
+ )
20
+ console = Console()
21
+
22
+
23
+ def _validate_template(template: str) -> Path:
24
+ """Validate and return the path to the specified template.
25
+
26
+ Args:
27
+ template (str): Name of the project template.
28
+
29
+ Returns:
30
+ Path: Path to the template directory.
31
+
32
+ Raises:
33
+ typer.BadParameter: If template is not found.
34
+
35
+ """
36
+ templates_dir = Path(__file__).parent.parent / "templates"
37
+ template_path = templates_dir / f"{template}-template"
38
+
39
+ console.print(f"[yellow]Checking template path: {template_path}[/]")
40
+
41
+ if not template_path.exists():
42
+ available_templates = [
43
+ d.name.replace("-template", "") for d in templates_dir.glob("*-template") if d.is_dir()
44
+ ]
45
+
46
+ error_text = Text("Template not found!", style="bold red")
47
+ suggestion_text = Text(
48
+ f"\nAvailable templates: {', '.join(available_templates)}", style="yellow"
49
+ )
50
+
51
+ console.print(Panel(Text.assemble(error_text, suggestion_text), border_style="red"))
52
+ raise typer.BadParameter(f"Template '{template}' not found")
53
+
54
+ console.print(f"[green]Using template path: {template_path}[/]")
55
+ return template_path
56
+
57
+
58
+ def _get_context() -> dict[str, str]:
59
+ """Retrieve context variables for project template.
60
+
61
+ Returns:
62
+ A dictionary of context variables.
63
+
64
+ """
65
+ return {
66
+ "author": os.environ.get("USER", "your name"),
67
+ "email": os.environ.get("USER_EMAIL", "your@email.com"),
68
+ "github_username": os.environ.get("GITHUB_USERNAME", "your_username"),
69
+ }
70
+
71
+
72
+ def _build_cookiecutter_command(
73
+ template_path: Path, context: dict, no_input: bool = False, force: bool = False
74
+ ) -> list[str]:
75
+ """Build the cookiecutter command with appropriate options.
76
+ Args:
77
+ template_path: Path to the project template
78
+ context: Context variables for the template
79
+ no_input: Whether to skip interactive prompts
80
+ force: Whether to overwrite existing project directory
81
+ Returns:
82
+ A list of command arguments.
83
+
84
+ """ # noqa: D205, D411
85
+ cookiecutter_cmd = [
86
+ "cookiecutter",
87
+ str(template_path),
88
+ *[f"{k}={v}" for k, v in context.items()],
89
+ ]
90
+
91
+ if no_input:
92
+ cookiecutter_cmd.append("--no-input")
93
+
94
+ if force:
95
+ cookiecutter_cmd.append("--overwrite-if-exists")
96
+
97
+ return cookiecutter_cmd
98
+
99
+
100
+ @app.command()
101
+ def create_project(
102
+ project_name: str = typer.Argument(None, help="Name of the project"),
103
+ template: str = typer.Option(
104
+ "pyproject", "--template", "-t", help="Template to use for project creation"
105
+ ),
106
+ no_input: bool = typer.Option(
107
+ False, "--no-input", "-y", help="Skip prompts and use default values"
108
+ ),
109
+ force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing project directory"),
110
+ ):
111
+ """Create a new project from a specified template."""
112
+ template_path = _validate_template(template)
113
+ context = _get_context()
114
+ if project_name:
115
+ context["project_name"] = project_name
116
+
117
+ cookiecutter_cmd = _build_cookiecutter_command(template_path, context, no_input, force)
118
+
119
+ try:
120
+ result = subprocess.run(cookiecutter_cmd, text=True, check=True)
121
+ console.print("[green]Project created successfully![/]")
122
+
123
+ if result.stdout:
124
+ console.print(f"[green]{result.stdout.strip()}[/]")
125
+
126
+ except subprocess.CalledProcessError as e:
127
+ console.print("[red]Project creation failed:[/]")
128
+ console.print(f"Command: {' '.join(e.cmd)}")
129
+
130
+ if e.stdout:
131
+ console.print("[yellow]Standard Output:[/]")
132
+ console.print(e.stdout)
133
+
134
+ if e.stderr:
135
+ console.print("[red]Error Output:[/]")
136
+ console.print(e.stderr)
137
+
138
+ raise typer.Exit(code=1) # noqa: B904
139
+
140
+
141
+ if __name__ == "__main__":
142
+ app()
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Leo Liu
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,142 @@
1
+ Metadata-Version: 2.2
2
+ Name: pytemplate-uv
3
+ Version: 0.1.0
4
+ Summary: A template for creating Python projects using uv package manager
5
+ Author-email: Leo Liu <yuxuzi@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yuxuzi/pytemplate-uv
8
+ Project-URL: Repository, https://github.com/yuxuzi/pytemplate-uv
9
+ Project-URL: Issues, https://github.com/yuxuzi/pytemplate-uv/issues
10
+ Project-URL: Changelog, https://github.com/yuxuzi/pytemplate-uv/blob/main/CHANGELOG.md
11
+ Keywords: python,template,project-generator,uv,cookiecutter,cli
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Topic :: Utilities
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: typer>=0.9.0
24
+ Requires-Dist: rich>=13.7.0
25
+ Requires-Dist: cookiecutter>=2.5.0
26
+ Requires-Dist: pytest>=7.4.4
27
+ Provides-Extra: dev
28
+ Requires-Dist: ruff>=0.1.9; extra == "dev"
29
+ Requires-Dist: black>=23.12.1; extra == "dev"
30
+ Requires-Dist: pytest>=7.4.4; extra == "dev"
31
+ Requires-Dist: pre-commit>=3.6.0; extra == "dev"
32
+ Requires-Dist: mypy>=1.7.1; extra == "dev"
33
+ Requires-Dist: coverage>=7.3.2; extra == "dev"
34
+ Provides-Extra: docs
35
+ Requires-Dist: mkdocs>=1.5.3; extra == "docs"
36
+ Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
37
+
38
+ # PyTemplate UV
39
+
40
+ ## Overview
41
+
42
+ PyTemplate UV is a powerful CLI tool for creating Python project templates using the `uv` package manager. It provides a seamless way to generate standardized project structures with modern development practices.
43
+
44
+ ## Features
45
+
46
+ - ๐Ÿš€ Quick project initialization
47
+ - ๐Ÿ”ง Support for multiple project templates (FastAPI, Standard Python)
48
+ - ๐Ÿ“ฆ Integrated with `uv` package management
49
+ - ๐Ÿงช Comprehensive testing infrastructure
50
+ - ๐Ÿ” Linting and type checking support
51
+
52
+ ## Prerequisites
53
+
54
+ - Python 3.11+
55
+ - `uv` package manager
56
+ - `cookiecutter`
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install pytemplate-uv
62
+ # or
63
+ uv pip install pytemplate-uv
64
+ ```
65
+
66
+ ## Usage
67
+
68
+ ### Create a Project
69
+
70
+ ```bash
71
+ # Create a standard Python project (default)
72
+ pytemplate-uv create-project
73
+
74
+ # Create a FastAPI project
75
+ pytemplate-uv create-project --template fastapi
76
+
77
+ # Create a project with a custom name
78
+ pytemplate-uv create-project --name my-awesome-project
79
+
80
+ # Create a project with custom template and name
81
+ pytemplate-uv create-project --template fastapi --name my-api-project
82
+ ```
83
+
84
+ ### Project Creation Options
85
+
86
+ - `--template`: Choose the project template (default: pyproject)
87
+ - Options: `pyproject`, `fastapi`
88
+ - `--name`: Specify a custom project name
89
+ - Additional template-specific options can be passed as needed
90
+
91
+ ### Next Steps After Project Creation
92
+
93
+ 1. `cd` into your project directory
94
+ 2. Run `uv venv` to create a virtual environment
95
+ 3. Run `uv pip install -e .` to install dependencies
96
+ 4. Run `make setup` to set up the development environment
97
+
98
+ ## Development
99
+
100
+ ### Setup
101
+
102
+ 1. Clone the repository
103
+ 2. Create a virtual environment:
104
+ ```bash
105
+ uv venv
106
+ source .venv/bin/activate
107
+ ```
108
+
109
+ 3. Install development dependencies:
110
+ ```bash
111
+ uv pip install -e .[dev]
112
+ ```
113
+
114
+ ### Running Tests
115
+
116
+ ```bash
117
+ pytest
118
+ ```
119
+
120
+ ### Linting
121
+
122
+ ```bash
123
+ ruff check .
124
+ black .
125
+ mypy .
126
+ ```
127
+
128
+ ## Contributing
129
+
130
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.
131
+
132
+ ## License
133
+
134
+ MIT License - See [LICENSE](LICENSE) for details.
135
+
136
+ ## Contact
137
+
138
+ Leo Liu - [GitHub](https://github.com/yuxuzi)
139
+
140
+ ---
141
+
142
+ *Simplifying Python project creation with modern best practices* ๐Ÿโœจ
@@ -0,0 +1,53 @@
1
+ pytemplate/__init__.py,sha256=VY5oWgjrWxifkHlWGCMvKNgCXT-MHQKoHTCerVYpd_I,36
2
+ pytemplate/main.py,sha256=ZWq98WOMtwcXkA_pVqWS0Tmc7aeij3woeQuOOjIqmNU,4258
3
+ templates/fastapi-template/cookiecutter.json,sha256=PPdGDw3mt0qIdkke_Sh0u_yWbTWzobwmXZnVV5WrKcA,660
4
+ templates/fastapi-template/{{cookiecutter.project_name}}/Dockerfile,sha256=dA0wD9ct9jyrYy-hRoUZUYI-TYApaRVT4vsCOwz9vJ4,1057
5
+ templates/fastapi-template/{{cookiecutter.project_name}}/Makefile,sha256=PFeKW96hdb9Wyq9Y09m_H0RXgSe976IfoD8qXqrlndQ,3689
6
+ templates/fastapi-template/{{cookiecutter.project_name}}/README.md,sha256=vmSIwHIK--ZyyREBmqM-WXXeqWEVHFUopUExtUNXRtc,1649
7
+ templates/fastapi-template/{{cookiecutter.project_name}}/pyproject.toml,sha256=vBacMor5LFcX9bzehgZhMcbElet89ldGAUA5IWImoQI,2964
8
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.envfile}},sha256=F7VgE-qK4V5UkncPsSXI6fs8nTGMpX7TPumXyuHni14,782
9
+ templates/fastapi-template/{{cookiecutter.project_name}}/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ templates/fastapi-template/{{cookiecutter.project_name}}/tests/conftest.py,sha256=K8ePAhQuDhc-3IqmDy-zX8OzJOv722VfOjJeiwqieK8,2382
11
+ templates/fastapi-template/{{cookiecutter.project_name}}/tests/test_cli.py,sha256=WrAM11xHJYToK9vGDMzWLDe5Rul1XU3lxrd13_AHIn8,1047
12
+ templates/fastapi-template/{{cookiecutter.project_name}}/tests/test_example.py,sha256=EUF-8PnvP-abBjH-cDR8v02ZGFctIlGb18AVLcZu7n4,3573
13
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/cli.py,sha256=bkn_TQxTYy0QLHHWMirhPChqOitffSA1KwNtk82VjT4,1595
15
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/db.py,sha256=R9OTAOt8WZWLP8ZtmbobrLbtGV_8PzEQaBJZbRStMQI,458
16
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/main.py,sha256=m7Iwt8I__9BOTFRKIOiE-OXuxiPw-9NS6zZRbVCEmjQ,1481
17
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/models.py,sha256=WLLtpctDIO6P39d4nUobRdmn774177KONrQjgzxdngU,273
18
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/__init__.cpython-311.pyc,sha256=rpvf30Q0nPPW6jJW27HgT77rn5Uytuj7Pxg41InoMUs,397
19
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/db.cpython-311.pyc,sha256=MZNvPK3jTLBQtgX6zIl-_rv1Fy1QsrcrdPFQAIY4mlM,1366
20
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/main.cpython-311.pyc,sha256=WTK9Oj_JfSC_FYY5foGSKBJCV0O6UMFgARtFdVjQLRU,2826
21
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/models.cpython-311.pyc,sha256=j46wmZckuJXvXJA08bU1Elu8QnqoJXpTBOUIIBrJELc,847
22
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/config.py,sha256=LfXNZVw2oju5HwUxO0vYrwIcb6n5Z9ljy6AxAEjmBxc,1236
23
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/exceptions.py,sha256=QxlrAOTTvEQAcrvGHVzfWAalGBLKEvRPRAeRVfShjSU,2125
24
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/middleware.py,sha256=ZsYXcPvIcOYBD2sIueXUIsXBu7zCeCKnF3iufwH_ltg,3122
25
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/__pycache__/config.cpython-311.pyc,sha256=kCGo1K1u1TusGDardoXyIQ4HnZzzy9S1D0oocnTDyEE,2294
26
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/__pycache__/exceptions.cpython-311.pyc,sha256=cB6SKzzzwWHjpfnv24pRgZeF9TdKoF9qAi_uPNfL5_A,5211
27
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/core/__pycache__/middleware.cpython-311.pyc,sha256=dTVnxQBZ1SyhVEoXld2qbx6CNZIzlVi3CfaueoRsSLc,4434
28
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/example.py,sha256=oS1kC18aJK9xhFvqGGkHpDY7XGUK0yEsSWn2l6LsY98,2831
30
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/__pycache__/__init__.cpython-311.pyc,sha256=oF7_NSYEmm7TINmuYJ8zAdubRdMrpLkmbFbw1u_Sr6s,252
31
+ templates/fastapi-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/routers/__pycache__/example.cpython-311.pyc,sha256=W4wS240XIEuXNiRXXRAtlXqI5yQx7baaTLQ2hY3dDm0,5244
32
+ templates/pyproject-template/cookiecutter.json,sha256=ZCqlDi3Z4nG8wN8Cf3vNwyTE7_aBdmZDVQdmMla6Xx8,688
33
+ templates/pyproject-template/{{cookiecutter.project_name}}/Dockerfile,sha256=YBLJVbKfJQlhImd_eT9IFAvk899PpVqDirdD4aiDF5w,1046
34
+ templates/pyproject-template/{{cookiecutter.project_name}}/Makefile,sha256=CQnKkpd8inbVDZRcIg8LPKPzSpV6kX1pJg4t3WCAzCc,3683
35
+ templates/pyproject-template/{{cookiecutter.project_name}}/README.md,sha256=6CXB-ke6-TjH47dQ-KXlZHFCLA7_6A9XPs8iPShmiEM,1248
36
+ templates/pyproject-template/{{cookiecutter.project_name}}/pyproject.toml,sha256=wADwFzOGeYil-Z7_JDNpc7c3LyPQ3mFbYzeNCXJFnAs,2396
37
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.envfile}},sha256=H0tMaYSKUwgObikNNGd1mXivYpIjasxNG27HvHF7WJU,968
38
+ templates/pyproject-template/{{cookiecutter.project_name}}/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
+ templates/pyproject-template/{{cookiecutter.project_name}}/tests/test_cli.py,sha256=WrAM11xHJYToK9vGDMzWLDe5Rul1XU3lxrd13_AHIn8,1047
40
+ templates/pyproject-template/{{cookiecutter.project_name}}/tests/test_main.py,sha256=KG9-9kwp105ODKM-UV0TvOoA49h7E9nxSfNIt78X3tw,36
41
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/cli.py,sha256=oVkN8vEs-k1LTzYB7jyNT01IiZ_v9xO_xSlENXfpFII,1594
43
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/example_module.py,sha256=UfwjmUgqo_Pev8mZi6HuAOk4PT0Z1tWReZB7WapENl8,17
44
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/main.py,sha256=bkPX2DwXt65x2NLnIFPNoOWMTn0M5OXmr8XMr9xTl8o,78
45
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/__init__.cpython-311.pyc,sha256=64PchSH6nA26CgiIvfN1S-Ko7sSjEXft2c9q9rH43uU,399
46
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/example_module.cpython-311.pyc,sha256=m6eflFezuGlnjcwcZR_InP0IhHNQSLBGAMJ3a-nc8m4,252
47
+ templates/pyproject-template/{{cookiecutter.project_name}}/{{cookiecutter.package_name}}/__pycache__/main.cpython-311.pyc,sha256=Xre-KLGyTkkicox5fIEgahZ-ouxEW_lkvsn-F8cXXRI,498
48
+ pytemplate_uv-0.1.0.dist-info/LICENSE,sha256=qGN1csUyIHsyQcOo3taVjJbE0Z_mNoZUULIGY0Mc-lY,1064
49
+ pytemplate_uv-0.1.0.dist-info/METADATA,sha256=8mwONgHSxrnSReZbo9osggah3DpAxYExCoJRNtF3ars,3702
50
+ pytemplate_uv-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
51
+ pytemplate_uv-0.1.0.dist-info/entry_points.txt,sha256=JpY20DCqntUnmu5HOA8sXqoHpB2oKZ10pi1n8DrrLek,88
52
+ pytemplate_uv-0.1.0.dist-info/top_level.txt,sha256=m4b8YiLi0BJ7kR2AXXY3_Me075SCU1C7qEzucz92qgY,11
53
+ pytemplate_uv-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ create-project = pytemplate.main:app
3
+ pytemplate = pytemplate.main:app
@@ -0,0 +1 @@
1
+ pytemplate
@@ -0,0 +1,23 @@
1
+ {
2
+ "project_name": "my-fastapi-project",
3
+ "package_name": "{{cookiecutter.project_name|lower|replace('-', '_')}}",
4
+ "author": "{{ cookiecutter.get('author', 'Your Name') }}",
5
+ "email": "{{ cookiecutter.get('email', 'your@email.com') }}",
6
+ "github_username": "{{ cookiecutter.get('github_username', 'your_username') }}",
7
+ "description": "A FastAPI project template",
8
+ "python_version": "3.11",
9
+ "docs": "y",
10
+ "coverage": "y",
11
+ "dockerfile": "y",
12
+ "mypy": "y",
13
+ "license": "MIT",
14
+ "envfile": ".env",
15
+ "_copy_without_render": [
16
+ "docs",
17
+ "coverage",
18
+ "dockerfile",
19
+ "mypy",
20
+ "envfile",
21
+ "license"
22
+ ]
23
+ }
@@ -0,0 +1,38 @@
1
+ FROM python:{{cookiecutter.python_version}}-slim as builder
2
+
3
+ WORKDIR /{{cookiecutter.project_name}}
4
+
5
+ # Install uv
6
+ RUN pip install --no-cache-dir uv
7
+
8
+ # Copy only the files needed for dependency installation
9
+ COPY pyproject.toml .
10
+ COPY {{cookiecutter.project_name}} ./{{cookiecutter.project_name}}
11
+
12
+ # Use uv to install dependencies
13
+ RUN uv pip install --system .
14
+
15
+ FROM python:{{cookiecutter.python_version}}-slim
16
+
17
+ WORKDIR /{{cookiecutter.project_name}}
18
+
19
+ # Create non-root user
20
+ RUN adduser --disabled-password --gecos '' appuser && \
21
+ pip install --no-cache-dir uv
22
+
23
+ # Copy the installed dependencies and project files
24
+ COPY --from=builder /usr/local/lib/python*/site-packages /usr/local/lib/python*/site-packages/
25
+ COPY {{cookiecutter.project_name}} ./{{cookiecutter.project_name}}
26
+ COPY pyproject.toml .
27
+
28
+ # Switch to non-root user
29
+ USER appuser
30
+
31
+ EXPOSE 8000
32
+
33
+ HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
34
+ CMD curl -f http://localhost:8000/health || exit 1
35
+
36
+ # Use make start to run the application
37
+ ENTRYPOINT ["make"]
38
+ CMD ["start"]
@@ -0,0 +1,145 @@
1
+ # Detect the operating system
2
+ ifeq ($(OS),Windows_NT)
3
+ VENV_ACTIVATE = .venv\Scripts\activate
4
+ PYTHON = .venv\Scripts\python
5
+ RM = rmdir /s /q
6
+ MKDIR = mkdir
7
+ else
8
+ VENV_ACTIVATE = . .venv/bin/activate
9
+ PYTHON = .venv/bin/python
10
+ RM = rm -rf
11
+ MKDIR = mkdir -p
12
+ endif
13
+
14
+ # Global prerequisite to ensure virtual environment is activated
15
+ .PHONY: venv-activate
16
+ venv-activate:
17
+ @if [ ! -d ".venv" ]; then \
18
+ echo "Virtual environment not found. Creating..."; \
19
+ uv venv; \
20
+ fi
21
+ @echo "Activating virtual environment..."
22
+ @$(VENV_ACTIVATE)
23
+
24
+ # Wrapper function to ensure virtual environment is activated
25
+ define ensure_venv
26
+ @if [ -z "$(VIRTUAL_ENV)" ]; then \
27
+ echo "Activating virtual environment..."; \
28
+ . .venv/bin/activate; \
29
+ fi
30
+ endef
31
+
32
+ # Apply venv-activate as a global prerequisite
33
+ .PHONY: all
34
+ all: venv-activate
35
+
36
+ # Modify all targets to depend on venv-activate
37
+ .PHONY: help setup dev start run lint lint-fix format format-check test test-cov clean docs build publish
38
+
39
+ help: venv-activate
40
+ @echo " {{cookiecutter.project_name}} - Project Management Commands"
41
+ @echo ""
42
+ @echo "Development:"
43
+ @echo " make setup - Create virtual environment and install dependencies"
44
+ @echo " make dev - Set up development environment (pre-commit, etc.)"
45
+ @echo " make start - Start the application"
46
+ @echo " make run - Alias for 'start'"
47
+ @echo ""
48
+ @echo "Code Quality:"
49
+ @echo " make lint - Run code linting"
50
+ @echo " make lint-fix - Run linter with auto-fix"
51
+ @echo " make format - Format code using Black"
52
+ @echo " make format-check - Check code formatting"
53
+ @echo ""
54
+ @echo "Testing:"
55
+ @echo " make test - Run tests"
56
+ @echo " make test-cov - Run tests with coverage report"
57
+ @echo ""
58
+ @echo "Documentation:"
59
+ @echo " make docs - Generate documentation"
60
+ @echo ""
61
+ @echo "Packaging:"
62
+ @echo " make build - Build distribution packages"
63
+ @echo " make publish - Publish package to PyPI"
64
+ @echo ""
65
+ @echo "Cleanup:"
66
+ @echo " make clean - Remove virtual environment and cache files"
67
+
68
+ # Setup project dependencies
69
+ setup: venv-activate
70
+ @echo "Installing dependencies..."
71
+ $(ensure_venv)
72
+ uv pip install -e ".[dev, docs, test]" && pre-commit install
73
+
74
+ # Start the application
75
+ start: venv-activate
76
+ @echo "Starting application..."
77
+ $(ensure_venv)
78
+ fastapi dev {{cookiecutter.package_name}}/main.py
79
+
80
+ # Alias for start
81
+ run: start
82
+
83
+ # Linting
84
+ lint: venv-activate
85
+ @echo "Running linter..."
86
+ $(ensure_venv)
87
+ ruff check .
88
+
89
+ # Linting with auto-fix
90
+ lint-fix: venv-activate
91
+ @echo "Running linter with auto-fix..."
92
+ $(ensure_venv)
93
+ ruff check . --fix
94
+
95
+ # Code formatting
96
+ format: venv-activate
97
+ @echo "Formatting code with Black..."
98
+ $(ensure_venv)
99
+ black .
100
+
101
+ # Check code formatting
102
+ format-check: venv-activate
103
+ @echo "Checking code formatting..."
104
+ $(ensure_venv)
105
+ black . --check
106
+
107
+ # Run tests
108
+ test: venv-activate
109
+ @echo "Running tests..."
110
+ $(ensure_venv)
111
+ pytest tests/
112
+
113
+ # Run tests with coverage
114
+ test-cov: venv-activate
115
+ @echo "Running tests with coverage..."
116
+ $(ensure_venv)
117
+ pytest --cov={{cookiecutter.package_name}} --cov-report=term-missing
118
+
119
+ # Clean up virtual environment and cache files
120
+ clean:
121
+ @echo "Cleaning up..."
122
+ $(RM) .venv
123
+ $(RM) .pytest_cache
124
+ $(RM) .coverage
125
+ find . -type d -name "__pycache__" -exec $(RM) {} +
126
+
127
+ # Generate documentation
128
+ docs: venv-activate
129
+ @echo "Generating documentation..."
130
+ $(ensure_venv)
131
+ pdoc -o docs {{cookiecutter.package_name}}
132
+
133
+ # Build distribution packages
134
+ build: venv-activate
135
+ @echo "Building distribution packages..."
136
+ $(ensure_venv)
137
+ uv pip install build
138
+ python -m build
139
+
140
+ # Publish to PyPI
141
+ publish: build
142
+ @echo "Publishing to PyPI..."
143
+ $(ensure_venv)
144
+ uv pip install twine
145
+ twine upload dist/*
@@ -0,0 +1,99 @@
1
+ # {{cookiecutter.project_name}}
2
+
3
+ {{cookiecutter.description}}
4
+
5
+ ## ๐Ÿš€ Features
6
+
7
+ - Modern FastAPI web application
8
+ - Async SQLModel database integration
9
+ - Comprehensive development tooling
10
+ - Robust testing and type checking
11
+ - Docker support
12
+
13
+ ## ๐Ÿ“ฆ Installation
14
+
15
+ ```bash
16
+ # Using pip
17
+ pip install {{cookiecutter.package_name}}
18
+
19
+ # Using uv
20
+ uv pip install {{cookiecutter.package_name}}
21
+ ```
22
+
23
+ ## ๐Ÿ”ง Development Setup
24
+
25
+ 1. Clone the repository
26
+ 2. Create a virtual environment
27
+ ```bash
28
+ uv venv
29
+ . .venv/bin/activate
30
+ ```
31
+
32
+ 3. Install dependencies
33
+ ```bash
34
+ make setup
35
+ ```
36
+
37
+ ## ๐Ÿ’ป Usage
38
+
39
+ ### CLI Commands
40
+
41
+ ```bash
42
+ # Show help
43
+ {{cookiecutter.package_name}} --help
44
+
45
+ # Hello command
46
+ {{cookiecutter.package_name}} hello --name World
47
+
48
+ # Project info
49
+ {{cookiecutter.package_name}} info
50
+ ```
51
+
52
+ ### API Endpoints
53
+
54
+ - Swagger UI: `http://localhost:8000/docs`
55
+ - OpenAPI JSON: `http://localhost:8000/openapi.json`
56
+
57
+ ## ๐Ÿงช Testing
58
+
59
+ Run tests with comprehensive coverage:
60
+
61
+ ```bash
62
+ make test
63
+ ```
64
+
65
+ ## ๐Ÿ“ Development Workflow
66
+
67
+ - `make start`: Start the FastAPI server
68
+ - `make lint`: Run code linters
69
+ - `make format`: Auto-format code
70
+ - `make test`: Run tests
71
+ - `make docs`: Generate documentation
72
+
73
+ ## ๐Ÿณ Docker Support
74
+
75
+ Build and run the Docker container:
76
+
77
+ ```bash
78
+ # Build the image
79
+ docker build -t {{cookiecutter.package_name}} .
80
+
81
+ # Run the container
82
+ docker run -p 8000:8000 {{cookiecutter.package_name}}
83
+ ```
84
+
85
+ ## ๐Ÿค Contributing
86
+
87
+ 1. Fork the repository
88
+ 2. Create your feature branch
89
+ 3. Commit your changes
90
+ 4. Push to the branch
91
+ 5. Create a Pull Request
92
+
93
+ ## ๐Ÿ“„ License
94
+
95
+ {{cookiecutter.license}} License
96
+
97
+ ## ๐Ÿ‘ฅ Authors
98
+
99
+ - {{cookiecutter.author}} <{{cookiecutter.email}}>