Newer
Older
TIASDataHub / src / tiasdata / importers / base.py
"""importer に共通の型(取り込みの文脈・結果)."""

import sqlite3
from dataclasses import dataclass
from pathlib import Path
from typing import Protocol

from tiasdata.config import SourceConfig
from tiasdata.importers.holds import Holds


@dataclass(frozen=True)
class ImportContext:
    """importer に渡す取り込みの文脈.

    Attributes:
        source_name: 取り込み元の名前(設定ファイルの `sources.<名前>`).
        source: 取り込み元の設定.
        store_dir: ストアのフォルダ.
        holds: 保留の番号.
        show_source_names: エラーメッセージに取り込み元の番号・名前を出すか
            (原因の特定に必要なときだけ明示する.error-handling.md).
    """

    source_name: str
    source: SourceConfig
    store_dir: Path
    holds: Holds
    show_source_names: bool = False


@dataclass(frozen=True)
class ImportResult:
    """取り込みの結果(件数だけ.CLI がそのまま表示する).

    Attributes:
        source_name: 取り込み元の名前.
        importer: importer の名前.
        found: 取り込み元で見つけた画像の数(保留を含む).
        held: 保留リストにより飛ばした数.
        hold_filename: 保留リストのファイル名(`holds/<名前>.toml`).
        unused_map_rows: 対応表で番号が整数でないため使わなかった行の行番号(xlsx の 1 始まり.
            位置であり対応表の中身ではない.表示は件数だけで,行番号は
            `--show-source-names` を指定したときだけ出す).
        skipped_existing: 既に登録済みで飛ばした数.
        copied_to_store: ストアにコピーした数(同じ中身が既にあったものは含まない).
        subjects_added: 登録した症例の数.
        captures_added: 登録した撮影の数.
        assets_added: 登録したファイルの数.
        annotations_added: 登録した所見の数.
        derivations_added: 登録した由来の数.
    """

    source_name: str
    importer: str
    found: int
    held: int
    hold_filename: str
    unused_map_rows: tuple[int, ...]
    skipped_existing: int
    copied_to_store: int
    subjects_added: int
    captures_added: int
    assets_added: int
    annotations_added: int
    derivations_added: int


class Importer(Protocol):
    """importer の関数の形(対応表を ATTACH した目録の接続と文脈を受け取る)."""

    def __call__(self, conn: sqlite3.Connection, context: ImportContext) -> ImportResult: ...