Module signals_notebook.entities.stoichiometry.data_grid

Expand source code
import logging
from decimal import Decimal
from enum import Enum
from typing import Any, cast, Generic, Optional, TypeVar, Union
from uuid import UUID

from pydantic import BaseModel, Field, PrivateAttr
from pydantic.generics import GenericModel

from signals_notebook.entities.stoichiometry.cell import ColumnDefinition
from signals_notebook.jinja_env import env

log = logging.getLogger(__name__)


class DataGridKind(str, Enum):
    REACTANTS = 'reactants'
    PRODUCTS = 'products'
    SOLVENTS = 'solvents'
    CONDITIONS = 'conditions'


class Cell(BaseModel):
    value: Union[bool, Decimal, str]
    display: Optional[str] = Field(default='')
    units: Optional[str]

    class Config:
        frozen = True


class Row(BaseModel):
    row_id: Union[UUID, str]

    class Config:
        frozen = True


RowClass = TypeVar('RowClass', bound=Row)


class Rows(GenericModel, Generic[RowClass]):
    __root__: list[RowClass]
    _rows_by_id: dict[Union[str, UUID], RowClass] = PrivateAttr(default={})
    _column_definitions: list[ColumnDefinition] = PrivateAttr(default=[])
    _template_name: str = 'data_grid.html'

    def __init__(self, **data: Any):
        """Stoichiometry Row

        Args:
            data: data to initialize Rows class
        """
        super(Rows, self).__init__(**data)

        for row in self.__root__:
            self._rows_by_id[row.row_id] = row

    def __iter__(self):
        return iter(self.__root__)

    def __getitem__(self, index: Union[int, str, UUID]) -> RowClass:
        if isinstance(index, int):
            return self.__root__[index]

        if isinstance(index, str):
            try:
                return self._rows_by_id[index]
            except KeyError:
                log.exception('Row will be returned by UUID index')
                return self._rows_by_id[UUID(index)]

        if isinstance(index, UUID):
            return self._rows_by_id[index]

        raise IndexError('Invalid index')

    @property
    def column_definitions(self) -> list[ColumnDefinition]:
        """Get column_definitions

        Returns:
            list of ColumnDefinition objects
        """
        return self._column_definitions

    def set_column_definitions(self, value: list[ColumnDefinition]) -> None:
        """Set column definitions to value

        Args:
            value: list of ColumnDefinition objects

        Returns:

        """
        self._column_definitions = value

    def get_html(self) -> str:
        """Get in HTML format

        Returns:
            Rendered template as a string
        """
        rows = []
        for row in self.__root__:
            reformatted_row = {}

            for column_definition in self.column_definitions:
                if hasattr(row, column_definition.key) and not column_definition.hidden:
                    cell = getattr(row, column_definition.key, None)
                    cell = cast(Cell, cell)
                    reformatted_row[column_definition.title] = '' if cell is None else (cell.display or cell.value)

            rows.append(reformatted_row)

        template = env.get_template(self._template_name)
        log.info('Html template for %s has been rendered.', self.__class__.__name__)

        return template.render(rows=rows)


class Reactant(Row):
    rxnid: Cell
    name: Optional[Cell]
    cas: Optional[Cell]
    formula: Cell
    mf: Cell
    mw: Cell
    em: Cell
    limit: Optional[Cell]
    eq: Optional[Cell]
    sm: Optional[Cell]
    moles: Optional[Cell]
    loading: Optional[Cell]
    molarity: Optional[Cell]
    volume: Optional[Cell]
    density: Optional[Cell]
    wt: Optional[Cell]
    supplier: Optional[Cell]
    lot: Optional[Cell]
    iupac_name: Cell = Field(alias='IUPACName')
    barcode: Optional[Cell]
    material_id: Optional[Cell] = Field(alias='materialId')
    container_id: Optional[Cell] = Field(alias='containerId')
    inchi: Optional[str]
    hash: Optional[str]

    class Config:
        frozen = True


class Reactants(Rows[Reactant]):
    pass


