Skip to content

Instantly share code, notes, and snippets.

@gidgid
Last active November 14, 2020 18:32
Show Gist options
  • Select an option

  • Save gidgid/06f3138d497c34679e43a997006b6459 to your computer and use it in GitHub Desktop.

Select an option

Save gidgid/06f3138d497c34679e43a997006b6459 to your computer and use it in GitHub Desktop.
A slightly more concise way to read envs with literal types
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): # 1
env: Literal["local"] # 1
echo_server_url: str
class ProdContext(BaseSettings): # 1
env: Literal["prod"] # 1
external_server_url: HttpUrl
external_server_port: int
Context = Union[LocalContext, ProdContext] # 2
def test_reads_local_context():
os.environ.clear()
os.environ["ENV"] = "local" # 4
os.environ["ECHO_SERVER_URL"] = "http://localhost"
context = parse_obj_as(Context, {}) # 3
assert context.env == "local" # 4
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" # 5
os.environ["EXTERNAL_SERVER_URL"] = "http://some.echo.serv.er"
os.environ["EXTERNAL_SERVER_PORT"] = "8080"
context = parse_obj_as(Context, {}) # 3
assert context.env == "prod" # 5
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): # 6
parse_obj_as(Context, {}) # 6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment