Skip to content

Commit f307023

Browse files
committed
initial
0 parents  commit f307023

12 files changed

Lines changed: 231 additions & 0 deletions

File tree

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# cookiecutter-python
2+
3+
A [Cookiecutter](https://github.com/cookiecutter/cookiecutter) template for a new Python app.
4+
5+
Scaffolds out a new minimal python project with everything setup and ready to code.
6+
7+
8+
## Usage
9+
10+
### uv
11+
12+
```sh
13+
uvx cookiecutter https://github.com/jritsema/cookiecutter-python.git
14+
```
15+
16+
### pip
17+
18+
```sh
19+
pip install cookiecutter
20+
cookiecutter https://github.com/jritsema/cookiecutter-python.git
21+
```
22+
23+
## Example
24+
25+
```
26+
$ cookiecutter https://github.com/jritsema/cookiecutter-python.git
27+
[1/7] Friendly name of your project (Python app):
28+
[2/7] Description of your project (This is a new python app):
29+
[3/7] Directory/URL friendly project name (python-app):
30+
[4/7] Do you use asdf? [y/n] (y):
31+
[5/7] Do you use direnv? [y/n] (y):
32+
[6/7] Do you want to add container support? [y/n] (y):
33+
[7/7] Do you want to include the AWS SDK? [y/n] (n):
34+
direnv allow .
35+
Creating virtual python environment...
36+
Initialized empty Git repository in /Users/john/code/python-app/.git/
37+
[main (root-commit) 36dde21] Initial commit
38+
10 files changed, 103 insertions(+)
39+
create mode 100644 .dockerignore
40+
create mode 100644 .envrc
41+
create mode 100644 .gitignore
42+
create mode 100644 .tool-versions
43+
create mode 100644 Dockerfile
44+
create mode 100644 Makefile
45+
create mode 100644 README.md
46+
create mode 100644 log.py
47+
create mode 100644 main.py
48+
create mode 100644 requirements.txt
49+
Done
50+
cd python-app
51+
```
52+
53+
54+
## TODO
55+
56+
- try to add dynamic python version as cookiecutter variable to be used in Dockerfile
57+
- `container_support` should add a `make build` command

cookiecutter.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"project_name": "Python app",
3+
"project_description": "This is a new python app",
4+
"project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}",
5+
"enable_asdf": true,
6+
"enable_direnv": true,
7+
"container_support": true,
8+
"enable_aws": false,
9+
"__prompts__": {
10+
"project_name": "Friendly name of your project",
11+
"project_description": "Description of your project",
12+
"project_slug": "Directory/URL friendly project name",
13+
"container_support": "Do you want to add container support?",
14+
"enable_asdf": "Do you use asdf?",
15+
"enable_direnv": "Do you use direnv?",
16+
"enable_aws": "Do you want to include the AWS SDK?"
17+
}
18+
}

hooks/post_gen_project.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import os
2+
import sys
3+
4+
PROJECT_DIRECTORY = os.path.realpath(os.path.curdir)
5+
6+
7+
def remove_file(filepath: str) -> None:
8+
os.remove(os.path.join(PROJECT_DIRECTORY, filepath))
9+
10+
11+
def post_gen_project():
12+
13+
if "{{ cookiecutter.container_support }}" != "True":
14+
remove_file("Dockerfile")
15+
remove_file(".dockerignore")
16+
17+
if "{{ cookiecutter.enable_asdf }}" == "True":
18+
19+
# write python version to .tool-versions
20+
python_version = f"{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}"
21+
lines = [f"python {python_version}\n"]
22+
23+
if "{{ cookiecutter.enable_direnv }}" == "True":
24+
lines.append("direnv 2.28.0\n")
25+
26+
with open(".tool-versions", "w") as f:
27+
f.writelines(lines)
28+
29+
if "{{ cookiecutter.enable_direnv }}" == "True":
30+
print("direnv allow .")
31+
os.system("direnv allow .")
32+
else:
33+
remove_file(".envrc")
34+
35+
if "{{ cookiecutter.enable_aws }}" == "True":
36+
with open("requirements.txt", "w") as f:
37+
f.write(f"boto3")
38+
39+
print("Creating virtual python environment...")
40+
os.system("python -m venv .venv")
41+
42+
# create git repo
43+
os.system("git init && git add . && git commit -m 'initial'")
44+
45+
print("Done")
46+
out = f"cd {{ cookiecutter.project_slug }}"
47+
if "{{ cookiecutter.enable_direnv }}" != "True":
48+
out += " && . .venv/bin/activate"
49+
if "{{ cookiecutter.enable_aws }}" == "True":
50+
out += " && make install"
51+
print(out)
52+
53+
54+
if __name__ == "__main__":
55+
post_gen_project()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.git
2+
.venv
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
. .venv/bin/activate
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.venv
2+
.vscode
3+
*.swp
4+
__pycache__
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM python:3.11-slim
2+
WORKDIR /app
3+
RUN apt-get update && apt-get install -y \
4+
&& rm -rf /var/lib/apt/lists/*
5+
COPY ./piplock.txt .
6+
RUN pip3 install -r piplock.txt
7+
COPY . .
8+
ENTRYPOINT ["python", "-u", "main.py"]
9+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
all: help
2+
3+
.PHONY: help
4+
help: Makefile
5+
@echo
6+
@echo " Choose a make command to run"
7+
@echo
8+
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
9+
@echo
10+
11+
## install: install project dependencies
12+
.PHONY: install
13+
install:
14+
python -m pip install --upgrade pip
15+
pip install -r requirements.txt
16+
pip freeze > piplock.txt
17+
18+
## start: run local project
19+
.PHONY: start
20+
start:
21+
clear
22+
@echo ""
23+
python -u main.py
24+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# {{ cookiecutter.project_name }}
2+
3+
{{ cookiecutter.project_description }}
4+
5+
6+
## Development
7+
```
8+
Choose a make command to run
9+
10+
install install project dependencies
11+
start run local project
12+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import logging
2+
import json
3+
4+
5+
def debug(obj):
6+
"""
7+
Print a JSON representation of the given object to the console, at debug level.
8+
"""
9+
if logging.getLogger().level == logging.DEBUG:
10+
print(json.dumps(obj, indent=2, default=str))
11+
12+
13+
def info(obj):
14+
"""
15+
Print a JSON representation of the given object to the console, at info level.
16+
"""
17+
if logging.getLogger().level <= logging.INFO:
18+
print(json.dumps(obj, indent=2, default=str))
19+
20+
21+
def warn(obj):
22+
"""
23+
Print a JSON representation of the given object to the console, at warn level.
24+
"""
25+
if logging.getLogger().level <= logging.WARNING:
26+
print(json.dumps(obj, indent=2, default=str))
27+
28+
29+
def error(obj):
30+
"""
31+
Print a JSON representation of the given object to the console, at error level.
32+
"""
33+
print(json.dumps(obj, indent=2, default=str))

0 commit comments

Comments
 (0)