Skip to content

parsing

parsing

Declarative field parsing for NIP data models.

Centralizes the type-coercion logic shared by all NIP-11 and NIP-66 data classes. Each model declares a FieldSpec describing which fields should be parsed as which types; parse_fields then applies the spec to raw dictionaries from external sources, silently dropping invalid values.

Supported field types: int, bool, str, float, list[int], list[str].

Note

This module is intentionally defensive: no exceptions are raised for invalid data. Values that fail type checks are silently excluded from the result dictionary. This design is critical for handling untrusted relay responses that may contain arbitrary or malformed JSON.

See Also

bigbrotr.nips.base.BaseData: Base class that uses FieldSpec and parse_fields for declarative parsing. bigbrotr.nips.nip11.data: NIP-11 data models that declare their own _FIELD_SPEC. bigbrotr.nips.nip66.data: NIP-66 data models that declare their own _FIELD_SPEC.

Classes

FieldSpec dataclass

FieldSpec(
    int_fields: frozenset[str] = frozenset(),
    bool_fields: frozenset[str] = frozenset(),
    str_fields: frozenset[str] = frozenset(),
    str_list_fields: frozenset[str] = frozenset(),
    float_fields: frozenset[str] = frozenset(),
    int_list_fields: frozenset[str] = frozenset(),
)

Declarative specification of expected field types for parsing.

Each attribute is a frozenset of field names that should be parsed as the corresponding Python type. Fields not listed in any set are ignored during parsing.

Attributes:

  • int_fields (frozenset[str]) –

    Fields expected as int (bool excluded).

  • bool_fields (frozenset[str]) –

    Fields expected as bool.

  • str_fields (frozenset[str]) –

    Fields expected as str.

  • str_list_fields (frozenset[str]) –

    Fields expected as list[str] (invalid elements filtered).

  • float_fields (frozenset[str]) –

    Fields expected as float (int accepted and converted).

  • int_list_fields (frozenset[str]) –

    Fields expected as list[int] (invalid elements filtered).

Note

Python's bool is a subclass of int, so int_fields parsing explicitly excludes bool values to prevent True/False from being accepted as integers.

See Also

parse_fields: The function that applies this spec to raw data dictionaries.

Functions

parse_fields

parse_fields(
    data: dict[str, Any], spec: FieldSpec
) -> dict[str, Any]

Parse a dictionary according to a FieldSpec, dropping invalid values.

Each key-value pair is checked against the field sets in spec. Values that do not match the expected type are silently excluded from the result. Keys not present in any field set are ignored.

Type-specific behavior:

  • int_fields -- must be int and not bool (Python's bool is a subclass of int).
  • bool_fields -- must be bool.
  • str_fields -- must be str.
  • str_list_fields -- must be list; non-string elements are filtered out.
  • float_fields -- accepts int or float (not bool); converts to float.
  • int_list_fields -- must be list; non-int elements (and bools) are filtered out.

Parameters:

  • data (dict[str, Any]) –

    Raw dictionary to parse.

  • spec (FieldSpec) –

    FieldSpec type specification.

Returns:

  • dict[str, Any]

    A new dictionary containing only valid, type-checked fields.

See Also

bigbrotr.nips.base.BaseData.parse: Class method that delegates to this function.

Source code in src/bigbrotr/nips/parsing.py
def parse_fields(data: dict[str, Any], spec: FieldSpec) -> dict[str, Any]:
    """Parse a dictionary according to a ``FieldSpec``, dropping invalid values.

    Each key-value pair is checked against the field sets in *spec*.
    Values that do not match the expected type are silently excluded
    from the result. Keys not present in any field set are ignored.

    Type-specific behavior:

    * ``int_fields`` -- must be ``int`` and not ``bool`` (Python's ``bool``
      is a subclass of ``int``).
    * ``bool_fields`` -- must be ``bool``.
    * ``str_fields`` -- must be ``str``.
    * ``str_list_fields`` -- must be ``list``; non-string elements are filtered out.
    * ``float_fields`` -- accepts ``int`` or ``float`` (not ``bool``); converts to ``float``.
    * ``int_list_fields`` -- must be ``list``; non-int elements (and bools) are filtered out.

    Args:
        data: Raw dictionary to parse.
        spec: [FieldSpec][bigbrotr.nips.parsing.FieldSpec] type specification.

    Returns:
        A new dictionary containing only valid, type-checked fields.

    See Also:
        [bigbrotr.nips.base.BaseData.parse][bigbrotr.nips.base.BaseData.parse]:
            Class method that delegates to this function.
    """
    dispatch = _build_dispatch(spec)

    result: dict[str, Any] = {}
    for key, value in data.items():
        handler = dispatch.get(key)
        if handler is not None:
            parsed = handler(value)
            if parsed is not _SKIP:
                result[key] = parsed

    return result