atlanticwave-sdx / datamodel

Parsing and validation library for AtlanticWave SDX.
https://www.atlanticwave-sdx.net
MIT License
0 stars 1 forks source link

Consider using pydantic #144

Open sajith opened 1 month ago

sajith commented 1 month ago

The models in datamodel are generated by Swagger Editor, using the API definitions in SDX Controller and SDX LC. The parsing and validation code is hand-rolled. A nicer way to do this same thing would be using pydantic.

Consider a simple model, Location, re-written using pydantic:

from pydantic import BaseModel

class Location(BaseModel):
    address: str | None = None
    latitude: float | None = None
    longitude: float | None = None
    iso3166_2_lvl4: str | None = None

We can now do:

>>> loc = Location()
>>> loc.dict()
{'address': None, 'latitude': None, 'longitude': None, 'iso3166_2_lvl4': None}
>>> loc.json()
'{"address":null,"latitude":null,"longitude":null,"iso3166_2_lvl4":null}'
>>> Location.parse_raw('{"address":null,"latitude":null,"longitude":null,"iso3166_2_lvl4":null}')
Location(address=None, latitude=None, longitude=None, iso3166_2_lvl4=None)
>>> Location.parse_obj({'address': None, 'latitude': None, 'longitude': None, 'iso3166_2_lvl4': None})
Location(address=None, latitude=None, longitude=None, iso3166_2_lvl4=None)

And the validation errors have more information:

>>> from pprint import pprint
>>> from pydantic import ValidationError
>>> try:
...     l2 = Location(address=1, latitude="top", longitude="bottom", iso3166_2_lvl4=1)
... except ValidationError as e:
...     pprint(e.errors())
...
[{'input': 1,
  'loc': ('address',),
  'msg': 'Input should be a valid string',
  'type': 'string_type',
  'url': 'https://errors.pydantic.dev/2.8/v/string_type'},
 {'input': 'top',
  'loc': ('latitude',),
  'msg': 'Input should be a valid number, unable to parse string as a number',
  'type': 'float_parsing',
  'url': 'https://errors.pydantic.dev/2.8/v/float_parsing'},
 {'input': 'bottom',
  'loc': ('longitude',),
  'msg': 'Input should be a valid number, unable to parse string as a number',
  'type': 'float_parsing',
  'url': 'https://errors.pydantic.dev/2.8/v/float_parsing'},
 {'input': 1,
  'loc': ('iso3166_2_lvl4',),
  'msg': 'Input should be a valid string',
  'type': 'string_type',
  'url': 'https://errors.pydantic.dev/2.8/v/string_type'}]