Skip to content

Commit 7178538

Browse files
committed
updates settings
1 parent cbf370b commit 7178538

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

packages/service-library/src/servicelib/db_asyncpg_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async def create_async_engine_and_pg_database_ready(
2323
settings: PostgresSettings,
2424
) -> AsyncEngine:
2525
"""
26-
- creates asynio engine
26+
- creates asyncio engine
2727
- waits until db service is up
2828
- waits until db data is migrated (i.e. ready to use)
2929
- returns engine

packages/settings-library/src/settings_library/postgres.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import urllib.parse
21
from functools import cached_property
32
from typing import Any, ClassVar
3+
from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse
44

55
from pydantic import Field, PostgresDsn, SecretStr, validator
66

@@ -69,17 +69,29 @@ def dsn_with_async_sqlalchemy(self) -> str:
6969
port=f"{self.POSTGRES_PORT}",
7070
path=f"/{self.POSTGRES_DB}",
7171
)
72-
return dsn
72+
return self._update_query(dsn)
7373

7474
@cached_property
7575
def dsn_with_query(self) -> str:
7676
"""Some clients do not support queries in the dsn"""
7777
dsn = self.dsn
78+
return self._update_query(dsn)
79+
80+
def _update_query(self, uri: str) -> str:
81+
# SEE https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS
82+
new_params: dict[str, str] = {}
7883
if self.POSTGRES_CLIENT_NAME:
79-
dsn += "?" + urllib.parse.urlencode(
80-
{"application_name": self.POSTGRES_CLIENT_NAME}
81-
)
82-
return dsn
84+
new_params = {
85+
"application_name": self.POSTGRES_CLIENT_NAME,
86+
}
87+
88+
if new_params:
89+
parsed_uri = urlparse(uri)
90+
query = dict(parse_qsl(parsed_uri.query))
91+
query.update(new_params)
92+
updated_query = urlencode(query)
93+
return urlunparse(parsed_uri._replace(query=updated_query))
94+
return uri
8395

8496
class Config(BaseCustomSettings.Config):
8597
schema_extra: ClassVar[dict[str, Any]] = { # type: ignore[misc]

packages/settings-library/tests/test_postgres.py

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
# pylint: disable=unused-variable
44

55

6+
from urllib.parse import parse_qsl, urlparse
7+
68
import pytest
9+
from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict
10+
from pytest_simcore.helpers.typing_env import EnvVarsDict
711
from settings_library.postgres import PostgresSettings
812

913

@@ -12,9 +16,16 @@ def env_file():
1216
return ".env-sample"
1317

1418

15-
def test_cached_property_dsn(mock_environment: dict):
19+
@pytest.fixture
20+
def mock_environment(mock_environment: EnvVarsDict, monkeypatch: pytest.MonkeyPatch):
21+
return mock_environment | setenvs_from_dict(
22+
monkeypatch, {"POSTGRES_CLIENT_NAME": "Some &43 funky name"}
23+
)
1624

17-
settings = PostgresSettings()
25+
26+
def test_cached_property_dsn(mock_environment: EnvVarsDict):
27+
28+
settings = PostgresSettings.create_from_envs()
1829

1930
# all are upper-case
2031
assert all(key == key.upper() for key in settings.dict())
@@ -28,20 +39,31 @@ def test_cached_property_dsn(mock_environment: dict):
2839
assert "dsn" in settings.dict()
2940

3041

31-
def test_dsn_with_query(mock_environment: dict, monkeypatch):
32-
42+
def test_dsn_with_query(mock_environment: EnvVarsDict, monkeypatch: pytest.MonkeyPatch):
3343
settings = PostgresSettings()
3444

35-
assert not settings.POSTGRES_CLIENT_NAME
45+
assert settings.POSTGRES_CLIENT_NAME
3646
assert settings.dsn == "postgresql://foo:secret@localhost:5432/foodb"
37-
38-
# now with app
39-
monkeypatch.setenv("POSTGRES_CLIENT_NAME", "Some &43 funky name")
40-
41-
settings_with_app = PostgresSettings()
42-
43-
assert settings_with_app.POSTGRES_CLIENT_NAME
4447
assert (
45-
settings_with_app.dsn_with_query
48+
settings.dsn_with_query
4649
== "postgresql://foo:secret@localhost:5432/foodb?application_name=Some+%2643+funky+name"
4750
)
51+
52+
with monkeypatch.context() as patch:
53+
patch.delenv("POSTGRES_CLIENT_NAME")
54+
settings = PostgresSettings()
55+
56+
assert not settings.POSTGRES_CLIENT_NAME
57+
assert settings.dsn == settings.dsn_with_query
58+
59+
60+
def test_dsn_with_async_sqlalchemy_has_query(
61+
mock_environment: EnvVarsDict, monkeypatch
62+
):
63+
settings = PostgresSettings()
64+
65+
parsed_url = urlparse(settings.dsn_with_async_sqlalchemy)
66+
query = dict(parse_qsl(parsed_url.query))
67+
68+
assert query
69+
assert query["application_name"] == settings.POSTGRES_CLIENT_NAME

0 commit comments

Comments
 (0)