Source registry¶
Every data source — file or live — registers here under a name, the one
registry shared by both. Built-in sources self-register on import; third-party
sources load through the ob_analytics.sources entry-point group (see
Extending). A registered
value is a Source class; construct it and use the capability
you need — OfflineSource for file replay (Pipeline(source=...)), LiveSource
for live capture.
Per-source configuration is a typed SourceSettings (a frozen pydantic model),
not an untyped dict — subclass it per source, e.g. CcxtSettings. A source
that needs an API key marks the field with Credential (see
Use an API key). A field marked with CliOption
names and describes its flag on ob-analytics capture <source>.
register_source ¶
Register a :class:~ob_analytics.protocols.Source class under name.
Case-insensitive; overwriting an existing registration is allowed (handy for tests and for a plug-in that intentionally shadows a built-in).
get_source ¶
Return the source class registered under name (case-insensitive).
Raises:
| Type | Description |
|---|---|
UnknownNameError
|
If no source is registered under name; the message names the registered names closest to it. |
load_source_plugins ¶
Discover and register sources advertised via entry points.
Scans the :data:ENTRY_POINT_GROUP entry-point group; each entry's value
is loaded to a :class:~ob_analytics.protocols.Source class and registered
under the entry-point name. This is what lets a source live in a separate
installable package without editing ob-analytics.
The scan runs once per process unless force is set. A plug-in that fails to load is skipped with a warning, so one broken package cannot stop the rest from loading.
Returns:
| Type | Description |
|---|---|
list of str
|
The names newly registered by this call. |
SourceSettings ¶
Bases: _Settings
Base class for a data source's typed, immutable settings.
The typed replacement for the untyped per-source settings dict that live
capturers used to carry (CaptureConfig.extras). Every
:class:~ob_analytics.protocols.Source declares a settings value of
this type; a source that needs no configuration uses the empty base, and a
source with venue knobs subclasses it with typed, validated fields — e.g.
:class:~ob_analytics.live.ccxt_source.CcxtSettings (exchange /
depth_limit / poll_interval).
Frozen so a source's settings are fixed for the run, matching
:class:PipelineConfig.
A source that needs an API key declares it as a field marked with
:class:Credential. The settings read an unset credential from its
environment variable, and every credential's value is removed from the
files a capture writes.
credentials
classmethod
¶
The fields marked with :class:Credential, by field name.
remember_secrets ¶
Register every SecretStr value held here for redaction.
Validation does this already. A capture does it again as it starts,
for settings built without validation (model_copy(update=...)).
check_credentials ¶
Raise :class:~ob_analytics.exceptions.ConfigError if a credential is unset.
The message names each missing key's environment variable and where the venue issues keys. source is the source's name, for the message. The keys that are set are registered for redaction.
Credential
dataclass
¶
Marks a :class:SourceSettings field as a key the user supplies.
Put it on a SecretStr | None field with typing.Annotated. When the
field is not given, the settings read it from the environment variable
env. A key is never a command-line option, because a command line stays
in the shell history::
class VenueSettings(SourceSettings):
api_key: Annotated[
SecretStr | None,
Credential(env="VENUE_API_KEY", issued_at="https://venue.example/keys"),
] = None
An empty value counts as unset. A value shorter than eight characters is
refused, since no venue issues a key that short. A capture checks that
every credential is set before it writes anything
(:meth:SourceSettings.check_credentials).
Attributes:
| Name | Type | Description |
|---|---|---|
env |
str
|
The environment variable the key is read from. |
issued_at |
str
|
Where the venue issues keys, usually a URL. The error for a missing key names it. |
from_file |
bool
|
The variable holds the path of a file, and the field holds the file's
contents. For a private key, which lives in a file. From Python, pass
a :class: |
CliOption
dataclass
¶
How a :class:~ob_analytics.config.SourceSettings field shows on the command line.
ob-analytics capture <source> has one flag for each field of the
source's settings class, so a plug-in source can be set up from the
command line as from Python. Put this marker on a field with
typing.Annotated to give the flag its help text, another name, or a
way to read its value::
class VenueSettings(SourceSettings):
venue: Annotated[str, CliOption(help="The venue id")] = ""
depth: Annotated[int, CliOption(help="Levels a side", flag="levels")] = 10
A field without the marker still gets a flag named after it, when its
type is one the command line can read: str, int, float,
bool, a Literal, an Enum or Path, or None or one of
those. A field of any other type gets no flag unless the marker gives a
type. A :class:~ob_analytics.config.Credential field never gets one.
Attributes:
| Name | Type | Description |
|---|---|---|
help |
str
|
The flag's help text. |
flag |
(str, optional)
|
The flag's name without the leading |
type |
(callable, optional)
|
Turns the text given on the command line into the field's value.
|