class Product(Row):
    rxnid: Cell
    product_id: Cell = Field(alias='productId')
    name: Optional[Cell]
    formula: Cell
    mf: Cell
    mw: Cell
    em: Cell
    theo_mass: Optional[Cell] = Field(alias='theoMass')
    actual_mass: Optional[Cell] = Field(alias='actualMass')
    purity: Optional[Cell]
    density: Optional[Cell]
    yield_: Optional[Cell] = Field(alias='yield')
    theo_mol: Optional[Cell] = Field(alias='theoMol')
    actual_mol: Optional[Cell] = Field(alias='actualMol')
    conversion: Optional[Cell]
    iupac_name: Cell = Field(alias='IUPACName')
    barcode: Optional[Cell]
    material_id: Optional[Cell] = Field(alias='materialId')
    container_id: Optional[Cell] = Field(alias='containerId')
    inchi: Optional[str]
    hash: Optional[str]

    class Config:
        frozen = True


class Products(Rows[Product]):
    pass


class Solvent(Row):
    solvent: Cell
    ratio: Cell
    volume: Optional[Cell]

    class Config:
        frozen = True


class Solvents(Rows[Solvent]):
    pass


class Condition(Row):
    pressure: Optional[Cell]
    temperature: Optional[Cell]
    duration: Optional[Cell]

    class Config:
        frozen = True


class Conditions(Rows[Condition]):
    pass


class DataGrids(BaseModel):
    reactants: Reactants
    products: Products
    solvents: Solvents
    conditions: Conditions

Classes

class Cell (**data: Any)

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 Cell(BaseModel):
    value: Union[bool, Decimal, str]
    display: Optional[str] = Field(default='')
    units: Optional[str]

    class Config:
        frozen = True

Ancestors

  • pydantic.main.BaseModel
  • pydantic.utils.Representation

Class variables

var Config
var display : Optional[str]
var units : Optional[str]
var value : Union[bool, decimal.Decimal, str]
class Condition (**data: Any)

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 Condition(Row):
    pressure: Optional[Cell]
    temperature: Optional[Cell]
    duration: Optional[Cell]

    class Config:
        frozen = True

Ancestors

  • Row
  • pydantic.main.BaseModel
  • pydantic.utils.Representation

Class variables

