Skip to content

kaptive.db

Kaptive reference database management and data models.

The kaptive.db sub-package handles downloading, loading, validating, and managing Kaptive reference databases containing locus sequences, gene metadata, and serotype phenotype definitions.

Exports:

  • Database: Core reference database containing indexed locus sequences (Database).
  • DatabaseManager: Remote database downloading and local directory management (DatabaseManager).
  • DatabaseMetadata: Metadata container for database versioning and locus definitions (DatabaseMetadata).
  • DatabaseError: Base exception for database formatting and loading failures (DatabaseError).
  • Phenotype: Single locus phenotype definition (Phenotype).
  • Phenotypes: Collection container for locus phenotype mapping records (Phenotypes).

Modules:

  • cli –

    Command-line interface commands for managing and querying Kaptive reference databases.

  • core –

    Core in-memory representation of Kaptive antigen reference databases.

  • manager –

    Database management module for downloading, compiling, and managing Kaptive databases.

  • models –

    Data models and custom exception classes for Kaptive database representation.

Classes:

  • Database –

    Optimized representation of a Kaptive antigen database in memory using Structure-of-Arrays (SoA).

  • DatabaseError –

    Exception raised for database loading, metadata validation, or format errors.

  • DatabaseManager –

    Class for managing Kaptive databases both on the user's disk and in curator GitHub repositories.

  • DatabaseMetadata –

    Strict schema for Database metadata with dependency-free validation and ergonomic attribute access.

  • Phenotype –

    Single locus phenotype rule mapping loci and gene requirements to a serotype identifier.

  • Phenotypes –

    Structure-of-Arrays (SoA) container for vectorized phenotype evaluation.

Database dataclass

Database(metadata: DatabaseMetadata, loci: Sequences, serotypes: tuple[str, ...], locus_gene_offsets: NDArray[uint32], locus_gene_lengths: NDArray[uint32], gene_intervals: Intervals, genes: Sequences, translations: Sequences, extra_genes: NDArray[bool_], gene_locus_indices: NDArray[uint16], cluster_keys: tuple[str, ...], gene_cluster_ids: NDArray[uint16], description_keys: tuple[str, ...], gene_description_ids: NDArray[uint16], gene_positions: NDArray[uint16], phenotypes: Phenotypes, loci_sketches: FracMinHashIndex)

Optimized representation of a Kaptive antigen database in memory using Structure-of-Arrays (SoA).

This class eschews traditional object hierarchies (e.g., Locus -> Gene -> Sequence) in favor of flat, parallel arrays (Structure of Arrays). This layout provides significant performance benefits:

  1. Memory Locality: Data of the same type (e.g., all gene cluster IDs) is stored contiguously, drastically reducing cache misses during iterative alignment.
  2. Vectorization: NumPy arrays allow operations to be performed on thousands of genes simultaneously without Python loop overhead.
  3. Fast Lookups: Vocabularies convert strings into integer IDs (gene_cluster_ids). Comparing integers is orders of magnitude faster than string comparison.

The database manages two main entities: Loci (full locus sequences) and Genes (individual coding sequences). Mappings between these entities are maintained via indices and slices rather than object references.

Attributes:

  • metadata (DatabaseMetadata) –

    Strict, validated metadata schema associated with the database (DatabaseMetadata).

  • loci (Sequences) –

    Vectorized batch of locus nucleotide sequences and IDs (Sequences). Length is N_loci.

  • serotypes (tuple[str, ...]) –

    Tuple of length N_loci mapping each locus index to its serotype name.

  • locus_gene_offsets (NDArray[uint32]) –

    1D array of length N_loci containing global gene start indices.

  • locus_gene_lengths (NDArray[uint32]) –

    1D array of length N_loci containing gene counts per locus.

  • gene_intervals (Intervals) –

    Vectorized batch of gene coordinates relative to parent loci (Intervals). Length is N_genes.

  • genes (Sequences) –

    Vectorized batch of gene nucleotide sequences (Sequences). Length is N_genes.

  • translations (Sequences) –

    Vectorized batch of translated protein sequences (Sequences). Length is N_genes.

  • extra_genes (NDArray[bool_]) –

    Boolean mask of length N_genes indicating extra genes without synteny.

  • gene_locus_indices (NDArray[uint16]) –

    1D array of length N_genes mapping gene back to locus index.

  • cluster_keys (tuple[str, ...]) –

    Vocabulary of unique gene cluster names.

  • gene_cluster_ids (NDArray[uint16]) –

    1D array of length N_genes storing cluster integer IDs.

  • description_keys (tuple[str, ...]) –

    Vocabulary of unique gene product descriptions.

  • gene_description_ids (NDArray[uint16]) –

    1D array of length N_genes storing product description IDs.

  • gene_positions (NDArray[uint16]) –

    1D array of length N_genes storing expected gene position (1-indexed).

  • phenotypes (Phenotypes) –

    Vectorized batch dictating serotype assignment logic (Phenotypes).

  • loci_sketches (FracMinHashIndex) –

    Precomputed FracMinHash sketches for locus containment testing (FracMinHashIndex).

See Also

DatabaseManager, DatabaseMetadata, Phenotypes

Methods:

  • from_genbank –

    Compiles a Database object by parsing a legacy GenBank format file and its associated TOML metadata.

  • from_pickle –

    Loads a pre-compiled Database object from a serialized pickle file.

  • get_locus_data –

    Extracts locus data including protein sequences, coordinate backbone, gene states, and product descriptions for a specific locus.

  • load –

    Loads a Database from a file path (GenBank or Pickle).

cluster_vocab property

cluster_vocab: dict[str, int]

Dictionary mapping gene cluster names (strings) to integer IDs.

Convenience property for O(1) string-to-ID lookups.

Returns:

  • dict[str, int] –

    dict[str, int]: Mapping from cluster string name to integer ID.

See Also

Database

description_vocab property

description_vocab: dict[str, int]

Dictionary mapping gene product descriptions (strings) to integer IDs.

Convenience property for O(1) string-to-ID lookups.

Returns:

  • dict[str, int] –

    dict[str, int]: Mapping from product description string to integer ID.

See Also

Database

max_locus_length property

max_locus_length: int

Length of the longest locus sequence in the database.

Useful for pre-allocating memory buffers of sufficient size when aligning against the database.

Returns:

  • int ( int ) –

    The maximum sequence length among all loci, or 0 if the database contains no loci.

from_genbank classmethod

from_genbank(file: str | Path) -> Database

Compiles a Database object by parsing a legacy GenBank format file and its associated TOML metadata.

This is an expensive compilation step that converts the nested, string-heavy GenBank structure into the flat, integer-based SoA layout defined by this class.

The method performs the following tasks:

  1. Iterates through loci in the .gbk file, extracting sequence data.
  2. Parses CDS (Coding Sequence) features to extract gene coordinates, clusters, and descriptions.
  3. Builds the string-to-integer vocabularies (cluster_vocab, description_vocab).
  4. Constructs the flat numpy arrays (e.g., gene_cluster_ids, gene_positions).
  5. Creates Sequences and Intervals objects for vectorized sequence operations.
  6. Translates all extracted gene nucleotide sequences into protein sequences.
  7. Loads and validates metadata from a companion .toml file (which must have the same name as the .gbk file).
  8. Parses complex phenotype logic from the metadata.

