Skip to content

data

data

NIP-11 relay information data models.

Defines the typed Pydantic models that represent the fields of a NIP-11 relay information document, including server limitations, retention policies, and fee schedules.

Note

All data classes extend BaseData and use declarative FieldSpec parsing. Complex nested structures (limitation, retention, fees) override parse() with custom logic while still leveraging the base mechanism for flat fields.

See Also

bigbrotr.nips.nip11.info.Nip11InfoMetadata: Container that pairs these data models with fetch logs. bigbrotr.nips.nip11.nip11.Nip11: Top-level model that wraps the fetch result. bigbrotr.nips.base.BaseData: Base class providing the parse() / from_dict() / to_dict() interface.

Classes

Nip11InfoDataLimitation

Bases: BaseData

Server-imposed limitations advertised in the NIP-11 document.

All fields are optional; relays may omit any or all of them.

See Also

Nip11InfoData: Parent model that contains this as the limitation field.

Nip11InfoDataRetentionEntry

Bases: BaseData

Single retention policy entry from a NIP-11 document.

The kinds field can contain plain integers or [start, end] range pairs, requiring custom parsing logic in parse().

Note

The parse() override handles the mixed int | [int, int] format specified by NIP-11. Lists are converted to tuples for immutability, and to_dict() uses mode="json" to convert tuples back to lists for JSON serialization.

See Also

Nip11InfoData: Parent model that contains these as the retention list.

Functions
parse classmethod
parse(data: Any) -> dict[str, Any]

Parse a retention entry, handling mixed int/range kinds lists.

Parameters:

  • data (Any) –

    Raw dictionary for a single retention entry.

Returns:

  • dict[str, Any]

    Validated dictionary with kinds, time, and count.

Source code in src/bigbrotr/nips/nip11/data.py
@classmethod
def parse(cls, data: Any) -> dict[str, Any]:
    """Parse a retention entry, handling mixed int/range kinds lists.

    Args:
        data: Raw dictionary for a single retention entry.

    Returns:
        Validated dictionary with ``kinds``, ``time``, and ``count``.
    """
    if not isinstance(data, dict):
        return {}
    result: dict[str, Any] = {}

    if "kinds" in data and isinstance(data["kinds"], list):
        kinds: list[int | tuple[int, int]] = []
        for item in data["kinds"]:
            if isinstance(item, int) and not isinstance(item, bool):
                kinds.append(item)
            elif (
                isinstance(item, list)
                and len(item) == 2  # noqa: PLR2004 - [min, max] range pair
                and isinstance(item[0], int)
                and not isinstance(item[0], bool)
                and isinstance(item[1], int)
                and not isinstance(item[1], bool)
            ):
                kinds.append((item[0], item[1]))
        if kinds:
            result["kinds"] = kinds

    for key in ("time", "count"):
        if key in data:
            value = data[key]
            if isinstance(value, int) and not isinstance(value, bool):
                result[key] = value
    return result
to_dict
to_dict() -> dict[str, Any]

Serialize to a dictionary, converting tuples to lists for JSON.

Source code in src/bigbrotr/nips/nip11/data.py
def to_dict(self) -> dict[str, Any]:
    """Serialize to a dictionary, converting tuples to lists for JSON."""
    return self.model_dump(exclude_none=True, mode="json")

Nip11InfoDataFeeEntry

Bases: BaseData

Single fee entry (admission, subscription, or publication).

See Also

Nip11InfoDataFees: Parent model that groups fee entries by category.

Nip11InfoDataFees

Bases: BaseData

Fee schedule categories from a NIP-11 document.

Contains nested lists of Nip11InfoDataFeeEntry objects for admission, subscription, and publication fees.

See Also

Nip11InfoData: Parent model that contains this as the fees field.

Functions
parse classmethod
parse(data: Any) -> dict[str, Any]

Parse fee schedule data with nested fee entry objects.

Parameters:

  • data (Any) –

    Raw dictionary containing fee category lists.

Returns:

  • dict[str, Any]

    Validated dictionary with non-empty fee entry lists.

Source code in src/bigbrotr/nips/nip11/data.py
@classmethod
def parse(cls, data: Any) -> dict[str, Any]:
    """Parse fee schedule data with nested fee entry objects.

    Args:
        data: Raw dictionary containing fee category lists.

    Returns:
        Validated dictionary with non-empty fee entry lists.
    """
    if not isinstance(data, dict):
        return {}
    result: dict[str, Any] = {}
    for key in ("admission", "subscription", "publication"):
        if key in data and isinstance(data[key], list):
            entries = [Nip11InfoDataFeeEntry.parse(e) for e in data[key]]
            entries = [e for e in entries if e]
            if entries:
                result[key] = entries
    return result

Nip11InfoData

Bases: BaseData

Complete NIP-11 relay information document.

Overrides parse() to handle nested objects (limitation, retention, fees) and to_dict() to use by_alias=True for the self field, which maps to self_pubkey internally.

Note

The NIP-11 self field is a reserved Python keyword, so it is mapped to self_pubkey with a Pydantic alias. The to_dict() method uses by_alias=True to ensure the JSON output uses the correct self key name as specified by the NIP.

See Also

Nip11InfoMetadata: Container that wraps this data model with fetch logs. Nip11InfoDataLimitation: Nested limitation sub-model. Nip11InfoDataFees: Nested fee schedule sub-model.

Attributes
self property
self: str | None

Relay's own public key from the NIP-11 self field.

Functions
parse classmethod
parse(data: Any) -> dict[str, Any]

Parse a complete NIP-11 document with nested sub-objects.

Handles string fields, supported_nips list, and nested limitation, retention, and fees objects.

Parameters:

  • data (Any) –

    Raw dictionary from the relay HTTP response.

Returns:

  • dict[str, Any]

    Validated dictionary suitable for model construction.

Source code in src/bigbrotr/nips/nip11/data.py
@classmethod
def parse(cls, data: Any) -> dict[str, Any]:
    """Parse a complete NIP-11 document with nested sub-objects.

    Handles string fields, supported_nips list, and nested limitation,
    retention, and fees objects.

    Args:
        data: Raw dictionary from the relay HTTP response.

    Returns:
        Validated dictionary suitable for model construction.
    """
    if not isinstance(data, dict):
        return {}
    result = parse_fields(data, cls._FIELD_SPEC)

    if "supported_nips" in data and isinstance(data["supported_nips"], list):
        nips = [
            n for n in data["supported_nips"] if isinstance(n, int) and not isinstance(n, bool)
        ]
        if nips:
            result["supported_nips"] = sorted(set(nips))

    result.update(cls._parse_sub_objects(data))
    return result
to_dict
to_dict() -> dict[str, Any]

Serialize to a dictionary using field aliases (self instead of self_pubkey).

Source code in src/bigbrotr/nips/nip11/data.py
def to_dict(self) -> dict[str, Any]:
    """Serialize to a dictionary using field aliases (``self`` instead of ``self_pubkey``)."""
    return self.model_dump(exclude_none=True, by_alias=True, mode="json")

Functions