Skip to content

report

django_spire.metric.report

__all__ = ['BaseReport', 'ReportRegistry'] module-attribute

BaseReport

Bases: ABC

Source code in django_spire/metric/report/report.py
def __init__(self):
    if not self.title:
        message = 'Report title is required'
        raise ValueError(message)

    self.columns: list[ReportColumn] = []
    self.rows: list[ReportRow] = []

title instance-attribute

description = None class-attribute instance-attribute

is_financially_accurate = False class-attribute instance-attribute

ColumnType = ColumnType class-attribute instance-attribute

helper = Helper() class-attribute instance-attribute

columns = [] instance-attribute

rows = [] instance-attribute

column_count property

is_ready property

run_arguments property

run abstractmethod

Source code in django_spire/metric/report/report.py
@abstractmethod
def run(self, **kwargs: Any):
    raise NotImplementedError

add_blank_row

Source code in django_spire/metric/report/report.py
def add_blank_row(
        self,
        text: str = '',
        page_break: bool = False,
        border_top: bool = False,
        border_bottom: bool = False
):
    self.add_row(
        cell_values=[
            text
        ],
        span_all_columns=True,
        page_break=page_break,
        border_top=border_top,
        border_bottom=border_bottom,
    )

add_column

Source code in django_spire/metric/report/report.py
def add_column(
        self,
        title: str,
        sub_title: str | None = None,
        type: ColumnType = ColumnType.TEXT,
        sub_type: ColumnType = ColumnType.TEXT,

):
    self.columns.append(
        ReportColumn(title=title, sub_title=sub_title, type=type, sub_type=sub_type)
    )

add_divider_row

Source code in django_spire/metric/report/report.py
def add_divider_row(
        self,
        title: str,
        description: str | None = None,
        page_break: bool = False,
        border_bottom: bool = True,
):
    self.add_row(
        cell_values=[title],
        cell_sub_values=[description] if description else None,
        bold=True,
        page_break=page_break,
        span_all_columns=True,
        border_bottom=border_bottom,
    )
Source code in django_spire/metric/report/report.py
def add_footer_row(
        self,
        cell_values: list[Any],
        cell_sub_values: list[Any] | None = None,
        border_top: bool = True,
):
    self.add_row(
        cell_values=cell_values,
        cell_sub_values=cell_sub_values,
        bold=True,
        border_top=border_top,
    )

add_row

Source code in django_spire/metric/report/report.py
def add_row(
        self,
        cell_values: list[Any],
        cell_sub_values: list[Any] | None = None,
        bold: bool = False,
        page_break: bool = False,
        span_all_columns: bool = False,
        table_break: bool = False,
        border_top: bool = False,
        border_bottom: bool = False,
):
    if span_all_columns or table_break:
        if len(cell_values) > 1:
            message = 'Cannot span all columns or have a table break with more than one cell value'
            raise ValueError(message)

    elif len(cell_values) != len(self.columns) or (
            cell_sub_values is not None and len(cell_sub_values) != len(self.columns)):
        message = f'Number of cell values ({len(cell_values)}) and sub values ({len(cell_sub_values) if cell_sub_values else "None"}) must match number of columns: {len(self.columns)}'
        raise ValueError(message)

    self.rows.append(
        ReportRow(
            cells=[
                ReportCell(
                    value=cell_values[i],
                    sub_value=cell_sub_values[i] if cell_sub_values else None,
                    type=self.columns[i].type,
                    sub_type=self.columns[i].sub_type
                )
                for i in range(len(cell_values))
            ],
            bold=bold,
            page_break=page_break,
            span_all_columns=span_all_columns,
            table_break=table_break,
            border_top=border_top,
            border_bottom=border_bottom,
        )
    )

validate_choices staticmethod

Source code in django_spire/metric/report/report.py
@staticmethod
def validate_choices(choices: tuple):
    if not isinstance(choices, tuple):
        raise TypeError(f'choices must be a tuple not {type(choices)}')
    if not all(isinstance(item, tuple) and len(item) == 2 for item in choices):
        raise ValueError('choices must contain tuples of length 2')

to_markdown

Source code in django_spire/metric/report/report.py
def to_markdown(self) -> str:
    markdown = ''

    for column in self.columns:
        markdown += f'| {column.title} '

    markdown += '|\n'

    for column in self.columns:
        markdown += '| ' + '-' * len(column.title) + ' '

    markdown += '|\n'

    for row in self.rows:
        if row.span_all_columns:
            markdown += f'| {row.cells[0].value}' + '|' * len(self.columns) + '\n'
            continue

        else:
            for cell in row.cells:
                markdown += f'| {cell.value_verbose()} '

        markdown += '|\n'

    return markdown

ReportRegistry

Source code in django_spire/metric/report/registry.py
def __init__(self):
    for report_registry in self.report_registries:
        self.add_registry(report_registry)

category = None class-attribute instance-attribute

report_names_classes = {} class-attribute instance-attribute

report_registries = [] class-attribute instance-attribute

add_registry

Source code in django_spire/metric/report/registry.py
def add_registry(
        self,
        report_registry: Self
):
    if report_registry.category is None:
        message = 'Report Registry category is required'
        raise ValueError(message)

    # if report_registry.category in self.report_names_classes:
    #     message = f'Report Registry category "{report_registry.category}" already exists'
    #     raise ValueError(message)

    self.report_names_classes[report_registry.category] = report_registry.report_names_classes

get_report_from_key_stack

Source code in django_spire/metric/report/registry.py
def get_report_from_key_stack(self, report_key_stack: str) -> BaseReport | None:
    current = self.report_names_classes

    for key in report_key_stack.split('|'):
        if isinstance(current, dict) and key in current:
            current = current[key]
        else:
            return None

    return current()