Parameters:

  • file

    (str | Path) –

    The path to the .gbk database file. A companion .toml file must exist in the same directory.

Returns:

  • Database ( Database ) –

    The newly compiled, optimized Database object.

Raises:

  • DatabaseError –

    If loci lack required qualifiers ('note', 'locus'), or if the associated .toml metadata file is missing.

Source code in src/kaptive/db/core.py
@classmethod
def from_genbank(cls, file: str | Path) -> "Database":
    r"""Compiles a Database object by parsing a legacy GenBank format file and its associated TOML metadata.

    This is an expensive compilation step that converts the nested, string-heavy GenBank structure
    into the flat, integer-based SoA layout defined by this class.

    The method performs the following tasks:

    1.  Iterates through loci in the `.gbk` file, extracting sequence data.
    2.  Parses CDS (Coding Sequence) features to extract gene coordinates, clusters, and descriptions.
    3.  Builds the string-to-integer vocabularies (`cluster_vocab`, `description_vocab`).
    4.  Constructs the flat numpy arrays (e.g., `gene_cluster_ids`, `gene_positions`).
    5.  Creates `Sequences` and `Intervals` objects for vectorized sequence operations.
    6.  Translates all extracted gene nucleotide sequences into protein sequences.
    7.  Loads and validates metadata from a companion `.toml` file (which must have the same name as
        the `.gbk` file).
    8.  Parses complex phenotype logic from the metadata.

    Args:
        file (str | Path): The path to the `.gbk` database file. A companion `.toml` file
            must exist in the same directory.

    Returns:
        Database: The newly compiled, optimized Database object.

    Raises:
        DatabaseError: If loci lack required qualifiers ('note', 'locus'), or if the associated
            `.toml` metadata file is missing.
    """
    file = cls._check_file(file)
    from gb_io import iter as GenbankIterator

    _LOCUS_REGEX = re_compile(r"locus:\s?(.*)$")
    _SEROTYPE_REGEX = re_compile(r"type:\s?(.*)$")
    _EXTRA_REGEX = re_compile(r"Extra genes:\s?(.*)$")

    global_gene_idx = 0

    # Locus trackers
    locus_records, serotype_names, locus_gene_offsets, locus_gene_lengths, locus_intervals = (
        [],
        [],
        [],
        [],
        [],
    )

    # Gene trackers
    gene_ids, extra_genes = [], []
    gene_cluster_ids, gene_description_ids, gene_expected_positions = [], [], []

    # Global Vocabulary tracker
    cluster_vocab, description_vocab = {}, {}

    with file.open("rb") as fh:
        for rec in GenbankIterator(fh):
            locus_name, serotype, extra = None, None, False

            if not (notes := [i.value for i in rec.features[0].qualifiers if i.key == "note"]):
                raise DatabaseError(f'Locus has no "note" qualifiers: {rec.name}')

            # Iterate over notes to extract locus and type names, or whether the locus is an "Extra genes" locus
            for note in notes:
                if match := _EXTRA_REGEX.search(note):  # type: ignore
                    extra = True
                    locus_name = match.group(1)
                    break

                if not locus_name and (match := _LOCUS_REGEX.search(note)):  # type: ignore
                    locus_name = match.group(1)

                if not serotype and (match := _SEROTYPE_REGEX.search(note)):  # type: ignore
                    serotype = match.group(1)

            if not locus_name:
                raise DatabaseError(f'Locus has no valid "locus" qualifiers: {rec.name}')

            locus_record = SeqRecord(locus_name, rec.sequence.upper())  # type: ignore

            # Local trackers for the current locus
            starts, ends, strands = [], [], []

            local_gene_idx = 0
            locus_start_idx = global_gene_idx

            for feat in rec.features[1:]:
                if feat.kind != "CDS":
                    continue

                cluster, description = "", ""
                for i in feat.qualifiers:
                    if not cluster and i.key == "gene":
                        cluster = i.value
                    if not description and i.key == "product":
                        description = i.value

                if not extra:
                    gene_id = f"{locus_name}_{local_gene_idx + 1:02}_{cluster}"
                else:
                    gene_id = cluster

                if cluster not in cluster_vocab:
                    cluster_vocab[cluster] = len(cluster_vocab)
                cluster_id = cluster_vocab[cluster]

                if description not in description_vocab:
                    description_vocab[description] = len(description_vocab)
                description_id = description_vocab[description]

                expected_pos = local_gene_idx + 1  # Standardizing biological position

                # Coordinate parsing
                loc = feat.location
                start, end = sorted((loc.start, loc.end))  # type: ignore
                strand_val = -1 if loc.strand in (-1, "-") else 1  # type: ignore

                # Append to flat gene arrays
                starts.append(start)
                ends.append(end)
                strands.append(strand_val)
                gene_ids.append(gene_id)
                gene_cluster_ids.append(cluster_id)
                gene_description_ids.append(description_id)

                # Extra genes do not have expected biological positions or synteny matrices
                gene_expected_positions.append(0 if extra else expected_pos)

                local_gene_idx += 1
                global_gene_idx += 1

            if local_gene_idx == 0:
                continue

            locus_gene_offsets.append(locus_start_idx)
            locus_gene_lengths.append(local_gene_idx)

            # 2. Handle Sequence Extraction via Intervals
            intervals = Intervals(
                np.array(starts, dtype=np.int32),
                np.array(ends, dtype=np.int32),
                np.array(strands, dtype=np.int8),
            )

            # 4. Append final locus metadata
            locus_records.append(locus_record)
            serotype_names.append(serotype or "")
            locus_intervals.append(intervals)
            extra_genes.extend([extra] * local_gene_idx)

        # Pre-compute an array mapping every global gene index back to its locus index
        gene_locus_indices = np.zeros(global_gene_idx, dtype=np.uint16)
        for i, (o, length) in enumerate(zip(locus_gene_offsets, locus_gene_lengths)):
            gene_locus_indices[o : o + length] = i

    db_gene_ids = tuple(gene_ids)
    loci = Sequences.from_records(locus_records)
    cluster_keys = tuple(cluster_vocab.keys())
    phenotype_objs = []
    if (metadata_file := file.with_suffix(".toml")).is_file():
        with metadata_file.open("rb") as fp:
            metadata = DatabaseMetadata.from_dict(tomllib.load(fp))
            for k, v in metadata.phenotype_logic.items():
                phenotype_objs.append(cls._parse_phenotype(k, v, loci.ids, cluster_keys))
    else:
        raise DatabaseError("Missing required TOML metadata file alongside Genbank file.")

    # Initialize Phenotype SoA arrays
    n_pheno, n_loci, n_clusters = len(phenotype_objs), len(loci), len(cluster_keys)
    pheno_ids = []
    locus_vocab = {name: i for i, name in enumerate(loci.ids)}
    locus_masks = np.zeros((n_pheno, n_loci), dtype=bool)
    extra_masks = np.zeros((n_pheno, n_clusters), dtype=np.int8)
    inactive_masks = np.zeros((n_pheno, n_clusters), dtype=np.int8)
    priorities = np.zeros(n_pheno, dtype=np.int8)
    as_suffix = np.zeros(n_pheno, dtype=bool)

    for i, p in enumerate(phenotype_objs):
        pheno_ids.append(p.id)
        for loc in p.loci:
            locus_masks[i, locus_vocab[loc]] = True
        for ext in p.extra_genes:
            extra_masks[i, cluster_vocab[ext]] = 1
        for ina in p.inactive_genes:
            inactive_masks[i, cluster_vocab[ina]] = 1
        priorities[i] = p.priority
        as_suffix[i] = p.as_suffix

    global_intervals = Intervals.concat(locus_intervals)
    genes = loci.extract_intervals(gene_locus_indices, global_intervals, new_ids=db_gene_ids)
    translations = genes.translate()

    return cls(
        metadata=metadata,
        loci=loci,
        serotypes=tuple(serotype_names),
        locus_gene_offsets=np.array(locus_gene_offsets, dtype=np.uint32),
        locus_gene_lengths=np.array(locus_gene_lengths, dtype=np.uint32),
        gene_intervals=global_intervals,
        genes=genes,
        translations=translations,
        extra_genes=np.array(extra_genes, dtype=bool),
        gene_locus_indices=gene_locus_indices,
        cluster_keys=cluster_keys,
        gene_cluster_ids=np.array(gene_cluster_ids, dtype=np.uint16),
        description_keys=tuple(description_vocab.keys()),
        gene_description_ids=np.array(gene_description_ids, dtype=np.uint16),
        gene_positions=np.array(gene_expected_positions, dtype=np.uint16),
        phenotypes=Phenotypes(
            ids=np.array([p.encode("utf-8") for p in pheno_ids], dtype="S32"),
            locus_masks=locus_masks,
            extra_masks=extra_masks,
            inactive_masks=inactive_masks,
            extra_counts=extra_masks.sum(axis=1, dtype=np.int8),
            priorities=priorities,
            as_suffix=as_suffix,
        ),
        loci_sketches=FracMinHashIndex.build(loci, sort_by_hash=False),
    )

