Last active
October 17, 2021 13:48
-
-
Save AlcibiadesCleinias/5cc37ba0ebefabdf22e3cbb9c9913c51 to your computer and use it in GitHub Desktop.
Example of a settings.py file with validation & different context {dev, prod, test} | Pydantic settings.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| In order to share and have easy access on to | |
| how a settings.py file should be written. | |
| Advantages: | |
| - in a manner of Django project | |
| - with validation | |
| - with state-of-the-art validation | |
| - even for several context, e.g. dev, prod | |
| Aknowlegment | |
| - https://medium.com/swlh/cool-things-you-can-do-with-pydantic-fc1c948fbde0 | |
| - Check out, e.g. PostgresDSN: https://pydantic-docs.helpmanual.io/usage/settings/ | |
| """ | |
| import os | |
| from typing import Union | |
| import pytest | |
| from pydantic import BaseSettings, HttpUrl, ValidationError, parse_obj_as | |
| from typing_extensions import Literal | |
| class LocalContext(BaseSettings): | |
| env: Literal["local"] | |
| echo_server_url: str | |
| class ProdContext(BaseSettings): | |
| env: Literal["prod"] | |
| external_server_url: HttpUrl | |
| external_server_port: int | |
| Context = Union[LocalContext, ProdContext] | |
| def test_reads_local_context(): | |
| os.environ.clear() | |
| os.environ["ENV"] = "local" | |
| os.environ["ECHO_SERVER_URL"] = "http://localhost" | |
| context = parse_obj_as(Context, {}) | |
| assert context.env == "local" | |
| assert context.echo_server_url == "http://localhost" | |
| assert not hasattr(context, "external_server_url") | |
| assert not hasattr(context, "external_server_port") | |
| def test_reads_prod_context(): | |
| os.environ.clear() | |
| os.environ["ENV"] = "prod" | |
| os.environ["EXTERNAL_SERVER_URL"] = "http://some.echo.serv.er" | |
| os.environ["EXTERNAL_SERVER_PORT"] = "8080" | |
| context = parse_obj_as(Context, {}) | |
| assert context.env == "prod" | |
| assert context.external_server_url == "http://some.echo.serv.er" | |
| assert not hasattr(context, "echo_server_url") | |
| def test_only_given_literals_are_supported(): | |
| os.environ.clear() | |
| os.environ["ENV"] = "staging" | |
| with pytest.raises(ValidationError): | |
| parse_obj_as(Context, {}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment