From 2ea515ca7ccca1da68ad4f55664c96f71080f390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20L=C3=B3pez=20Dato?= Date: Wed, 12 Mar 2025 15:35:43 -0300 Subject: [PATCH 1/3] Accept numbered replica db URLs --- api/app/settings/common.py | 25 ++++++++++++++++------- api/app/utils.py | 17 +++++++++++++++ api/tests/unit/app/test_unit_app_utils.py | 15 +++++++++++++- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/api/app/settings/common.py b/api/app/settings/common.py index 42f7817f6338..822fa8364b49 100644 --- a/api/app/settings/common.py +++ b/api/app/settings/common.py @@ -24,9 +24,10 @@ from django.core.exceptions import ImproperlyConfigured from django.core.management.utils import get_random_secret_key from environs import Env -from task_processor.task_run_method import TaskRunMethod # type: ignore[import-untyped] from app.routers import ReplicaReadStrategy +from app.utils import get_numbered_env_vars_with_prefix +from task_processor.task_run_method import TaskRunMethod # type: ignore[import-untyped] env = Env() @@ -176,8 +177,14 @@ ), } REPLICA_DATABASE_URLS_DELIMITER = env("REPLICA_DATABASE_URLS_DELIMITER", ",") - REPLICA_DATABASE_URLS = env.list( - "REPLICA_DATABASE_URLS", default=[], delimiter=REPLICA_DATABASE_URLS_DELIMITER + REPLICA_DATABASE_URLS = ( + env.list( + "REPLICA_DATABASE_URLS", + default=[], + delimiter=REPLICA_DATABASE_URLS_DELIMITER, + ) + if not os.getenv("REPLICA_DATABASE_URL_0") + else get_numbered_env_vars_with_prefix("REPLICA_DATABASE_URL_") ) NUM_DB_REPLICAS = len(REPLICA_DATABASE_URLS) @@ -186,10 +193,14 @@ CROSS_REGION_REPLICA_DATABASE_URLS_DELIMITER = env( "CROSS_REGION_REPLICA_DATABASE_URLS_DELIMITER", "," ) - CROSS_REGION_REPLICA_DATABASE_URLS = env.list( - "CROSS_REGION_REPLICA_DATABASE_URLS", - default=[], - delimiter=CROSS_REGION_REPLICA_DATABASE_URLS_DELIMITER, + CROSS_REGION_REPLICA_DATABASE_URLS = ( + env.list( + "CROSS_REGION_REPLICA_DATABASE_URLS", + default=[], + delimiter=CROSS_REGION_REPLICA_DATABASE_URLS_DELIMITER, + ) + if not os.getenv("CROSS_REGION_REPLICA_DATABASE_URL_0") + else get_numbered_env_vars_with_prefix("CROSS_REGION_REPLICA_DATABASE_URL_") ) NUM_CROSS_REGION_DB_REPLICAS = len(CROSS_REGION_REPLICA_DATABASE_URLS) diff --git a/api/app/utils.py b/api/app/utils.py index 3a1d9e405a50..ccd29d71e8c0 100644 --- a/api/app/utils.py +++ b/api/app/utils.py @@ -1,4 +1,5 @@ import json +import os import pathlib from functools import lru_cache from typing import TypedDict @@ -73,3 +74,19 @@ def _get_file_contents(file_path: str) -> str: return f.read().replace("\n", "") except FileNotFoundError: return UNKNOWN + + +def get_numbered_env_vars_with_prefix(prefix: str) -> list[str]: + """ + Returns a list containing the values of all environment variables whose names have a given prefix followed by an + integer, starting from 0, until no more variables with that prefix are found. + """ + db_urls = [] + i = 0 + while True: + db_url = os.getenv(f"{prefix}{i}") + if not db_url: + break + db_urls.append(db_url) + i += 1 + return db_urls diff --git a/api/tests/unit/app/test_unit_app_utils.py b/api/tests/unit/app/test_unit_app_utils.py index 46eca015bf47..0512f3c49a9d 100644 --- a/api/tests/unit/app/test_unit_app_utils.py +++ b/api/tests/unit/app/test_unit_app_utils.py @@ -4,7 +4,7 @@ from pyfakefs.fake_filesystem import FakeFilesystem from pytest_django.fixtures import SettingsWrapper -from app.utils import get_version_info +from app.utils import get_numbered_env_vars_with_prefix, get_version_info def test_get_version_info(fs: FakeFilesystem) -> None: @@ -97,3 +97,16 @@ def test_get_version_info__email_config_disabled__return_expected( # Then assert result["has_email_provider"] is False + + +def test_get_numbered_env_vars_with_prefix(monkeypatch: pytest.MonkeyPatch) -> None: + # Given + monkeypatch.setenv("DB_URL_0", "0") + monkeypatch.setenv("DB_URL_1", "1") + monkeypatch.setenv("DB_URL_3", "3") + + # When + env_vars = get_numbered_env_vars_with_prefix("DB_URL_") + + # Then + assert env_vars == ["0", "1"] From 550686058cbfbe2c6d7025052cededa22b7ff113 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:47:11 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- api/app/settings/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/app/settings/common.py b/api/app/settings/common.py index 822fa8364b49..7b030915cb74 100644 --- a/api/app/settings/common.py +++ b/api/app/settings/common.py @@ -24,10 +24,10 @@ from django.core.exceptions import ImproperlyConfigured from django.core.management.utils import get_random_secret_key from environs import Env +from task_processor.task_run_method import TaskRunMethod # type: ignore[import-untyped] from app.routers import ReplicaReadStrategy from app.utils import get_numbered_env_vars_with_prefix -from task_processor.task_run_method import TaskRunMethod # type: ignore[import-untyped] env = Env() From d098102bb75e93072ed0ad3653e6b3b0d2fcf448 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 23:43:16 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- api/app/settings/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/app/settings/common.py b/api/app/settings/common.py index 509192971fda..cb84d5f2627b 100644 --- a/api/app/settings/common.py +++ b/api/app/settings/common.py @@ -25,10 +25,10 @@ from django.core.exceptions import ImproperlyConfigured from django.core.management.utils import get_random_secret_key from environs import Env +from task_processor.task_run_method import TaskRunMethod # type: ignore[import-untyped] from app.routers import ReplicaReadStrategy from app.utils import get_numbered_env_vars_with_prefix -from task_processor.task_run_method import TaskRunMethod # type: ignore[import-untyped] env = Env()