from_pickle classmethod

from_pickle(file: str | Path) -> Database

Loads a pre-compiled Database object from a serialized pickle file.

Parameters:

  • file

    (str | Path) –

    Path to .pkl database file.

Returns:

Raises:

See Also

load

Source code in src/kaptive/db/core.py
@classmethod
def from_pickle(cls, file: str | Path) -> "Database":
    r"""Loads a pre-compiled Database object from a serialized pickle file.

    Args:
        file (str | Path): Path to `.pkl` database file.

    Returns:
        Database: Deserialized [`Database`][kaptive.db.core.Database] instance.

    Raises:
        FileNotFoundError: If the file does not exist.

    See Also:
        [`load`][kaptive.db.core.Database.load]
    """
    return pickle.loads(cls._check_file(file).read_bytes())

get_locus_data

get_locus_data(locus_name: str) -> LocusData

Extracts locus data including protein sequences, coordinate backbone, gene states, and product descriptions for a specific locus.

Parameters:

  • locus_name

    (str) –

    Identifier of the locus sequence (e.g., 'K1').

Returns:

  • LocusData ( LocusData ) –

    Container object populated with locus proteins, coordinate backbone, gene states, and product descriptions (LocusData).

Raises:

  • ValueError –

    If locus_name is not present in self.loci.ids.

See Also

LocusData

Source code in src/kaptive/db/core.py
def get_locus_data(self, locus_name: str) -> "LocusData":
    r"""Extracts locus data including protein sequences, coordinate backbone, gene states, and product descriptions for a specific locus.

    Args:
        locus_name (str): Identifier of the locus sequence (e.g., 'K1').

    Returns:
        LocusData: Container object populated with locus proteins, coordinate backbone, gene states, and product descriptions
            ([`LocusData`][kaptive.compare.LocusData]).

    Raises:
        ValueError: If `locus_name` is not present in `self.loci.ids`.

    See Also:
        [`LocusData`][kaptive.compare.LocusData]
    """
    from kaptive.compare import LocusData
    from kaptive.serotyping.models import GeneState

    locus_idx = self.loci.ids.index(locus_name)
    start = self.locus_gene_offsets[locus_idx]
    length = self.locus_gene_lengths[locus_idx]

    desc_ids = self.gene_description_ids[start : start + length]
    raw_descs = [
        self.description_keys[i].decode("utf-8")
        if isinstance(self.description_keys[i], bytes)
        else str(self.description_keys[i])
        for i in desc_ids
    ]
    descriptions = np.asarray(raw_descs, dtype=object)
    states = np.full(length, GeneState.NORMAL.value, dtype=np.int8)

    return LocusData(
        proteins=self.translations[start : start + length],  # type: ignore
        name=locus_name,
        backbone=self.gene_intervals[start : start + length],  # type: ignore
        pieces=None,
        gene_ctg_indices=None,
        gene_states=states,
        gene_descriptions=descriptions,
    )

load classmethod

load(file: str | Path) -> Database

Loads a Database from a file path (GenBank or Pickle).

Factory entry point that delegates loading based on file extension: 1. If .gbk file path is provided, invokes from_genbank. 2. If .pkl file path is provided, invokes from_pickle.

Parameters:

  • file

    (str | Path) –

    Path to .gbk/.pkl file.

Returns:

Raises:

See Also

from_genbank, from_pickle

Source code in src/kaptive/db/core.py
@classmethod
def load(cls, file: str | Path) -> "Database":
    r"""Loads a Database from a file path (GenBank or Pickle).

    Factory entry point that delegates loading based on file extension:
    1. If `.gbk` file path is provided, invokes [`from_genbank`][kaptive.db.core.Database.from_genbank].
    2. If `.pkl` file path is provided, invokes [`from_pickle`][kaptive.db.core.Database.from_pickle].

    Args:
        file (str | Path): Path to `.gbk`/`.pkl` file.

    Returns:
        Database: Loaded and initialized [`Database`][kaptive.db.core.Database] instance.

    Raises:
        DatabaseError: If file extension is unsupported.
        FileNotFoundError: If the file does not exist.

    See Also:
        [`from_genbank`][kaptive.db.core.Database.from_genbank],
        [`from_pickle`][kaptive.db.core.Database.from_pickle]
    """
    file_path = cls._check_file(file)
    if file_path.suffix == ".gbk":
        return cls.from_genbank(file_path)
    elif file_path.suffix == ".pkl":
        return cls.from_pickle(file_path)
    raise DatabaseError(f"File {file} not supported")

DatabaseError


              flowchart TD
              kaptive.db.DatabaseError[DatabaseError]

              

              click kaptive.db.DatabaseError href "" "kaptive.db.DatabaseError"
            

Exception raised for database loading, metadata validation, or format errors.

This exception is raised when database metadata is invalid, required files are missing, or reference database files fail validation in DatabaseMetadata, Database, or DatabaseManager.

