diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..537cc4c --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +# Copy this file to .env and fill in SECRET_KEY. +# Generate one with: +# python -c "import secrets; print(secrets.token_urlsafe(50))" +SECRET_KEY= + +# Optional overrides (defaults shown): +# DEBUG=True +# ALLOWED_HOSTS=* +# CSRF_TRUSTED_ORIGINS=http://* diff --git a/CLAUDE.md b/CLAUDE.md index 15463e7..34b3723 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,6 +13,7 @@ A Django-based cloud translation management system. Manages translation projects Local dev uses SQLite by default — no database setup needed. ```bash +cp .env.example .env # then fill in SECRET_KEY uv sync # or: pip install --group dev python manage.py migrate python manage.py runserver 0.0.0.0:8080 diff --git a/kaplancloud/settings.py b/kaplancloud/settings.py index 968f43e..1647106 100644 --- a/kaplancloud/settings.py +++ b/kaplancloud/settings.py @@ -5,9 +5,13 @@ import os from pathlib import Path +from dotenv import load_dotenv + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent +load_dotenv(BASE_DIR / ".env") + # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ diff --git a/pyproject.toml b/pyproject.toml index 5ad3ead..00fa5a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ prod = [ "psycopg2-binary>=2.9,<3.0", "django-tailwind>=4.4,<5.0", "gunicorn>=25.0,<26.0", + "python-dotenv>=1.0,<2.0", ] dev = [ {include-group = "prod"}, diff --git a/uv.lock b/uv.lock index 28126e0..2c1cabc 100644 --- a/uv.lock +++ b/uv.lock @@ -457,6 +457,7 @@ dev = [ { name = "gunicorn" }, { name = "kaplan" }, { name = "psycopg2-binary" }, + { name = "python-dotenv" }, { name = "ruff" }, ] prod = [ @@ -467,6 +468,7 @@ prod = [ { name = "gunicorn" }, { name = "kaplan" }, { name = "psycopg2-binary" }, + { name = "python-dotenv" }, ] [package.metadata] @@ -480,6 +482,7 @@ dev = [ { name = "gunicorn", specifier = ">=25.0,<26.0" }, { name = "kaplan", specifier = ">=0.16,<0.17" }, { name = "psycopg2-binary", specifier = ">=2.9,<3.0" }, + { name = "python-dotenv", specifier = ">=1.0,<2.0" }, { name = "ruff" }, ] prod = [ @@ -490,6 +493,7 @@ prod = [ { name = "gunicorn", specifier = ">=25.0,<26.0" }, { name = "kaplan", specifier = ">=0.16,<0.17" }, { name = "psycopg2-binary", specifier = ">=2.9,<3.0" }, + { name = "python-dotenv", specifier = ">=1.0,<2.0" }, ] [[package]] @@ -700,6 +704,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "python-dotenv" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, +] + [[package]] name = "regex" version = "2026.4.4"