PyNCBI Package Reference

Every public symbol is documented once, under the top-level PyNCBI package. The module sections below carry each module’s overview so you can see where a piece lives.

Top-Level Package (PyNCBI)

PyNCBI - Programmatic & Agent-Ready Python Engine, CLI, and MCP Server for NCBI.

Provides fast, non-interactive tools for searching, inspecting, organizing metadata, and downloading raw/tabular data from NCBI (GEO Series/Samples/Platforms, Entrez, PubMed, Gene, BioProject, and SRA) without altering scientific measurements.

Main Capabilities:
  • Inspect & Organize GEO Data: inspect_accession, extract_gse_samples, preview_geo_file, GSE, GSM, GEOReader

  • Raw & Tabular Downloads: download_geo_files, load_series_matrix, load_rnaseq_counts

  • NCBI-Wide Search & Linking: search_geo, search_pubmed, fetch_pubmed, search_gene, fetch_genes, fetch_sra_runs, fetch_fasta, link_accession

  • Gene & Platform Annotation: fetch_gpl_table, load_rnaseq_annotation, annotate_gene_ids, annotate_probes

  • Cohort & Parallel Downloads: download_geo_files(where=…), download_many, resolve_cohort_files

  • Literature: fetch_pmc_text (PMC Methods / Data Availability), resolve_pmc_id

  • Study Bundles: build_study_bundle

  • Variants: search_clinvar, fetch_clinvar, fetch_dbsnp, fetch_variants

  • Backend Client & Telemetry: NCBIClient, get_client, realm-aware rate limiters & health diagnostics

  • CLI & MCP Server: pyncbi CLI and pyncbi mcp server for AI agents

class PyNCBI.Table[source]

Bases: TypedDict

A JSON-compatible table; identifiers are ordinary, explicit columns.

columns: list[str]
rows: list[list[Any]]
PyNCBI.iter_records(value)[source]

Expose row dictionaries lazily; callers choose their own analysis library.

Return type:

Iterator[dict[str, Any]]

Parameters:

value (Table)

class PyNCBI.GSM(gsm_id, shell_only=False, overwrite_cache=False, *, _http_client=None, _cache=None)[source]

Bases: object

A sample’s metadata and data, loaded through the common retrieval functions.

Parameters:
  • gsm_id (str)

  • shell_only (bool)

  • overwrite_cache (bool)

  • _http_client (HttpClient | None)

  • _cache (Cache[dict[str, Any]] | None)

property gsm_id: str

The GSM identifier (e.g., ‘GSM1518180’).

property array_type: str

The platform GPL ID (e.g., ‘GPL13534’).

property platform_id: str

Alias for array_type (GPL ID).

property gse: str

The parent GSE series ID.

property info: dict[str, Any]

All sample metadata fields as a dictionary.

property data: Table | None

On-page or tabular sample data as a native table (or None if shell_only=True).

property characteristics: dict[str, Any]

Parsed sample characteristics (key: value) as a dictionary.

property supplementary_files: list[str]

List of supplementary file HTTPS URLs attached to this GSM.

property has_data: bool

True if tabular data was loaded into .data.

property title: str

Sample title.

property data_status: DataStatus

Check data availability status from NCBI.

inspect(check_file_sizes=True)[source]

Return a comprehensive InspectionReport for this GSM (including file sizes).

Return type:

InspectionReport

Parameters:

check_file_sizes (bool)

download_supplementary(output_dir=None, *, file_index=None, pattern=None, unpack=False)[source]

Download raw supplementary files for this GSM directly from NCBI.

Return type:

list[Path]

Parameters:
  • output_dir (str | Path | None)

  • file_index (int | None)

  • pattern (str | None)

  • unpack (bool)

to_dict()[source]

Serialize GSM metadata and data summary to a clean dictionary.

Return type:

dict[str, Any]

to_markdown()[source]

Render a clean Markdown summary of this GSM.

Return type:

str

save(output_path, section='data')[source]

Save GSM data or metadata to a file (.csv, .tsv, .json).

Return type:

Path

Parameters:
  • output_path (str | Path)

  • section (str)

is_cached()[source]

Whether this requested sample state has a usable cache entry.

Return type:

bool

store_cache()[source]

Persist the current sample state and its source identity.

Return type:

None

load_cache()[source]

Restore this request’s state when a valid entry exists.

Return type:

None

clear_cache()[source]

Remove sample metadata and all discoverable data variants.

Return type:

bool

class PyNCBI.GSE(gse_id, mode=FetchMode.AUTO, overwrite_cache=False, n_threads=1, remove_gsm_caches=True, shell_only=False, *, file_index=None, file_pattern=None, file_selector=None, _http_client=None, _cache=None)[source]

Bases: object

A study and its samples. Retrieval policy belongs to the shared domain engine.

Parameters:
  • gse_id (str)

  • mode (str | FetchMode)

  • overwrite_cache (bool)

  • n_threads (int)

  • remove_gsm_caches (bool)

  • shell_only (bool)

  • file_index (int | None)

  • file_pattern (str | None)

  • file_selector (FileSelector | None)

  • _http_client (HttpClient | None)

  • _cache (Cache[dict[str, Any]] | None)

property gse_id: str

The GSE identifier (e.g., ‘GSE85506’).

property gsms: dict[str, Any]

Dictionary mapping GSM IDs to GSM objects.

property info: dict[str, Any]

Series metadata as a dictionary.

Setter accepts:

dict[str, Any] | None

property sample_table: Table

native table of all samples in the GSE with metadata and unpacked characteristics.

property characteristics_table: Table

Native sample characteristics, with explicit GSM identifiers.

property characteristics_summary: list[CharacteristicSummary]

Structured breakdown of sample characteristics across the cohort.

property supplementary_files: list[str]

List of supplementary file HTTPS URLs attached to this GSE.

property failed_samples: list[str]

List of GSM IDs that failed to fetch.

property title: str

Series title.

property platform_id: str

Primary platform GPL ID.

property sample_count: int

Number of samples in this series.

keys()[source]

Return view of GSM IDs in this series.

Return type:

KeysView[str]

values()[source]

Return view of GSM objects in this series.

Return type:

ValuesView[Any]

items()[source]

Return (gsm_id, gsm) pairs in this series.

Return type:

ItemsView[str, Any]

list_samples()[source]

Get list of all GSM IDs in this series.

Return type:

list[str]

classmethod inspect(gse_id, *, check_file_sizes=True)[source]

Inspect series metadata without downloading large data files.

Return type:

InspectionReport

Parameters:
  • gse_id (str)

  • check_file_sizes (bool)

download_supplementary(output_dir=None, *, file_index=None, pattern=None, unpack=False)[source]

Download raw supplementary files for this GSE directly from NCBI.

Return type:

list[Path]

Parameters:
  • output_dir (str | Path | None)

  • file_index (int | None)

  • pattern (str | None)

  • unpack (bool)

load_series_matrix(save_to=None)[source]

Download and parse the GEO Series Matrix table for this GSE.

Return type:

Table

Parameters:

save_to (str | Path | None)

load_rnaseq_counts(count_type='raw_counts', save_to=None)[source]

Download and parse NCBI-generated RNA-seq counts for this GSE.

Return type:

Table

Parameters:
  • count_type (str)

  • save_to (str | Path | None)

to_table(section='data')[source]

Export GSE metadata, characteristics, or sample data matrix as a native table.

Return type:

Table

Parameters:

section (str)

to_records(section='data')[source]

Return row dictionaries for callers that prefer record-oriented data.

Return type:

list[dict[str, Any]]

Parameters:

section (str)

to_dict()[source]

Serialize GSE summary and sample characteristics breakdown to a dictionary.

Return type:

dict[str, Any]

to_markdown()[source]

Render a clean Markdown summary of this GSE.

Return type:

str

save(output_path, section='samples')[source]

Save GSE table (samples, characteristics, info, or data) to disk.

Return type:

Path

Parameters:
  • output_path (str | Path)

  • section (str)

is_cached()[source]

Whether this source/file request has a valid cached snapshot.

Return type:

bool

store_cache()[source]

Persist metadata separately from source/file-specific measurements.

Return type:

None

load_cache()[source]

Restore this request’s snapshot without fetching.

Return type:

None

clear_cache()[source]

Remove metadata and all discoverable source/file variants for this study.

Return type:

bool

remove_gsm_cache()[source]

Remove persistent caches of samples held by this series.

Return type:

None

class PyNCBI.GEOReader(*, _http_client=None, _parser=None)[source]

Bases: object

High-level connector for the NCBI GEO database.

Parameters:
  • _http_client (HttpClient | None)

  • _parser (SOFTParser | None)

inspect(accession, check_file_sizes=True)[source]

Inspect any GSE, GSM, or GPL record on NCBI GEO.

Return type:

InspectionReport

Parameters:
  • accession (str)

  • check_file_sizes (bool)

parse_gsm_soft(gsm_soft)[source]

Parse SOFT format text for a GSM into a dictionary.

Return type:

dict[str, Any]

Parameters:

gsm_soft (str)

gsms_from_gse_soft(gse_soft)[source]

Extract GSM IDs from GSE SOFT format text.

Return type:

list[str]

Parameters:

gse_soft (str)

extract_gsm_info(gsm_id)[source]

Extract metadata for a single GSM.

Return type:

dict[str, Any]

Parameters:

gsm_id (str)

extract_gse_sample_info(gse_id, *, where=None, save_to=None)[source]

Extract metadata and unpacked characteristics for all GSM samples in a GSE in O(1) batch request.

Return type:

Table

Parameters:
  • gse_id (str)

  • where (str | None)

  • save_to (str | Path | None)

download_gse_data(gse_id, to_path=None, *, source='auto', unpack=False)[source]

Download data files for a GSE (supplementary, matrix, or rnaseq).

Return type:

list[Path]

Parameters:
  • gse_id (str)

  • to_path (str | Path | None)

  • source (str)

  • unpack (bool)

load_series_matrix(gse_id, *, platform_id=None, save_to=None)[source]

Download and parse the GEO Series Matrix file for a GSE.

Return type:

SeriesMatrixResult

Parameters:
  • gse_id (str)

  • platform_id (str | None)

  • save_to (str | Path | None)

load_rnaseq_counts(gse_id, *, count_type='raw_counts', save_to=None)[source]

Download and parse NCBI-generated RNA-seq count tables for a GSE.

Return type:

Table

Parameters:
  • gse_id (str)

  • count_type (str)

  • save_to (str | Path | None)

get_gsm_data_status(gsm_id)[source]

Check data availability for a GSM (0 = on page, 1 = supplementary files, -1 = no data).

Return type:

int

Parameters:

gsm_id (str)

get_gse_info(gse_id)[source]

Get GSE series metadata.

Return type:

dict[str, Any]

Parameters:

gse_id (str)

list_gse_samples(gse_id)[source]

Get list of GSM IDs in a GSE.

Return type:

list[str]

Parameters:

gse_id (str)

class PyNCBI.NCBIClient(config=None, *, app_config=None)[source]

Bases: object

Realm-aware standard-library HTTP backend client for NCBI.

Manages standard-library HTTP transport, realm-specific rate limiters (eutils, geo, ftp), automatic E-Utilities parameter injection (tool, email, api_key), automatic GET -> POST promotion for long UID queries, application-level error detection, atomic .part resumable downloads, and request telemetry.

Parameters:
clear_response_cache()[source]

Drop every cached response held by this client.

Return type:

None

property app_config: Config

The configuration this client reads credentials and rate limits from.

get_text(url, timeout=None, params=None)[source]

Fetch URL content as UTF-8 text.

Return type:

str

Parameters:
get_json(url, timeout=None, params=None)[source]

Fetch URL content and parse as JSON dictionary.

Return type:

dict[str, Any]

Parameters:
get_bytes(url, timeout=None, params=None)[source]

Fetch URL content as raw bytes.

Return type:

bytes

Parameters:
get_range_bytes(url, max_bytes=32768, timeout=None)[source]

Fetch only the first max_bytes of a remote file via HTTP Range / streaming.

Allows instant previewing of large remote .gz, .csv, .tsv, or .tar files without downloading the full file body.

Return type:

bytes

Parameters:
stream_lines(url, *, params=None, timeout=None, chunk_size=65536, encoding='utf-8')[source]

Stream a remote text (or gzip-compressed text) resource line by line.

Decompresses gzip payloads transparently (by magic bytes, not by extension), so multi-GB GEO CGI tables (acc.cgi?…&view=data) can be parsed incrementally and abandoned early (e.g., limit= rows) without downloading the entire body. Closing the generator early closes the underlying HTTP connection.

Return type:

Iterator[str]

Parameters:
inspect_url(url, source='supplementary', timeout=10.0)[source]

Inspect a remote file via HTTP HEAD without downloading its body.

Returns:

name, url, size_bytes, size_human, last_modified, file_type, source, exists.

Return type:

dict[str, Any]

Parameters:
download_file(url, destination, progress_callback=None, chunk_size=65536, *, resume=True)[source]

Download a file atomically via a .part staging file with HTTP Range resume support.

If an interrupted <destination>.part file exists and resume=True, automatically requests the remaining byte range (Range: bytes=<offset>-) from static NCBI servers and atomically renames <destination>.part -> <destination> on completion.

Return type:

Path

Parameters:
  • url (str)

  • destination (Path)

  • progress_callback (ProgressCallback | None)

  • chunk_size (int)

  • resume (bool)

rate_limit_stats()[source]

Return live token-bucket rate limiter statistics across all NCBI realms.

Return type:

dict[str, dict[str, Any]]

check_health(probe_network=True)[source]

Run a comprehensive diagnostic check of PyNCBI configuration, cache, and NCBI backends.

Parameters:

probe_network (bool) – If True, probes NCBI E-Utilities and GEO endpoints to measure live latency and validate NCBI_API_KEY if configured.

Return type:

dict[str, Any]

Returns:

Structured dictionary suitable for terminal display, JSON output, or MCP tools.

close()[source]

Close the client-owned transport and cookie store.

Return type:

None

class PyNCBI.NCBIClientConfig(timeout=30.0, max_retries=3, retry_backoff=0.5, retry_statuses=(429, 500, 502, 503, 504), rate_limit_per_sec=None, geo_rate_limit_per_sec=8.0, ftp_rate_limit_per_sec=20.0, eutils_post_threshold_chars=1800, extra_headers=dict())[source]

Bases: object

Configuration for NCBIClient.

Variables:
  • timeout (float) – Default request timeout in seconds

  • max_retries (int) – Maximum number of retry attempts on transient/rate-limit errors

  • retry_backoff (float) – Exponential backoff factor between retries

  • retry_statuses (tuple[int, ...]) – HTTP status codes to retry on

  • rate_limit_per_sec (float | None) – Override E-Utilities rate limit (None = auto from Config)

  • geo_rate_limit_per_sec (float) – Max requests/sec to GEO CGI endpoints

  • ftp_rate_limit_per_sec (float) – Max requests/sec to static NCBI FTP/HTTPS servers

  • eutils_post_threshold_chars (int) – Promote E-Utilities GET to POST when URL exceeds this length

Parameters:
  • timeout (float)

  • max_retries (int)

  • retry_backoff (float)

  • retry_statuses (tuple[int, ...])

  • rate_limit_per_sec (float | None)

  • geo_rate_limit_per_sec (float)

  • ftp_rate_limit_per_sec (float)

  • eutils_post_threshold_chars (int)

  • extra_headers (dict[str, str])

timeout: float = 30.0
max_retries: int = 3
retry_backoff: float = 0.5
retry_statuses: tuple[int, ...] = (429, 500, 502, 503, 504)
rate_limit_per_sec: float | None = None
geo_rate_limit_per_sec: float = 8.0
ftp_rate_limit_per_sec: float = 20.0
eutils_post_threshold_chars: int = 1800
extra_headers: dict[str, str]
class PyNCBI.ClientMetrics(max_recent=100, audit_path=None)[source]

Bases: object

Thread-safe telemetry aggregator for NCBIClient.

When audit_path is set (or PYNCBI_AUDIT_LOG is exported) every recorded request is also appended to that file as one JSON object per line, with API keys redacted, so an operator can audit exactly what an autonomous agent asked NCBI for.

Parameters:
  • max_recent (int)

  • audit_path (Path | None)

record(event)[source]

Record a completed or failed HTTP request event.

Return type:

None

Parameters:

event (RequestEvent)

attach_cache(cache)[source]

Expose a client’s response cache in the telemetry summary.

Return type:

None

Parameters:

cache (ResponseCache)

record_cache_hit()[source]

Count a request that was served from the response cache (no NCBI traffic).

Return type:

None

record_retry()[source]
Return type:

None

reset()[source]
Return type:

None

summary(include_recent=10)[source]

Return a structured summary of client telemetry.

Return type:

dict[str, Any]

Parameters:

include_recent (int)

class PyNCBI.RequestEvent(method, realm, url, status_code, elapsed_ms, rate_wait_ms, bytes_received, error=None)[source]

Bases: object

Telemetry record for a single outgoing NCBI HTTP request.

Parameters:
method: str
realm: str
url: str
status_code: int
elapsed_ms: float
rate_wait_ms: float
bytes_received: int
error: str | None = None
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.NCBIRealmLimiter(eutils_rate=2.8, geo_rate=8.0, ftp_rate=20.0, ncbi_rate=5.0, blast_rate=0.1)[source]

Bases: object

Manages independent TokenBucketLimiter instances for each NCBI backend realm.

Parameters:
update_eutils_rate(rate_per_sec)[source]

Update the Entrez E-Utilities rate limit (e.g., when API key is configured).

Return type:

None

Parameters:

rate_per_sec (float)

acquire(url)[source]

Acquire a rate-limit token for the given URL’s realm.

Return type:

tuple[str, float]

Returns:

Tuple of (realm_name, wait_seconds).

Parameters:

url (str)

pause(url, seconds)[source]

Pause the rate limiter for the realm matching url.

Return type:

None

Parameters:
stats()[source]

Return rate-limiter statistics across all NCBI realms.

Return type:

dict[str, dict[str, Any]]

class PyNCBI.TokenBucketLimiter(rate_per_sec=2.8, capacity=None)[source]

Bases: object

Thread-safe token-bucket rate limiter with telemetry and Retry-After support.

Ensures outgoing requests across all threads never exceed the configured requests-per-second limit, and allows global pause when a Retry-After header or rate-limit payload (HTTP 429/503) is encountered.

Parameters:
property rate_per_sec: float

Configured token refill rate per second.

acquire(tokens=1.0)[source]

Block until the requested number of tokens is available.

Return type:

float

Returns:

Total time spent waiting in seconds.

Parameters:

tokens (float)

pause(seconds)[source]

Pause all threads on this bucket for seconds (e.g., on HTTP 429 Retry-After).

Return type:

None

Parameters:

seconds (float)

stats()[source]

Return diagnostic snapshot of this rate limiter.

Return type:

dict[str, Any]

PyNCBI.get_client()[source]

Get the default shared NCBIClient singleton.

Return type:

NCBIClient

PyNCBI.get_default_client()[source]

Alias for get_client().

Return type:

NCBIClient

class PyNCBI.BlastHit(hit_num, accession='', hit_id='', title='', length=0, bit_score=None, score=None, evalue=None, identity=None, align_len=None, gaps=None, query_from=None, query_to=None, hit_from=None, hit_to=None, query_frame=None, hit_frame=None, hsp_count=0)[source]

Bases: object

One BLAST hit, summarized by its best (highest-scoring) HSP.

Parameters:
  • hit_num (int)

  • accession (str)

  • hit_id (str)

  • title (str)

  • length (int)

  • bit_score (float | None)

  • score (int | None)

  • evalue (float | None)

  • identity (int | None)

  • align_len (int | None)

  • gaps (int | None)

  • query_from (int | None)

  • query_to (int | None)

  • hit_from (int | None)

  • hit_to (int | None)

  • query_frame (int | None)

  • hit_frame (int | None)

  • hsp_count (int)

hit_num: int
accession: str = ''
hit_id: str = ''
title: str = ''
length: int = 0
bit_score: float | None = None
score: int | None = None
evalue: float | None = None
identity: int | None = None
align_len: int | None = None
gaps: int | None = None
query_from: int | None = None
query_to: int | None = None
hit_from: int | None = None
hit_to: int | None = None
query_frame: int | None = None
hit_frame: int | None = None
hsp_count: int = 0
property percent_identity: float | None
property query_coverage: int | None
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.BlastJob(rid, program='', database='', status='waiting', there_are_hits=None, estimated_seconds=None, submitted_at='', message='')[source]

Bases: object

A submitted BLAST search.

Parameters:
  • rid (str)

  • program (str)

  • database (str)

  • status (str)

  • there_are_hits (bool | None)

  • estimated_seconds (int | None)

  • submitted_at (str)

  • message (str)

rid: str
program: str = ''
database: str = ''
status: str = 'waiting'
there_are_hits: bool | None = None
estimated_seconds: int | None = None
submitted_at: str = ''
message: str = ''
property url: str
property is_ready: bool
to_dict()[source]
Return type:

dict[str, Any]

to_markdown()[source]
Return type:

str

to_text()[source]
Return type:

str

class PyNCBI.BlastResult(rid='', program='', version='', database='', query_id='', query_def='', query_len=0, hits=list(), stats=dict(), saved_path=None)[source]

Bases: object

Parsed BLAST results.

Parameters:
rid: str = ''
program: str = ''
version: str = ''
database: str = ''
query_id: str = ''
query_def: str = ''
query_len: int = 0
hits: list[BlastHit]
stats: dict[str, Any]
saved_path: Path | None = None
property hit_count: int
hits_table()[source]

Hits as a native table with an explicit accession field, best HSP per hit.

Return type:

Table

to_dict()[source]
Return type:

dict[str, Any]

to_markdown(*, max_hits=20)[source]
Return type:

str

Parameters:

max_hits (int)

to_text()[source]
Return type:

str

PyNCBI.blast(query, *, program='blastn', database=None, megablast=True, evalue=None, hitlist_size=50, word_size=None, entrez_query=None, wait=True, poll_interval=60.0, timeout=900.0, save_to=None, http_client=None)[source]

Run a BLAST search end to end: submit, poll until ready, and return the parsed results.

Parameters:
  • query (str | Path) – Sequence, FASTA text, accession, or a path to a file holding one

  • entrez_query (str | None) – Passed to submit_blast

  • wait (bool) – If False, return the BlastJob immediately after submission

  • poll_interval (float) – Seconds between status checks (clamped to >=10s against NCBI, per their usage policy; default 60)

  • timeout (float) – Give up after this many seconds and raise TimeoutError naming the RID, so the job can still be fetched later

  • save_to (str | Path | None) – Optional path for the hit table

  • http_client (HttpClient | None) – Optional HTTP client

  • program (str)

  • database (str | None)

  • megablast (bool)

  • evalue (float | None)

  • hitlist_size (int)

  • word_size (int | None)

Raises:
  • TimeoutError – Still running when timeout elapsed (the message carries the RID)

  • DataError – NCBI reports the job as unknown/expired or failed

  • NoDataAvailableError – The search finished with no hits

Return type:

BlastResult | BlastJob

PyNCBI.check_blast(rid, *, http_client=None)[source]

Check the status of a submitted BLAST job.

Return type:

BlastJob

Parameters:
  • rid (str)

  • http_client (HttpClient | None)

PyNCBI.delete_blast(rid, *, http_client=None)[source]

Ask NCBI to release a BLAST job (frees shared resources; jobs also expire on their own).

Return type:

bool

Parameters:
  • rid (str)

  • http_client (HttpClient | None)

PyNCBI.fetch_blast(rid, *, save_to=None, http_client=None)[source]

Fetch and parse the results of a finished BLAST job.

Return type:

BlastResult

Parameters:
  • rid (str)

  • save_to (str | Path | None)

  • http_client (HttpClient | None)

PyNCBI.parse_blast_xml(xml_text, *, rid='')[source]

Parse NCBI BLAST XML (BlastOutput) into a BlastResult.

Each hit is summarized by its best HSP (highest bit score) while hsp_count records how many alignments that hit had.

Return type:

BlastResult

Parameters:
PyNCBI.submit_blast(query, *, program='blastn', database=None, megablast=True, evalue=None, hitlist_size=50, word_size=None, entrez_query=None, http_client=None)[source]

Submit a BLAST search and return its job (does not wait for results).

Parameters:
  • query (str | Path) – Nucleotide/protein sequence, FASTA text, an accession, or a path to a file

  • program (str) – ‘blastn’, ‘blastp’, ‘blastx’, ‘tblastn’ or ‘tblastx’

  • database (str | None) – Target database (defaults per program: nt for nucleotide, nr for protein)

  • megablast (bool) – For blastn, use the faster megablast algorithm (default True)

  • evalue (float | None) – Expect-value threshold

  • hitlist_size (int) – Maximum hits to keep (default 50)

  • word_size (int | None) – Optional word size

  • entrez_query (str | None) – Optional Entrez filter, e.g. "Homo sapiens"[organism]

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

BlastJob

class PyNCBI.DownloadPlan(accession, destination, source, files=list(), total_bytes=0, free_bytes=None, notes=list())[source]

Bases: object

What a download would fetch: the files, their sizes, and whether they fit on disk.

Parameters:
accession: str
destination: Path
source: str
files: list[dict[str, Any]]
total_bytes: int = 0
free_bytes: int | None = None
notes: list[str]
property file_count: int
property total_human: str
property fits_on_disk: bool
to_dict()[source]
Return type:

dict[str, Any]

to_markdown()[source]
Return type:

str

to_text()[source]
Return type:

str

class PyNCBI.ScreeningResult(rows=list(), errors=dict(), notes=list(), query='', require=(), saved_path=None)[source]

Bases: object

A comparison table over several GEO series, plus per-study failures.

Parameters:
rows: list[dict[str, Any]]
errors: dict[str, dict[str, Any]]
notes: list[str]
query: str = ''
require: tuple[str, ...] = ()
saved_path: Path | None = None
property table: Table

Native study comparison records, with an explicit gse_id field.

property study_count: int
to_dict()[source]
Return type:

dict[str, Any]

to_markdown(*, max_studies=30)[source]
Return type:

str

Parameters:

max_studies (int)

to_text()[source]
Return type:

str

PyNCBI.plan_geo_download(accession, output_dir=None, *, source='auto', file_index=None, pattern=None, where=None, http_client=None, parser=None)[source]

Report exactly what download_geo_files would fetch, without downloading anything.

Parameters:
  • accession (str) – GSE, GSM, GPL, or GDS accession

  • output_dir (str | Path | None) – Destination the plan is sized against (default ./{accession})

  • source (str) – Same values as download_geo_files

  • file_index (int | None) – 0-based supplementary file index

  • pattern (str | None) – Filename glob filter

  • where (str | None) – For a GSE, a cohort filter selecting per-sample files

  • http_client (HttpClient | None) – Optional HTTP client

  • parser (SOFTParser | None) – Optional SOFT parser

Return type:

DownloadPlan

Returns:

DownloadPlan with the file list, byte total, free space, and fits_on_disk.

PyNCBI.screen_studies(accessions_or_query, *, organism=None, dataset_type=None, min_samples=None, max_samples=None, limit=20, require=(), harmonize=True, check_file_sizes=True, sort_by=None, max_workers=4, save_to=None, http_client=None)[source]

Screen many GEO series into one comparison table.

Parameters:
  • accessions_or_query (str | list[str]) – A list of GSE accessions, a single accession, or a GEO search query

  • organism (str | None) – Search filter (query mode)

  • dataset_type (str | None) – Search filter (query mode): ‘rnaseq’, ‘methylation’, ‘microarray’, …

  • max_samples (int | None) – Search filters (query mode)

  • limit (int) – Maximum studies to screen when searching (default 20)

  • require (tuple[str, ...] | list[str]) – Keep only studies whose harmonized metadata includes all of these canonical fields (e.g. ("sex", "age"))

  • harmonize (bool) – Harmonize characteristics so the coverage columns are populated (default True)

  • check_file_sizes (bool) – HTTP HEAD every file so download_bytes is exact (default True)

  • sort_by (str | None) – Column to sort by, descending (e.g. 'sample_count', 'quality_score'); None keeps the input / search order

  • max_workers (int) – Studies screened in parallel (default 4)

  • save_to (str | Path | None) – Optional path for the table (.csv, .tsv, .json)

  • http_client (HttpClient | None) – Optional HTTP client

  • min_samples (int | None)

Return type:

ScreeningResult

Returns:

ScreeningResult with .table, .rows, .errors and .notes.

class PyNCBI.ExpressionResult(gse_id, source, matrix=table(), sample_table=table(), source_file='', source_url='', column_mapping=dict(), candidates=list(), notes=list(), saved_path=None)[source]

Bases: object

An analysis-ready expression matrix plus how it was obtained.

Parameters:
gse_id: str
source: str
matrix: Table
sample_table: Table
source_file: str = ''
source_url: str = ''
column_mapping: dict[str, str]
candidates: list[dict[str, Any]]
notes: list[str]
saved_path: Path | None = None
property shape: tuple[int, int]
to_dict()[source]
Return type:

dict[str, Any]

to_markdown(*, max_rows=8)[source]
Return type:

str

Parameters:

max_rows (int)

to_text()[source]
Return type:

str

PyNCBI.load_expression(gse_id, *, prefer='auto', count_type='raw_counts', annotate=False, where=None, save_to=None, max_download_mb=None, max_workers=4, http_client=None, parser=None)[source]

Resolve and load the best analysis-ready expression matrix for a GEO series.

Parameters:
  • gse_id (str) – GSE accession

  • prefer (str) – 'auto' (default cascade) or try a source first: 'rnaseq', 'matrix', 'supp', 'per_sample', 'table', 'tar'

  • count_type (str) – For NCBI counts: 'raw_counts', 'norm_counts_TPM', …

  • annotate (bool) – Prepend gene/probe annotation columns to the matrix

  • where (str | None) – Optional cohort filter restricting the sample sheet (and matrix columns)

  • save_to (str | Path | None) – Optional path for the matrix; the sample sheet is written next to it as <stem>_samples.csv

  • max_download_mb (float | None) – Refuse candidates larger than this (default 2048 MB)

  • max_workers (int) – Parallel workers for per-sample sources

  • http_client (HttpClient | None) – Optional HTTP client

  • parser (SOFTParser | None) – Optional SOFT parser

Return type:

ExpressionResult

Returns:

ExpressionResult with matrix (features x GSM), the aligned sample_table, the source used, every candidate considered, and notes.

Raises:
PyNCBI.map_columns_to_gsms(columns, sample_table, *, identifying_fields=('title', 'description', 'source_name_ch1', 'source_name'))[source]

Map matrix column labels onto GSM IDs.

Strategies, in order: the column is a GSM accession, it contains one, it matches a sample title exactly, or it matches another identifying sample field. Matches must be unique; ambiguous labels are left unmapped (and reported) rather than guessed.

Return type:

tuple[dict[str, str], list[str]]

Returns:

(mapping, notes) where mapping maps original column -> GSM ID.

Parameters:
class PyNCBI.GenomeDownloadResult(accession, output_dir, files=list(), include=list(), estimated_size_mb=None)[source]

Bases: object

Outcome of download_genome.

Parameters:
accession: str
output_dir: Path
files: list[Path]
include: list[str]
estimated_size_mb: int | None = None
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.StudyBundle(gse_id, output_dir, files=dict(), report=None, sample_count=0, sra_run_count=0, pubmed_ids=list(), methods_available=False, warnings=list(), created_at='', subseries_bundles=dict(), quality_score=None, harmonization=dict())[source]

Bases: object

Result of build_study_bundle: where everything was written plus key facts.

Parameters:
gse_id: str
output_dir: Path
files: dict[str, Path]
report: InspectionReport | None = None
sample_count: int = 0
sra_run_count: int = 0
pubmed_ids: list[str]
methods_available: bool = False
warnings: list[str]
created_at: str = ''
subseries_bundles: dict[str, StudyBundle]
quality_score: int | None = None
harmonization: dict[str, Any]
to_dict()[source]
Return type:

dict[str, Any]

to_markdown()[source]
Return type:

str

to_text()[source]
Return type:

str

PyNCBI.inspect_accession(accession, *, check_file_sizes=True, include_sample_breakdown=True, http_client=None, parser=None)[source]

Inspect any GSE, GSM, or GPL accession and return a structured InspectionReport.

Performs fast metadata extraction, sample characteristics breakdown, and HTTP HEAD file size checks without downloading large data bodies.

Return type:

InspectionReport

Parameters:
  • accession (str)

  • check_file_sizes (bool)

  • include_sample_breakdown (bool)

  • http_client (HttpClient | None)

  • parser (SOFTParser | None)

PyNCBI.extract_gse_samples(gse_id, *, where=None, save_to=None, http_client=None, parser=None)[source]

Return combined metadata, characteristics and summaries using one batch request.

Return type:

tuple[Table, Table, list[CharacteristicSummary]]

Parameters:
  • gse_id (str)

  • where (str | None)

  • save_to (str | Path | None)

  • http_client (HttpClient | None)

  • parser (SOFTParser | None)

PyNCBI.preview_geo_file(accession, *, source='auto', file_index=None, pattern=None, max_rows=10, http_client=None, parser=None)[source]

Preview columns, row identifiers or archive members from a bounded remote prefix.

Streams only the first 16–64 KB via HTTP Range / streaming without downloading the full file body.

Parameters:
  • accession (str) – GSE, GSM, or GPL accession

  • source (str) – ‘auto’, ‘supp’, ‘matrix’, ‘rnaseq’, or ‘table’

  • file_index (int | None) – 0-based supplementary file index

  • pattern (str | None) – Optional glob/substring pattern for supplementary filename

  • max_rows (int) – Number of rows to include in preview (default 10)

  • http_client (HttpClient | None) – Optional HTTP client

  • parser (SOFTParser | None) – Optional SOFT parser

Return type:

FilePreview

Returns:

FilePreview object with column names, index identifier type, and sample rows

PyNCBI.load_series_matrix(gse_id, *, platform_id=None, annotate=False, annotation_columns=None, save_to=None, http_client=None)[source]

Download and parse a GEO Series Matrix (GSE*_series_matrix.txt.gz) file.

Parameters:
  • gse_id (str) – GSE accession

  • platform_id (str | None) – Platform (GPL) for multi-platform series

  • annotate (bool) – If True, prepend probe→gene annotation columns (e.g. Gene Symbol, ENTREZ_GENE_ID) from the platform’s GPL table to matrix

  • annotation_columns (tuple[str, ...] | list[str] | None) – Override which GPL columns to join

  • save_to (str | Path | None) – Optional path to save matrix

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

SeriesMatrixResult

Returns:

SeriesMatrixResult containing .matrix, .sample_table, .characteristics_table, and .series_info.

PyNCBI.load_rnaseq_counts(gse_id, *, count_type='raw_counts', assembly='auto', annotate=False, annotation_columns=None, save_to=None, http_client=None, parser=None)[source]

Download and parse NCBI-generated RNA-seq count matrices for a GEO Series.

Parameters:
  • gse_id (str) – GSE accession (e.g., ‘GSE152418’)

  • count_type (str) – ‘raw_counts’, ‘norm_counts_TPM’, or ‘norm_counts_FPKM’

  • assembly (str | None) – Genome assembly (‘GRCh38.p13’ for human, ‘GRCm39’ for mouse) or ‘auto’ (default) to resolve from the series organism

  • annotate (bool) – If True, prepend gene annotation columns (Symbol, GeneType, EnsemblGeneID) resolved from the numeric Entrez GeneID index. Measurement columns are never altered.

  • annotation_columns (tuple[str, ...] | list[str] | None) – Override which annotation columns to prepend

  • save_to (str | Path | None) – Optional destination path to save the table (.csv, .tsv)

  • http_client (HttpClient | None) – Optional HTTP client

  • parser (SOFTParser | None) – Optional SOFT parser (used only to resolve the assembly)

Return type:

Table

Returns:

native table with GeneID as index and GSM sample IDs as columns

PyNCBI.read_supplementary_table(url_or_path, *, http_client=None)[source]

Read a tabular supplementary file (.csv, .tsv, .txt, .tab, or .gz).

Delimited text is read straight from the response; binary formats are left to the caller.

Return type:

Table

Parameters:
  • url_or_path (str | Path)

  • http_client (HttpClient | None)

PyNCBI.iter_supplementary_records(url_or_path, *, max_download_mb=None, http_client=None)[source]

Stream native row dictionaries, closing network/files on exhaustion or close().

The caller owns iteration and can wrap rows in any analysis library. This function never materializes the complete table.

Return type:

Iterator[dict[str, Any]]

Parameters:
  • url_or_path (str | Path)

  • max_download_mb (float | None)

  • http_client (HttpClient | None)

PyNCBI.download_geo_files(accession, output_dir=None, *, source='auto', file_index=None, pattern=None, where=None, unpack=False, annotate=False, max_workers=4, expand_subseries=False, max_download_mb=None, check_disk_space=True, http_client=None, parser=None)[source]

Download raw files or data tables for a GSE, GSM, GPL, or GDS exactly as hosted on NCBI.

Parameters:
  • accession (str) – GSE, GSM, or GPL accession

  • output_dir (str | Path | None) – Destination folder or file path (default: ./{accession})

  • source (str) – ‘auto’, ‘supp’ (supplementary), ‘matrix’ (Series Matrix), ‘rnaseq’ (NCBI RNA-seq counts), or ‘table’ (on-page table)

  • file_index (int | None) – 0-based index of supplementary file to download

  • pattern (str | None) – Optional glob filter for supplementary filenames (e.g., *.txt.gz)

  • where (str | None) – For a GSE, a cohort filter (same syntax as extract_gse_samples); only the per-sample supplementary files of matching GSMs are downloaded, in parallel, instead of the series-level GSE_RAW.tar.

  • unpack (bool) – If True, safely extract .tar archives and gunzip .gz files

  • annotate (bool) – For source=’rnaseq’/’matrix’ saved as a table file, prepend gene annotation columns (symbols) to the exported table

  • max_workers (int) – Parallel download workers for multi-file downloads (default 4)

  • expand_subseries (bool) – For a SuperSeries (which owns no data itself), download each SubSeries into <output_dir>/<SubSeries>/ instead of raising

  • max_download_mb (float | None) – Refuse the download if the selected files exceed this budget (default: Config.max_download_mb / PYNCBI_MAX_DOWNLOAD_MB, 2048 MB)

  • check_disk_space (bool) – Refuse the download if it would not fit on the destination filesystem (default True)

  • http_client (HttpClient | None) – Optional HTTP client

  • parser (SOFTParser | None) – Optional SOFT parser

Return type:

list[Path]

Returns:

List of downloaded (and optionally unpacked) local file Paths

PyNCBI.download_many(accessions, output_dir=None, *, source='auto', file_index=None, pattern=None, unpack=False, max_workers=4, annotate=False, expand_subseries=False, max_download_mb=None, check_disk_space=True, http_client=None, parser=None)[source]

Download files for several accessions concurrently (one sub-folder per accession).

Each accession is processed by download_geo_files in its own worker; realm rate limits are still enforced globally by the shared client. All accessions are attempted and failures are aggregated into one DownloadError (with completed_paths).

Return type:

dict[str, list[Path]]

Parameters:
  • accessions (list[str])

  • output_dir (str | Path | None)

  • source (str)

  • file_index (int | None)

  • pattern (str | None)

  • unpack (bool)

  • max_workers (int)

  • annotate (bool)

  • expand_subseries (bool)

  • max_download_mb (float | None)

  • check_disk_space (bool)

  • http_client (HttpClient | None)

  • parser (SOFTParser | None)

PyNCBI.build_study_bundle(gse_id, output_dir=None, *, include_matrix=False, include_sra=True, include_pubmed=True, include_methods=True, where=None, check_file_sizes=True, expand_subseries=False, http_client=None)[source]

Build a complete, self-contained local study directory for a GEO Series.

Parameters:
  • gse_id (str) – GSE accession

  • output_dir (str | Path | None) – Destination directory (default ./<GSE>_bundle)

  • include_matrix (bool) – Also download the primary data table (annotated NCBI RNA-seq counts for sequencing studies, Series Matrix for arrays)

  • include_sra (bool) – Fetch the SRA RunInfo table when the series has sequencing runs

  • include_pubmed (bool) – Fetch linked PubMed articles

  • include_methods (bool) – Also fetch PMC open-access Methods / Data Availability sections

  • where (str | None) – Optional cohort filter applied to samples_metadata.csv

  • check_file_sizes (bool) – HTTP HEAD remote files for byte sizes (default True)

  • expand_subseries (bool) – For a SuperSeries, also build one bundle per SubSeries under <output_dir>/subseries/<GSE>/

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

StudyBundle

Returns:

StudyBundle with the written file paths; optional steps that fail are recorded in warnings instead of aborting the bundle.

PyNCBI.resolve_cohort_files(gse_id, *, where=None, pattern=None, http_client=None, parser=None)[source]

Resolve per-sample supplementary files for a (filtered) GSE cohort in ONE request.

The GEO batch sample view already lists every !Sample_supplementary_file, so the cohort filter (where) and filename pattern are applied without any per-GSM requests.

Return type:

list[CohortFile]

Returns:

List of CohortFile(gsm_id, url, file_name) in GSM order.

Parameters:
  • gse_id (str)

  • where (str | None)

  • pattern (str | None)

  • http_client (HttpClient | None)

  • parser (SOFTParser | None)

PyNCBI.fetch_gpl_table(gpl_id, *, columns=None, limit=None, save_to=None, source='auto', use_cache=True, http_client=None, parser=None)[source]

Retrieve published platform annotation as a native columns/rows payload.

Return type:

Table

Parameters:
  • gpl_id (str)

  • columns (Sequence[str] | None)

  • limit (int | None)

  • save_to (str | Path | None)

  • source (str)

  • use_cache (bool)

  • http_client (HttpClient | None)

  • parser (SOFTParser | None)

PyNCBI.load_rnaseq_annotation(assembly='GRCh38.p13', *, gene_ids=None, refresh=False, http_client=None)[source]

Retrieve gene annotation as native data; full and partial caches remain distinct.

Return type:

Table

Parameters:
  • assembly (str)

  • gene_ids (Iterable[str | int] | None)

  • refresh (bool)

  • http_client (HttpClient | None)

PyNCBI.annotate_gene_ids(data, *, assembly='GRCh38.p13', columns=('Symbol', 'GeneType', 'EnsemblGeneID'), http_client=None)[source]

Retrieve annotations for gene IDs, optionally attaching them to native measurements.

Return type:

Table

Parameters:
  • data (Table | Iterable[str | int])

  • assembly (str)

  • columns (Sequence[str] | None)

  • http_client (HttpClient | None)

PyNCBI.annotate_probes(data, gpl_id, *, columns=None, http_client=None)[source]

Attach retrieved probe annotation by explicit feature ID without changing values.

Return type:

Table

Parameters:
  • data (Table)

  • gpl_id (str)

  • columns (Sequence[str] | None)

  • http_client (HttpClient | None)

PyNCBI.gse_of_gsm(gsm_id, *, http_client=None, parser=None)[source]

Return the parent GSE accession(s) for a GSM sample.

Return type:

str | list[str]

Parameters:
  • gsm_id (str)

  • http_client (HttpClient | None)

  • parser (SOFTParser | None)

PyNCBI.platform_of_gsm(gsm_id, *, http_client=None, parser=None)[source]

Return the platform GPL accession(s) for a GSM sample.

Return type:

str | list[str]

Parameters:
  • gsm_id (str)

  • http_client (HttpClient | None)

  • parser (SOFTParser | None)

PyNCBI.parse_characteristics(char_sections, indices=None)[source]

Parse characteristics into native records with explicit GSM identifiers.

Return type:

Table

Parameters:
PyNCBI.search_geo(query, *, organism=None, entry_type='gse', dataset_type=None, min_samples=None, max_samples=None, limit=20, http_client=None)[source]

Search NCBI GEO (db=gds) and return structured GEOSearchHit records.

Automatically handles NCBI’s GDS numeric UID-to-GSE accession translation and entry-type filtering.

Parameters:
  • query (str) – Search query (e.g., ‘fibromyalgia methylation’, ‘breast cancer single cell’)

  • organism (str | None) – Optional organism filter (e.g., ‘Homo sapiens’, ‘Mus musculus’)

  • entry_type (str) – ‘gse’ (series, default), ‘gsm’ (samples), ‘gpl’ (platforms), ‘gds’, or ‘all’

  • dataset_type (str | None) – Optional dataset type shorthand (‘rnaseq’, ‘methylation’, ‘microarray’, ‘scrnaseq’) or full NCBI DataSet Type string

  • min_samples (int | None) – Minimum number of samples in series

  • max_samples (int | None) – Maximum number of samples in series

  • limit (int | None) – Maximum number of hits to return (default 20; None returns every match)

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

list[GEOSearchHit]

Returns:

List of GEOSearchHit objects

PyNCBI.search_pubmed(query, *, limit=10, sort='relevance', http_client=None)[source]

Search PubMed and return full PubMedArticle records including abstracts.

Return type:

list[PubMedArticle]

Parameters:
  • query (str)

  • limit (int | None)

  • sort (str)

  • http_client (HttpClient | None)

PyNCBI.fetch_pubmed(pmids, *, http_client=None)[source]

Fetch full PubMed articles (including abstracts, authors, DOIs) by PMID.

Return type:

list[PubMedArticle]

Parameters:
  • pmids (list[str] | str)

  • http_client (HttpClient | None)

PyNCBI.fetch_pmc_text(pmid_or_pmcid, *, sections=None, http_client=None)[source]

Fetch the open-access full text of an article from PubMed Central as sections.

Parameters:
  • pmid_or_pmcid (str) – PMID (e.g. ‘32433946’), ‘PMID:…’, or PMCID (e.g. ‘PMC7236739’)

  • sections (list[str] | tuple[str, ...] | None) – Optional filter: kinds (‘methods’, ‘results’, ‘discussion’, ‘data_availability’, ‘introduction’, ‘supplementary’) and/or title substrings. None keeps every section.

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

PMCFullText

Returns:

PMCFullText; is_open_access=False with an explanatory notes when PMC has no redistributable XML for the article (or the PMID is not in PMC at all).

PyNCBI.resolve_pmc_id(pmid_or_pmcid, *, http_client=None)[source]

Resolve a PMID or PMCID into (pmid, pmcid); missing parts are empty strings.

A PMCID input is returned as-is (its PMID is filled in later from the article XML). A PMID is linked to PMC via elink (pubmed_pmc); ‘’ when the paper is not in PMC.

Return type:

tuple[str, str]

Parameters:
  • pmid_or_pmcid (str)

  • http_client (HttpClient | None)

PyNCBI.attach_full_text(articles, *, sections=('methods', 'data_availability'), http_client=None)[source]

Attach PMC full text (filtered to sections) to each PubMedArticle in place.

Return type:

list[PubMedArticle]

Parameters:
PyNCBI.search_gene(query, *, organism='Homo sapiens', limit=10, http_client=None)[source]

Search NCBI Gene by symbol, keyword, or ID and return GeneRecord objects.

Return type:

list[GeneRecord]

Parameters:
  • query (str)

  • organism (str | None)

  • limit (int)

  • http_client (HttpClient | None)

PyNCBI.fetch_genes(gene_ids, *, http_client=None)[source]

Fetch structured NCBI Gene records by numeric Entrez Gene ID(s).

Return type:

list[GeneRecord]

Parameters:
  • gene_ids (list[str] | str)

  • http_client (HttpClient | None)

PyNCBI.fetch_sra_runs(accession_or_query, *, limit=500, save_to=None, http_client=None)[source]

Fetch an NCBI SRA RunInfo table for any GSE, GSM, PRJNA, SRP, SRX, SRR, or search query.

Automatically resolves GEO Series (GSE) or Sample (GSM) accessions to their linked BioProject/SRA identifiers before querying SRA.

Parameters:
  • accession_or_query (str) – GSE, GSM, PRJNA, SRP, SRX, SRR accession, or Entrez SRA query

  • limit (int | None) – Maximum number of SRA experiments to fetch (default 500)

  • save_to (str | Path | None) – Optional path (.csv, .tsv, .json) to save the RunInfo table

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

Table

Returns:

Native table with an explicit Run field (SRR…) with sequencing metadata, layout, size_MB, and download_path

PyNCBI.fetch_fasta(accessions, *, db='nuccore', seq_start=None, seq_stop=None, save_to=None, http_client=None)[source]

Fetch Nucleotide or Protein FASTA sequence(s) from NCBI Entrez (efetch).

Parameters:
  • accessions (list[str] | str) – Accession ID or list of IDs (e.g., ‘NM_007294.4’, ‘NP_009225.1’)

  • db (str) – ‘nuccore’ (nucleotide, default) or ‘protein’

  • seq_start (int | None) – Optional 1-based start coordinate for sequence region slicing

  • seq_stop (int | None) – Optional 1-based stop coordinate for sequence region slicing

  • save_to (str | Path | None) – Optional file path (.fasta, .fa, .txt) to save raw FASTA output

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

list[FASTASequence]

Returns:

List of FASTASequence objects

PyNCBI.search_ncbi(db, query, *, limit=20, raw=False, http_client=None)[source]

Search any NCBI Entrez database and return clean record dictionaries.

For biosample, bioproject, nuccore/nucleotide, protein, and taxonomy the raw esummary documents are flattened into structured records (see BioSampleRecord, BioProjectRecord, NucleotideRecord, TaxonRecord). Pass raw=True to get NCBI’s original esummary dictionaries. limit=None returns every match (paginated).

Return type:

list[dict[str, Any]]

Parameters:
  • db (str)

  • query (str)

  • limit (int | None)

  • raw (bool)

  • http_client (HttpClient | None)

PyNCBI.search_clinvar(query, *, significance=None, gene=None, limit=20, save_to=None, http_client=None)[source]

Search ClinVar and return clean ClinVarRecord objects.

Parameters:
  • query (str) – Gene symbol (‘BRCA1’), rsID (‘rs80357906’), HGVS (‘NM_007294.4:c.5266dupC’), VCV accession, or free text (‘BRCA1 frameshift’)

  • significance (str | None) – Optional clinical significance filter (‘pathogenic’, ‘likely pathogenic’, ‘benign’, ‘uncertain significance’, …)

  • gene (str | None) – Optional gene symbol restriction (for free-text queries)

  • limit (int | None) – Maximum number of variants (default 20)

  • save_to (str | None) – Optional path (.csv, .tsv, .json) to save the records

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

list[ClinVarRecord]

PyNCBI.esearch_ids(db, term, *, limit=20, sort=None, http_client=None)[source]

Run esearch with transparent retstart pagination.

Parameters:
  • db (str) – Entrez database

  • term (str) – Entrez query

  • limit (int | None) – Maximum UIDs to return; None fetches every match (pages of 1000)

  • sort (str | None) – Optional Entrez sort key (e.g. ‘relevance’, ‘pub_date’)

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

tuple[list[str], int]

Returns:

(uids, total_count) where total_count is NCBI’s full hit count.

PyNCBI.esummary_docs(db, uids, *, http_client=None, batch_size=500)[source]

Fetch esummary documents for many UIDs in batches (POST-promoted automatically).

Return type:

dict[str, dict[str, Any]]

Parameters:
  • db (str)

  • uids (list[str])

  • http_client (HttpClient | None)

  • batch_size (int)

PyNCBI.fetch_biosamples(ids, *, http_client=None)[source]

Fetch BioSample records by SAMN accession, numeric UID, GSM, or SRS identifier.

Return type:

list[BioSampleRecord]

Parameters:
  • ids (list[str] | str)

  • http_client (HttpClient | None)

PyNCBI.fetch_bioprojects(ids, *, http_client=None)[source]

Fetch BioProject records by PRJNA/PRJEB/PRJDB accession or numeric UID.

Return type:

list[BioProjectRecord]

Parameters:
  • ids (list[str] | str)

  • http_client (HttpClient | None)

PyNCBI.fetch_taxonomy(ids_or_names, *, http_client=None)[source]

Fetch Taxonomy records (with full lineage) by TaxID or exact scientific name.

Return type:

list[TaxonRecord]

Parameters:
  • ids_or_names (list[str] | str)

  • http_client (HttpClient | None)

PyNCBI.search_taxonomy(query, *, limit=10, http_client=None)[source]

Search NCBI Taxonomy by any name (common, scientific, synonym) and return lineage-aware records.

Return type:

list[TaxonRecord]

Parameters:
  • query (str)

  • limit (int)

  • http_client (HttpClient | None)

PyNCBI.fetch_fastq_urls(accession, *, save_to=None, http_client=None)[source]

Resolve an accession to its FASTQ files (one row per file) via the ENA mirror.

Parameters:
  • accession (str) – GSE, GSM, PRJNA/PRJEB, SRP/ERP, SRX, SRS, SAMN, or SRR/ERR accession

  • save_to (str | Path | None) – Optional path (.csv/.tsv/.json) to save the manifest

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

Table

Returns:

Native table with run_accession, sample_alias (GSM when submitted via GEO), file_name, file_url (HTTPS), size_bytes, md5, read_index, layout, strategy, instrument, read/base counts, and linked sample/experiment/study accessions.

PyNCBI.download_fastq(accession_or_manifest, output_dir=None, *, runs=None, max_workers=4, verify_md5=True, max_download_mb=None, check_disk_space=True, http_client=None)[source]

Download FASTQ files (parallel, resumable, MD5-verified) for an accession or manifest.

Parameters:
  • accession_or_manifest (str | Table) – Accession accepted by fetch_fastq_urls, or its native table

  • output_dir (str | Path | None) – Destination folder (default ./<accession>_fastq)

  • runs (list[str] | None) – Optional subset of run accessions (SRR…) to download

  • max_workers (int) – Parallel transfers (default 4)

  • verify_md5 (bool) – Verify each file against ENA’s MD5 (default True)

  • http_client (HttpClient | None) – Optional HTTP client

  • max_download_mb (float | None)

  • check_disk_space (bool)

Raises:

DownloadError – On transfer failure or MD5 mismatch (bad files are removed)

Return type:

list[Path]

PyNCBI.search_assemblies(taxon, *, reference_only=True, limit=20, http_client=None)[source]

List genome assemblies for an organism name or TaxID (reference assemblies by default).

Return type:

list[AssemblyRecord]

Parameters:
  • taxon (str)

  • reference_only (bool)

  • limit (int)

  • http_client (HttpClient | None)

PyNCBI.fetch_assembly(accession, *, http_client=None)[source]

Fetch the report for one genome assembly accession (GCF_... or GCA_...).

Return type:

AssemblyRecord

Parameters:
  • accession (str)

  • http_client (HttpClient | None)

PyNCBI.download_genome(accession, output_dir=None, *, include=('genome',), unpack=True, max_download_mb=None, check_disk_space=True, http_client=None)[source]

Download a genome data package (FASTA/GFF3/GTF/protein…) and unpack it safely.

Parameters:
  • accession (str) – Assembly accession (GCF_... or GCA_...)

  • output_dir (str | Path | None) – Destination folder (default ./<accession>)

  • include (tuple[str, ...] | list[str]) – Any of ‘genome’, ‘gff3’, ‘gtf’, ‘gbff’, ‘rna’, ‘protein’, ‘cds’, ‘seq-report’

  • unpack (bool) – Extract the zip and flatten the data files into output_dir (default True)

  • http_client (HttpClient | None) – Optional HTTP client

  • max_download_mb (float | None)

  • check_disk_space (bool)

Return type:

GenomeDownloadResult

PyNCBI.export_citations(articles, save_to, *, fmt=None)[source]

Export articles as BibTeX or RIS; returns the written Path, or the text when save_to is None.

fmt defaults from the file suffix (‘.bib’ -> bibtex, ‘.ris’ -> ris).

Return type:

Path | str

Parameters:
PyNCBI.to_bibtex(article, key=None)[source]

Render a PubMed article as a BibTeX @article entry.

Return type:

str

Parameters:
PyNCBI.to_ris(article)[source]

Render a PubMed article as an RIS record.

Return type:

str

Parameters:

article (PubMedArticle)

PyNCBI.load_gds(gds_id, *, full=False, save_to=None, http_client=None)[source]

Download and parse a GEO DataSet (GDS) value table with its experimental subsets.

Parameters:
  • gds_id (str) – GDS accession (e.g., ‘GDS1234’)

  • full (bool) – Fetch the _full.soft.gz variant (includes extra platform annotation columns)

  • save_to (str | Path | None) – Optional path to save the value table (.csv, .tsv, .json)

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

GDSResult

Returns:

GDSResult with .table (ID_REF x [IDENTIFIER, GSM…]), .subsets, .sample_groups, and .info.

PyNCBI.fetch_clinvar(ids, *, http_client=None)[source]

Fetch ClinVar records by Variation ID(s) (numeric) or VCV accession(s).

Return type:

list[ClinVarRecord]

Parameters:
  • ids (list[str] | str)

  • http_client (HttpClient | None)

PyNCBI.fetch_dbsnp(rsids, *, http_client=None)[source]

Fetch dbSNP reference SNP records by rsID(s) (e.g. ‘rs7412’ or ‘7412’).

Return type:

list[DbSNPRecord]

Parameters:
  • rsids (list[str] | str)

  • http_client (HttpClient | None)

PyNCBI.fetch_variants(query, *, source='auto', significance=None, gene=None, limit=20, http_client=None)[source]

Look up a gene / rsID / HGVS / VCV in ClinVar and/or dbSNP in one call.

source=’auto’ queries ClinVar always and dbSNP additionally when the query is an rsID. Returns {‘query’, ‘source’, ‘clinvar’: […], ‘dbsnp’: […]} with record dicts.

Return type:

dict[str, Any]

Parameters:
  • query (str)

  • source (str)

  • significance (str | None)

  • gene (str | None)

  • limit (int)

  • http_client (HttpClient | None)

Find cross-database links for a GEO (GSE/GSM) or PubMed (PMID) accession.

For a GSE: returns linked PubMed IDs, BioProject ID, platforms, sample count, and FTP URL. For a PMID: finds any GEO datasets (db=gds) citing or deposited by that paper!

Return type:

dict[str, Any]

Parameters:
  • accession (str)

  • http_client (HttpClient | None)

class PyNCBI.StudyRecord(gse_id, title='', summary='', overall_design='', organisms=list(), platforms=list(), experiment_types=list(), pubmed_ids=list(), bioproject_id='', superseries_id='', subseries_ids=list(), declared_sample_count=0, samples=list(), files=list(), links=dict(), harmonization=dict(), quality=None, retrieved_at='', source_versions=dict(), extra=dict())[source]

Bases: object

One GEO series (GSE) with its samples, files, links, harmonization summary, and quality.

Parameters:
gse_id: str
title: str = ''
summary: str = ''
overall_design: str = ''
organisms: list[str]
platforms: list[str]
experiment_types: list[str]
pubmed_ids: list[str]
bioproject_id: str = ''
superseries_id: str = ''
subseries_ids: list[str]
declared_sample_count: int = 0
samples: list[SampleRecord]
files: list[dict[str, Any]]
harmonization: dict[str, Any]
quality: QualityReport | None = None
retrieved_at: str = ''
source_versions: dict[str, str]
extra: dict[str, Any]
property sample_count: int
sample_table()[source]

Raw sample table: core fields + original characteristics columns, indexed by GSM.

Return type:

Table

harmonized_table()[source]

Harmonized sample table (canonical columns + derived + raw:<key> for unmapped).

Return type:

Table

provenance_table()[source]
Return type:

Table

to_dict(*, include_samples=True)[source]
Return type:

dict[str, Any]

Parameters:

include_samples (bool)

classmethod from_dict(data)[source]
Return type:

StudyRecord

Parameters:

data (dict[str, Any])

canonical_json()[source]

Deterministic JSON of the NCBI-derived content (excludes retrieval time and quality).

Return type:

str

content_hash()[source]

SHA-256 of the canonical JSON; equal hashes mean identical NCBI content.

Return type:

str

to_markdown(*, max_samples=15)[source]
Return type:

str

Parameters:

max_samples (int)

to_text()[source]
Return type:

str

save(output_dir)[source]
Return type:

dict[str, Any]

Parameters:

output_dir (str | Any)

class PyNCBI.SampleRecord(gsm_id, title='', organism='', platform_id='', source_name='', molecule='', library_strategy='', characteristics=dict(), harmonized=dict(), supplementary_files=list(), links=dict(), data_row_count=0, extra=dict())[source]

Bases: object

One GEO sample (GSM) with raw characteristics, harmonized values, and cross-database links.

Parameters:
gsm_id: str
title: str = ''
organism: str = ''
platform_id: str = ''
source_name: str = ''
molecule: str = ''
library_strategy: str = ''
characteristics: dict[str, str]
harmonized: dict[str, NormalizedValue]
supplementary_files: list[str]
data_row_count: int = 0
extra: dict[str, Any]
to_dict()[source]
Return type:

dict[str, Any]

classmethod from_dict(data)[source]
Return type:

SampleRecord

Parameters:

data (dict[str, Any])

class PyNCBI.NormalizedValue(value=None, raw='', unit=None, confidence='verbatim', rule='', source_key='', source='geo:characteristics_ch1', extra=dict())[source]

Bases: object

A harmonized value plus the raw string it was derived from.

Parameters:
value: Any = None
raw: str = ''
unit: str | None = None
confidence: str = 'verbatim'
rule: str = ''
source_key: str = ''
source: str = 'geo:characteristics_ch1'
extra: dict[str, Any]
property provenance: Provenance
to_dict()[source]
Return type:

dict[str, Any]

classmethod from_dict(data)[source]
Return type:

NormalizedValue

Parameters:

data (dict[str, Any])

class PyNCBI.QualityReport(score=100, issues=list(), completeness=dict(), assessed_at='')[source]

Bases: object

Completeness score (0-100) and issues for a study record.

Parameters:
score: int = 100
issues: list[QualityIssue]
completeness: dict[str, float]
assessed_at: str = ''
to_dict()[source]
Return type:

dict[str, Any]

classmethod from_dict(data)[source]
Return type:

QualityReport

Parameters:

data (dict[str, Any])

class PyNCBI.HarmonizedTable(normalized_table, raw_table, provenance_table, field_map=dict(), unmapped_keys=list(), conflicts=list(), coverage=0.0)[source]

Bases: object

Result of harmonize_characteristics().

Parameters:
normalized_table: Table
raw_table: Table
provenance_table: Table
field_map: dict[str, str]
unmapped_keys: list[str]
conflicts: list[dict[str, Any]]
coverage: float = 0.0
summary()[source]
Return type:

dict[str, Any]

PyNCBI.build_study_record(gse_id, *, harmonize=True, assess=True, enrich=(), where=None, check_file_sizes=False, http_client=None)[source]

Assemble a complete, versioned StudyRecord for a GEO series.

Two GEO requests are needed (series header + batch sample view); HEAD requests are added when check_file_sizes is True; each enrichment adds E-utilities calls.

Parameters:
  • gse_id (str) – GSE accession

  • harmonize (bool) – Map characteristics to the controlled vocabulary (default True)

  • assess (bool) – Attach a quality report (default True)

  • enrich (tuple[str, ...] | list[str]) – Any of 'biosample' (attributes merged + harmonized), 'sra' (run accessions per sample), 'pubmed' (linked articles in extra['pubmed'])

  • where (str | None) – Optional cohort filter (same syntax as extract_gse_samples)

  • check_file_sizes (bool) – HTTP HEAD file sizes for the file inventory

  • http_client (HttpClient | None) – Optional HTTP client

Return type:

StudyRecord

PyNCBI.harmonize_characteristics(char_df, *, source='geo:characteristics_ch1')[source]

Harmonize a samples x characteristics native table (as returned by extract_gse_samples).

Returns canonical columns (e.g. sex, age, disease) plus derived columns (age_unit, age_years, is_control) and raw:<key> columns for keys the conservative vocabulary does not map, with a per-cell provenance table.

Return type:

HarmonizedTable

Parameters:
PyNCBI.harmonize_sample(characteristics, *, source='geo:characteristics_ch1')[source]

Harmonize one sample’s {key: value} characteristics into canonical NormalizedValues.

Unmapped keys are returned under raw:<key> with confidence unmapped so nothing is lost.

Return type:

dict[str, NormalizedValue]

Parameters:
PyNCBI.assess_study(record, *, ragged_threshold=0.5)[source]

Score a study record 0-100 and list its quality issues.

Return type:

QualityReport

Parameters:
class PyNCBI.MetadataStore(cache_dir=None, *, ttl_seconds=604800)[source]

Bases: object

TTL-aware, content-hashed store of StudyRecords built on the pickle-free LocalCache.

Parameters:
  • cache_dir (str | Path | None)

  • ttl_seconds (float)

property cache_dir: Path
get(gse_id, *, max_age=None)[source]

Return the stored record if present and younger than max_age (default: TTL).

Return type:

StudyRecord | None

Parameters:
put(record)[source]
Return type:

dict[str, Any]

Parameters:

record (StudyRecord)

get_or_build(gse_id, *, max_age=None, **build_kwargs)[source]

Return a fresh stored record or build (and store) a new one.

Return type:

StudyRecord

Parameters:
  • gse_id (str)

  • max_age (float | None)

  • build_kwargs (Any)

delete(gse_id)[source]
Return type:

bool

Parameters:

gse_id (str)

index()[source]

Summaries of every stored record (no sample payloads).

Return type:

list[dict[str, Any]]

PyNCBI.save_study_record(record, output_dir)[source]

Write the documented study layout and a checksummed manifest; returns the manifest.

Return type:

dict[str, Any]

Parameters:
PyNCBI.load_study_record(directory, *, verify=True)[source]

Load a saved study layout, verifying every file against manifest.json by default.

Return type:

StudyRecord

Parameters:
PyNCBI.json_schema(name='study')[source]

Return the JSON Schema (draft 2020-12) for the study or sample record.

Return type:

dict[str, Any]

Parameters:

name (str)

class PyNCBI.NCBIFileInfo(name, url, size_bytes=None, size_human='unknown', last_modified=None, file_type='file', source='supplementary', exists=True)[source]

Bases: object

Metadata for a downloadable file hosted on NCBI.

Parameters:
  • name (str)

  • url (str)

  • size_bytes (int | None)

  • size_human (str)

  • last_modified (str | None)

  • file_type (str)

  • source (str)

  • exists (bool)

name: str
url: str
size_bytes: int | None = None
size_human: str = 'unknown'
last_modified: str | None = None
file_type: str = 'file'
source: str = 'supplementary'
exists: bool = True
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.CharacteristicSummary(name, dtype, non_null_count, total_count, unique_count, value_counts=None, numeric_stats=None)[source]

Bases: object

Summary of a parsed sample characteristic column across a GSE cohort.

Parameters:
name: str
dtype: str
non_null_count: int
total_count: int
unique_count: int
value_counts: dict[str, int] | None = None
numeric_stats: dict[str, float] | None = None
to_dict()[source]
Return type:

dict[str, Any]

format_brief()[source]

Concise 1-line summary for terminal and Markdown views.

Return type:

str

class PyNCBI.InspectionReport(accession, record_type, title='', summary='', overall_design='', organisms=list(), platforms=list(), experiment_types=list(), pubmed_ids=list(), bioproject_id='', sra_url='', biosample_url='', parent_gse='', superseries_id='', subseries_ids=list(), sample_count=0, gsm_ids=list(), data_row_count=0, characteristics=dict(), characteristics_summary=list(), files=list(), extra_metadata=dict())[source]

Bases: object

Comprehensive overview of an NCBI GEO accession (GSE, GSM, or GPL).

Parameters:
accession: str
record_type: str
title: str = ''
summary: str = ''
overall_design: str = ''
organisms: list[str]
platforms: list[str]
experiment_types: list[str]
pubmed_ids: list[str]
bioproject_id: str = ''
sra_url: str = ''
biosample_url: str = ''
parent_gse: str = ''
superseries_id: str = ''
subseries_ids: list[str]
sample_count: int = 0
gsm_ids: list[str]
data_row_count: int = 0
characteristics: dict[str, str]
characteristics_summary: list[CharacteristicSummary]
files: list[NCBIFileInfo]
extra_metadata: dict[str, Any]
to_dict()[source]
Return type:

dict[str, Any]

to_markdown()[source]

Render a clean, structured Markdown overview.

Return type:

str

to_text()[source]

Render a clean terminal text overview.

Return type:

str

class PyNCBI.FilePreview(accession, file_name, url, source, file_type, total_columns=0, columns=list(), index_name='', sample_ids_preview=list(), preview_rows=list(), archive_members=list(), notes='')[source]

Bases: object

Instant streaming preview of a remote NCBI GEO file or archive without full download.

Parameters:
accession: str
file_name: str
url: str
source: str
file_type: str
total_columns: int = 0
columns: list[str]
index_name: str = ''
sample_ids_preview: list[str]
preview_rows: list[dict[str, Any]]
archive_members: list[dict[str, Any]]
notes: str = ''
to_dict()[source]
Return type:

dict[str, Any]

to_markdown()[source]
Return type:

str

to_text()[source]
Return type:

str

class PyNCBI.FASTASequence(accession, description, db, length, sequence, fasta_text)[source]

Bases: object

Structured NCBI Nucleotide or Protein FASTA sequence record.

Parameters:
accession: str
description: str
db: str
length: int
sequence: str
fasta_text: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.GEOSearchHit(accession, gds_uid, entry_type, title='', summary='', organism='', dataset_type='', platforms=list(), sample_count=0, pubmed_ids=list(), bioproject_id='', supp_file_types='', ftp_url='', release_date='')[source]

Bases: object

Single result from an NCBI GEO (db=gds) search.

Parameters:
accession: str
gds_uid: str
entry_type: str
title: str = ''
summary: str = ''
organism: str = ''
dataset_type: str = ''
platforms: list[str]
sample_count: int = 0
pubmed_ids: list[str]
bioproject_id: str = ''
supp_file_types: str = ''
ftp_url: str = ''
release_date: str = ''
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.PubMedArticle(pmid, title='', abstract='', authors=list(), journal='', pub_date='', doi='', pmc_id='', keywords=list(), full_text=None, author_details=list())[source]

Bases: object

Structured PubMed article metadata and abstract.

Parameters:
pmid: str
title: str = ''
abstract: str = ''
authors: list[str]
journal: str = ''
pub_date: str = ''
doi: str = ''
pmc_id: str = ''
keywords: list[str]
full_text: PMCFullText | None = None
author_details: list[dict[str, str]]
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.PMCFullText(pmcid, pmid='', doi='', title='', journal='', pub_year='', abstract='', is_open_access=False, sections=list(), notes='', section_filter=None)[source]

Bases: object

Structured open-access full text of a PubMed Central article.

Parameters:
pmcid: str
pmid: str = ''
doi: str = ''
title: str = ''
journal: str = ''
pub_year: str = ''
abstract: str = ''
is_open_access: bool = False
sections: list[PMCSection]
notes: str = ''
section_filter: list[str] | None = None
filter_sections(sections)[source]

Select sections by kind (e.g. ‘methods’) or case-insensitive title substring.

A kind match also returns subsections inheriting that kind. None, [] or ‘all’ return every section.

Return type:

list[PMCSection]

Parameters:

sections (list[str] | tuple[str, ...] | None)

selected_sections()[source]

Sections matching the stored section_filter (all sections when unset).

Return type:

list[PMCSection]

text_for(kind)[source]

Concatenated text of all sections of a kind (subsection titles kept as headings).