DatabaseManager

Class for managing Kaptive databases both on the user's disk and in curator GitHub repositories.

This class provides a comprehensive mechanism for downloading, compiling, and managing Kaptive databases. Databases are maintained as source files (GenBank and TOML) in Git repositories. The DatabaseManager fetches these files, compiles them into optimized, flat Database objects (using a Structure-of-Arrays layout for vectorized operations), and stores them locally as serialized pickle files (.pkl) alongside .json metadata sidecars in the user's local directory (defaults to ~/.kaptive or $KAPTIVE_DB_DIR).

The manager handles:

  • Installation: Fetching a known database from its remote repository (install), or a custom database from any GitHub repository (add), compiling it, and caching the result locally.
  • Updates: Checking the local compiled database against the remote repository's version (specified in the TOML metadata) and downloading/recompiling if a newer version exists (update).
  • Storage & Retrieval: Saving (save) and loading (load) these compiled .pkl files efficiently.
  • Lifecycle Management: Uninstalling specific databases (uninstall) or completely resetting the local cache (reset).

Attributes:

  • _KNOWN (dict[str, tuple[str, str, str]]) –

    Internal lookup mapping of officially supported database keywords to tuples of (repository_owner, repository_name, database_base_name).

  • _DB_DIR (Path) –

    Local cache directory path where .pkl database files and .json metadata sidecars are stored.

Methods:

  • add –

    Add or update a database directly from a specified remote Git repository.

  • get –

    Load a Database from a file path or resolve and load it by keyword.

  • install –

    Install known, officially supported databases by keyword.

  • installed –

    Return a list of keywords for all currently installed databases.

  • known –

    Return a list of keywords for all currently known, officially supported databases.

  • load –

    Load a locally installed, compiled database using its keyword.

  • reset –

    Remove all installed databases by deleting their compiled files from the local directory.

  • save –

    Serialize and save a compiled Database object and its metadata to local storage.

  • uninstall –

    Uninstall a specific database by removing its compiled local .pkl and .json files.

  • update –

    Update installed databases by checking against their remote GitHub repositories.

add classmethod

add(owner: str, repo_name: str, db_name: str, branch: str = 'main', local_meta: DatabaseMetadata | None = None) -> Database | None

Add or update a database directly from a specified remote Git repository.

This is the primary method for adding custom or official databases from GitHub. The procedure:

  1. Constructs raw GitHub URL endpoints for the repository's .toml metadata and .gbk GenBank files.
  2. Downloads and parses the remote TOML metadata to extract version information.
  3. Compares the remote version against local metadata (if available). If up-to-date, skips remaining steps and returns None.
  4. Downloads the raw GenBank file content over HTTP.
  5. Writes source files into a temporary directory and compiles them using from_genbank.
  6. Serializes and caches the compiled Database object into the local storage directory.

Parameters:

  • owner

    (str) –

    Owner or organization of the GitHub repository (e.g., 'klebgenomics').

  • repo_name

    (str) –

    Name of the GitHub repository (e.g., 'KpSC_surface_antigen_loci').

  • db_name

    (str) –

    Base name of the database files in the repository (e.g., 'Klebsiella_pneumoniae_Species_Complex_K').

  • branch

    (str, default: 'main' ) –

    Git branch name to fetch from. Defaults to 'main'.

  • local_meta

    (DatabaseMetadata | None, default: None ) –

    Pre-loaded metadata of local database installation. Defaults to None.

Returns:

  • Database | None –

    Database | None: The newly compiled Database object if installed or updated, or None if the local version was already up-to-date.

Raises:

  • DatabaseError –

    If repository files are not found, network issues occur, or file compilation fails.

See Also

DatabaseManager, Database, DatabaseMetadata, DatabaseError

Source code in src/kaptive/db/manager.py
@classmethod
def add(
    cls,
    owner: str,
    repo_name: str,
    db_name: str,
    branch: str = "main",
    local_meta: DatabaseMetadata | None = None,
) -> Database | None:
    r"""Add or update a database directly from a specified remote Git repository.

    This is the primary method for adding custom or official databases from GitHub. The procedure:

    1. Constructs raw GitHub URL endpoints for the repository's `.toml` metadata and `.gbk` GenBank files.
    2. Downloads and parses the remote TOML metadata to extract version information.
    3. Compares the remote version against local metadata (if available). If up-to-date, skips remaining steps and
       returns `None`.
    4. Downloads the raw GenBank file content over HTTP.
    5. Writes source files into a temporary directory and compiles them using
       [`from_genbank`][kaptive.db.core.Database.from_genbank].
    6. Serializes and caches the compiled [`Database`][kaptive.db.core.Database] object into the local storage
       directory.

    Args:
        owner (str): Owner or organization of the GitHub repository (e.g., `'klebgenomics'`).
        repo_name (str): Name of the GitHub repository (e.g., `'KpSC_surface_antigen_loci'`).
        db_name (str): Base name of the database files in the repository
            (e.g., `'Klebsiella_pneumoniae_Species_Complex_K'`).
        branch (str): Git branch name to fetch from. Defaults to `'main'`.
        local_meta (DatabaseMetadata | None): Pre-loaded metadata of local database installation.
            Defaults to `None`.

    Returns:
        Database | None: The newly compiled [`Database`][kaptive.db.core.Database] object if installed or updated,
            or `None` if the local version was already up-to-date.

    Raises:
        DatabaseError: If repository files are not found, network issues occur, or file compilation fails.

    See Also:
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`Database`][kaptive.db.core.Database],
        [`DatabaseMetadata`][kaptive.db.models.DatabaseMetadata],
        [`DatabaseError`][kaptive.db.models.DatabaseError]
    """
    fetched = cls._fetch_files(owner, repo_name, db_name, branch=branch, local_meta=local_meta)
    if fetched is None:
        return None
    return cls._compile_and_save(*fetched)

get classmethod

Load a Database from a file path or resolve and load it by keyword.

If file_or_keyword points to an existing file, it is loaded directly. Otherwise, it is treated as a keyword. If the keyword is not installed locally, it will be automatically downloaded and installed.

Parameters:

  • file_or_keyword

    (str | Path) –

    File path or recognized database keyword.

Returns:

Source code in src/kaptive/db/manager.py
@classmethod
def get(cls, file_or_keyword: str | Path) -> Database:
    r"""Load a Database from a file path or resolve and load it by keyword.

    If `file_or_keyword` points to an existing file, it is loaded directly.
    Otherwise, it is treated as a keyword. If the keyword is not installed locally,
    it will be automatically downloaded and installed.

    Args:
        file_or_keyword (str | Path): File path or recognized database keyword.

    Returns:
        Database: The loaded [`Database`][kaptive.db.core.Database] instance.
    """
    from kaptive.db.core import Database

    try:
        file_path = Path(file_or_keyword)
        if file_path.is_file():
            return Database.load(file_path)
    except (TypeError, ValueError, OSError):
        pass

    try:
        return cls.load(str(file_or_keyword))
    except DatabaseError:
        result = cls.install(str(file_or_keyword))
        if isinstance(result, list):
            result = result[0]
        if result is None:
            return cls.load(str(file_or_keyword))
        return result

