Skip to content

Commit 53bc146

Browse files
Merge pull request #119 from developmentseed/pgSettingsTypeAndTests
fix pg settings type and add tests
2 parents 6478f8d + 58a4044 commit 53bc146

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ Note: Minor version `0.X.0` update might break the API, It's recommended to pin
1212

1313
- forward `catalog_dependency` in `OGCFeaturesFactory` and `OGCTilesFactory` when using `Endpoints` factory
1414
- allow Factory's prefix with path parameter
15+
- changed `database_url` type in `PostgresSettings` to always be of `pydantic.PostgresDsn` type
16+
- `postgres_port` type in `PostgresSettings` to be of `integer` type
17+
- remove additional `/` prefix for dbname when constructing the database url from individual parameters
1518

1619
### changed
1720

tests/test_settings.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""test tipg settings classes."""
2+
3+
import pytest
4+
from pydantic import ValidationError
5+
6+
from tipg.settings import PostgresSettings
7+
8+
9+
def test_pg_settings(monkeypatch):
10+
"""test PostgresSettings class."""
11+
# Makes sure we don't have any pg env set
12+
monkeypatch.delenv("DATABASE_URL", raising=False)
13+
monkeypatch.delenv("POSTGRES_USER", raising=False)
14+
monkeypatch.delenv("POSTGRES_PASS", raising=False)
15+
monkeypatch.delenv("POSTGRES_HOST", raising=False)
16+
monkeypatch.delenv("POSTGRES_PORT", raising=False)
17+
monkeypatch.delenv("POSTGRES_DBNAME", raising=False)
18+
19+
# Should raises a validation error if no env or parameters is passed
20+
with pytest.raises(ValidationError):
21+
# we use `_env_file=None` to make sure pydantic do not use any `.env` files in local environment
22+
PostgresSettings(_env_file=None)
23+
24+
settings = PostgresSettings(
25+
postgres_user="user",
26+
postgres_pass="secret",
27+
postgres_host="0.0.0.0",
28+
postgres_port=8888,
29+
postgres_dbname="db",
30+
_env_file=None,
31+
)
32+
assert str(settings.database_url) == "postgresql://user:[email protected]:8888/db"
33+
34+
# Make sure pydantic will cast the port to integer
35+
settings = PostgresSettings(
36+
postgres_user="user",
37+
postgres_pass="secret",
38+
postgres_host="0.0.0.0",
39+
postgres_port="8888",
40+
postgres_dbname="db",
41+
_env_file=None,
42+
)
43+
assert str(settings.database_url) == "postgresql://user:[email protected]:8888/db"
44+
assert settings.postgres_port == 8888
45+
46+
settings = PostgresSettings(
47+
database_url="postgresql://user:[email protected]:8888/db", _env_file=None
48+
)
49+
assert str(settings.database_url) == "postgresql://user:[email protected]:8888/db"
50+
assert not settings.postgres_port

tipg/settings.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""tipg config."""
22

33
import pathlib
4-
from typing import Any, Dict, List, Optional
4+
from typing import Dict, List, Optional
55

66
from pydantic import (
77
DirectoryPath,
@@ -117,7 +117,7 @@ class PostgresSettings(BaseSettings):
117117
postgres_user: Optional[str] = None
118118
postgres_pass: Optional[str] = None
119119
postgres_host: Optional[str] = None
120-
postgres_port: Optional[str] = None
120+
postgres_port: Optional[int] = None
121121
postgres_dbname: Optional[str] = None
122122

123123
database_url: Optional[PostgresDsn] = None
@@ -131,18 +131,20 @@ class PostgresSettings(BaseSettings):
131131

132132
# https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/core/config.py#L42
133133
@field_validator("database_url", mode="before")
134-
def assemble_db_connection(cls, v: Optional[str], info: FieldValidationInfo) -> Any:
134+
def assemble_db_connection(
135+
cls, v: Optional[str], info: FieldValidationInfo
136+
) -> PostgresDsn:
135137
"""Validate db url settings."""
136138
if isinstance(v, str):
137-
return v
139+
return PostgresDsn(v)
138140

139141
return PostgresDsn.build(
140142
scheme="postgresql",
141143
username=info.data.get("postgres_user"),
142144
password=info.data.get("postgres_pass"),
143145
host=info.data.get("postgres_host", ""),
144146
port=info.data.get("postgres_port", 5432),
145-
path=f"/{info.data.get('postgres_dbname') or ''}",
147+
path=info.data.get("postgres_dbname", ""),
146148
)
147149

148150

0 commit comments

Comments
 (0)