-
OnlineCredentials — Credentials for the online sources Codex may enable.
-
OnlinePrompt — Codex-facing handoff for an ambiguous match.
-
PromptResponse — Codex-side decision for one prompt.
-
PromptHandler — Codex’s prompt-resolution callback.
-
BatchedPromptHandler — A PromptHandler that also supports batched prompt delivery.
-
OnlineResult — Per-file outcome of an online tagging call.
-
DeferredPrompt — A prompt the session skipped under defer_prompts mode.
-
OnlineSession — Codex-friendly faΓ§ade over Comicbox’s online lookup.
comicbox.online_session¶
source module comicbox.online_session
OnlineSession β Codex-facing API for batch online metadata tagging.
Wraps the existing Comicbox.run_online_lookup() per-file flow with a Codex-friendly surface:
- Per-source credential validation up front (fail-fast).
- Direct :class:
MatchModeAPI (no string alias layer;ASKis rejected since the session has no built-in prompt resolver for it). - One programmatic PromptHandler per session that the matcher calls whenever it would otherwise hit the CLI questionary prompt.
- Event stream via on_event= for UI feedback.
- Cancellation token: callers stop the batch between files.
The internal matcher / selector / rate-limit machinery is untouched; this module is a faΓ§ade.
Classes
source class OnlineCredentials()
Credentials for the online sources Codex may enable.
source class OnlinePrompt()
Codex-facing handoff for an ambiguous match.
The PromptHandler receives one of these and returns a PromptResponse.
source class PromptResponse()
Codex-side decision for one prompt.
action mirrors :data:SelectorAction; payload is the index for choose, the "<source>:<id>" string for manual, the new :class:MatchMode value (e.g. "auto") for set_policy, or None otherwise.
source class PromptHandler()
Bases : Protocol
Codex’s prompt-resolution callback.
All handlers must implement :meth:request β the single-prompt form used by every code path that ships today. Handlers MAY additionally implement :meth:request_many to opt into the future batched-prompt delivery path (plan Β§3.4 / step 8): when the engine grows the per-session prompt queue, handlers exposing request_many get the full pending window in one call; handlers without it continue to be invoked one prompt at a time. v1 delivers prompts via request only β see tasks/prepare-for-codex-writing/03-batched-prompt-handler.md for the deferred implementation plan.
Methods
-
request — Resolve one prompt; return the chosen action/payload.
source method PromptHandler.request(prompt: OnlinePrompt) β PromptResponse
Resolve one prompt; return the chosen action/payload.
source class BatchedPromptHandler()
Bases : Protocol
A PromptHandler that also supports batched prompt delivery.
Codex’s defer-mode UI naturally yields a window of prompts the user will resolve together. When the engine gains the per-session prompt queue (step 8), it will prefer request_many over request for handlers structurally matching this Protocol.
Methods
-
request — Resolve one prompt; return the chosen action/payload.
-
request_many — Resolve a window of prompts in one call.
source method BatchedPromptHandler.request(prompt: OnlinePrompt) β PromptResponse
Resolve one prompt; return the chosen action/payload.
source method BatchedPromptHandler.request_many(prompts: Sequence[OnlinePrompt]) β Sequence[PromptResponse]
Resolve a window of prompts in one call.
Return one response per prompt, in the same order. The engine will not interleave request and request_many calls within a single drain window.
source class OnlineResult()
Per-file outcome of an online tagging call.
tags is the file’s full merged metadata, present even when the lookup applied nothing new (skip, no-match, deferred prompt) β it is NOT evidence of a match. matched is: it’s True only when an online source actually contributed metadata, so writers should gate on it to avoid re-writing a file with its own existing tags.
source class DeferredPrompt()
A prompt the session skipped under defer_prompts mode.
Captures everything Codex needs to render the prompt later in a review-tagging UI: the file it came from, source, candidates, mode context, and the fingerprint used to key the dedup cache. Codex feeds the user’s resolution back via :meth:OnlineSession.preload_resolution.
source class OnlineSession(*, sources: Iterable[str] = (‘metron’, ‘comicvine’), credentials: OnlineCredentials | None = None, mode: MatchMode = MatchMode.AUTO, unattended: bool = False, prompt_handler: PromptHandler | None = None, on_event: EventHandler | None = None, rematch: bool = False, first_wins: bool = True, defer_prompts: bool = False, series_batching: bool = True)
Codex-friendly faΓ§ade over Comicbox’s online lookup.
Construction validates per-source credentials and pre-computes the ComicboxSettings layer that each per-file Comicbox instance will see. Mutable state β mode, unattended, the cancel token β lives on the instance and may be updated from any thread.
Validate inputs, build per-session state. See class docstring.
Attributes
-
mode : MatchMode — Current session mode (read-only; mutate via set_mode()).
-
unattended : bool — Current session unattended flag.
-
cancelled : bool — Whether cancel() has been called.
-
defer_prompts : bool — Whether the session is currently in defer-prompts mode.
Methods
-
set_mode — Change the session mode for subsequent file lookups.
-
set_unattended — Toggle the unattended flag for subsequent file lookups.
-
cancel — Stop accepting new files. In-flight lookup runs to completion.
-
set_defer_prompts — Toggle defer-prompts mode for subsequent file lookups.
-
deferred_prompts — Snapshot the queued deferred prompts. Codex’s review-UI input.
-
clear_deferred_prompts — Drop the deferred-prompt queue without resolving them.
-
preload_resolution — Seed the dedup cache so a re-run auto-resolves the fingerprint.
-
preload_series_resolution — Seed the series cache from outside the session.
-
series_cache_snapshot — Snapshot the current series cache. Useful for persistence.
-
clear_series_cache — Drop every series resolution from the cache.
-
rate_limit_status — Snapshot of each enabled source’s current rate-limit budget.
-
tag — Tag one file synchronously.
-
tag_many — Tag many files sequentially. Stops accepting new ones on cancel.
source property OnlineSession.mode: MatchMode
Current session mode (read-only; mutate via set_mode()).
source property OnlineSession.unattended: bool
Current session unattended flag.
source method OnlineSession.set_mode(mode: MatchMode) β None
Change the session mode for subsequent file lookups.
source method OnlineSession.set_unattended(*, unattended: bool) β None
Toggle the unattended flag for subsequent file lookups.
source method OnlineSession.cancel() β None
Stop accepting new files. In-flight lookup runs to completion.
source property OnlineSession.cancelled: bool
Whether cancel() has been called.
source property OnlineSession.defer_prompts: bool
Whether the session is currently in defer-prompts mode.
source method OnlineSession.set_defer_prompts(*, defer: bool) β None
Toggle defer-prompts mode for subsequent file lookups.
source method OnlineSession.deferred_prompts() β tuple[DeferredPrompt, …]
Snapshot the queued deferred prompts. Codex’s review-UI input.
source method OnlineSession.clear_deferred_prompts() β None
Drop the deferred-prompt queue without resolving them.
source method OnlineSession.preload_resolution(fingerprint: str, *, action: Literal[‘choose’, ‘skip’, ‘manual’], payload: int | str | None = None, chosen_volume_id: int | None = None) β None
Seed the dedup cache so a re-run auto-resolves the fingerprint.
Codex’s defer-mode flow: drain deferred_prompts() after the batch, present them in a review UI, call preload_resolution() for each one the user resolves, then re-tag the affected files (with defer_prompts toggled off if desired). The cache hit fires the same way it does for in-batch dedup. A non-empty cache is enough to install the bridged selector β but with no handler and defer_prompts off, a cache MISS (the re-search produced a different candidate set than the fingerprint was minted from) raises rather than falling back to the interactive CLI prompt.
source method OnlineSession.preload_series_resolution(*, source: str, series_fingerprint: str, volume_id: int) β None
Seed the series cache from outside the session.
Codex’s use case: persist resolved series across runs in its own DB and replay them at session-start to skip the cold-path search entirely on subsequent imports. Same first-writer-wins semantic as in-batch population β if the key is already cached, this is a no-op.
source method OnlineSession.series_cache_snapshot() β dict[tuple[str, str], int]
Snapshot the current series cache. Useful for persistence.
source method OnlineSession.clear_series_cache() β None
Drop every series resolution from the cache.
source method OnlineSession.rate_limit_status() β dict[str, dict[str, Any]]
Snapshot of each enabled source’s current rate-limit budget.
v1 stub: returns an empty dict for every enabled source. The wiring to mokkari / simyan rate-limit buckets lands in the follow-up commit (see plan Β§3.5 / Β§3.6).
source method OnlineSession.tag(path: Path) β OnlineResult
Tag one file synchronously.
source method OnlineSession.tag_many(paths: Iterable[Path]) β Iterator[OnlineResult]
Tag many files sequentially. Stops accepting new ones on cancel.
When series_batching is on (the default), paths are reordered upfront by a lightweight filename-derived fingerprint so issues of the same series cluster together. The first issue of each cluster triggers the cold-path search; the remaining issues hit the per-session series cache and skip the search entirely. Order within a cluster is the original input order; the cluster order itself is deterministic (sorted by fingerprint) so re-runs produce identical cache-key sequences.