install classmethod

install(kwd: str | list[str]) -> Database | list[Database | None]

Install known, officially supported databases by keyword.

Looks up the repository details (owner, repo, database name) associated with the provided keyword(s) in the internal registry (_KNOWN) and delegates file retrieval and compilation to add. If 'all' or a list of keywords is supplied, fetching is performed concurrently via a thread pool executor.

Parameters:

  • kwd

    (str | list[str]) –

    The keyword(s) of the known database(s) to install (e.g., 'kpsc_k', ['kpsc_k', 'ab_k'], or 'all').

Returns:

  • Database | list[Database | None] –

    Database | list[Database | None]: For a single keyword, returns the compiled Database object (or None if already up-to-date). For a list of keywords or 'all', returns a list of compiled Database objects (or None for entries that were up-to-date).

Raises:

  • DatabaseError –

    If any keyword is not recognized in the list of known databases, or if network/parsing errors occur.

See Also

known, DatabaseManager, add, Database, DatabaseError

Source code in src/kaptive/db/manager.py
@classmethod
def install(cls, kwd: str | list[str]) -> Database | list[Database | None]:
    r"""Install known, officially supported databases by keyword.

    Looks up the repository details (owner, repo, database name) associated with the provided keyword(s)
    in the internal registry (`_KNOWN`) and delegates file retrieval
    and compilation to [`add`][kaptive.db.manager.DatabaseManager.add]. If `'all'` or a list of keywords is
    supplied, fetching is performed concurrently via a thread pool executor.

    Args:
        kwd (str | list[str]): The keyword(s) of the known database(s) to install (e.g., `'kpsc_k'`,
            `['kpsc_k', 'ab_k']`, or `'all'`).

    Returns:
        Database | list[Database | None]: For a single keyword, returns the compiled
            [`Database`][kaptive.db.core.Database] object (or `None` if already up-to-date). For a list of
            keywords or `'all'`, returns a list of compiled [`Database`][kaptive.db.core.Database] objects
            (or `None` for entries that were up-to-date).

    Raises:
        DatabaseError: If any keyword is not recognized in the list of known databases, or if network/parsing
            errors occur.

    See Also:
        [`known`][kaptive.db.manager.DatabaseManager.known],
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`add`][kaptive.db.manager.DatabaseManager.add],
        [`Database`][kaptive.db.core.Database],
        [`DatabaseError`][kaptive.db.models.DatabaseError]
    """
    if kwd == "all":
        kwd = list(cls._KNOWN.keys())

    if isinstance(kwd, list):

        def _fetch_one(k: str):
            if (known_info := cls._KNOWN.get(k, None)) is None:
                raise DatabaseError(f'"{k}" is not a known database, choose from {list(cls._KNOWN.keys())}')
            return cls._fetch_files(*known_info)

        with concurrent.futures.ThreadPoolExecutor() as executor:
            fetched_list = list(executor.map(_fetch_one, kwd))

        results = []
        for fetched in fetched_list:
            if fetched is None:
                results.append(None)
            else:
                results.append(cls._compile_and_save(*fetched))
        return results

    if (known_info := cls._KNOWN.get(kwd, None)) is None:
        raise DatabaseError(f'"{kwd}" is not a known database, choose from {list(cls._KNOWN.keys())}')
    return cls.add(*known_info)  # type: ignore

installed classmethod

installed() -> list[str]

Return a list of keywords for all currently installed databases.

Scans the local storage directory for .pkl files and extracts their keywords from the file stems.

Returns:

  • list[str] –

    list[str]: A list of database keywords corresponding to installed .pkl database files. Returns an empty list if no databases are installed or if the storage directory does not exist.

See Also

DatabaseManager, known

Source code in src/kaptive/db/manager.py
@classmethod
def installed(cls) -> list[str]:
    r"""Return a list of keywords for all currently installed databases.

    Scans the local storage directory for `.pkl` files and extracts their keywords from the file stems.

    Returns:
        list[str]: A list of database keywords corresponding to installed `.pkl` database files.
            Returns an empty list if no databases are installed or if the storage directory does not exist.

    See Also:
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`known`][kaptive.db.manager.DatabaseManager.known]
    """
    if not cls._DB_DIR.exists():
        return []
    return [p.stem for p in cls._DB_DIR.glob("*.pkl")]

known classmethod

known() -> list[str]

Return a list of keywords for all currently known, officially supported databases.

These databases can be installed directly by providing their keyword to install.

Returns:

  • list[str] –

    list[str]: A list of known database keywords (e.g., ['kpsc_k', 'kpsc_o', 'kosc_k', ...]).

See Also

DatabaseManager, install

Source code in src/kaptive/db/manager.py
@classmethod
def known(cls) -> list[str]:
    r"""Return a list of keywords for all currently known, officially supported databases.

    These databases can be installed directly by providing their keyword to
    [`install`][kaptive.db.manager.DatabaseManager.install].

    Returns:
        list[str]: A list of known database keywords (e.g., `['kpsc_k', 'kpsc_o', 'kosc_k', ...]`).

    See Also:
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`install`][kaptive.db.manager.DatabaseManager.install]
    """
    return list(cls._KNOWN.keys())

load classmethod

load(kwd: str) -> Database

Load a locally installed, compiled database using its keyword.

Reads and unpickles the serialized .pkl database file from the local cache directory.

Parameters:

  • kwd

    (str) –

    The keyword identifier of the database to load (e.g., 'kpsc_k').

Returns:

Raises:

  • DatabaseError –

    If the specified database is not installed locally.

See Also

DatabaseManager, Database, DatabaseError

Source code in src/kaptive/db/manager.py
@classmethod
def load(cls, kwd: str) -> Database:
    r"""Load a locally installed, compiled database using its keyword.

    Reads and unpickles the serialized `.pkl` database file from the local cache directory.

    Args:
        kwd (str): The keyword identifier of the database to load (e.g., `'kpsc_k'`).

    Returns:
        Database: The deserialized [`Database`][kaptive.db.core.Database] instance.

    Raises:
        DatabaseError: If the specified database is not installed locally.

    See Also:
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`Database`][kaptive.db.core.Database],
        [`DatabaseError`][kaptive.db.models.DatabaseError]
    """
    return pickle.loads(cls._get_existing_db_path(kwd).read_bytes())

reset classmethod

reset() -> None

Remove all installed databases by deleting their compiled files from the local directory.

This clears the user's ~/.kaptive cache directory of any .pkl database files and .json metadata sidecar files, effectively uninstalling all downloaded and compiled databases.

Returns:

  • None –

    None

See Also

DatabaseManager, uninstall

Source code in src/kaptive/db/manager.py
@classmethod
def reset(cls) -> None:
    r"""Remove all installed databases by deleting their compiled files from the local directory.

    This clears the user's `~/.kaptive` cache directory of any `.pkl` database files and `.json` metadata
    sidecar files, effectively uninstalling all downloaded and compiled databases.

    Returns:
        None

    See Also:
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`uninstall`][kaptive.db.manager.DatabaseManager.uninstall]
    """
    if cls._DB_DIR.exists():
        for file_path in cls._DB_DIR.glob("*.pkl"):
            file_path.unlink()
        for file_path in cls._DB_DIR.glob("*.json"):
            file_path.unlink()

