Skip to main content
viralfetch logo

Version Python License CLI Output Tests

A command-line tool for querying and downloading viral taxonomy, metadata and sequences. It combines three sources:
Source Content Access
VMR (ICTV Virus Metadata Resource) taxonomic hierarchy + exemplar isolates + GenBank/RefSeq accessions local, embedded TSV
NCBI E-utilities sequence metadata, sequences (nt/aa), NCBI taxonomy remote, on demand
ICTV Report descriptive chapter text per family remote, on demand

The VMR is the local index; everything else is fetched on demand and cached.


Installation

pip install -e .

This installs the viralfetch command. Python 3.10+ is required.

NCBI configuration

Commands that reach NCBI (seq, tax --compare-ncbi) require a real email address, per NCBI usage policy. There is no default — the command fails with an explanation if none is set.

export NCBI_EMAIL="you@example.com"
export NCBI_API_KEY="..."   # optional; raises the rate limit from 3 to 10 req/s

You can also pass --email / --api-key on any command.

Global options

These go before the command:

Option Effect
--json Emit pure JSON on stdout (warnings/errors go to stderr) — ready for jq.
--no-cache Ignore the cache and refetch.
--verbose Extra diagnostics on stderr.
--email, --api-key Override the NCBI credentials for this run.

Run viralfetch COMMAND --help to see a command's own arguments and options.


tax — taxonomy lineage (local)

Show the full ICTV lineage of a taxon (realm → species). Case-insensitive, with "did you mean" suggestions on a near miss. A species also gets an isolate summary.

viralfetch tax Coronaviridae
╭─ Coronaviridae  (family) ─────────────────────────╮
│ lineage                                           │
│ └── realm: Riboviria                              │
│     └── kingdom: Orthornavirae                    │
│         └── phylum: Pisuviricota                  │
│             └── class: Pisoniviricetes            │
│                 └── order: Nidovirales            │
│                     └── suborder: Cornidovirineae │
│                         └── family: Coronaviridae │
╰───────────────────────────────────────────────────╯

Same query as JSON:

viralfetch --json tax Coronaviridae
{
  "name": "Coronaviridae",
  "rank": "family",
  "lineage": {
    "realm": "Riboviria",
    "kingdom": "Orthornavirae",
    "phylum": "Pisuviricota",
    "class": "Pisoniviricetes",
    "order": "Nidovirales",
    "suborder": "Cornidovirineae",
    "family": "Coronaviridae"
  }
}

tax --compare-ncbi (remote)

Fetch the NCBI taxonomy lineage for a representative accession and render it beside the ICTV lineage, highlighting divergences. Divergences are expected — NCBI commonly lags ICTV — and are the point of the command.

viralfetch tax "Betacoronavirus pandemicum" --compare-ncbi
             ICTV vs NCBI lineage — Betacoronavirus pandemicum
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ICTV (VMR)                          ┃ NCBI (taxid 227984)                ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ realm: Riboviria                    │ acellular root: Viruses            │
│ kingdom: Orthornavirae              │ realm: Riboviria                   │
│ …                                   │ …                                  │
│ species: Betacoronavirus pandemicum │ species: Betacoronavirus pandemi…  │
│                                     │ no rank: SARS coronavirus Tor2     │
└─────────────────────────────────────┴────────────────────────────────────┘

members — child taxa (local, no network)

List the taxa below a given taxon.

At a specific rank

viralfetch members Coronaviridae --rank genus
genera in family Coronaviridae
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ genus            ┃ species ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ Alphacoronavirus │      26 │
│ Alphaletovirus   │       1 │
│ Alphapironavirus │       1 │
│ Betacoronavirus  │      14 │
│ Deltacoronavirus │       7 │
│ Gammacoronavirus │       5 │
└──────────────────┴─────────┘
           6 genera

Counts only

viralfetch members Riboviria --rank family --count
158 families in realm Riboviria

Per-rank breakdown (no flags)

viralfetch members Coronaviridae
  members of family
Coronaviridae by rank
┏━━━━━━━━━━━┳━━━━━━━┓
┃ rank      ┃ count ┃
┡━━━━━━━━━━━╇━━━━━━━┩
│ subfamily │     3 │
│ genus     │     6 │
│ subgenus  │    28 │
│ species   │    54 │
└───────────┴───────┘
Tip: add --tree to list every member of Coronaviridae as a hierarchy.

