From 1d2a945aa12f1447a57a8b5dabde445226636495 Mon Sep 17 00:00:00 2001 From: Colin Maudry Date: Wed, 24 Jun 2026 17:00:34 +0200 Subject: [PATCH] =?UTF-8?q?feat(backup):=20config=20et=20d=C3=A9pendances?= =?UTF-8?q?=20pour=20la=20sauvegarde=20S3=20(#89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 3 +++ src/backup/__init__.py | 0 src/backup/config.py | 26 +++++++++++++++++++++++++ tests/backup/__init__.py | 0 tests/backup/test_config.py | 39 +++++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+) create mode 100644 src/backup/__init__.py create mode 100644 src/backup/config.py create mode 100644 tests/backup/__init__.py create mode 100644 tests/backup/test_config.py diff --git a/pyproject.toml b/pyproject.toml index cf4e569..b407ad8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,8 @@ dependencies = [ "flask-cors>=6.0.2", "flask-smorest>=0.46.0", "marshmallow>=3.20.0", + "boto3", + "cryptography", ] [dependency-groups] @@ -40,6 +42,7 @@ dev = [ "dash[testing]", "fastexcel", "openpyxl", + "moto[s3]", ] [tool.pytest.ini_options] diff --git a/src/backup/__init__.py b/src/backup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/backup/config.py b/src/backup/config.py new file mode 100644 index 0000000..bffcce5 --- /dev/null +++ b/src/backup/config.py @@ -0,0 +1,26 @@ +from collections.abc import Mapping +from dataclasses import dataclass +from pathlib import Path + + +@dataclass(frozen=True) +class BackupConfig: + db_path: Path + bucket: str + prefix: str + endpoint_url: str | None + access_key: str + secret_key: str + encryption_key: str + + +def load_config(env: Mapping[str, str]) -> BackupConfig: + return BackupConfig( + db_path=Path(env["USERS_DB_PATH"]), + bucket=env["S3_BUCKET"], + prefix=env.get("S3_BACKUP_PREFIX", "backups"), + endpoint_url=env.get("S3_ENDPOINT_URL") or None, + access_key=env["S3_ACCESS_KEY_ID"], + secret_key=env["S3_SECRET_ACCESS_KEY"], + encryption_key=env["BACKUP_ENCRYPTION_KEY"], + ) diff --git a/tests/backup/__init__.py b/tests/backup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/backup/test_config.py b/tests/backup/test_config.py new file mode 100644 index 0000000..dccb72f --- /dev/null +++ b/tests/backup/test_config.py @@ -0,0 +1,39 @@ +from pathlib import Path + +from src.backup.config import BackupConfig, load_config + + +def test_load_config_reads_env(): + env = { + "USERS_DB_PATH": "users.sqlite", + "S3_BUCKET": "decp-backups", + "S3_BACKUP_PREFIX": "backups", + "S3_ENDPOINT_URL": "https://s3.example.net", + "S3_ACCESS_KEY_ID": "AK", + "S3_SECRET_ACCESS_KEY": "SK", + "BACKUP_ENCRYPTION_KEY": "key123", + } + cfg = load_config(env) + assert cfg == BackupConfig( + db_path=Path("users.sqlite"), + bucket="decp-backups", + prefix="backups", + endpoint_url="https://s3.example.net", + access_key="AK", + secret_key="SK", + encryption_key="key123", + ) + + +def test_load_config_defaults_prefix_and_empty_endpoint(): + env = { + "USERS_DB_PATH": "users.sqlite", + "S3_BUCKET": "b", + "S3_ENDPOINT_URL": "", + "S3_ACCESS_KEY_ID": "AK", + "S3_SECRET_ACCESS_KEY": "SK", + "BACKUP_ENCRYPTION_KEY": "k", + } + cfg = load_config(env) + assert cfg.prefix == "backups" + assert cfg.endpoint_url is None