save classmethod

save(db: Database) -> int

Serialize and save a compiled Database object and its metadata to local storage.

Saves the database as a .pkl file named {keyword}.pkl in the local cache directory (_DB_DIR). Also writes a companion {keyword}.json file containing the serialized metadata for fast version checking.

Parameters:

Returns:

  • int ( int ) –

    The total number of bytes written to the .pkl database file.

See Also

DatabaseManager, Database, DatabaseMetadata

Source code in src/kaptive/db/manager.py
@classmethod
def save(cls, db: Database) -> int:
    r"""Serialize and save a compiled Database object and its metadata to local storage.

    Saves the database as a `.pkl` file named `{keyword}.pkl` in the local cache directory (`_DB_DIR`).
    Also writes a companion `{keyword}.json` file containing the serialized metadata for fast version checking.

    Args:
        db (Database): The compiled [`Database`][kaptive.db.core.Database] object to save.

    Returns:
        int: The total number of bytes written to the `.pkl` database file.

    See Also:
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`Database`][kaptive.db.core.Database],
        [`DatabaseMetadata`][kaptive.db.models.DatabaseMetadata]
    """
    db_path = cls._get_db_path(db.metadata.keyword)
    db_path.with_suffix(".json").write_text(json.dumps(asdict(db.metadata)))
    return db_path.write_bytes(pickle.dumps(db, protocol=pickle.HIGHEST_PROTOCOL))

uninstall classmethod

uninstall(kwd: str) -> None

Uninstall a specific database by removing its compiled local .pkl and .json files.

Parameters:

  • kwd

    (str) –

    The keyword of the database to uninstall (e.g., 'kpsc_k').

Returns:

  • None –

    None

Raises:

  • DatabaseError –

    If the specified database is not currently installed locally.

See Also

DatabaseManager, DatabaseError

Source code in src/kaptive/db/manager.py
@classmethod
def uninstall(cls, kwd: str) -> None:
    r"""Uninstall a specific database by removing its compiled local `.pkl` and `.json` files.

    Args:
        kwd (str): The keyword of the database to uninstall (e.g., `'kpsc_k'`).

    Returns:
        None

    Raises:
        DatabaseError: If the specified database is not currently installed locally.

    See Also:
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`DatabaseError`][kaptive.db.models.DatabaseError]
    """
    db_path = cls._get_existing_db_path(kwd)
    db_path.unlink()
    if db_path.with_suffix(".json").exists():
        db_path.with_suffix(".json").unlink()

update classmethod

update(kwd: str | list[str] = 'all') -> Generator[Database, None, None]

Update installed databases by checking against their remote GitHub repositories.

Extracts local metadata to determine the source repository and version, then checks the remote GitHub repository for a newer version. If a newer version is available, the source files (.gbk and .toml) are fetched, compiled into a new Database object, and saved to disk. When updating multiple databases or "all", remote fetches are executed concurrently using a thread pool executor.

Parameters:

  • kwd

    (str | list[str], default: 'all' ) –

    The keyword(s) of the database to update (e.g., 'kpsc_k', ['kpsc_k', 'ab_k'], or 'all'). Defaults to "all", which updates all currently installed databases.

Yields:

  • Database ( Database ) –

    The newly compiled Database object for each database that required an update. Databases that are already up-to-date yield nothing.

Raises:

  • DatabaseError –

    If a requested database is not installed locally, or if network/parsing failures occur during update.

See Also

installed, add, DatabaseManager, Database, DatabaseMetadata, DatabaseError

Source code in src/kaptive/db/manager.py
@classmethod
def update(cls, kwd: str | list[str] = "all") -> Generator[Database, None, None]:
    r"""Update installed databases by checking against their remote GitHub repositories.

    Extracts local metadata to determine the source repository and version, then checks the remote GitHub
    repository for a newer version. If a newer version is available, the source files (`.gbk` and `.toml`)
    are fetched, compiled into a new [`Database`][kaptive.db.core.Database] object, and saved to disk. When
    updating multiple databases or `"all"`, remote fetches are executed concurrently using a thread pool executor.

    Args:
        kwd (str | list[str]): The keyword(s) of the database to update (e.g., `'kpsc_k'`,
            `['kpsc_k', 'ab_k']`, or `'all'`). Defaults to `"all"`, which updates all currently installed databases.

    Yields:
        Database: The newly compiled [`Database`][kaptive.db.core.Database] object for each database that
            required an update. Databases that are already up-to-date yield nothing.

    Raises:
        DatabaseError: If a requested database is not installed locally, or if network/parsing failures occur
            during update.

    See Also:
        [`installed`][kaptive.db.manager.DatabaseManager.installed],
        [`add`][kaptive.db.manager.DatabaseManager.add],
        [`DatabaseManager`][kaptive.db.manager.DatabaseManager],
        [`Database`][kaptive.db.core.Database],
        [`DatabaseMetadata`][kaptive.db.models.DatabaseMetadata],
        [`DatabaseError`][kaptive.db.models.DatabaseError]
    """
    if kwd == "all":
        kwd = cls.installed()
        if not kwd:
            return

    if isinstance(kwd, list):

        def _fetch_update_one(k: str):
            db_path = cls._get_existing_db_path(k)
            json_path = db_path.with_suffix(".json")
            if json_path.is_file():
                meta = DatabaseMetadata.from_dict(json.loads(json_path.read_text()))
            else:
                meta = pickle.loads(db_path.read_bytes()).metadata
            db_name = Path(meta.genbank).with_suffix("").name
            return cls._fetch_files(meta.owner, meta.repo, db_name, branch=meta.branch, local_meta=meta)

        with concurrent.futures.ThreadPoolExecutor() as executor:
            fetched_list = list(executor.map(_fetch_update_one, kwd))

        for fetched in fetched_list:
            if fetched is not None:
                yield cls._compile_and_save(*fetched)
    else:
        db_path = cls._get_existing_db_path(kwd)
        json_path = db_path.with_suffix(".json")
        if json_path.is_file():
            meta = DatabaseMetadata.from_dict(json.loads(json_path.read_text()))
        else:
            meta = pickle.loads(db_path.read_bytes()).metadata
        db_name = Path(meta.genbank).with_suffix("").name
        if (res := cls.add(meta.owner, meta.repo, db_name, branch=meta.branch, local_meta=meta)) is not None:
            yield res

DatabaseMetadata dataclass

DatabaseMetadata(name: str, keyword: str, genbank: str, organism: str, taxon: int, antigen: str, pathway: str, version: str, id_threshold: float, doi: list[str], owner: str, repo: str, branch: str, contact: dict, phenotype_logic: dict, antigenic_units: dict)

Strict schema for Database metadata with dependency-free validation and ergonomic attribute access.

