Skip to content

Commit

Permalink
✨ Add Copier, migrate from Cookiecutter, in a way that supports using…
Browse files Browse the repository at this point in the history
… the project as is, forking or cloning it (fastapi#612)

* 🔧 Add first Copier config

* 🔧 Add custom copier answers file

* 🔨 Add Copier script to update .env after generating/copying

* 🙈 Update .gitignores from Copier updates

* 🔧 Update .env, restructure in order of relevance

* 🔧 Remove Copier config for SMTP port, if necessary, it can be overwritten in .env

* ♻️ Refactor Copier files, make them less visible

* 🔧 Update Copier config

* 🔥 Remove Cookiecutter files
  • Loading branch information
tiangolo authored Feb 25, 2024
1 parent 0cc802e commit 4272619
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 97 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
.vscode
.mypy_cache
poetry.lock
44 changes: 0 additions & 44 deletions cookiecutter.json

This file was deleted.

1 change: 1 addition & 0 deletions src/.copier/.copier-answers.yml.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ _copier_answers|to_json -}}
22 changes: 22 additions & 0 deletions src/.copier/update_dotenv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from pathlib import Path
import json

# Update the .env file with the answers from the .copier-answers.yml file
# without using Jinja2 templates in the .env file, this way the code works as is
# without needing Copier, but if Copier is used, the .env file will be updated
root_path = Path(__file__).parent.parent
answers_path = Path(__file__).parent / ".copier-answers.yml"
answers = json.loads(answers_path.read_text())
env_path = root_path / ".env"
env_content = env_path.read_text()
lines = []
for line in env_content.splitlines():
for key, value in answers.items():
upper_key = key.upper()
if line.startswith(f"{upper_key}="):
new_line = line.replace(line, f"{upper_key}={value}")
lines.append(new_line)
break
else:
lines.append(line)
env_path.write_text("\n".join(lines))
42 changes: 22 additions & 20 deletions src/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,47 @@
DOMAIN=localhost
# DOMAIN=localhost.tiangolo.com

STACK_NAME=full-stack-fastapi-postgresql

TRAEFIK_PUBLIC_NETWORK=traefik-public
TRAEFIK_TAG=traefik
TRAEFIK_PUBLIC_TAG=traefik-public
PROJECT_NAME="FastAPI Project"

# Configure these with your own Docker registry images
DOCKER_IMAGE_BACKEND=backend
DOCKER_IMAGE_CELERYWORKER=celery
DOCKER_IMAGE_FRONTEND=frontend
DOCKER_IMAGE_NEW_FRONTEND=new-frontend
STACK_NAME=fastapi-project

# Backend
BACKEND_CORS_ORIGINS="[\"http://localhost\", \"http://localhost:4200\", \"http://localhost:3000\", \"http://localhost:8080\", \"https://localhost\", \"https://localhost:4200\", \"https://localhost:3000\", \"https://localhost:8080\", \"http://local.dockertoolbox.tiangolo.com\", \"http://localhost.tiangolo.com\"]"
PROJECT_NAME="FastAPI Project"
SECRET_KEY=changethis
FIRST_SUPERUSER=[email protected]
FIRST_SUPERUSER_PASSWORD=changethis
SMTP_TLS=True
SMTP_PORT=587
SMTP_HOST=
SMTP_USER=
SMTP_PASSWORD=
EMAILS_FROM_EMAIL=[email protected]
SMTP_TLS=True
SMTP_PORT=587

USERS_OPEN_REGISTRATION=False

SENTRY_DSN=

# Flower
FLOWER_BASIC_AUTH=

# Postgres
POSTGRES_SERVER=db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=changethis
POSTGRES_DB=app
POSTGRES_PASSWORD=changethis

# PgAdmin
PGADMIN_LISTEN_PORT=5050
PGADMIN_DEFAULT_EMAIL=[email protected]
PGADMIN_DEFAULT_PASSWORD=changethis
PGADMIN_LISTEN_PORT=5050

SENTRY_DSN=

# Flower
FLOWER_BASIC_AUTH=

# Traefik
TRAEFIK_PUBLIC_NETWORK=traefik-public
TRAEFIK_TAG=traefik
TRAEFIK_PUBLIC_TAG=traefik-public

# Configure these with your own Docker registry images
DOCKER_IMAGE_BACKEND=backend
DOCKER_IMAGE_CELERYWORKER=celery
DOCKER_IMAGE_FRONTEND=frontend
DOCKER_IMAGE_NEW_FRONTEND=new-frontend
3 changes: 3 additions & 0 deletions src/backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ app.egg-info
.mypy_cache
.coverage
htmlcov
poetry.lock
.cache
.venv
1 change: 0 additions & 1 deletion src/backend/app/tests/.gitignore

This file was deleted.

30 changes: 0 additions & 30 deletions src/cookiecutter-config-file.yml

This file was deleted.

119 changes: 119 additions & 0 deletions src/copier.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
domain:
type: str
help: |
Which domain name to use for the project, by default,
localhost, but you should change it later (in .env)
default: localhost

project_name:
type: str
help: The name of the project, shown to API users (in .env)
default: FastAPI Project

stack_name:
type: str
help: The name of the stack used for Docker Compose labels (no spaces) (in .env)
default: fastapi-project

secret_key:
type: str
help: |
'The secret key for the project, used for security,
stored in .env, you can generate one with:
python -c "import secrets; print(secrets.token_urlsafe(32))"'
default: changethis

first_superuser:
type: str
help: The email of the first superuser (in .env)
default: [email protected]

first_superuser_password:
type: str
help: The password of the first superuser (in .env)
default: changethis

smtp_host:
type: str
help: The SMTP server host to send emails, you can set it later in .env
default: ""

smtp_user:
type: str
help: The SMTP server user to send emails, you can set it later in .env
default: ""

smtp_password:
type: str
help: The SMTP server password to send emails, you can set it later in .env
default: ""

emails_from_email:
type: str
help: The email account to send emails from, you can set it later in .env
default: [email protected]

postgres_password:
type: str
help: |
'The password for the PostgreSQL database, stored in .env,
you can generate one with:
python -c "import secrets; print(secrets.token_urlsafe(32))"'
default: changethis

pgadmin_default_email:
type: str
help: The default user email for pgAdmin, you can set it later in .env
default: [email protected]

pgadmin_default_password:
type: str
help: The default user password for pgAdmin, stored in .env
default: changethis

sentry_dsn:
type: str
help: The DSN for Sentry, if you are using it, you can set it later in .env
default: ""

_exclude:
# Global
- .vscode
- .mypy_cache
- poetry.lock
# Python
- __pycache__
- app.egg-info
- "*.pyc"
- .mypy_cache
- .coverage
- htmlcov
- poetry.lock
- .cache
- .venv
# Frontend
# Logs
- logs
- "*.log"
- npm-debug.log*
- yarn-debug.log*
- yarn-error.log*
- pnpm-debug.log*
- lerna-debug.log*
- node_modules
- dist
- dist-ssr
- "*.local"
# Editor directories and files
- .idea
- .DS_Store
- "*.suo"
- "*.ntvs*"
- "*.njsproj"
- "*.sln"
- "*.sw?"

_answers_file: .copier/.copier-answers.yml

_tasks:
- "python .copier/update_dotenv.py"

0 comments on commit 4272619

Please sign in to comment.