Full descendant tree

viralfetch members Coronaviridae --tree
Coronaviridae  (family)
├── Letovirinae  (subfamily)
│   └── Alphaletovirus  (genus)
│       └── Milecovirus  (subgenus)
│           └── Alphaletovirus microhylae  (species)
├── Orthocoronavirinae  (subfamily)
│   ├── Alphacoronavirus  (genus)
│   │   ├── Amalacovirus  (subgenus)
│   │   │   └── Alphacoronavirus almalfi  (species)
│   │   └── …
│   └── …
└── …
91 descendant taxa

--rank, --tree, and the breakdown all work with --json too.


seq — NCBI sequence data (remote)

Accessions are resolved locally from the VMR, then metadata or records are fetched from NCBI. Output formats are mutually exclusive; --meta is the default.

Flag Fetches
--meta metadata via esummary (~1 KB/accession)
--fasta FASTA sequences via efetch
--gb full GenBank records via efetch

Metadata for a species

viralfetch seq "Betacoronavirus pandemicum" --meta
             nuccore metadata — Betacoronavirus pandemicum
┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━┈
┃ accession  ┃ organism            ┃   len ┃ moltype ┃ biomol  ┃ …
┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━┈
│ AY274119.3 │ SARS coronavirus…   │ 29751 │ rna     │ genomic │ …
│ AY613950.1 │ SARS coronavirus…   │ 29728 │ rna     │ genomic │ …
│ MN908947.3 │ SARS-CoV-2 Wuhan-…  │ 29903 │ rna     │ genomic │ …
│ KY352407.1 │ SARS-related coro…  │ 29274 │ rna     │ genomic │ …
└────────────┴─────────────────────┴───────┴─────────┴─────────┴───┈

(Columns topology, completeness, sourcedb and updatedate are shown too; trimmed here for width. Add --json for the full, untruncated records.)

Download FASTA to a file

viralfetch seq "Betacoronavirus pandemicum" --fasta -o out.fa
Wrote 4 fasta record(s) for Betacoronavirus pandemicum to out.fa

Without -o, records go to stdout (pipeable), and the summary goes to stderr.

A whole taxon

--taxon operates on every species beneath a taxon. With --meta it shows a local aggregate (no network) so you can decide whether a download is worth it:

viralfetch seq --taxon Coronaviridae --meta
╭─ Coronaviridae (family) — download estimate ─╮
│ species     54                               │
│ isolates    59                               │
│ accessions  59                               │
│ RefSeq       0                               │
╰──────────────────────────────────────────────╯
   by genome composition
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ composition ┃ accessions ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ ssRNA(+)    │         59 │
└─────────────┴────────────┘
{
  "name": "Coronaviridae",
  "rank": "family",
  "species": 54,
  "isolates": 59,
  "accessions": 59,
  "refseq": 0,
  "moltype_breakdown": { "ssRNA(+)": 59 }
}

Fetches of more than 500 accessions ask for confirmation unless --yes is given (in --json / non-interactive mode they refuse without --yes).

Molecule selection

--moltype and --biomol are db=nuccore fields, filtered locally over the metadata (matching is lenient — --moltype ssRNA matches ss-RNA):

viralfetch seq --taxon Filoviridae --moltype ssRNA --fasta -o filo.fa
viralfetch seq "Betacoronavirus pandemicum" --biomol genomic

--protein is a separate path, not a nuccore filter: proteins live in db=protein, reached via elink (nuccore → protein).

viralfetch seq "Betacoronavirus pandemicum" --protein --fasta

text — ICTV Report chapter (remote)

Fetch the ICTV Report chapter for a family, convert its main content to Markdown, and render it with headings, subsection titles, characteristic tables, and the italics of scientific names preserved. The original page URL and the chapter's references/attribution are shown at the top, and the content is CC BY 4.0. Images are omitted.

viralfetch text Coronaviridae
                          Family: Coronaviridae

Source: https://ictv.global/report/chapter/coronaviridae/coronaviridae

Patrick C.Y. Woo, Raoul J. de Groot, Bart Haagmans, Susanna K.P. Lau, …

The citation for this ICTV Report chapter is the summary published as:
Woo et al., (2023), ICTV Virus Taxonomy Profile: Coronaviridae 2023,
Journal of General Virology (2023) 104, 001843

