Module fontai.io.formats
This module contains classes that deal with encoding/decoding bytestreams from/to the data formats that act as the interface between pipeline stages and storage, and between different ML pipeline stages.
Expand source code
"""This module contains classes that deal with encoding/decoding bytestreams from/to the data formats that act as the interface between pipeline stages and storage, and between different ML pipeline stages.
"""
from __future__ import annotations
import zipfile
import sys
import typing as t
import logging
import io
from abc import ABC, abstractmethod
from pydantic import BaseModel
from numpy import ndarray
import imageio
from PIL import ImageFont
#from tensorflow import string as tf_str
#from tensorflow.train import (Example as TFExample, Feature as TFFeature, Features as TFFeatures, BytesList as TFBytesList)
from tensorflow.io import FixedLenFeature, parse_single_example
from fontai.io.storage import BytestreamPath
logger = logging.getLogger(__name__)
class InMemoryFile(BaseModel):
"""Wrapper class for retrieved file bytestreams
"""
filename: str
content: bytes
def to_format(self, file_format: InMemoryFile) -> InMemoryFile:
"""Cast instance as a different file type inehriting from InMemoryFile
Args:
file_format (InMemoryFile): Target file type
Returns:
InMemoryFile: cast file instance.
"""
return file_format(**self.dict())
def deserialise(self):
"""Parse instance as the corresponding Python object such as a ZipFile or an ImageFont.truetype
"""
return self
@classmethod
def from_file(cls, filepath: str) -> InMemoryFile:
"""Instantiate from file path
Args:
filepath (str): FIle path
Returns:
InMemoryFile: instantiated object
"""
return cls(filename = filepath, content = BytestreamPath(filepath).read_bytes())
@classmethod
def from_bytestream_path(cls, bsp: BytestreamPath) -> InMemoryFile:
"""Instantiate from bytestream path
Returns:
InMemoryFile: instantiated object
"""
return cls(filename = str(bsp), content = bsp.read_bytes())
@classmethod
def serialise(cls, obj: t.Any):
"""Serialises a Python object to an instance of InMemoryFile
Args:
obj (t.Any): Python object
Returns:
InMemoryFile: Description
Raises:
TypeError: If passed object is not an instance of InMemoryFile
"""
if not isinstance(obj, InMemoryFile):
raise TypeError("InMemoryFile only can be serialised from an instance of the same class.")
else:
return obj
def __str__(self):
return f"Filename: {self.filename}, content size: {sys.getsizeof(self.content)/1e6} MB."
class InMemoryZipfile(InMemoryFile):
"""In-memory buffer class for ingested zip bytestream
"""
def deserialise(self):
"""
Returns:
zipfile.ZipFile: An open ZipFile instance with the current instance's contents
"""
return zipfile.ZipFile(io.BytesIO(self.content),"r")
@classmethod
def serialise(self, obj: zipfile.ZipFile):
raise NotImplementError("Serialisation to InMemoryZipfile is not implemented.")
# bf = io.BytesIO()
# zipped = zipfile.ZipFile(bf,"w")
# for file in obj.filelist():
# zipped.writestr(file, obj.read(file))
# return InMemoryZipfile(filename="holder", content = bf.getvalue())
class InMemoryFontfile(InMemoryFile):
"""In-memory buffer class for ingested ttf or otf font files
"""
def deserialise(self, font_size: int):
"""
Args:
font_size (int)
No Longer Returned:
font: A parsed font object.
"""
return ImageFont.truetype(io.BytesIO(self.content),font_size)
def serialise(self, font: ImageFont.FreeTypeFont):
raise NotImplementError("Serialisation to InMemoryFontfile is not implemented.")
Classes
class InMemoryFile (**data: Any)
-
Wrapper class for retrieved file bytestreams
Create a new model by parsing and validating input data from keyword arguments.
Raises ValidationError if the input data cannot be parsed to form a valid model.
Expand source code
class InMemoryFile(BaseModel): """Wrapper class for retrieved file bytestreams """ filename: str content: bytes def to_format(self, file_format: InMemoryFile) -> InMemoryFile: """Cast instance as a different file type inehriting from InMemoryFile Args: file_format (InMemoryFile): Target file type Returns: InMemoryFile: cast file instance. """ return file_format(**self.dict()) def deserialise(self): """Parse instance as the corresponding Python object such as a ZipFile or an ImageFont.truetype """ return self @classmethod def from_file(cls, filepath: str) -> InMemoryFile: """Instantiate from file path Args: filepath (str): FIle path Returns: InMemoryFile: instantiated object """ return cls(filename = filepath, content = BytestreamPath(filepath).read_bytes()) @classmethod def from_bytestream_path(cls, bsp: BytestreamPath) -> InMemoryFile: """Instantiate from bytestream path Returns: InMemoryFile: instantiated object """ return cls(filename = str(bsp), content = bsp.read_bytes()) @classmethod def serialise(cls, obj: t.Any): """Serialises a Python object to an instance of InMemoryFile Args: obj (t.Any): Python object Returns: InMemoryFile: Description Raises: TypeError: If passed object is not an instance of InMemoryFile """ if not isinstance(obj, InMemoryFile): raise TypeError("InMemoryFile only can be serialised from an instance of the same class.") else: return obj def __str__(self): return f"Filename: {self.filename}, content size: {sys.getsizeof(self.content)/1e6} MB."
Ancestors
- pydantic.main.BaseModel
- pydantic.utils.Representation
Subclasses
Class variables
var content : bytes
var filename : str
Static methods
def from_bytestream_path(bsp: BytestreamPath) ‑> InMemoryFile
-
Expand source code
@classmethod def from_bytestream_path(cls, bsp: BytestreamPath) -> InMemoryFile: """Instantiate from bytestream path Returns: InMemoryFile: instantiated object """ return cls(filename = str(bsp), content = bsp.read_bytes())
def from_file(filepath: str) ‑> InMemoryFile
-
Expand source code
@classmethod def from_file(cls, filepath: str) -> InMemoryFile: """Instantiate from file path Args: filepath (str): FIle path Returns: InMemoryFile: instantiated object """ return cls(filename = filepath, content = BytestreamPath(filepath).read_bytes())
def serialise(obj: t.Any)
-
Serialises a Python object to an instance of InMemoryFile
Args
obj
:t.Any
- Python object
Returns
InMemoryFile
- Description
Raises
TypeError
- If passed object is not an instance of InMemoryFile
Expand source code
@classmethod def serialise(cls, obj: t.Any): """Serialises a Python object to an instance of InMemoryFile Args: obj (t.Any): Python object Returns: InMemoryFile: Description Raises: TypeError: If passed object is not an instance of InMemoryFile """ if not isinstance(obj, InMemoryFile): raise TypeError("InMemoryFile only can be serialised from an instance of the same class.") else: return obj
Methods
def deserialise(self)
-
Parse instance as the corresponding Python object such as a ZipFile or an ImageFont.truetype
Expand source code
def deserialise(self): """Parse instance as the corresponding Python object such as a ZipFile or an ImageFont.truetype """ return self
def to_format(self, file_format: InMemoryFile) ‑> InMemoryFile
-
Cast instance as a different file type inehriting from InMemoryFile
Args
file_format
:InMemoryFile
- Target file type
Returns
InMemoryFile
- cast file instance.
Expand source code
def to_format(self, file_format: InMemoryFile) -> InMemoryFile: """Cast instance as a different file type inehriting from InMemoryFile Args: file_format (InMemoryFile): Target file type Returns: InMemoryFile: cast file instance. """ return file_format(**self.dict())
class InMemoryFontfile (**data: Any)
-
In-memory buffer class for ingested ttf or otf font files
Create a new model by parsing and validating input data from keyword arguments.
Raises ValidationError if the input data cannot be parsed to form a valid model.
Expand source code
class InMemoryFontfile(InMemoryFile): """In-memory buffer class for ingested ttf or otf font files """ def deserialise(self, font_size: int): """ Args: font_size (int) No Longer Returned: font: A parsed font object. """ return ImageFont.truetype(io.BytesIO(self.content),font_size) def serialise(self, font: ImageFont.FreeTypeFont): raise NotImplementError("Serialisation to InMemoryFontfile is not implemented.")
Ancestors
- InMemoryFile
- pydantic.main.BaseModel
- pydantic.utils.Representation
Class variables
var content : bytes
var filename : str
Methods
def deserialise(self, font_size: int)
-
Args
font_size (int) No Longer Returned: font: A parsed font object.
Expand source code
def deserialise(self, font_size: int): """ Args: font_size (int) No Longer Returned: font: A parsed font object. """ return ImageFont.truetype(io.BytesIO(self.content),font_size)
Inherited members
class InMemoryZipfile (**data: Any)
-
In-memory buffer class for ingested zip bytestream
Create a new model by parsing and validating input data from keyword arguments.
Raises ValidationError if the input data cannot be parsed to form a valid model.
Expand source code
class InMemoryZipfile(InMemoryFile): """In-memory buffer class for ingested zip bytestream """ def deserialise(self): """ Returns: zipfile.ZipFile: An open ZipFile instance with the current instance's contents """ return zipfile.ZipFile(io.BytesIO(self.content),"r") @classmethod def serialise(self, obj: zipfile.ZipFile): raise NotImplementError("Serialisation to InMemoryZipfile is not implemented.") # bf = io.BytesIO() # zipped = zipfile.ZipFile(bf,"w") # for file in obj.filelist(): # zipped.writestr(file, obj.read(file)) # return InMemoryZipfile(filename="holder", content = bf.getvalue())
Ancestors
- InMemoryFile
- pydantic.main.BaseModel
- pydantic.utils.Representation
Class variables
var content : bytes
var filename : str
Methods
def deserialise(self)
-
Returns
zipfile.ZipFile
- An open ZipFile instance with the current instance's contents
Expand source code
def deserialise(self): """ Returns: zipfile.ZipFile: An open ZipFile instance with the current instance's contents """ return zipfile.ZipFile(io.BytesIO(self.content),"r")
Inherited members