Represents the metadata associated with a Kaptive reference database, including organism details, locus pathway classifications, repository location, curator contact details, and phenotype logic rules. Used by Database and DatabaseManager.

Attributes:

  • name (str) –

    The name of the database, e.g. 'Klebsiella pneumoniae Species Complex K'.

  • keyword (str) –

    The database keyword, e.g. 'kpsc_k'.

  • genbank (str) –

    The name of the main database file, e.g. 'Klebsiella_pneumoniae_Species_Complex_K.gbk'.

  • organism (str) –

    The name of the database organism, e.g. 'Klebsiella pneumoniae Species Complex'.

  • taxon (int) –

    The NCBI Taxonomy ID of the database organism, e.g. 3390273.

  • antigen (str) –

    The name of the database antigen, e.g. 'Capsular polysaccharide'.

  • pathway (str) –

    The name of the database antigen synthesis pathway, e.g. 'Wzx/Wzy-dependent'.

  • version (str) –

    The version of the database, e.g. '3.2.1'.

  • id_threshold (float) –

    The identity threshold of the database, e.g. 82.5.

  • doi (list[str]) –

    A list of DOIs associated with the database, e.g. ['TBD'].

  • owner (str) –

    The owner of the database Github repo, e.g. 'klebgenomics'.

  • repo (str) –

    The name of the database Github repo, e.g. 'KpSC_surface_antigen_loci'.

  • branch (str) –

    The branch of the database Github repo, e.g. 'main'.

  • contact (dict) –

    The details of the database curators, e.g. {'Kelly Wyres': 'kaptive.typing@gmail.com'}.

  • phenotype_logic (dict) –

    Phenotype logic rules defining required loci and genes.

  • antigenic_units (dict) –

    Antigenic unit mappings.

Methods:

  • from_dict –

    Instantiates a DatabaseMetadata object from a dictionary.

parsed_version property

parsed_version: tuple[int, ...]

Parses the semantic version string into a tuple of integers for numeric comparison.

Extracts numeric digit sequences from the DatabaseMetadata attribute and converts them into a tuple of integers (e.g., '3.2.1' becomes (3, 2, 1)).

Returns:

  • tuple[int, ...] –

    tuple[int, ...]: A tuple of extracted integer components representing the database version.

from_dict classmethod

from_dict(data: dict) -> DatabaseMetadata

Instantiates a DatabaseMetadata object from a dictionary.

Validates required fields, casts numeric types, and sets default fallback dictionaries for phenotype logic and antigenic units.

Parameters:

  • data

    (dict) –

    Dictionary containing metadata fields (e.g., parsed from JSON or TOML).

Returns:

Raises:

  • DatabaseError –

    If data is not a dict, missing required keys, or contains invalid attribute types.

Source code in src/kaptive/db/models.py
@classmethod
def from_dict(cls, data: dict) -> "DatabaseMetadata":  # type: ignore
    r"""Instantiates a `DatabaseMetadata` object from a dictionary.

    Validates required fields, casts numeric types, and sets default fallback dictionaries for
    phenotype logic and antigenic units.

    Args:
        data (dict): Dictionary containing metadata fields (e.g., parsed from JSON or TOML).

    Returns:
        DatabaseMetadata: Validated [`DatabaseMetadata`][kaptive.db.models.DatabaseMetadata] instance.

    Raises:
        DatabaseError: If `data` is not a dict, missing required keys, or contains invalid attribute types.
    """
    if not isinstance(data, dict):
        raise DatabaseError("Metadata must be a dictionary.")

    try:
        meta = cls(
            name=data["name"],
            keyword=data["keyword"],
            genbank=data["genbank"],
            organism=data["organism"],
            taxon=int(data["taxon"]),
            antigen=data["antigen"],
            pathway=data["pathway"],
            version=data["version"],
            id_threshold=float(data["id_threshold"]),
            doi=data["doi"],
            owner=data["owner"],
            repo=data["repo"],
            branch=data["branch"],
            contact=data["contact"],
            phenotype_logic=data.get("phenotype_logic", data.get("logic", {})),
            antigenic_units=data.get("antigenic_units", data.get("units", {})),
        )
    except KeyError as e:
        raise DatabaseError(f"Metadata is missing required field: {e.args[0]!r}")
    except ValueError as e:
        raise DatabaseError(f"Metadata has an invalid value type: {e}")

    return meta

Phenotype dataclass

Phenotype(id: str, loci: set[str], extra_genes: set[str], inactive_genes: set[str], priority: int = 50, as_suffix: bool = False)

Single locus phenotype rule mapping loci and gene requirements to a serotype identifier.

Defines criteria for assigning a specific phenotype (e.g., K-type or O-type serotype) based on identified reference loci, required extra genes, and forbidden inactive genes. Processed by Database into vectorized Phenotypes batches.

Attributes:

  • id (str) –

    Unique phenotype or serotype identifier string.

  • loci (set[str]) –

    Locus names in the database to which this phenotype applies.

  • extra_genes (set[str]) –

    Set of gene cluster names that must all be present for this phenotype match.

  • inactive_genes (set[str]) –

    Set of gene cluster names that must not be inactivated for this phenotype match.

  • priority (int) –

    Sorting priority when resolving multiple matching phenotypes. Defaults to 50.

  • as_suffix (bool) –

    Whether to append this phenotype identifier as a suffix to matching phenotypes. Defaults to False.

Phenotypes dataclass

Phenotypes(ids: NDArray[bytes_], locus_masks: NDArray[bool_], extra_masks: NDArray[int8], inactive_masks: NDArray[int8], extra_counts: NDArray[int8], priorities: NDArray[int8], as_suffix: NDArray[bool_])

              flowchart TD
              kaptive.db.Phenotypes[Phenotypes]
              kaptive.core.collections.BatchedContainer[BatchedContainer]

                              kaptive.core.collections.BatchedContainer --> kaptive.db.Phenotypes
                


              click kaptive.db.Phenotypes href "" "kaptive.db.Phenotypes"
              click kaptive.core.collections.BatchedContainer href "" "kaptive.core.collections.BatchedContainer"
            

Structure-of-Arrays (SoA) container for vectorized phenotype evaluation.

Encapsulates boolean matrix masks and priority arrays across a batch of Phenotype definitions for high-performance vectorized evaluation during serotyping. Inherits from BatchedContainer.

Attributes:

  • ids (NDArray[bytes_]) –

    1D byte string array (e.g. S32) of phenotype identifier strings.

  • locus_masks (NDArray[bool_]) –

    2D boolean array of shape (N, num_loci) indicating locus requirements.

  • extra_masks (NDArray[int8]) –

    2D integer array of shape (N, num_extra_genes) for required extra genes.

  • inactive_masks (NDArray[int8]) –

    2D integer array of shape (N, num_inactive_genes) for forbidden inactive genes.

  • extra_counts (NDArray[int8]) –

    1D integer array storing the sum of extra required genes per phenotype.

  • priorities (NDArray[int8]) –

    1D integer array of shape (N,) indicating resolution priority values.

  • as_suffix (NDArray[bool_]) –

    1D boolean array of shape (N,) indicating if phenotype is used as a suffix.

