convert to pydantic model from tuple

Viewed 2424

I want to map a tuple(list) to a pydantic model.

Is there a best practice to map tuple indexes to attributes in the following cases?

from pydantic import BaseModel

class Ohlc(BaseModel):
    close_time: float
    open_time: float
    high_price: float
    low_price: float
    close_price: float
    volume: float
    quote_volume: float

data = [
  1495324800,
  232660,
  242460,
  231962,
  242460,
  231.863,
  0
]
2 Answers

Assuming that data's length is always equal to the number of fields in your model, you can use __fields__ to achieve that.

Ohlc(**{key: data[i] for i, key in enumerate(Ohlc.__fields__.keys())})

(There used to be fields which required you to use construct() first but now it is deprecated and now they tell you to use __fields__ instead).

I faced a simular problem and realized it can be solved using named tuples and pydantic. Modified solution below

from pydantic import BaseModel
import typing as t

data = [
  1495324800,
  232660,
  242460,
  231962,
  242460,
  231.863,
  0
]

class OhlcEntry(t.NamedTuple):
    close_time: float
    open_time: float
    high_price: float
    low_price: float
    close_price: float
    volume: float
    quote_volume: float

class Ohlc(BaseModel):
    data: OhlcEntry
    

Ohlc(data=data)

If you work with lists of mixed types, then the same approach can be extended to parse the data in the list:

from pydantic import BaseModel
import datetime as dt
import typing as t

js_data= """[
        [43.88,-32.24,"2021-12-20T00:01:59Z"],
        [43.95,-32.21,"2021-12-20T00:14:46Z"]
]"""

class Point(t.NamedTuple):
    longitude: float
    latitude: float
    ts: dt.datetime

class Track(BaseModel):
    __root__: t.List[Point]

Track.parse_raw(js_data)
Related