Source code for webgrid.types

from dataclasses import dataclass, field
from typing import Any


class ValidationError(Exception):
    pass


class FieldValidationError(ValidationError):
    def __init__(self, field, value, type_):
        message = f'Received {field}={value}; should be of type {type_}'
        super().__init__(message)


[docs] @dataclass class Filter: op: str value1: str | list[str] value2: str | None = None
[docs] @dataclass class Paging: pager_on: bool = False per_page: int | None = None on_page: int | None = None def __post_init__(self): if self.per_page is not None and not isinstance(self.per_page, int): raise FieldValidationError('per_page', self.per_page, 'int') if self.on_page is not None and not isinstance(self.on_page, int): raise FieldValidationError('on_page', self.on_page, 'int')
[docs] @dataclass class Sort: key: str flag_desc: bool
[docs] @dataclass class FilterOperator: key: str label: str field_type: str | None hint: str | None = None
[docs] @dataclass class FilterOption: key: str value: str
[docs] @dataclass class FilterSpec: operators: list[FilterOperator] primary_op: FilterOperator | None
@dataclass class OptionsFilterSpec(FilterSpec): options: list[FilterOption]
[docs] @dataclass class ColumnGroup: label: str columns: list[str]
@dataclass class GridTotals: page: dict[str, Any] | None = None grand: dict[str, Any] | None = None
[docs] @dataclass class GridSettings: search_expr: str | None = None filters: dict[str, Filter] = field(default_factory=dict) paging: Paging = field(default_factory=Paging) sort: list[Sort] = field(default_factory=list) export_to: str | None = None
[docs] @classmethod def from_dict(cls, data: dict[str, Any]) -> 'GridSettings': """Create from deserialized json""" try: filters = {key: Filter(**filter_) for key, filter_ in data.get('filters', {}).items()} except TypeError as e: raise ValidationError(f'Filter: {e}') from e try: paging = Paging(**data.get('paging', {})) except TypeError as e: raise ValidationError(f'Paging: {e}') from e try: sort = [Sort(**sort) for sort in data.get('sort', [])] except TypeError as e: raise ValidationError(f'Sort: {e}') from e return cls( search_expr=data.get('search_expr'), filters=filters, paging=paging, sort=sort, export_to=data.get('export_to'), )
[docs] def to_args(self) -> dict[str, Any]: """Convert grid parameters to request args format""" args = { 'search': self.search_expr, 'onpage': self.paging.on_page, 'perpage': self.paging.per_page, 'export_to': self.export_to, } for key, filter_ in self.filters.items(): args[f'op({key})'] = filter_.op args[f'v1({key})'] = filter_.value1 if filter_.value2: args[f'v2({key})'] = filter_.value2 for i, s in enumerate(self.sort, 1): prefix = '-' if s.flag_desc else '' args[f'sort{i}'] = f'{prefix}{s.key}' return args
[docs] @dataclass class GridSpec: columns: list[dict[str, str]] column_groups: list[ColumnGroup] column_types: list[dict[str, str]] export_targets: list[str] enable_search: bool enable_sort: bool sortable_columns: list[str] filters: dict[str, FilterSpec] = field(default_factory=dict)
[docs] @dataclass class GridState: page_count: int record_count: int warnings: list[str]
[docs] @dataclass class Grid: settings: GridSettings spec: GridSpec state: GridState records: list[dict[str, Any]] totals: GridTotals errors: list[str]