Quickstart
Why PyNCBI
Working with NCBI by hand means juggling E-utilities rate limits, SOFT and Series Matrix
formats, GEO’s CGI download endpoints (some browser-gated), ftp:// links, ragged sample
characteristics, and five different JSON schemas for esummary. PyNCBI turns all of that
into a handful of calls that return native Python table dictionaries and small serializable records, preserve parsed measurements through caching/export and report operational failures with
clear exceptions, hint and stable error_code values.
Five-minute tour (CLI)
# 1. Discover
pyncbi search geo "fibromyalgia methylation" --organism "Homo sapiens" --markdown
# 2. Everything about a study in one directory (overview, samples, files, SRA, paper + Methods)
pyncbi bundle GSE152418 -o ./GSE152418/
# 3. Only the files you need, for the samples you need, in parallel
pyncbi download GSE85506 --where "group == 'case'" --pattern "*.idat.gz" -o ./fm/
# 4a. The matrix, wherever the study keeps it (counts / Series Matrix / supplementary / tar)
pyncbi expression GSE152418 -o counts.csv
# 4. Tables with gene symbols, not bare GeneIDs / probe IDs
pyncbi download GSE152418 --source rnaseq --annotate -o counts_annotated.csv
# 5. Reads, variants, genomes, taxonomy
pyncbi fastq GSE152418 --download -o ./fastq/
pyncbi variant BRCA1 --significance pathogenic
pyncbi genome search "Escherichia coli" ; pyncbi genome download GCF_000005845.2 --include genome,gff3
pyncbi taxonomy human
Five-minute tour (Python)
import PyNCBI
report = PyNCBI.inspect_accession("GSE152418") # design, cohort breakdown, files + sizes
samples, chars, summary = PyNCBI.extract_gse_samples("GSE152418", where="severity == 'Severe'")
matrix = PyNCBI.load_expression("GSE152418") # resolves whichever source the study actually uses
counts = PyNCBI.load_rnaseq_counts("GSE152418", annotate=True)
paper = PyNCBI.fetch_pmc_text("32788292", sections=["methods", "data_availability"])
fastq = PyNCBI.fetch_fastq_urls("GSE152418") # one row per FASTQ file, with MD5s
variants = PyNCBI.search_clinvar("BRCA1", significance="pathogenic", limit=None) # paginated
bundle = PyNCBI.build_study_bundle("GSE152418", "./GSE152418/")
Errors you can branch on
Operational exceptions derive from PyNCBI.PyNCBIError and carries .message and
.hint; PyNCBI.error_code_for(exc) maps it to a stable code (not_found,
private, no_data, rate_limited, bot_challenge, timeout …) and
PyNCBI.is_retryable(exc) says whether to retry. The CLI --json error envelope and the
MCP server return the same fields.