Skip to content

configs

configs

Monitor service configuration models.

See Also

Monitor: The service class that consumes these configurations. BaseServiceConfig: Base class providing interval and log_level fields.

Classes

MetadataFlags

Bases: BaseModel

Boolean flags controlling which metadata types to compute, store, or publish.

Used in three contexts within ProcessingConfig: compute (which checks to run), store (which results to persist), and discovery.include (which results to publish as NIP-66 tags).

See Also

MonitorConfig.validate_store_requires_compute: Validator ensuring stored flags are a subset of computed flags.

Functions
get_missing_from
get_missing_from(superset: MetadataFlags) -> list[str]

Return field names that are enabled in self but disabled in superset.

Source code in src/bigbrotr/services/monitor/configs.py
def get_missing_from(self, superset: MetadataFlags) -> list[str]:
    """Return field names that are enabled in self but disabled in superset."""
    return [
        field
        for field in MetadataFlags.model_fields
        if getattr(self, field) and not getattr(superset, field)
    ]

RetryConfig

Bases: BaseModel

Retry settings with exponential backoff and jitter for metadata operations.

Warning

The jitter parameter uses random.uniform() (PRNG, not crypto-safe) which is intentional -- jitter only needs to decorrelate concurrent retries, not provide cryptographic randomness.

See Also

Monitor._with_retry: The method that consumes these settings.

RetriesConfig

Bases: BaseModel

Per-metadata-type retry settings.

Each field corresponds to one of the seven health check types and holds a RetryConfig with independent max_attempts, initial_delay, max_delay, and jitter values.

See Also

ProcessingConfig: Parent config that embeds this model.

ProcessingConfig

Bases: BaseModel

Processing settings: chunk size, retry policies, and compute/store flags.

See Also

MonitorConfig: Parent config that embeds this model. MetadataFlags: The compute and store flag sets.

GeoConfig

Bases: BaseModel

GeoLite2 database paths, download URLs, and staleness settings.

Note

GeoLite2 databases are downloaded at the start of each cycle if missing or stale (older than max_age_days). Downloads use async HTTP via aiohttp with bounded reads to prevent memory exhaustion from oversized payloads.

See Also

MonitorConfig: Parent config that embeds this model. Nip66GeoMetadata: The NIP-66 check that reads the City database. Nip66NetMetadata: The NIP-66 check that reads the ASN database.

PublishingConfig

Bases: BaseModel

Default relay list used as fallback for event publishing.

See Also

DiscoveryConfig, AnnouncementConfig, ProfileConfig: Each can override this list with their own relays field.

DiscoveryConfig

Bases: BaseModel

Kind 30166 relay discovery event settings (NIP-66).

See Also

build_relay_discovery: Builds the event from check results using include flags.

AnnouncementConfig

Bases: BaseModel

Kind 10166 monitor announcement settings (NIP-66).

See Also

build_monitor_announcement: Builds the announcement event with frequency and timeout tags.

ProfileConfig

Bases: BaseModel

Kind 0 profile metadata settings (NIP-01).

See Also

build_profile_event: Builds the profile event from these fields.

MonitorConfig

Bases: BaseServiceConfig

Monitor service configuration with validation for dependency constraints.

Note

Three model_validator methods enforce dependency constraints at config load time (fail-fast):

  • validate_geo_databases: GeoLite2 files must be downloadable.
  • validate_store_requires_compute: Cannot store uncalculated metadata.
  • validate_publish_requires_compute: Cannot publish uncalculated metadata.
See Also

Monitor: The service class that consumes this configuration. BaseServiceConfig: Base class providing interval and log_level fields. KeysConfig: Nostr key management for event signing.

Functions
validate_geo_databases
validate_geo_databases() -> MonitorConfig

Validate GeoLite2 database paths have download URLs if files are missing.

Actual downloads are deferred to _update_geo_databases() which downloads asynchronously via aiohttp.

Source code in src/bigbrotr/services/monitor/configs.py
@model_validator(mode="after")
def validate_geo_databases(self) -> MonitorConfig:
    """Validate GeoLite2 database paths have download URLs if files are missing.

    Actual downloads are deferred to ``_update_geo_databases()`` which
    downloads asynchronously via ``aiohttp``.
    """
    if self.processing.compute.nip66_geo:
        city_path = Path(self.geo.city_database_path)
        if not city_path.exists() and not self.geo.city_download_url:
            raise ValueError(
                f"GeoLite2 City database not found at {city_path} "
                "and no download URL configured in geo.city_download_url"
            )

    if self.processing.compute.nip66_net:
        asn_path = Path(self.geo.asn_database_path)
        if not asn_path.exists() and not self.geo.asn_download_url:
            raise ValueError(
                f"GeoLite2 ASN database not found at {asn_path} "
                "and no download URL configured in geo.asn_download_url"
            )

    return self
validate_store_requires_compute
validate_store_requires_compute() -> MonitorConfig

Ensure every stored metadata type is also computed.

Source code in src/bigbrotr/services/monitor/configs.py
@model_validator(mode="after")
def validate_store_requires_compute(self) -> MonitorConfig:
    """Ensure every stored metadata type is also computed."""
    errors = self.processing.store.get_missing_from(self.processing.compute)
    if errors:
        raise ValueError(
            f"Cannot store metadata that is not computed: {', '.join(errors)}. "
            "Enable in processing.compute.* or disable in processing.store.*"
        )
    return self
validate_publish_requires_compute
validate_publish_requires_compute() -> MonitorConfig

Ensure every published metadata type is also computed.

Source code in src/bigbrotr/services/monitor/configs.py
@model_validator(mode="after")
def validate_publish_requires_compute(self) -> MonitorConfig:
    """Ensure every published metadata type is also computed."""
    if not self.discovery.enabled:
        return self
    errors = self.discovery.include.get_missing_from(self.processing.compute)
    if errors:
        raise ValueError(
            f"Cannot publish metadata that is not computed: {', '.join(errors)}. "
            "Enable in processing.compute.* or disable in discovery.include.*"
        )
    return self

Functions