var Config
var duration : Optional[Cell]
var pressure : Optional[Cell]
var temperature : Optional[Cell]
class Conditions (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class
Expand source code
class Conditions(Rows[Condition]):
    pass

Ancestors

  • Rows[Condition]
  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Inherited members

class DataGridKind (value, names=None, *, module=None, qualname=None, type=None, start=1)

An enumeration.

Expand source code
class DataGridKind(str, Enum):
    REACTANTS = 'reactants'
    PRODUCTS = 'products'
    SOLVENTS = 'solvents'
    CONDITIONS = 'conditions'

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var CONDITIONS
var PRODUCTS
var REACTANTS
var SOLVENTS
class DataGrids (**data: Any)

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 DataGrids(BaseModel):
    reactants: Reactants
    products: Products
    solvents: Solvents
    conditions: Conditions

Ancestors

  • pydantic.main.BaseModel
  • pydantic.utils.Representation

Class variables

var conditionsConditions
var productsProducts
var reactantsReactants
var solventsSolvents
class Product (**data: Any)

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 Product(Row):
    rxnid: Cell
    product_id: Cell = Field(alias='productId')
    name: Optional[Cell]
    formula: Cell
    mf: Cell
    mw: Cell
    em: Cell
    theo_mass: Optional[Cell] = Field(alias='theoMass')
    actual_mass: Optional[Cell] = Field(alias='actualMass')
    purity: Optional[Cell]
    density: Optional[Cell]
    yield_: Optional[Cell] = Field(alias='yield')
    theo_mol: Optional[Cell] = Field(alias='theoMol')
    actual_mol: Optional[Cell] = Field(alias='actualMol')
    conversion: Optional[Cell]
    iupac_name: Cell = Field(alias='IUPACName')
    barcode: Optional[Cell]
    material_id: Optional[Cell] = Field(alias='materialId')
    container_id: Optional[Cell] = Field(alias='containerId')
    inchi: Optional[str]
    hash: Optional[str]

    class Config:
        frozen = True

Ancestors

  • Row
  • pydantic.main.BaseModel
  • pydantic.utils.Representation

Class variables

var Config
var actual_mass : Optional[Cell]
var actual_mol : Optional[Cell]
var barcode : Optional[Cell]
var container_id : Optional[Cell]
var conversion : Optional[Cell]
var density : Optional[Cell]
var emCell
var formulaCell
var hash : Optional[str]
var inchi : Optional[str]
var iupac_nameCell
var material_id : Optional[Cell]
var mfCell
var mwCell
var name : Optional[Cell]
var product_idCell
var purity : Optional[Cell]
var rxnidCell
var theo_mass : Optional[Cell]
var theo_mol : Optional[Cell]
var yield_ : Optional[Cell]
class Products (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class
Expand source code
class Products(Rows[Product]):
    pass

Ancestors

  • Rows[Product]
  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Inherited members

class Reactant (**data: Any)

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 Reactant(Row):
    rxnid: Cell
    name: Optional[Cell]
    cas: Optional[Cell]
    formula: Cell
    mf: Cell
    mw: Cell
    em: Cell
    limit: Optional[Cell]
    eq: Optional[Cell]
    sm: Optional[Cell]
    moles: Optional[Cell]
    loading: Optional[Cell]
    molarity: Optional[Cell]
    volume: Optional[Cell]
    density: Optional[Cell]
    wt: Optional[Cell]
    supplier: Optional[Cell]
    lot: Optional[Cell]
    iupac_name: Cell = Field(alias='IUPACName')
    barcode: Optional[Cell]
    material_id: Optional[Cell] = Field(alias='materialId')
    container_id: Optional[Cell] = Field(alias='containerId')
    inchi: Optional[str]
    hash: Optional[str]

    class Config:
        frozen = True

Ancestors

  • Row
  • pydantic.main.BaseModel
  • pydantic.utils.Representation

Class variables

var Config
var barcode : Optional[Cell]
var cas : Optional[Cell]
var container_id : Optional[Cell]
var density : Optional[Cell]
var emCell
var eq : Optional[Cell]
var formulaCell
var hash : Optional[str]
var inchi : Optional[str]
var iupac_nameCell
var limit : Optional[Cell]
var loading : Optional[Cell]
var lot : Optional[Cell]
var material_id : Optional[Cell]
var mfCell
var molarity : Optional[Cell]
var moles : Optional[Cell]
var mwCell
var name : Optional[Cell]
var rxnidCell
var sm : Optional[Cell]
var supplier : Optional[Cell]
var volume : Optional[Cell]
var wt : Optional[Cell]
class Reactants (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class
Expand source code
class Reactants(Rows[Reactant]):
    pass

Ancestors

  • Rows[Reactant]
  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Inherited members

class Row (**data: Any)

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 Row(BaseModel):
    row_id: Union[UUID, str]

    class Config:
        frozen = True

Ancestors

  • pydantic.main.BaseModel
  • pydantic.utils.Representation

Subclasses

Class variables

var Config
var row_id : Union[uuid.UUID, str]
class Rows (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class
Expand source code
class Rows(GenericModel, Generic[RowClass]):
    __root__: list[RowClass]
    _rows_by_id: dict[Union[str, UUID], RowClass] = PrivateAttr(default={})
    _column_definitions: list[ColumnDefinition] = PrivateAttr(default=[])
    _template_name: str = 'data_grid.html'

    def __init__(self, **data: Any):
        """Stoichiometry Row

        Args:
            data: data to initialize Rows class
        """
        super(Rows, self).__init__(**data)

        for row in self.__root__:
            self._rows_by_id[row.row_id] = row

    def __iter__(self):
        return iter(self.__root__)

    def __getitem__(self, index: Union[int, str, UUID]) -> RowClass:
        if isinstance(index, int):
            return self.__root__[index]

        if isinstance(index, str):
            try:
                return self._rows_by_id[index]
            except KeyError:
                log.exception('Row will be returned by UUID index')
                return self._rows_by_id[UUID(index)]

        if isinstance(index, UUID):
            return self._rows_by_id[index]

        raise IndexError('Invalid index')

    @property
    def column_definitions(self) -> list[ColumnDefinition]:
        """Get column_definitions

        Returns:
            list of ColumnDefinition objects
        """
        return self._column_definitions

    def set_column_definitions(self, value: list[ColumnDefinition]) -> None:
        """Set column definitions to value

        Args:
            value: list of ColumnDefinition objects

        Returns:

        """
        self._column_definitions = value

    def get_html(self) -> str:
        """Get in HTML format

        Returns:
            Rendered template as a string
        """
        rows = []
        for row in self.__root__:
            reformatted_row = {}

            for column_definition in self.column_definitions:
                if hasattr(row, column_definition.key) and not column_definition.hidden:
                    cell = getattr(row, column_definition.key, None)
                    cell = cast(Cell, cell)
                    reformatted_row[column_definition.title] = '' if cell is None else (cell.display or cell.value)

            rows.append(reformatted_row)

        template = env.get_template(self._template_name)
        log.info('Html template for %s has been rendered.', self.__class__.__name__)

        return template.render(rows=rows)

Ancestors

  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Subclasses

Instance variables

var column_definitions : list

Get column_definitions

Returns

list of ColumnDefinition objects

Expand source code
@property
def column_definitions(self) -> list[ColumnDefinition]:
    """Get column_definitions

    Returns:
        list of ColumnDefinition objects
    """
    return self._column_definitions

Methods

def get_html(self) ‑> str

Get in HTML format

Returns

Rendered template as a string

Expand source code
def get_html(self) -> str:
    """Get in HTML format

    Returns:
        Rendered template as a string
    """
    rows = []
    for row in self.__root__:
        reformatted_row = {}

        for column_definition in self.column_definitions:
            if hasattr(row, column_definition.key) and not column_definition.hidden:
                cell = getattr(row, column_definition.key, None)
                cell = cast(Cell, cell)
                reformatted_row[column_definition.title] = '' if cell is None else (cell.display or cell.value)

        rows.append(reformatted_row)

    template = env.get_template(self._template_name)
    log.info('Html template for %s has been rendered.', self.__class__.__name__)

    return template.render(rows=rows)
def set_column_definitions(self, value: list) ‑> None

Set column definitions to value

Args

value
list of ColumnDefinition objects

Returns:

Expand source code
def set_column_definitions(self, value: list[ColumnDefinition]) -> None:
    """Set column definitions to value

    Args:
        value: list of ColumnDefinition objects

    Returns:

    """
    self._column_definitions = value
class Rows[Condition] (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class

Ancestors

  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Subclasses

Class variables

var Config

Inherited members

class Rows[Product] (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class

Ancestors

  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Subclasses

Class variables

var Config

Inherited members

class Rows[Reactant] (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class

Ancestors

  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Subclasses

Class variables

var Config

Inherited members

class Rows[Solvent] (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class

Ancestors

  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Subclasses

Class variables

var Config

Inherited members

class Solvent (**data: Any)

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 Solvent(Row):
    solvent: Cell
    ratio: Cell
    volume: Optional[Cell]

    class Config:
        frozen = True

Ancestors

  • Row
  • pydantic.main.BaseModel
  • pydantic.utils.Representation

Class variables

var Config
var ratioCell
var solventCell
var volume : Optional[Cell]
class Solvents (**data: Any)

Stoichiometry Row

Args

data
data to initialize Rows class
Expand source code
class Solvents(Rows[Solvent]):
    pass

Ancestors

  • Rows[Solvent]
  • Rows
  • pydantic.generics.GenericModel
  • pydantic.main.BaseModel
  • pydantic.utils.Representation
  • typing.Generic

Inherited members