Methods:

  • __getitem__ –

    Slices or masks the Phenotypes container batch along the primary dimension.

  • __len__ –

    Returns the number of phenotype records in the container batch.

  • concat –

    Concatenates multiple Phenotypes batch containers into a single Phenotypes instance.

  • empty –

    Constructs an empty Phenotypes batch container.

  • from_dict –

    Reconstructs a Phenotypes batch container from a dictionary of array data.

  • to_dict –

    Converts the Phenotypes container attributes into a dictionary representation.

__getitem__

__getitem__(item: int | slice | NDArray[Any] | list[int]) -> Any | Phenotypes

Slices or masks the Phenotypes container batch along the primary dimension.

Parameters:

  • item

    (int | slice | NDArray | list) –

    Slice object, boolean mask array, or list of indices to select.

Returns:

  • Any | Phenotypes –

    Any | Phenotypes: A new Phenotypes container containing the selected subset of records.

Raises:

  • NotImplementedError –

    If a single integer index is provided, as scalar indexing is not supported on SoA containers.

Source code in src/kaptive/db/models.py
def __getitem__(self, item: int | slice | npt.NDArray[Any] | list[int]) -> "Any | Phenotypes":
    r"""Slices or masks the `Phenotypes` container batch along the primary dimension.

    Args:
        item (int | slice | npt.NDArray | list): Slice object, boolean mask array, or list of indices to select.

    Returns:
        Any | Phenotypes: A new [`Phenotypes`][kaptive.db.models.Phenotypes] container containing
            the selected subset of records.

    Raises:
        NotImplementedError: If a single integer index is provided, as scalar indexing is not supported
            on SoA containers.
    """
    if isinstance(item, (int, np.integer)):
        raise NotImplementedError("Single item access not implemented for Phenotypes")
    return Phenotypes(
        ids=self.ids[item],
        locus_masks=self.locus_masks[item],
        extra_masks=self.extra_masks[item],
        inactive_masks=self.inactive_masks[item],
        extra_counts=self.extra_counts[item],
        priorities=self.priorities[item],
        as_suffix=self.as_suffix[item],
    )

__len__

__len__() -> int

Returns the number of phenotype records in the container batch.

Returns:

  • int ( int ) –

    Number of phenotype records.

Source code in src/kaptive/db/models.py
def __len__(self) -> int:
    r"""Returns the number of phenotype records in the container batch.

    Returns:
        int: Number of phenotype records.
    """
    return len(self.ids)

concat classmethod

concat(batches: Iterable[Self]) -> Self

Concatenates multiple Phenotypes batch containers into a single Phenotypes instance.

Parameters:

Returns:

  • Phenotypes ( Self ) –

    A single combined Phenotypes batch container. Returns an empty container if batches is empty.

Source code in src/kaptive/db/models.py
@classmethod
def concat(cls, batches: Iterable[Self]) -> Self:  # type: ignore
    r"""Concatenates multiple `Phenotypes` batch containers into a single `Phenotypes` instance.

    Args:
        batches (Iterable[Phenotypes]): An iterable of [`Phenotypes`][kaptive.db.models.Phenotypes]
            container batches to concatenate.

    Returns:
        Phenotypes: A single combined [`Phenotypes`][kaptive.db.models.Phenotypes] batch container.
            Returns an empty container if `batches` is empty.
    """
    batches = list(batches)
    if not batches:
        return cls.empty()  # type: ignore
    return cls(
        ids=np.concatenate([b.ids for b in batches]),
        locus_masks=np.concatenate([b.locus_masks for b in batches]),
        extra_masks=np.concatenate([b.extra_masks for b in batches]),
        inactive_masks=np.concatenate([b.inactive_masks for b in batches]),
        extra_counts=np.concatenate([b.extra_counts for b in batches]),
        priorities=np.concatenate([b.priorities for b in batches]),
        as_suffix=np.concatenate([b.as_suffix for b in batches]),
    )

empty classmethod

empty() -> Phenotypes

Constructs an empty Phenotypes batch container.

Returns:

  • Phenotypes ( Phenotypes ) –

    An empty Phenotypes instance with 0 elements and 2D empty arrays.

Source code in src/kaptive/db/models.py
@classmethod
def empty(cls) -> "Phenotypes":
    r"""Constructs an empty `Phenotypes` batch container.

    Returns:
        Phenotypes: An empty [`Phenotypes`][kaptive.db.models.Phenotypes] instance with 0 elements
            and 2D empty arrays.
    """
    return cls(
        ids=np.empty(0, dtype="S32"),
        locus_masks=np.empty((0, 0), dtype=bool),
        extra_masks=np.empty((0, 0), dtype=np.int8),
        inactive_masks=np.empty((0, 0), dtype=np.int8),
        extra_counts=np.empty(0, dtype=np.int8),
        priorities=np.empty(0, dtype=np.int8),
        as_suffix=np.empty(0, dtype=bool),
    )

from_dict classmethod

from_dict(data: dict) -> Phenotypes

Reconstructs a Phenotypes batch container from a dictionary of array data.

Parameters:

  • data

    (dict) –

    Dictionary containing array and tuple entries corresponding to Phenotypes attributes.

Returns:

Source code in src/kaptive/db/models.py
@classmethod
def from_dict(cls, data: dict) -> "Phenotypes":  # type: ignore
    r"""Reconstructs a `Phenotypes` batch container from a dictionary of array data.

    Args:
        data (dict): Dictionary containing array and tuple entries corresponding to `Phenotypes` attributes.

    Returns:
        Phenotypes: Reconstructed [`Phenotypes`][kaptive.db.models.Phenotypes] container instance.
    """
    return cls(  # type: ignore
        ids=np.array([p.encode("utf-8") for p in data["ids"]], dtype="S32"),
        locus_masks=np.array(data["locus_masks"], dtype=bool),
        extra_masks=np.array(data["extra_masks"], dtype=bool),
        inactive_masks=np.array(data["inactive_masks"], dtype=bool),
        priorities=np.array(data["priorities"], dtype=np.int32),
        as_suffix=np.array(data["as_suffix"], dtype=bool),
    )

to_dict

to_dict() -> dict

Converts the Phenotypes container attributes into a dictionary representation.

Returns:

  • dict ( dict ) –

    Dictionary mapping attribute names (ids, locus_masks, extra_masks, inactive_masks, priorities, as_suffix) to their stored values/arrays.

Source code in src/kaptive/db/models.py
def to_dict(self) -> dict:  # type: ignore
    r"""Converts the `Phenotypes` container attributes into a dictionary representation.

    Returns:
        dict: Dictionary mapping attribute names (`ids`, `locus_masks`, `extra_masks`,
            `inactive_masks`, `priorities`, `as_suffix`) to their stored values/arrays.
    """
    return {
        "ids": np.char.decode(self.ids, "utf-8").tolist(),
        "locus_masks": self.locus_masks,
        "extra_masks": self.extra_masks,
        "inactive_masks": self.inactive_masks,
        "extra_counts": self.extra_counts,
        "priorities": self.priorities,
        "as_suffix": self.as_suffix,
    }