Skip to content

Instantly share code, notes, and snippets.

@piotrgredowski
Last active June 9, 2020 11:36
Show Gist options
  • Save piotrgredowski/7609e6eefa75ae4092043a4abbec637d to your computer and use it in GitHub Desktop.
Save piotrgredowski/7609e6eefa75ae4092043a4abbec637d to your computer and use it in GitHub Desktop.
Example of handling application config using pydantic https://github.com/samuelcolvin/pydantic
# Example of handling application config using pydantic https://github.com/samuelcolvin/pydantic
# Use python>=3.6 and install pydantic==1.3.1 to run it
import unittest
from dataclasses import FrozenInstanceError
from typing import Optional
from pydantic.dataclasses import dataclass
from pydantic import ValidationError
# With `frozen=True` we ensure immutability of data
@dataclass(frozen=True)
class Location:
# Writing types allows us to validate data, also if provided value
# is e.g. int - pydantic tries to cast it to string. If fails - ValidationError is raised
street: str
house_number: int
city: str
postal_code: str
flat_number: Optional[int] = None
@dataclass(frozen=True)
class User:
first_name: str
last_name: str
location: Location
good_cfg_1 = {
"first_name": "John",
"last_name": "Snow",
"location": {
"street": "Frozen St.",
"house_number": 17,
"city": "Winterfell",
"postal_code": "34-567",
},
}
john_snow_1: User = User(**good_cfg_1)
assert john_snow_1.location.postal_code == good_cfg_1["location"]["postal_code"]
assert john_snow_1.location.flat_number is None
good_cfg_2 = {
"first_name": "John",
"last_name": "Snow",
"location": {
"street": "Frozen St.",
"house_number": 17,
"city": "Winterfell",
"flat_number": 15,
"postal_code": 12123,
},
}
john_snow_2 = User(**good_cfg_2)
assert john_snow_2.location.postal_code == str(good_cfg_2["location"]["postal_code"])
assert john_snow_2.location.flat_number == good_cfg_2["location"]["flat_number"]
with unittest.TestCase().assertRaises(FrozenInstanceError):
john_snow_2.last_name = "Targaryen"
with unittest.TestCase().assertRaises(FrozenInstanceError):
john_snow_2.location.flat_number = 16
with unittest.TestCase().assertRaises(ValidationError):
bad_cfg = {**good_cfg_2, **{"location": {"flat_number": "abc"}}}
john_snow_2 = User(**bad_cfg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment