feat(ucsc): add gget ucsc module to fetch UCSC IDs (#18)#233
feat(ucsc): add gget ucsc module to fetch UCSC IDs (#18)#233Elarwei001 wants to merge 5 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #233 +/- ##
==========================================
+ Coverage 56.70% 57.20% +0.49%
==========================================
Files 29 30 +1
Lines 9392 9473 +81
==========================================
+ Hits 5326 5419 +93
+ Misses 4066 4054 -12 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
New module `gget ucsc` searches the UCSC Genome Browser REST API for a gene symbol, accession, or term and returns the matching UCSC identifiers (e.g. known gene / transcript IDs) with their genomic positions, grouped by track — analogous to gget search for Ensembl. Supports filtering by genome, track, and limit. Exposed via the Python API and the command line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add network-free mocked tests for empty search_term, _parse_position no-range branch, verbose logging, request-exception handling, and the save CSV/JSON branches. gget_ucsc.py now 100%. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4ed3b23 to
e649236
Compare
…se#18) - docs: put the UCSC (Kent 2002) citation before gget's, per convention - docs: drop the issue link from the updates.md changelog entry - docs: add Spanish page (es/ucsc.md) + SUMMARY Espanol entry - gget_ucsc: surface UCSC's own error message on 4xx (e.g. bad genome) instead of a generic 'try again later'; add a non-JSON guard - tests: add a bad-genome (HTTP 400) test and a truth-anchored live test against the real UCSC /search API (skipped when offline) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e search (scverse#18) - add a mocked case for the majority track shape (no match-level 'description' key + an 'extraSel' field) exercising the group-description fallback - add a live test that runs an unfiltered BRCA2 search so the parser is exercised across every real UCSC track type, not just gene-model tracks Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…/--limit (scverse#18) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Note on the red CI: the only failing test is It's an upstream live-data drift: |
|
Hi @lauraluebbert — this PR is ready for review whenever you have time. Quick overview:
Happy to adjust anything — thanks! |
Resolves #18
Summary
gget ucsc: new module to fetch UCSC Genome Browser IDs for a gene or term — the UCSC counterpart ofgget search(Ensembl). It queries UCSC's official, documented/searchREST endpoint and returns the matching identifiers (UCSC known-gene / transcript IDs, HGNC IDs, …) together with their genomic positions, grouped by the track they come from. Available in the Python API and on the command line.What it returns
One row per match, flattened from UCSC's
positionMatchesand tagged with the track it came from (snippet — first 3 rows):With
json=True(the command-line default) the same rows come back as records:[ { "track": "mane", "ucsc_id": "ENST00000380152.8", "chrom": "chr13", "start": 32315508, "end": 32400268, "name": "BRCA2 (NM_000059.4 / ENST00000380152.8)", "description": "breast cancer type 2 susceptibility protein" } ]Options:
genome(defaulthg38),track(case-insensitive substring filter),limit, plusjson/save. URL-encoded IDs (HGNC%3A1101→HGNC:1101) and HTML entities in labels are decoded. Because/searchis a text search, a broad term can also surface related genes (e.g. BRCA2 also matches BCCIP / BRCC3, whose descriptions mention BRCA2), so a common gene returns many rows across many tracks — narrow withtrack/limit.Full example output —
gget.ucsc("BRCA2", genome="hg38")returns 641 rows across 45 tracks; the complete result (CSV + JSON) is attached here: https://gist.github.com/Elarwei001/0879c9c75f6bb7f87d60c81111f929cbWhat is a "track group"?
UCSC stacks every kind of annotation over a genomic region as a horizontal track (gene models, gene naming, RefSeq, GENCODE, variants, …). A search returns its matches grouped by track (
positionMatches), andgget ucscflattens each group's matches into rows tagged with theirtrack. You can see these tracks visually here — BRCA2 in hg38:https://genome.ucsc.edu/cgi-bin/hgTracks?db=hg38&position=chr13:32315508-32400268
Each stacked row in that view corresponds to a track group in the API response. A common gene like BRCA2 hits dozens of tracks (~46), which is why
track/limitare provided to narrow the result.Testing
Unit tests in
tests/test_ucsc.py(with fixtures intests/fixtures/) cover: position parsing, the URL-encoded-ID and HTML-entity quirks, the group-description fallback (including the majority of tracks that omit a match-leveldescription), thetrackfilter,limit/json/save, and the error paths (empty term, request failure, and a bad genome that now surfaces UCSC's own error message rather than a generic one).Two live tests (skipped when the network is unavailable, so CI stays green) hit the real UCSC
/searchAPI: a truth-anchored BRCA2 check (chr13,ENST00000380152), and an unfiltered search that exercises the parser across every real track type — not just the gene-model tracks.