Skip to content
GitHubRSS

Package Structure

BigBrotr is organized into five packages, each with a single clear responsibility. This page details the contents and purpose of every package.

Pure domain foundations. Frozen dataclasses representing Nostr concepts with invariants enforced at construction.

ModuleContents
relay.pyRelay — URL validation (RFC 3986), network detection (clearnet/tor/i2p/loki/local), local IP rejection
event.pyEvent — Nostr event with signature, EventRelay — junction model
metadata.pyMetadata — content-addressed with SHA-256 hash, MetadataType enum (7 types), RelayMetadata — junction model
constants.pyNetworkType, ServiceName (StrEnum), EventKind (IntEnum), EVENT_KIND_MAX
service_state.pyServiceState — service checkpoint data, ServiceStateType (StrEnum), ServiceStateDbParams (NamedTuple)

Key patterns:

  • All models use @dataclass(frozen=True, slots=True) for immutability and memory efficiency.
  • All models cache to_db_params() in __post_init__ via a _db_params field (using object.__setattr__ frozen workaround).
  • from_db_params() classmethod reconstructs objects from database tuples with full re-validation.
  • stdlib logging only — no bigbrotr imports.

Infrastructure and lifecycle. Manages the connection pool, database operations, service lifecycle, logging, and metrics.

ModuleContents
pool.pyPool — asyncpg connection pool with retry/backoff and health-checked acquisition. PoolConfig Pydantic model.
brotr.pyBrotr — database facade. _call_procedure() for stored functions, generic query methods: fetch(), fetchrow(), fetchval(), execute(), transaction(). BrotrConfig with BatchConfig and TimeoutsConfig.
base_service.pyBaseService[ConfigT] — abstract base class. run() cycle, run_forever() loop, graceful shutdown. from_yaml()/from_dict() factory methods.
logger.pyLogger — structured key=value logging with JSON output mode. format_kv_pairs() utility.
metrics.pyPrometheus /metrics endpoint. Four metric types: SERVICE_INFO, SERVICE_GAUGE, SERVICE_COUNTER, CYCLE_DURATION_SECONDS.
yaml.pyYAML configuration file loading with environment variable interpolation.

Key patterns:

  • Brotr._pool is private. Services use Brotr methods, never the pool directly.
  • BaseService is generic over ConfigT (a Pydantic BaseModel), enabling type-safe configuration.
  • Pool implements async with context management for automatic cleanup.

Protocol-aware I/O. Each NIP implementation is a “sensor” that produces typed Metadata objects. The package contains shared base classes and two sub-packages.

ModuleContents
base.pyShared base classes for NIP implementations
event_builders.pyNostr event construction for publishing monitoring data
parsing.pyDeclarative field parsing utilities
nip11/Sub-package: nip11.py (main class), data.py (data models), logs.py (result logging), info.py (field extraction)
nip66/Sub-package: nip66.py (main class), data.py, logs.py, plus one module per test: rtt.py, ssl.py, dns.py, geo.py, net.py, http.py

NIP-66 health tests:

TestMetadataTypeMeasures
RTTNIP66_RTT3-phase WebSocket latency: open, read, write (milliseconds)
SSLNIP66_SSLCertificate validity, expiration, issuer, SANs, cipher, fingerprint (SHA-256)
DNSNIP66_DNSA, AAAA, CNAME, NS, PTR records, TTL
GeoNIP66_GEOCountry, city, coordinates, timezone, geohash (precision 9) via GeoLite2-City
NetNIP66_NETAS number, ISP name, CIDR network ranges (IPv4 + IPv6) via GeoLite2-ASN
HTTPNIP66_HTTPServer and X-Powered-By headers from WebSocket upgrade handshake

NIP-11 produces MetadataType.NIP11_INFO.

Key patterns:

  • Fetch methods never raise exceptions. Always check logs.success on the result.
  • Depends on utils (for transport) and models (for data types). Does not depend on core.

Network and crypto primitives. Stateless helper functions with no business logic.

ModuleContents
protocol.pycreate_client(), connect_relay(), broadcast_events(), is_nostr_relay() — WebSocket client creation and relay connectivity testing.
transport.pyDEFAULT_TIMEOUT, InsecureWebSocketTransport — HTTP/WebSocket transport with SSL fallback and timeout configuration.
http.pyBounded JSON reading and file downloads with size limits.
dns.pyDNS resolution utilities for relay URL validation.
keys.pyload_keys_from_env(), KeysConfig Pydantic model — Nostr key management for event signing and publishing.
parsing.pysafe_parse() — tolerant data parsing that catches and logs failures without crashing.
streaming.pyData-driven windowing algorithm for streaming Nostr events with completeness guarantees and binary-split fallback.

Key patterns:

  • All functions are stateless. No class instances, no side effects beyond I/O.
  • SOCKS5 proxy support for Tor/I2P/Lokinet relays.
  • Depends only on models.

Business logic. Eight independent services, each inheriting BaseService[ConfigT] and implementing async def run().

ServiceModePurpose
seederOne-shotLoad relay URLs from seed files and known relay lists
finderContinuousDiscover relay URLs from event tags and public APIs
validatorContinuousTest WebSocket connectivity, promote candidates to relay table
monitorContinuousNIP-11 + NIP-66 health checks, publish kind 10166/30166 events
refresherScheduledOrchestrate materialized view refresh cycles
synchronizerContinuousCursor-based event collection from validated relays
apiContinuousFastAPI read-only HTTP API for relay and event data
dvmContinuousNIP-90 Data Vending Machine for Nostr-native data access

Shared infrastructure in services/common/:

ModuleContents
configs.pyPer-network Pydantic models: ClearnetConfig, TorConfig, I2pConfig, LokiConfig with timeouts, proxy URLs, concurrency limits
queries.pyBatch insert utilities (batched_insert, upsert_service_states). Domain queries distributed across service-specific modules.
mixins.py5 cooperative mixins: ConcurrentStreamMixin (TaskGroup streaming), NetworkSemaphoresMixin (per-network concurrency), GeoReaderMixin (GeoIP lifecycle), ClientsMixin (Nostr client pool), CatalogAccessMixin (schema discovery)
catalog.pyCatalog — runtime schema introspection and safe parameterized query builder, raises CatalogError to prevent leaking database internals
types.pyCheckpoint hierarchy (Api, Monitor, Publish, Candidate) and Cursor hierarchy (Sync, Finder)