bikes.io.datasets

Read/Write datasets from/to external sources/destinations.

  1"""Read/Write datasets from/to external sources/destinations."""
  2
  3# %% IMPORTS
  4
  5import abc
  6import typing as T
  7
  8import mlflow.data.pandas_dataset as lineage
  9import mlflow.data.sources as sources
 10import pandas as pd
 11import pydantic as pdt
 12
 13# %% TYPINGS
 14
 15Lineage: T.TypeAlias = lineage.PandasDataset
 16
 17# %% READERS
 18
 19
 20class Reader(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"):
 21    """Base class for a dataset reader.
 22
 23    Use a reader to load a dataset in memory.
 24    e.g., to read file, database, cloud storage, ...
 25
 26    Parameters:
 27        limit (int, optional): maximum number of rows to read. Defaults to None.
 28    """
 29
 30    KIND: str
 31
 32    limit: int | None = None
 33
 34    @abc.abstractmethod
 35    def read(self) -> pd.DataFrame:
 36        """Read a dataframe from a dataset.
 37
 38        Returns:
 39            pd.DataFrame: dataframe representation.
 40        """
 41
 42    @abc.abstractmethod
 43    def lineage(
 44        self,
 45        name: str,
 46        data: pd.DataFrame,
 47        targets: str | None = None,
 48        predictions: str | None = None,
 49    ) -> Lineage:
 50        """Generate lineage information.
 51
 52        Args:
 53            name (str): dataset name.
 54            data (pd.DataFrame): reader dataframe.
 55            targets (str | None): name of the target column.
 56            predictions (str | None): name of the prediction column.
 57
 58        Returns:
 59            Lineage: lineage information.
 60        """
 61
 62
 63class ParquetReader(Reader):
 64    """Read a dataframe from a parquet file.
 65
 66    Parameters:
 67        path (str): local path to the dataset.
 68    """
 69
 70    KIND: T.Literal["ParquetReader"] = "ParquetReader"
 71
 72    path: str
 73    backend: T.Literal["pyarrow", "numpy_nullable"] = "pyarrow"
 74
 75    @T.override
 76    def read(self) -> pd.DataFrame:
 77        # can't limit rows at read time
 78        data = pd.read_parquet(self.path, dtype_backend=self.backend)
 79        if self.limit is not None:
 80            data = data.head(self.limit)
 81        return data
 82
 83    @T.override
 84    def lineage(
 85        self,
 86        name: str,
 87        data: pd.DataFrame,
 88        targets: str | None = None,
 89        predictions: str | None = None,
 90    ) -> Lineage:
 91        return lineage.from_pandas(
 92            df=data,
 93            name=name,
 94            # an explicit source: the path string matches two registered local sources,
 95            # and MLflow warns on every lineage while picking one
 96            source=sources.LocalArtifactDatasetSource(self.path),
 97            targets=targets,
 98            predictions=predictions,
 99        )
100
101
102ReaderKind = ParquetReader
103
104# %% WRITERS
105
106
107class Writer(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"):
108    """Base class for a dataset writer.
109
110    Use a writer to save a dataset from memory.
111    e.g., to write file, database, cloud storage, ...
112    """
113
114    KIND: str
115
116    @abc.abstractmethod
117    def write(self, data: pd.DataFrame) -> None:
118        """Write a dataframe to a dataset.
119
120        Args:
121            data (pd.DataFrame): dataframe representation.
122        """
123
124
125class ParquetWriter(Writer):
126    """Writer a dataframe to a parquet file.
127
128    Parameters:
129        path (str): local or S3 path to the dataset.
130    """
131
132    KIND: T.Literal["ParquetWriter"] = "ParquetWriter"
133
134    path: str
135
136    @T.override
137    def write(self, data: pd.DataFrame) -> None:
138        pd.DataFrame.to_parquet(data, self.path)
139
140
141WriterKind = ParquetWriter
Lineage: TypeAlias = mlflow.data.pandas_dataset.PandasDataset
class Reader(abc.ABC, pydantic.main.BaseModel):
21class Reader(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"):
22    """Base class for a dataset reader.
23
24    Use a reader to load a dataset in memory.
25    e.g., to read file, database, cloud storage, ...
26
27    Parameters:
28        limit (int, optional): maximum number of rows to read. Defaults to None.
29    """
30
31    KIND: str
32
33    limit: int | None = None
34
35    @abc.abstractmethod
36    def read(self) -> pd.DataFrame:
37        """Read a dataframe from a dataset.
38
39        Returns:
40            pd.DataFrame: dataframe representation.
41        """
42
43    @abc.abstractmethod
44    def lineage(
45        self,
46        name: str,
47        data: pd.DataFrame,
48        targets: str | None = None,
49        predictions: str | None = None,
50    ) -> Lineage:
51        """Generate lineage information.
52
53        Args:
54            name (str): dataset name.
55            data (pd.DataFrame): reader dataframe.
56            targets (str | None): name of the target column.
57            predictions (str | None): name of the prediction column.
58
59        Returns:
60            Lineage: lineage information.
61        """

Base class for a dataset reader.

Use a reader to load a dataset in memory. e.g., to read file, database, cloud storage, ...

Arguments:
  • limit (int, optional): maximum number of rows to read. Defaults to None.
KIND: str = PydanticUndefined
limit: int | None = None
@abc.abstractmethod
def read(self) -> pandas.DataFrame:
35    @abc.abstractmethod
36    def read(self) -> pd.DataFrame:
37        """Read a dataframe from a dataset.
38
39        Returns:
40            pd.DataFrame: dataframe representation.
41        """

Read a dataframe from a dataset.

Returns:

pd.DataFrame: dataframe representation.

@abc.abstractmethod
def lineage( self, name: str, data: pandas.DataFrame, targets: str | None = None, predictions: str | None = None) -> mlflow.data.pandas_dataset.PandasDataset:
43    @abc.abstractmethod
44    def lineage(
45        self,
46        name: str,
47        data: pd.DataFrame,
48        targets: str | None = None,
49        predictions: str | None = None,
50    ) -> Lineage:
51        """Generate lineage information.
52
53        Args:
54            name (str): dataset name.
55            data (pd.DataFrame): reader dataframe.
56            targets (str | None): name of the target column.
57            predictions (str | None): name of the prediction column.
58
59        Returns:
60            Lineage: lineage information.
61        """

Generate lineage information.

Arguments:
  • name (str): dataset name.
  • data (pd.DataFrame): reader dataframe.
  • targets (str | None): name of the target column.
  • predictions (str | None): name of the prediction column.
Returns:

Lineage: lineage information.

class ParquetReader(Reader):
 64class ParquetReader(Reader):
 65    """Read a dataframe from a parquet file.
 66
 67    Parameters:
 68        path (str): local path to the dataset.
 69    """
 70
 71    KIND: T.Literal["ParquetReader"] = "ParquetReader"
 72
 73    path: str
 74    backend: T.Literal["pyarrow", "numpy_nullable"] = "pyarrow"
 75
 76    @T.override
 77    def read(self) -> pd.DataFrame:
 78        # can't limit rows at read time
 79        data = pd.read_parquet(self.path, dtype_backend=self.backend)
 80        if self.limit is not None:
 81            data = data.head(self.limit)
 82        return data
 83
 84    @T.override
 85    def lineage(
 86        self,
 87        name: str,
 88        data: pd.DataFrame,
 89        targets: str | None = None,
 90        predictions: str | None = None,
 91    ) -> Lineage:
 92        return lineage.from_pandas(
 93            df=data,
 94            name=name,
 95            # an explicit source: the path string matches two registered local sources,
 96            # and MLflow warns on every lineage while picking one
 97            source=sources.LocalArtifactDatasetSource(self.path),
 98            targets=targets,
 99            predictions=predictions,
100        )

Read a dataframe from a parquet file.

Arguments:
  • path (str): local path to the dataset.
KIND: Literal['ParquetReader'] = 'ParquetReader'
path: str = PydanticUndefined
backend: Literal['pyarrow', 'numpy_nullable'] = 'pyarrow'
@T.override
def read(self) -> pandas.DataFrame:
76    @T.override
77    def read(self) -> pd.DataFrame:
78        # can't limit rows at read time
79        data = pd.read_parquet(self.path, dtype_backend=self.backend)
80        if self.limit is not None:
81            data = data.head(self.limit)
82        return data

Read a dataframe from a dataset.

Returns:

pd.DataFrame: dataframe representation.

@T.override
def lineage( self, name: str, data: pandas.DataFrame, targets: str | None = None, predictions: str | None = None) -> mlflow.data.pandas_dataset.PandasDataset:
 84    @T.override
 85    def lineage(
 86        self,
 87        name: str,
 88        data: pd.DataFrame,
 89        targets: str | None = None,
 90        predictions: str | None = None,
 91    ) -> Lineage:
 92        return lineage.from_pandas(
 93            df=data,
 94            name=name,
 95            # an explicit source: the path string matches two registered local sources,
 96            # and MLflow warns on every lineage while picking one
 97            source=sources.LocalArtifactDatasetSource(self.path),
 98            targets=targets,
 99            predictions=predictions,
100        )

Generate lineage information.

Arguments:
  • name (str): dataset name.
  • data (pd.DataFrame): reader dataframe.
  • targets (str | None): name of the target column.
  • predictions (str | None): name of the prediction column.
Returns:

Lineage: lineage information.

Inherited Members
Reader
limit
ReaderKind = <class 'ParquetReader'>
class Writer(abc.ABC, pydantic.main.BaseModel):
108class Writer(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"):
109    """Base class for a dataset writer.
110
111    Use a writer to save a dataset from memory.
112    e.g., to write file, database, cloud storage, ...
113    """
114
115    KIND: str
116
117    @abc.abstractmethod
118    def write(self, data: pd.DataFrame) -> None:
119        """Write a dataframe to a dataset.
120
121        Args:
122            data (pd.DataFrame): dataframe representation.
123        """

Base class for a dataset writer.

Use a writer to save a dataset from memory. e.g., to write file, database, cloud storage, ...

KIND: str = PydanticUndefined
@abc.abstractmethod
def write(self, data: pandas.DataFrame) -> None:
117    @abc.abstractmethod
118    def write(self, data: pd.DataFrame) -> None:
119        """Write a dataframe to a dataset.
120
121        Args:
122            data (pd.DataFrame): dataframe representation.
123        """

Write a dataframe to a dataset.

Arguments:
  • data (pd.DataFrame): dataframe representation.
class ParquetWriter(Writer):
126class ParquetWriter(Writer):
127    """Writer a dataframe to a parquet file.
128
129    Parameters:
130        path (str): local or S3 path to the dataset.
131    """
132
133    KIND: T.Literal["ParquetWriter"] = "ParquetWriter"
134
135    path: str
136
137    @T.override
138    def write(self, data: pd.DataFrame) -> None:
139        pd.DataFrame.to_parquet(data, self.path)

Writer a dataframe to a parquet file.

Arguments:
  • path (str): local or S3 path to the dataset.
KIND: Literal['ParquetWriter'] = 'ParquetWriter'
path: str = PydanticUndefined
@T.override
def write(self, data: pandas.DataFrame) -> None:
137    @T.override
138    def write(self, data: pd.DataFrame) -> None:
139        pd.DataFrame.to_parquet(data, self.path)

Write a dataframe to a dataset.

Arguments:
  • data (pd.DataFrame): dataframe representation.
WriterKind = <class 'ParquetWriter'>