Content is licensed CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/).
────────────────────────────────────────────────────────────────────────
Summary

Members of the family Coronaviridae, a monophyletic group of viruses in
the order Nidovirales, are enveloped, positive-sense RNA viruses …

A single section

--section restricts the output to one section, matched by heading (case-insensitive substring). The top attribution block is always kept.

viralfetch text Coronaviridae --section summary

Raw Markdown to a file

--raw emits the pure Markdown (no Rich decoration), ready to redirect:

viralfetch text Geminiviridae --raw > geminiviridae.md
# Family: Geminiviridae

*Source: https://ictv.global/report/chapter/geminiviridae/geminiviridae*

**Elvira Fiallo-Olivé, Jean-Michel Lett, Darren P. Martin, …**

The citation for this ICTV Report chapter is the summary published as
Fiallo-Olivé et al., ICTV Virus Taxonomy Profile: *Geminiviridae* 2021, …

With --json, the command emits {slug, title, url, doi, markdown} instead.

Genera and species resolve to their family chapter

The ICTV Report is organised by family — genera and species have no chapter of their own. Given one, text looks it up in the VMR and shows its family's chapter, with a note on stderr (so --raw/--json stdout stays clean):

viralfetch text Betacoronavirus
# stderr: 'Betacoronavirus' is a genus; the ICTV Report has no genus chapter
#         — showing its family, Coronaviridae.
# stdout: the Coronaviridae chapter

An unknown name gets "did you mean" suggestions and exit code 1.

Fetching honours ictv.global/robots.txt, sends a descriptive User-Agent carrying your contact email, waits at least 1 second between requests, and caches chapter HTML for 30 days.


Utilities

Small helper commands, all local except update.

viralfetch diagnose                 # VMR parser quality (zero-accession rows)
viralfetch update                   # is a newer VMR published on ictv.global?
viralfetch config                   # show email, masked API key, cache paths
viralfetch config --store-ncbi-email you@example.com   # persist credentials
viralfetch cache info               # per-namespace entry counts and size
viralfetch cache clear --texts      # drop cached ICTV chapters (or --seqs, or all)

diagnose reports the parser's quality indicator — how many VMR rows yielded zero accessions:

╭─ VMR accession-parser diagnostics ─╮
│ isolates              19271        │
│ accessions            23249        │
│ empty-accession rows  141          │
│ unparsed rows         0            │
╰────────────────────────────────────╯

Shell completion: taxon names complete from the VMR (viralfetch tax Corona<TAB>Coronaviridae). Install it once with viralfetch --install-completion.


Output & exit codes

  • Rich tables/panels/trees by default; --json for clean, jq-ready output. Colour is disabled automatically when stdout is not a TTY.
  • Errors go to stderr with a non-zero exit code: 1 not found, 2 bad usage, 3 missing NCBI email, 4 NCBI request failed.
  • Partial failures are reported, never swallowed: if you request 200 accessions and 197 come back, the 3 missing ones are listed.

Caching

Immutable data (sequences, accession metadata) is cached permanently; ICTV chapter HTML uses a 30-day TTL. The cache lives in the platform cache directory. Use --no-cache to bypass it for a single run.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

viralfetch-0.1.0.tar.gz (941.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

viralfetch-0.1.0-py3-none-any.whl (805.6 kB view details)

Uploaded Python 3

File details

Details for the file viralfetch-0.1.0.tar.gz.

File metadata

  • Download URL: viralfetch-0.1.0.tar.gz
  • Upload date:
  • Size: 941.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for viralfetch-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ceb3c42495c726ef17711634c71648e38978d6bb665103c4dfecbc9f787c7b65
MD5 7c7d7a43418067ba54fa822a01709f02
BLAKE2b-256 160ef16aacb921254caced5d9693e99bf442e6f8584a1e3f2dfdeb092d05b001

See more details on using hashes here.

File details

Details for the file viralfetch-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: viralfetch-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 805.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for viralfetch-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3a195d50fc31654c4d436df6da691097a56591e90aeb50f01e95a0256bf6928d
MD5 d58de15b70dc513057e7bac7852d5717
BLAKE2b-256 1e8ae1eb24e684fdd1b311baac60f2c892e585401f409392e54d8812bee0847d

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page