Return type:

str

Parameters:

kind (str)

property methods: str
property data_availability: str

Data-availability text; falls back to scanning paragraphs when no section is titled so.

Journals such as Science put the statement inside Acknowledgments (“Data and materials availability: … GSE152418”), so a titled section is not required for agents to find where the data lives.

property geo_accessions: list[str]

GEO Series accessions (GSE…) mentioned anywhere in the full text.

to_dict(sections=None)[source]
Return type:

dict[str, Any]

Parameters:

sections (list[str] | tuple[str, ...] | None)

to_markdown(sections=None)[source]
Return type:

str

Parameters:

sections (list[str] | tuple[str, ...] | None)

to_text()[source]
Return type:

str

class PyNCBI.PMCSection(title, kind, level, text, path='')[source]

Bases: object

One section (or subsection) of a PubMed Central full-text article.

Parameters:
title: str
kind: str
level: int
text: str
path: str = ''
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.GeneRecord(gene_id, symbol='', description='', organism='', chromosome='', map_location='', aliases=list(), summary='', other_designations=list())[source]

Bases: object

Structured NCBI Gene record.

Parameters:
gene_id: str
symbol: str = ''
description: str = ''
organism: str = ''
chromosome: str = ''
map_location: str = ''
aliases: list[str]
summary: str = ''
other_designations: list[str]
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.ClinVarRecord(variation_id, accession='', title='', gene_symbol='', gene_id='', variant_type='', cdna_change='', protein_change='', molecular_consequences=list(), clinical_significance='', review_status='', review_stars=0, last_evaluated='', conditions=list(), condition_xrefs=list(), rsid='', canonical_spdi='', grch38=dict(), grch37=dict(), oncogenicity='', clinical_impact='', submission_count=0)[source]

Bases: object

Clean, flattened ClinVar variation record (from the noisy esummary db=clinvar JSON).

Parameters:
variation_id: str
accession: str = ''
title: str = ''
gene_symbol: str = ''
gene_id: str = ''
variant_type: str = ''
cdna_change: str = ''
protein_change: str = ''
molecular_consequences: list[str]
clinical_significance: str = ''
review_status: str = ''
review_stars: int = 0
last_evaluated: str = ''
conditions: list[str]
condition_xrefs: list[str]
rsid: str = ''
canonical_spdi: str = ''
grch38: dict[str, Any]
grch37: dict[str, Any]
oncogenicity: str = ''
clinical_impact: str = ''
submission_count: int = 0
property url: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.DbSNPRecord(rsid, chromosome='', position_grch38=None, position_grch37=None, spdi='', ref_allele='', alt_alleles=list(), gene_symbols=list(), gene_ids=list(), functional_class=list(), clinical_significance=list(), hgvs=list(), protein_change='', allele_frequencies=dict(), validated=list())[source]

Bases: object

Clean dbSNP reference SNP record (from esummary db=snp).

Parameters:
rsid: str
chromosome: str = ''
position_grch38: int | None = None
position_grch37: int | None = None
spdi: str = ''
ref_allele: str = ''
alt_alleles: list[str]
gene_symbols: list[str]
gene_ids: list[str]
functional_class: list[str]
clinical_significance: list[str]
hgvs: list[str]
protein_change: str = ''
allele_frequencies: dict[str, float]
validated: list[str]
property url: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.BioSampleRecord(accession, uid='', title='', organism='', taxid='', package='', publication_date='', owner='', gsm_id='', sra_sample='', attributes=dict(), identifiers=dict())[source]

Bases: object

Clean NCBI BioSample record with unpacked attributes.

Parameters:
accession: str
uid: str = ''
title: str = ''
organism: str = ''
taxid: str = ''
package: str = ''
publication_date: str = ''
owner: str = ''
gsm_id: str = ''
sra_sample: str = ''
attributes: dict[str, str]
identifiers: dict[str, str]
property url: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.BioProjectRecord(accession, uid='', title='', name='', description='', project_type='', data_type='', target_scope='', target_material='', method='', organism='', taxid='', registration_date='', relevance=list())[source]

Bases: object

Clean NCBI BioProject record.

Parameters:
  • accession (str)

  • uid (str)

  • title (str)

  • name (str)

  • description (str)

  • project_type (str)

  • data_type (str)

  • target_scope (str)

  • target_material (str)

  • method (str)

  • organism (str)

  • taxid (str)

  • registration_date (str)

  • relevance (list[str])

accession: str
uid: str = ''
title: str = ''
name: str = ''
description: str = ''
project_type: str = ''
data_type: str = ''
target_scope: str = ''
target_material: str = ''
method: str = ''
organism: str = ''
taxid: str = ''
registration_date: str = ''
relevance: list[str]
property url: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.AssemblyRecord(accession, paired_accession='', organism='', taxid='', strain='', assembly_name='', assembly_level='', assembly_status='', assembly_type='', refseq_category='', source_db='', release_date='', submitter='', bioproject='', biosample='', total_length=0, contig_n50=0, scaffold_n50=0, chromosome_count=0, gc_percent=None, annotation_name='', annotation_date='', gene_count=0, protein_coding_count=0)[source]

Bases: object

Clean NCBI Datasets genome assembly report.

Parameters:
  • accession (str)

  • paired_accession (str)

  • organism (str)

  • taxid (str)

  • strain (str)

  • assembly_name (str)

  • assembly_level (str)

  • assembly_status (str)

  • assembly_type (str)

  • refseq_category (str)

  • source_db (str)

  • release_date (str)

  • submitter (str)

  • bioproject (str)

  • biosample (str)

  • total_length (int)

  • contig_n50 (int)

  • scaffold_n50 (int)

  • chromosome_count (int)

  • gc_percent (float | None)

  • annotation_name (str)

  • annotation_date (str)

  • gene_count (int)

  • protein_coding_count (int)

accession: str
paired_accession: str = ''
organism: str = ''
taxid: str = ''
strain: str = ''
assembly_name: str = ''
assembly_level: str = ''
assembly_status: str = ''
assembly_type: str = ''
refseq_category: str = ''
source_db: str = ''
release_date: str = ''
submitter: str = ''
bioproject: str = ''
biosample: str = ''
total_length: int = 0
contig_n50: int = 0
scaffold_n50: int = 0
chromosome_count: int = 0
gc_percent: float | None = None
annotation_name: str = ''
annotation_date: str = ''
gene_count: int = 0
protein_coding_count: int = 0
property url: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.NucleotideRecord(accession, uid='', title='', organism='', taxid='', length=0, moltype='', biomol='', topology='', source_db='', completeness='', create_date='', update_date='', db='nuccore')[source]

Bases: object

Clean Nucleotide / Protein sequence summary (esummary db=nuccore|protein).

Parameters:
accession: str
uid: str = ''
title: str = ''
organism: str = ''
taxid: str = ''
length: int = 0
moltype: str = ''
biomol: str = ''
topology: str = ''
source_db: str = ''
completeness: str = ''
create_date: str = ''
update_date: str = ''
db: str = 'nuccore'
property url: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.TaxonRecord(taxid, scientific_name='', common_name='', rank='', division='', parent_taxid='', genetic_code='', mito_genetic_code='', lineage=list(), lineage_ranks=dict(), synonyms=list())[source]

Bases: object

Clean NCBI Taxonomy record with lineage.

Parameters:
taxid: str
scientific_name: str = ''
common_name: str = ''
rank: str = ''
division: str = ''
parent_taxid: str = ''
genetic_code: str = ''
mito_genetic_code: str = ''
lineage: list[str]
lineage_ranks: dict[str, str]
synonyms: list[str]
property url: str
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.AgentEnvelope(ok, command, target, summary, data, saved_files=list(), next_steps=list(), warnings=list(), schema_version='2.0', pyncbi_version='', elapsed_ms=None, request_count=None)[source]

Bases: object

Deterministic, context-window safe JSON envelope for CLI and MCP agent output.

Parameters:
ok: bool
command: str
target: str
summary: str
data: Any
saved_files: list[str]
next_steps: list[str]
warnings: list[str]
schema_version: str = '2.0'
pyncbi_version: str = ''
elapsed_ms: float | None = None
request_count: int | None = None
to_dict()[source]
Return type:

dict[str, Any]

to_json(indent=2)[source]
Return type:

str

Parameters:

indent (int)

PyNCBI.summarize_characteristics(value)[source]

Describe metadata fields using native values; never transform source records.

Return type:

list[CharacteristicSummary]

Parameters:

value (Table)

PyNCBI.save_data(data, output_path)[source]

Write native data as JSON, CSV or TSV using only the Python standard library.

Return type:

Path

Parameters:
PyNCBI.format_table_preview(value, mode='text', max_rows=15, max_cols=10)[source]

Render bounded native data without an analysis library.

Return type:

str

Parameters:
PyNCBI.render_output(data, *, mode='text', command='pyncbi', target='', summary='', saved_files=None, next_steps=None, warnings=None, max_rows=15)[source]

Render native data or a domain record, including the versioned agent envelope.

Return type:

str

Parameters:
class PyNCBI.DataStatus(*values)[source]

Bases: Enum

Status of data availability on a GSM record.

Variables:
  • DATA_ON_PAGE – Data table is directly embedded in the GSM SOFT file.

  • SUPPLEMENTARY_FILES – Data is hosted in supplementary files on NCBI FTP/HTTPS.

  • NO_DATA – No downloadable data is available on the GSM record.

DATA_ON_PAGE = 0
SUPPLEMENTARY_FILES = 1
NO_DATA = -1
class PyNCBI.FetchMode(*values)[source]

Bases: Enum

Mode for GSE data fetching.

Variables:
  • AUTO – Automatically choose the best available source.

  • PER_GSM – Fetch each GSM sample individually.

  • SUPPLEMENTARY – Download GSE supplementary file(s).

  • SERIES_MATRIX – Download and parse the GEO Series Matrix file.

  • RNASEQ_COUNTS – Download NCBI-generated RNA-seq count matrix.

AUTO = 1
PER_GSM = 2
SUPPLEMENTARY = 3
SERIES_MATRIX = 4
RNASEQ_COUNTS = 5
classmethod from_string(value)[source]

Convert string mode to FetchMode enum.

Return type:

FetchMode

Parameters:

value (str)

class PyNCBI.GSMInfo(gsm_id, title='', series_id='', platform_id='', organism='', source_name='', molecule='', library_strategy='', characteristics=dict(), supplementary_files=list(), sra_url='', biosample_url='', data_row_count=0)[source]

Bases: object

Parsed GSM metadata.

Parameters:
  • gsm_id (str)

  • title (str)

  • series_id (str)

  • platform_id (str)

  • organism (str)

  • source_name (str)

  • molecule (str)

  • library_strategy (str)

  • characteristics (dict[str, str])

  • supplementary_files (list[str])

  • sra_url (str)

  • biosample_url (str)

  • data_row_count (int)

gsm_id: str
title: str = ''
series_id: str = ''
platform_id: str = ''
organism: str = ''
source_name: str = ''
molecule: str = ''
library_strategy: str = ''
characteristics: dict[str, str]
supplementary_files: list[str]
sra_url: str = ''
biosample_url: str = ''
data_row_count: int = 0
class PyNCBI.GSEInfo(gse_id, title='', summary='', overall_design='', platform_id='', platforms=list(), organisms=list(), experiment_types=list(), pubmed_ids=list(), bioproject_id='', gsm_ids=list(), supplementary_files=list(), relations=list())[source]

Bases: object

Parsed GSE metadata.

Parameters:
gse_id: str
title: str = ''
summary: str = ''
overall_design: str = ''
platform_id: str = ''
platforms: list[str]
organisms: list[str]
experiment_types: list[str]
pubmed_ids: list[str]
bioproject_id: str = ''
gsm_ids: list[str]
supplementary_files: list[str]
relations: list[str]
PyNCBI.validate_accession(accession, expected_prefix='')[source]

Validate an NCBI GEO / SRA / BioProject accession ID.

Parameters:
  • accession (str) – The accession ID to validate (e.g., ‘GSM1234567’, ‘GSE85506’)

  • expected_prefix (str) – Expected prefix (‘GSM’, ‘GSE’, ‘GPL’), or empty to accept any

Return type:

str

Returns:

The validated accession ID (stripped and uppercase)

Raises:

InvalidAccessionError – If the accession format is invalid

class PyNCBI.FirstFileSelector[source]

Bases: object

Select the first available supplementary file.

select(files, gse_id)[source]
Return type:

int

Parameters:
class PyNCBI.IndexFileSelector(index)[source]

Bases: object

Select supplementary file by 0-based index.

Parameters:

index (int)

select(files, gse_id)[source]
Return type:

int

Parameters:
class PyNCBI.PatternFileSelector(pattern)[source]

Bases: object

Select supplementary file matching a glob or substring pattern.

Parameters:

pattern (str)

select(files, gse_id)[source]
Return type:

int

Parameters:
class PyNCBI.SmartFileSelector[source]

Bases: object

Non-interactive selector that prioritizes tabular/matrix files over raw archives.

Never prompts on stdin, making it safe for AI agents and automated pipelines.

select(files, gse_id)[source]
Return type:

int

Parameters:
class PyNCBI.Config(cache_folder=_get_default_cache_folder(), downloads_folder=<factory>, request_timeout=_get_default_timeout(), max_retries=3, retry_backoff=0.5, api_key=_get_default_api_key(), email=_get_default_email(), rate_limit_per_sec=None, geo_rate_limit_per_sec=8.0, ftp_rate_limit_per_sec=20.0, agent_mode=_get_default_agent_mode(), max_download_mb=_get_default_max_download_mb(), http_cache_ttl=_get_default_http_cache_ttl(), audit_log_path=_get_default_audit_log())[source]

Bases: object

PyNCBI runtime configuration.

Parameters:
  • cache_folder (Path)

  • downloads_folder (Path)

  • request_timeout (float)

  • max_retries (int)

  • retry_backoff (float)

  • api_key (str | None)

  • email (str | None)

  • rate_limit_per_sec (float | None)

  • geo_rate_limit_per_sec (float)

  • ftp_rate_limit_per_sec (float)

  • agent_mode (bool)

  • max_download_mb (float)

  • http_cache_ttl (float)

  • audit_log_path (Path | None)

