From 12ca1e4a704c7d071c258bc4f17cb0da176d7fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 20:57:08 +0100 Subject: [PATCH 1/9] =?UTF-8?q?=F0=9F=94=A7=20Add=20first=20Copier=20confi?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/copier.yml | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/copier.yml diff --git a/src/copier.yml b/src/copier.yml new file mode 100644 index 0000000000..07e8d8a253 --- /dev/null +++ b/src/copier.yml @@ -0,0 +1,122 @@ +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: admin@example.com + +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: info@example.com + +smtp_port: + type: int + help: The SMTP server port to send emails, you can set it later in .env + default: 587 + +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: admin@example.com + +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?" + +_tasks: + - "python scripts/update_dotenv.py" From 654fa2d5f8a298902e6c95335fc8620249f20516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 20:57:31 +0100 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=94=A7=20Add=20custom=20copier=20answ?= =?UTF-8?q?ers=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{{_copier_conf.answers_file}}.jinja | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/{{_copier_conf.answers_file}}.jinja diff --git a/src/{{_copier_conf.answers_file}}.jinja b/src/{{_copier_conf.answers_file}}.jinja new file mode 100644 index 0000000000..0028a2398a --- /dev/null +++ b/src/{{_copier_conf.answers_file}}.jinja @@ -0,0 +1 @@ +{{ _copier_answers|to_json -}} From a49367eb9dc755e887aec5aaa35cb3bfb4419bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 20:58:41 +0100 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=94=A8=20Add=20Copier=20script=20to?= =?UTF-8?q?=20update=20.env=20after=20generating/copying?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scripts/update_dotenv.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/scripts/update_dotenv.py diff --git a/src/scripts/update_dotenv.py b/src/scripts/update_dotenv.py new file mode 100644 index 0000000000..fc717ab0a6 --- /dev/null +++ b/src/scripts/update_dotenv.py @@ -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 = root_path / ".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)) From f5261c887829254570681688fbc00b52027c3005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 20:59:25 +0100 Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=99=88=20Update=20.gitignores=20from?= =?UTF-8?q?=20Copier=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 -- src/backend/.gitignore | 3 +++ src/backend/app/tests/.gitignore | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100755 src/backend/app/tests/.gitignore diff --git a/.gitignore b/.gitignore index be16fd8a57..722d5e71d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ .vscode -.mypy_cache -poetry.lock diff --git a/src/backend/.gitignore b/src/backend/.gitignore index 8078a84461..9660d71665 100644 --- a/src/backend/.gitignore +++ b/src/backend/.gitignore @@ -4,3 +4,6 @@ app.egg-info .mypy_cache .coverage htmlcov +poetry.lock +.cache +.venv diff --git a/src/backend/app/tests/.gitignore b/src/backend/app/tests/.gitignore deleted file mode 100755 index 16d3c4dbbf..0000000000 --- a/src/backend/app/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.cache From f8057aee7936204219de52b136f9043892a17b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 20:59:55 +0100 Subject: [PATCH 5/9] =?UTF-8?q?=F0=9F=94=A7=20Update=20.env,=20restructure?= =?UTF-8?q?=20in=20order=20of=20relevance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/.env | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/.env b/src/.env index 78bf4c65cd..2cf8e643e9 100644 --- a/src/.env +++ b/src/.env @@ -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=admin@example.com FIRST_SUPERUSER_PASSWORD=changethis -SMTP_TLS=True -SMTP_PORT=587 SMTP_HOST= SMTP_USER= SMTP_PASSWORD= EMAILS_FROM_EMAIL=info@example.com +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=admin@example.com 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 From d7dc676d0662d6b46ca43caf05987ff7f90a2d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 21:01:10 +0100 Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=94=A7=20Remove=20Copier=20config=20f?= =?UTF-8?q?or=20SMTP=20port,=20if=20necessary,=20it=20can=20be=20overwritt?= =?UTF-8?q?en=20in=20.env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/copier.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/copier.yml b/src/copier.yml index 07e8d8a253..8ca8167f6a 100644 --- a/src/copier.yml +++ b/src/copier.yml @@ -53,11 +53,6 @@ emails_from_email: help: The email account to send emails from, you can set it later in .env default: info@example.com -smtp_port: - type: int - help: The SMTP server port to send emails, you can set it later in .env - default: 587 - postgres_password: type: str help: | From b3e430d7011d72a66ed32d51a3db1f4ce301ca92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 21:06:51 +0100 Subject: [PATCH 7/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20Copier=20fi?= =?UTF-8?q?les,=20make=20them=20less=20visible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.copier-answers.yml.jinja} | 0 src/{scripts => .copier}/update_dotenv.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{{{_copier_conf.answers_file}}.jinja => .copier/.copier-answers.yml.jinja} (100%) rename src/{scripts => .copier}/update_dotenv.py (92%) diff --git a/src/{{_copier_conf.answers_file}}.jinja b/src/.copier/.copier-answers.yml.jinja similarity index 100% rename from src/{{_copier_conf.answers_file}}.jinja rename to src/.copier/.copier-answers.yml.jinja diff --git a/src/scripts/update_dotenv.py b/src/.copier/update_dotenv.py similarity index 92% rename from src/scripts/update_dotenv.py rename to src/.copier/update_dotenv.py index fc717ab0a6..1eab4c8ffe 100644 --- a/src/scripts/update_dotenv.py +++ b/src/.copier/update_dotenv.py @@ -5,7 +5,7 @@ # 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 = root_path / ".copier-answers.yml" +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() From d6de64aac1450ed52e87980b861d4ed3174db7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 21:08:01 +0100 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=94=A7=20Update=20Copier=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/copier.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/copier.yml b/src/copier.yml index 8ca8167f6a..743b5ff523 100644 --- a/src/copier.yml +++ b/src/copier.yml @@ -113,5 +113,7 @@ _exclude: - "*.sln" - "*.sw?" +_answers_file: .copier/.copier-answers.yml + _tasks: - - "python scripts/update_dotenv.py" + - "python .copier/update_dotenv.py" From 339cf6fb5e62fb42be4fd9334693e9880f6b6eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 25 Feb 2024 21:13:09 +0100 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=94=A5=20Remove=20Cookiecutter=20file?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cookiecutter.json | 44 -------------------------------- src/cookiecutter-config-file.yml | 30 ---------------------- 2 files changed, 74 deletions(-) delete mode 100644 cookiecutter.json delete mode 100644 src/cookiecutter-config-file.yml diff --git a/cookiecutter.json b/cookiecutter.json deleted file mode 100644 index fc0e6fab00..0000000000 --- a/cookiecutter.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "project_name": "Base Project", - "project_slug": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}", - "domain_main": "{{cookiecutter.project_slug}}.com", - "domain_staging": "stag.{{cookiecutter.domain_main}}", - - "docker_swarm_stack_name_main": "{{cookiecutter.domain_main|replace('.', '-')}}", - "docker_swarm_stack_name_staging": "{{cookiecutter.domain_staging|replace('.', '-')}}", - - "secret_key": "changethis", - "first_superuser": "admin@{{cookiecutter.domain_main}}", - "first_superuser_password": "changethis", - "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://dev.{{cookiecutter.domain_main}}\", \"https://{{cookiecutter.domain_staging}}\", \"https://{{cookiecutter.domain_main}}\", \"http://local.dockertoolbox.tiangolo.com\", \"http://localhost.tiangolo.com\"]", - "smtp_port": "587", - "smtp_host": "", - "smtp_user": "", - "smtp_password": "", - "smtp_emails_from_email": "info@{{cookiecutter.domain_main}}", - - "postgres_password": "changethis", - "pgadmin_default_user": "{{cookiecutter.first_superuser}}", - "pgadmin_default_user_password": "{{cookiecutter.first_superuser_password}}", - - "traefik_constraint_tag": "{{cookiecutter.domain_main}}", - "traefik_constraint_tag_staging": "{{cookiecutter.domain_staging}}", - "traefik_public_constraint_tag": "traefik-public", - - "flower_auth": "admin:{{cookiecutter.first_superuser_password}}", - - "sentry_dsn": "", - - "docker_image_prefix": "", - - "docker_image_backend": "{{cookiecutter.docker_image_prefix}}backend", - "docker_image_celeryworker": "{{cookiecutter.docker_image_prefix}}celeryworker", - "docker_image_frontend": "{{cookiecutter.docker_image_prefix}}frontend", - - "_copy_without_render": [ - "frontend/src/**/*.html", - "frontend/src/**/*.vue", - "frontend/node_modules/*", - "backend/app/app/email-templates/**" - ] -} diff --git a/src/cookiecutter-config-file.yml b/src/cookiecutter-config-file.yml deleted file mode 100644 index b0e7dd2f77..0000000000 --- a/src/cookiecutter-config-file.yml +++ /dev/null @@ -1,30 +0,0 @@ -default_context: - project_name: '{{ cookiecutter.project_name }}' - project_slug: '{{ cookiecutter.project_slug }}' - domain_main: '{{ cookiecutter.domain_main }}' - domain_staging: '{{ cookiecutter.domain_staging }}' - docker_swarm_stack_name_main: '{{ cookiecutter.docker_swarm_stack_name_main }}' - docker_swarm_stack_name_staging: '{{ cookiecutter.docker_swarm_stack_name_staging }}' - secret_key: '{{ cookiecutter.secret_key }}' - first_superuser: '{{ cookiecutter.first_superuser }}' - first_superuser_password: '{{ cookiecutter.first_superuser_password }}' - backend_cors_origins: '{{ cookiecutter.backend_cors_origins }}' - smtp_port: '{{ cookiecutter.smtp_port }}' - smtp_host: '{{ cookiecutter.smtp_host }}' - smtp_user: '{{ cookiecutter.smtp_user }}' - smtp_password: '{{ cookiecutter.smtp_password }}' - smtp_emails_from_email: '{{ cookiecutter.smtp_emails_from_email }}' - postgres_password: '{{ cookiecutter.postgres_password }}' - pgadmin_default_user: '{{ cookiecutter.pgadmin_default_user }}' - pgadmin_default_user_password: '{{ cookiecutter.pgadmin_default_user_password }}' - traefik_constraint_tag: '{{ cookiecutter.traefik_constraint_tag }}' - traefik_constraint_tag_staging: '{{ cookiecutter.traefik_constraint_tag_staging }}' - traefik_public_constraint_tag: '{{ cookiecutter.traefik_public_constraint_tag }}' - flower_auth: '{{ cookiecutter.flower_auth }}' - sentry_dsn: '{{ cookiecutter.sentry_dsn }}' - docker_image_prefix: '{{ cookiecutter.docker_image_prefix }}' - docker_image_backend: '{{ cookiecutter.docker_image_backend }}' - docker_image_celeryworker: '{{ cookiecutter.docker_image_celeryworker }}' - docker_image_frontend: '{{ cookiecutter.docker_image_frontend }}' - _copy_without_render: [frontend/src/**/*.html, frontend/src/**/*.vue, frontend/node_modules/*, backend/app/app/email-templates/**] - _template: ./