cache_folder: Path
downloads_folder: Path
request_timeout: float
max_retries: int = 3
retry_backoff: float = 0.5
api_key: str | None
email: str | None
rate_limit_per_sec: float | None = None
geo_rate_limit_per_sec: float = 8.0
ftp_rate_limit_per_sec: float = 20.0
agent_mode: bool
max_download_mb: float
http_cache_ttl: float
audit_log_path: Path | None
NCBI_QUERY_BASE_URL: ClassVar[str] = 'https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi'
NCBI_QUERY_URL: ClassVar[str] = 'https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc='
NCBI_QUERY_URL_TEMPLATE: ClassVar[str] = 'https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={accession}&targ=self&form=text&view=quick'
NCBI_BATCH_GSM_URL_TEMPLATE: ClassVar[str] = 'https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={accession}&targ=gsm&form=text&view=brief'
NCBI_DATA_URL_TEMPLATE: ClassVar[str] = 'https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={accession}&targ=self&form=text&view=data'
NCBI_GEO_DOWNLOAD_URL: ClassVar[str] = 'https://www.ncbi.nlm.nih.gov/geo/download/'
NCBI_EUTILS_BASE_URL: ClassVar[str] = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils'
NCBI_DATASETS_BASE_URL: ClassVar[str] = 'https://api.ncbi.nlm.nih.gov/datasets/v2'
NCBI_FTP_HTTPS_BASE: ClassVar[str] = 'https://ftp.ncbi.nlm.nih.gov'
NCBI_BLAST_URL: ClassVar[str] = 'https://blast.ncbi.nlm.nih.gov/Blast.cgi'
ENA_PORTAL_API_URL: ClassVar[str] = 'https://www.ebi.ac.uk/ena/portal/api'
property effective_rate_limit: float

Effective requests per second limit for NCBI E-Utilities.

property local_downloads_folder: Path

Alias for downloads_folder.

ensure_cache_dir()[source]

Ensure cache directory exists and return its path.

Return type:

Path

get_ncbi_query_url(accession)[source]

Get the NCBI SOFT query URL for an accession.

Return type:

str

Parameters:

accession (str)

get_ncbi_batch_gsm_url(gse_id)[source]

Get the single-request batch GSM metadata URL for a GSE.

Return type:

str

Parameters:

gse_id (str)

get_ncbi_data_url(accession)[source]

Get the NCBI data table URL for a GSM or GPL.

Return type:

str

Parameters:

accession (str)

get_gds_soft_url(gds_id, full=False)[source]

Construct the HTTPS URL for a GEO DataSet (GDS) SOFT file on NCBI FTP.

Return type:

str

Parameters:
get_series_matrix_url(gse_id, platform_id=None)[source]

Construct the HTTPS URL for a GSE Series Matrix file on NCBI FTP.

Return type:

str

Parameters:
  • gse_id (str)

  • platform_id (str | None)

PyNCBI.get_config()[source]

Get the active configuration: the context-scoped one if any, else the global instance.

Session (and config_scope) install a configuration for the current context, so two workflows in one process can use different API keys, cache directories and budgets. Library-spawned worker threads see the process-wide configuration; anything a session needs inside those threads travels on its NCBIClient instead.

Return type:

Config

PyNCBI.set_config(config)[source]

Set the global configuration instance.

Return type:

None

Parameters:

config (Config)

PyNCBI.reset_config()[source]

Reset configuration to defaults.

Return type:

None

PyNCBI.config_scope(config)[source]

Use config for every get_config() call in this context (nestable, restored on exit).

Return type:

Iterator[Config]

Parameters:

config (Config)

PyNCBI.derive_config(base=None, **overrides)[source]

Copy a configuration, applying only the overrides that were given (not None).

Return type:

Config

Parameters:
class PyNCBI.Session(*, api_key=None, email=None, cache_dir=None, downloads_dir=None, max_download_mb=None, request_timeout=None, audit_log=None, agent_mode=None, rate_limit_per_sec=None, name='', config=None, client=None)[source]

Bases: object

An isolated PyNCBI workflow: its own credentials, caches, budget, client and telemetry.

Parameters:
  • api_key (str | None) – NCBI API key for this session only (raises its E-Utilities rate to 10 req/s)

  • email (str | None) – Contact address sent to E-Utilities for this session

  • cache_dir (str | Path | None) – Cache root for this session (study records, annotation and platform tables)

  • downloads_dir (str | Path | None) – Default downloads folder

  • max_download_mb (float | None) – Download budget applied to every transfer this session makes

  • request_timeout (float | None) – HTTP timeout in seconds

  • audit_log (str | Path | None) – Path to an append-only JSONL log of this session’s NCBI requests

  • agent_mode (bool | None) – Suppress progress bars and colors

  • rate_limit_per_sec (float | None) – Override the E-Utilities rate limit

  • name (str) – Label used in repr and telemetry (e.g. the agent or task id)

  • client (NCBIClient | None) – Supply a prepared Config / NCBIClient instead of building them

  • config (Config | None)

property cache_dir: Path

This session’s cache root.

property max_download_mb: float | None

The per-transfer budget this session injects (None when it was not set).

property closed: bool
property store: MetadataStore

This session’s private metadata store (TTL-cached study records).

static verbs()[source]

Names of the API functions available as methods on a session.

Return type:

list[str]

status(probe_network=False)[source]

Health, configuration, cache and telemetry for this session.

Return type:

dict[str, Any]

Parameters:

probe_network (bool)

metrics(include_recent=5)[source]

Request telemetry for this session’s client only.

Return type:

dict[str, Any]

Parameters:

include_recent (int)

to_dict()[source]
Return type:

dict[str, Any]

close()[source]

Close the session’s HTTP connection pool. Verbs raise afterwards.

Return type:

None

class PyNCBI.LogLevel(*values)[source]

Bases: IntEnum

Log levels for PyNCBI.

DEBUG = 10
INFO = 20
WARNING = 30
ERROR = 40
CRITICAL = 50
SILENT = 100
PyNCBI.configure_logging(level=LogLevel.INFO, *, stream=None, format_style='standard', use_colors=None)[source]

Configure PyNCBI logging.

Return type:

None

Parameters:
PyNCBI.get_logger(name=None)[source]

Get a logger under the PyNCBI namespace.

Return type:

Logger

Parameters:

name (str | None)

PyNCBI.set_level(level)[source]

Set the logging level.

Return type:

None

Parameters:

level (LogLevel | int)

PyNCBI.silence()[source]

Silence all PyNCBI logging and activity reporting output.

Return type:

None

PyNCBI.verbose(debug=False)[source]

Enable verbose step-by-step reporting (or full HTTP debug trace when debug=True).

Return type:

None

Parameters:

debug (bool)

class PyNCBI.log_level(level)[source]

Bases: object

Context manager to temporarily change log level.

Parameters:

level (LogLevel | int)

previous_level: int | None
class PyNCBI.Verbosity(*values)[source]

Bases: IntEnum

Verbosity levels for PyNCBI’s centralized reporter.

SILENT = 0
NORMAL = 1
VERBOSE = 2
DEBUG = 3
class PyNCBI.ActivityEvent(phase, domain, operation, message, target='', current=None, total=None, elapsed_ms=None, timestamp=time(), metadata=dict())[source]

Bases: object

Structured state/progress event emitted by PyNCBI operations.

Parameters:
phase: str
domain: str
operation: str
message: str
target: str = ''
current: int | None = None
total: int | None = None
elapsed_ms: float | None = None
timestamp: float
metadata: dict[str, Any]
to_dict()[source]
Return type:

dict[str, Any]

class PyNCBI.ByteProgressTracker(reporter, description, total_bytes=0, initial_bytes=0)[source]

Bases: object

Context-managed byte download progress bar writing strictly to sys.stderr.

Parameters:
property current_bytes: int

Bytes received so far (including any resumed offset).

update(chunk_bytes)[source]

Advance progress by chunk_bytes.

Return type:

None

Parameters:

chunk_bytes (int)

set_current(current_bytes, total_bytes=0)[source]

Update progress to an absolute current_bytes position.

Return type:

None

Parameters:
  • current_bytes (int)

  • total_bytes (int)

close()[source]
Return type:

None

class PyNCBI.TaskScope(reporter, domain, operation, message, target='')[source]

Bases: object

Context manager representing a high-level PyNCBI operation.

Parameters:
step(message, *, current=None, total=None)[source]

Report an intermediate sub-step within this task.

Return type:

None

Parameters:
  • message (str)

  • current (int | None)

  • total (int | None)

complete(summary_message)[source]

Set a custom completion message when the task finishes.

Return type:

None

Parameters:

summary_message (str)

class PyNCBI.ActivityReporter(verbosity=None)[source]

Bases: object

Centralized, thread-safe status, progress, and verbose reporter for PyNCBI.

Parameters:

verbosity (Verbosity | None)

property verbosity: Verbosity
set_verbosity(level)[source]

Set the active verbosity level and synchronize the root logger.

Return type:

None

Parameters:

level (Verbosity | int)

should_show_progress_bar()[source]

Return True if interactive native progress bars should be drawn on sys.stderr.

Return type:

bool

subscribe(callback)[source]

Register an event listener callback. Returns an unsubscribe function.

Return type:

Callable[[], None]

Parameters:

callback (Callable[[ActivityEvent], None])

recent_events(limit=50)[source]

Return the most recent structured activity events.

Return type:

list[dict[str, Any]]

Parameters:

limit (int)

clear_events()[source]

Clear recorded activity events.

Return type:

None

task(domain, operation, message, *, target='')[source]

Create a context-managed task scope that reports start, steps, and completion timing.

Return type:

TaskScope

Parameters:
step(domain, message, *, operation='', target='', current=None, total=None, metadata=None)[source]

Report an intermediate progress step.

Return type:

None

Parameters:
done(domain, message, *, operation='', target='', elapsed_ms=None)[source]

Report completion of an operation.

Return type:

None

Parameters:
warn(domain, message, *, operation='', target='')[source]

Report a non-fatal warning (e.g., rate-limit pause, retry, or fallback).

Return type:

None

Parameters:
download_bar(description, total_bytes=0, initial_bytes=0)[source]

Create a byte-level download progress bar on sys.stderr.

Return type:

ByteProgressTracker

Parameters:
  • description (str)

  • total_bytes (int)

  • initial_bytes (int)

track(iterable, description, *, total=None, unit='item')[source]

Report iterable progress with structured events and standard-library output.

Return type:

Iterator[Any]

Parameters:
  • iterable (Iterable[Any])

  • description (str)

  • total (int | None)

  • unit (str)

PyNCBI.get_reporter()[source]

Get the global shared ActivityReporter singleton.

Return type:

ActivityReporter

PyNCBI.verbosity_scope(level)[source]

Context manager to temporarily override PyNCBI reporter verbosity.

Return type:

Iterator[ActivityReporter]

Parameters:

level (Verbosity | int)

PyNCBI.redact_url(url)[source]

Redact api_key=… query parameter from URLs before logging or raising.

Return type:

str

Parameters:

url (str | None)

PyNCBI.error_code_for(exc)[source]

Map any exception to a stable, machine-readable error code.

Return type:

str

Parameters:

exc (BaseException)

PyNCBI.error_payload(exc, *, command='', target='')[source]

Build the structured error envelope used by pyncbi –json and the MCP server.

Return type:

dict[str, object]

Parameters:
PyNCBI.is_retryable(exc)[source]

Whether an agent should retry the same call later (transient failure).

Return type:

bool

Parameters:

exc (BaseException)

exception PyNCBI.PyNCBIError(message, *, hint=None)[source]

Bases: Exception

Base exception for all PyNCBI errors.

Variables:
  • message – Human-readable error message

  • hint – Optional suggestion for resolving the error

Parameters:
  • message (str)

  • hint (str | None)

Return type:

None

exception PyNCBI.NetworkError(message, *, url=None, **kwargs)[source]

Bases: PyNCBIError

Base for network-related errors.

Parameters:
Return type:

None

exception PyNCBI.ConnectionFailedError(url, cause=None)[source]

Bases: NetworkError

Failed to establish connection to NCBI.

Parameters:
Return type:

None

exception PyNCBI.RequestTimeoutError(url, timeout)[source]

Bases: NetworkError

Request timed out.

Parameters:
Return type:

None

exception PyNCBI.HTTPError(url, status_code, message='', *, hint=None)[source]

Bases: NetworkError

HTTP error response from server.

Parameters:
  • url (str)

  • status_code (int)

  • message (str)

  • hint (str | None)

Return type:

None

exception PyNCBI.RateLimitExceededError(url, retry_after=None, detail='')[source]

Bases: HTTPError

NCBI API rate limit exceeded (HTTP 429 or E-Utilities rate-limit payload).

Parameters:
Return type:

None

exception PyNCBI.InvalidAPIKeyError(url, detail='API key invalid')[source]

Bases: HTTPError

Configured NCBI_API_KEY was rejected by NCBI E-Utilities.

Parameters:
Return type:

None

exception PyNCBI.BotChallengeError(url, detail='')[source]

Bases: HTTPError

NCBI returned an interactive bot-challenge (reCAPTCHA) page instead of data.

Some GEO download CGI endpoints (notably the shared NCBI RNA-seq annotation tables) are protected by a browser challenge for non-interactive clients on some networks.

Parameters:
Return type:

None

exception PyNCBI.DownloadError(url, reason, *, completed_paths=None)[source]

Bases: NetworkError

Failed to download a file.

Variables:

completed_paths (list[object]) – Local paths that were downloaded successfully before/alongside the failure (populated by parallel multi-file downloads).

Parameters:
  • url (str)

  • reason (str)

  • completed_paths (Sequence[object] | None)

Return type:

None

exception PyNCBI.DataError(message, *, hint=None)[source]

Bases: PyNCBIError

Base for data-related errors.

Parameters:
  • message (str)

  • hint (str | None)

Return type:

None

exception PyNCBI.ParseError(format_type, detail='')[source]

Bases: DataError

Failed to parse data format.

Parameters:
  • format_type (str)

  • detail (str)

Return type:

None

exception PyNCBI.SOFTParseError(accession, detail='')[source]

Bases: ParseError

Failed to parse SOFT format.

Parameters:
  • accession (str)

  • detail (str)

Return type:

None

exception PyNCBI.NoDataAvailableError(accession, detail='', hint=None)[source]

Bases: DataError

GSM/GSE has no downloadable data.

Parameters:
  • accession (str)

  • detail (str)

  • hint (str | None)

Return type:

None

__init__(accession, detail='', hint=None)[source]
Parameters:
  • accession (str) – The record that has no data

  • detail (str) – Why, in the record’s own terms, appended to the message

  • hint (str | None) – Overrides the default “inspect the record” hint when the caller knows the better next step (for example, which function to use instead)

Return type:

None

exception PyNCBI.AccessionNotFoundError(accession, detail='')[source]

Bases: DataError

Requested accession does not exist in NCBI.

Parameters:
  • accession (str)

  • detail (str)

Return type:

None

exception PyNCBI.AccessionPrivateError(accession, detail='')[source]

Bases: DataError

Requested GEO accession is currently embargoed / private or deleted.

Parameters:
  • accession (str)

  • detail (str)

Return type:

None

exception PyNCBI.InvalidAccessionError(accession, expected_prefix='')[source]

Bases: DataError

Invalid GSM/GSE/GPL/PRJNA/SRA accession format.

Parameters:
  • accession (str)

  • expected_prefix (str)

Return type:

None

exception PyNCBI.DataProcessingError(accession, step, detail='')[source]

Bases: DataError

Error during data processing.

Parameters:
Return type:

None

exception PyNCBI.CacheError(message, *, hint=None)[source]

Bases: PyNCBIError

Base for cache-related errors.

Parameters:
  • message (str)

  • hint (str | None)

Return type:

None

exception PyNCBI.CacheCorruptedError(path, cause=None)[source]

Bases: CacheError

Cache file is corrupted and cannot be read.

Parameters:
Return type:

None

exception PyNCBI.CacheNotFoundError(key)[source]

Bases: CacheError

Expected cache entry not found.

Parameters:

key (str)

Return type:

None

exception PyNCBI.CacheWriteError(path, cause=None)[source]

Bases: CacheError

Failed to write to cache.

Parameters:
Return type:

None

exception PyNCBI.PathTraversalError(path, member)[source]

Bases: ArchiveExtractionError

Archive contains path traversal attack.

Parameters:
Return type:

None

exception PyNCBI.SymlinkError(path, member)[source]

Bases: ArchiveExtractionError

Archive contains symbolic/hard links.

Parameters:
Return type:

None

exception PyNCBI.ConfigurationError(message, *, hint=None)[source]

Bases: PyNCBIError

Invalid configuration.

Parameters:
  • message (str)

  • hint (str | None)

Return type:

None

exception PyNCBI.InvalidModeError(mode, valid_modes=None)[source]

Bases: ConfigurationError

Invalid mode parameter for GSE fetching.

Parameters:
Return type:

None

Core Subpackage (PyNCBI.core)

Core configuration, types, models, protocols, exceptions, logging, and formatting for PyNCBI.

Domains Subpackage (PyNCBI.domains)

NCBI domain engines for PyNCBI (GEO, Annotation, Entrez Search, PubMed, Gene, SRA, FASTA, and Linker).

GEO Objects Subpackage (PyNCBI.geo)

Object-oriented GEO entities (GSM, GSE, GEOReader).

I/O Subpackage (PyNCBI.io)

I/O package for PyNCBI.

Contains the production NCBIClient (HttpClient), realm-aware token-bucket rate limiters, request telemetry, caching, and safe archive decompression.

URL normalisation, size formatting, and file-type inference for NCBI endpoints.

Detecting what an NCBI reply actually is: bot challenges, private records, 404 pages.

Per-client request telemetry and the optional redacted audit log.

Metadata Subpackage (PyNCBI.metadata)

Industry-grade metadata layer: versioned records, controlled vocabulary with provenance, harmonization, quality assessment, durable storage and context-window aware serving.

Controlled vocabulary for sample characteristics (conservative, provenance-first).

A characteristic key is mapped to a canonical field only when it matches a registered synonym after light normalization (case, underscores, parenthetical units). Values are normalized only for fields with an unambiguous value space (sex), parsed for quantities (age, time_point), and otherwise kept verbatim. Every result is a NormalizedValue carrying the raw string, rule id and confidence. The registry is extensible at runtime (register_field / register_synonym).

class PyNCBI.metadata.vocabulary.CanonicalField(name, description, synonyms=list(), normalizer='verbatim', dtype='string')[source]

A canonical sample attribute with its synonyms and value normalizer.

Parameters:
PyNCBI.metadata.vocabulary.reset()[source]

Restore the default vocabulary (drops runtime registrations).

Return type:

None

PyNCBI.metadata.vocabulary.register_field(name, *, description, synonyms=(), normalizer='verbatim', dtype='string')[source]

Register a new canonical field (or extend an existing one).

Return type:

CanonicalField

Parameters:
PyNCBI.metadata.vocabulary.register_synonym(field_name, synonym)[source]

Map an additional characteristic key to a canonical field.

Return type:

None

Parameters:
  • field_name (str)

  • synonym (str)

PyNCBI.metadata.vocabulary.canonical_field(key)[source]

Resolve a raw characteristic key to a canonical field name, or None when ambiguous.

Return type:

str | None

Parameters:

key (str)

PyNCBI.metadata.vocabulary.fields()[source]

All canonical fields with descriptions and synonyms (for docs and agents).

Return type:

dict[str, CanonicalField]

PyNCBI.metadata.vocabulary.unit_from_key(key)[source]

Unit implied by the key itself, e.g. ‘age (years)’ -> ‘year’, ‘os.delay (months)’ -> ‘month’.

Return type:

str | None

Parameters:

key (str)

PyNCBI.metadata.vocabulary.parse_quantity(raw)[source]

Parse ‘45 years’, ‘6 mo’, ‘P56’, ‘E14.5’, ‘60-69’ -> (value, unit, rule).

Return type:

tuple[float | None, str | None, str]

Parameters:

raw (str)

PyNCBI.metadata.vocabulary.normalize_value(field_name, raw, *, source_key=None)[source]

Normalize a raw characteristic value for a canonical field.

Return type:

NormalizedValue

Parameters:
  • field_name (str)

  • raw (Any)

  • source_key (str | None)

Parsing Subpackage (PyNCBI.parsing)

Parsing package for PyNCBI.

Contains parsers for NCBI GEO SOFT format and Series Matrix files.

Domain Modules

GEO info, inspection, and raw-data retrieval engine for PyNCBI.

Provides fast, programmatic, zero-post-processing access to NCBI GEO. The package is split by responsibility and this module is the stable import surface for all of it:

  • urls - URL builders, assembly resolution, SuperSeries relations

  • transfer - gzip sanity checks, archive unpacking, parallel HTTP I/O

  • planning - download plans and the pre-transfer safety rails

  • samples - single-request sample metadata and cohort filtering

  • inspection - study design, cohort summary, remote file sizes

  • tables - Series Matrix, RNA-seq counts, GDS, supplementary tables

  • downloads - raw file downloads and cohort file resolution

  • preview - streaming previews without a full download

Key entry points:

  • inspect_accession(): complete overview of any GSE, GSM, or GPL with file sizes

  • extract_gse_samples(): O(1) single-request sample metadata & characteristics table

  • load_series_matrix(): download and parse GEO Series Matrix (.txt.gz) files

  • load_rnaseq_counts(): download and parse NCBI-generated RNA-seq count tables

  • download_geo_files(): download raw supplementary, matrix, or table files from NCBI

GEO URL builders and series-relationship helpers.

Byte-level transfer helpers: gzip sanity checks, archive unpacking, and parallel HTTP I/O.

Resolving what to fetch for a study: cohort file sets and genome assemblies.

Download planning and the safety rails that run before any transfer starts.

Single-request sample metadata and a small, safe native-record cohort filter.

Accession inspection: study design, cohort summary, and remote file sizes.

Loading GEO data tables (Series Matrix, NCBI RNA-seq counts, GDS, supplementary).

Raw file downloads: cohort file resolution, parallel fetches, and archive unpacking.

Streaming previews of remote GEO files without downloading them in full.

Gene & Platform Annotation Engine for PyNCBI.

Maps the row identifiers of NCBI/GEO data tables to gene-level annotation without touching any measurement values:

  • fetch_gpl_table: Stream a GPL platform annotation table (probe -> gene columns) with full column preservation, optional column subset / row limit, and local caching.

  • load_rnaseq_annotation: Load NCBI’s RNA-seq gene annotation table (Entrez GeneID -> Symbol, GeneType, EnsemblGeneID, …) for an assembly, with a resilient source cascade: local cache -> GEO annotation file -> NCBI Datasets API -> Entrez Gene esummary.

  • annotate_gene_ids: Prepend gene annotation columns to a GeneID-indexed count matrix.

  • annotate_probes: Prepend probe -> gene columns (from the GPL) to a probe-indexed matrix.

NCBI Entrez Search, PubMed, Gene & Cross-Database Linker for PyNCBI.

Provides clean, rate-limited programmatic access to NCBI E-Utilities: - search_geo: Search GEO datasets (db=gds) with structured filters and GSE resolution - search_pubmed / fetch_pubmed: Search PubMed and parse full article abstracts - search_gene / fetch_genes: Search and retrieve NCBI Gene records - search_ncbi: Generic search across SRA, BioProject, BioSample, ClinVar, etc. - link_accession: Discover cross-database links (GSE <-> PMID <-> BioProject <-> SRA)

PubMed Central full-text engine for PyNCBI.

  • resolve_pmc_id: PMID <-> PMCID resolution via E-Utilities elink

  • fetch_pmc_text: Open-access full text as classified sections (Methods, Results, Data Availability, …) ready for agents to read a study’s exact protocol

  • attach_full_text: Enrich PubMedArticle objects with their PMC full text / Methods

Sequencing read access for PyNCBI: resolve any GEO/SRA/BioProject accession to FASTQ files.

Uses the ENA Portal file report (mirrors every public SRA run with direct HTTPS FASTQ URLs, byte sizes, and MD5 checksums) so reads can be fetched without the SRA Toolkit:

  • fetch_fastq_urls: GSE / GSM / PRJNA / SRP / SRX / SRS / SAMN / SRR -> one row per FASTQ file

  • download_fastq: parallel, MD5-verified FASTQ downloads

Genome & assembly access via the NCBI Datasets v2 API (no extra dependencies).

  • search_assemblies(taxon): reference (or all) assemblies for an organism / TaxID

  • fetch_assembly(accession): one GCF_/GCA_ accession report

  • download_genome(accession, include=(…)): genome FASTA / GFF3 / GTF / proteins package, unpacked safely into a flat folder

Structured ClinVar & dbSNP variant lookup for PyNCBI.

Turns NCBI’s raw, nested esummary payloads (35+ XML-derived keys) into compact ClinVarRecord / DbSNPRecord objects that are readable by humans and LLM agents.

  • search_clinvar(query, significance=…, gene=…): gene symbol, rsID, HGVS, or free text

  • fetch_clinvar(ids): by ClinVar Variation ID(s) / VCV accession(s)

  • fetch_dbsnp(rsids): reference SNP records with position, alleles, genes, frequencies

  • fetch_variants(query, source=’auto’): one call that routes to ClinVar and/or dbSNP

One-command Study Bundle for PyNCBI.

build_study_bundle(gse_id) turns the usual 4-5 separate preflight commands (inspect, samples, pubmed, sra, files) into a single self-contained local study directory:

<output_dir>/

STUDY_OVERVIEW.md human/agent-readable overview (design, cohort, files, paper, methods) bundle.json bundle manifest + full InspectionReport (machine-readable) study.json versioned StudyRecord (harmonized samples, provenance, links, quality) samples_metadata.csv aligned GSM metadata + unpacked characteristics files_manifest.json every downloadable file with size, source, and URL sra_runs.csv SRA RunInfo table (when sequencing runs exist) pubmed_articles.json linked PubMed articles (+ PMC Methods sections when open access) paper_methods.md PMC Methods / Data Availability sections as Markdown <matrix table> optional: Series Matrix or annotated NCBI RNA-seq counts

Citation export (BibTeX / RIS) for PubMed articles — pure stdlib.

Sessions (PyNCBI.session)

Isolated PyNCBI sessions.

A Session bundles everything that should not be shared between concurrent workflows: its own configuration (API key, email, cache directory, download budget), its own NCBIClient with its own rate limiters and telemetry, and its own metadata store. Every networked verb of the public API is available as a method on the session, with the session’s client and budget applied automatically:

with PyNCBI.Session(api_key=KEY, cache_dir=”./agent-1”, max_download_mb=500) as s:

record = s.build_study_record(“GSE152418”) matrix = s.load_expression(“GSE152418”)

The module-level functions keep working exactly as before and use the process-wide configuration, so nothing has to change to adopt sessions.

MCP Server Modules (PyNCBI.mcp)

Model Context Protocol (MCP) server entry point for PyNCBI.

Implements a zero-dependency, standards-compliant JSON-RPC 2.0 MCP server over stdio and Streamable HTTP, so AI agents (Claude Desktop, Claude Code, Cursor, Antigravity, …) can natively search, inspect, extract metadata tables, and download raw files from NCBI.

The implementation is split by responsibility and this module is the stable import surface for all of it:

  • tools - the tool catalogue, behaviour annotations, output envelope

  • handlers - tool dispatch and rendering

  • resources - resources and resource templates

  • prompts - ready-made agent workflows

  • protocol - JSON-RPC handling, negotiation, and the manifest

  • transport - the stdio and HTTP transports

Launch via:

pyncbi mcp
pyncbi mcp --http --port 8765
python -m PyNCBI.mcp.server

The MCP tool catalogue: input schemas, behaviour annotations, and the output envelope.

Tool dispatch: every ncbi_* tool call is executed here and rendered as an envelope.

MCP resources and resource templates (schemas, vocabulary, per-study views).

MCP prompts: ready-made agent workflows rendered from templates.

JSON-RPC 2.0 message handling, capability negotiation, and the server manifest.

MCP stdio and Streamable HTTP transports (single JSON-RPC messages).

Schema integrity checks for the MCP server.

The tool schemas are an agent-facing contract, so they must not drift from the handlers that read them. These checks are pure (no network) and run in the test suite:

  • validate_tool_schemas: structural validity of every advertised tool

  • handler_argument_names: which arguments execute_mcp_tool actually reads for a tool, extracted from its own source, so an advertised-but-ignored parameter fails the build

CLI Modules (PyNCBI.cli)

Entry point: parses arguments, configures reporting, and dispatches to a command.

The full pyncbi argument parser: every command, flag, and help string.

Console plumbing shared by every command: safe printing, argument parser, output flags.

GEO commands: inspect, samples, files, download, preview, gds, expression, gpl.

Search and linking commands: search, pubmed, gene, link, taxonomy.

Sequence and read commands: sra, fasta, fastq, genome, blast.

Study-level commands: variant, bundle, metadata, schema, screen.

Local-state commands: cache, status, skill.