Skill Tracer
Skills › Scientific Agent Skills › gget › workflows.md

workflows.md

225 lines · skills/gget/references/workflows.md at 5f2bc03

Open on GitHub
1# gget workflow examples
2
3These are **illustrative integration recipes**, checked against gget 0.30.8
4signatures and response contracts, not fully executed scientific analyses.
5Remote results, optional dependencies, licenses, and input files vary. The
6[database contracts](database_info.md) record public verification and failures.
7Use the bundled scripts for tested export/control-flow behavior.
8

gget workflow examples

These are illustrative integration recipes, checked against gget 0.30.8 signatures and response contracts, not fully executed scientific analyses. Remote results, optional dependencies, licenses, and input files vary. The database contracts record public verification and failures. Use the bundled scripts for tested export/control-flow behavior.

Raw lines 1 to 8
9## Gene discovery to annotations and sequences
11`search` matches descriptions and synonyms. A search for `TP53` can return other
12genes before TP53; never use the first search hit as an exact identifier mapping.
14```python
15import gget
16from pathlib import Path
18symbol = "TP53"
19hits = gget.search(symbol, species="homo_sapiens")
20if hits is None:
21 raise RuntimeError("Search failed")
22exact = hits.loc[hits["gene_name"].eq(symbol)].drop_duplicates("ensembl_id")
23if len(exact) != 1:
24 raise ValueError("Resolve missing or ambiguous symbol before proceeding")
25gene_id = exact.iloc[0]["ensembl_id"]
27info = gget.info(gene_id, pdb=True)
28if info is None or info.empty:
29 raise RuntimeError("No annotation returned; inspect service errors")
30# Query IDs live in the index. Annotation fields can be missing or multi-valued.
31info.to_csv("tp53_info.csv", index_label="query_ensembl_id")
32print(info[["primary_gene_name", "ensembl_gene_name", "ensembl_description"]])
34protein_fasta = gget.seq(gene_id, translate=True)
35if not protein_fasta:
36 raise RuntimeError("No protein sequence returned")
37Path("tp53_protein.fasta").write_text("\n".join(protein_fasta) + "\n")
38```
40The released Ensembl HTTP adapter failed in this review. Do not treat that as
41absence of the gene; resolve transport before running this full recipe.
42Nucleotide `gget.seq(gene_id)` is genomic sequence, not an automatically selected CDS.

Gene discovery to annotations and sequences

search matches descriptions and synonyms. A search for TP53 can return other genes before TP53; never use the first search hit as an exact identifier mapping.

import gget
from pathlib import Path

symbol = "TP53"
hits = gget.search(symbol, species="homo_sapiens")
if hits is None:
    raise RuntimeError("Search failed")
exact = hits.loc[hits["gene_name"].eq(symbol)].drop_duplicates("ensembl_id")
if len(exact) != 1:
    raise ValueError("Resolve missing or ambiguous symbol before proceeding")
gene_id = exact.iloc[0]["ensembl_id"]

info = gget.info(gene_id, pdb=True)
if info is None or info.empty:
    raise RuntimeError("No annotation returned; inspect service errors")
# Query IDs live in the index. Annotation fields can be missing or multi-valued.
info.to_csv("tp53_info.csv", index_label="query_ensembl_id")
print(info[["primary_gene_name", "ensembl_gene_name", "ensembl_description"]])

protein_fasta = gget.seq(gene_id, translate=True)
if not protein_fasta:
    raise RuntimeError("No protein sequence returned")
Path("tp53_protein.fasta").write_text("\n".join(protein_fasta) + "\n")

The released Ensembl HTTP adapter failed in this review. Do not treat that as absence of the gene; resolve transport before running this full recipe. Nucleotide gget.seq(gene_id) is genomic sequence, not an automatically selected CDS.

Raw lines 9 to 43
44## Comparative sequences and structures
46Choose orthologs from `gget.bgee(..., type="orthologs")`; verify species and
47one-to-many orthology before comparing. Save flat FASTA records, not nested
48lists of the output from `seq`.
50```python
51import gget
52from pathlib import Path
54orthologs = gget.bgee("ENSG00000169174", type="orthologs") # human PCSK9
55print(orthologs[["gene_id", "gene_name", "species"]])
56# Select a confirmed mouse ortholog from the response, rather than guessing an ID.
57mouse = orthologs.loc[orthologs["species"].eq("musculus")]
58if len(mouse) != 1:
59 raise ValueError("Choose the intended mouse ortholog explicitly")
60human_lines = gget.seq("ENSG00000169174", translate=True)
61mouse_lines = gget.seq(mouse.iloc[0]["gene_id"], translate=True)
62if not human_lines or not mouse_lines:
63 raise RuntimeError("Sequence retrieval failed")
64Path("orthologs.fasta").write_text("\n".join(human_lines + mouse_lines) + "\n")
65gget.muscle("orthologs.fasta", out="orthologs.afa") # returns None
67# G2P connects a specified protein to existing isoforms and structures.
68structure_map = gget.g2p("TP53", uniprot_id="P04637", resource="map")
69if structure_map is not None:
70 print(structure_map[["UniProt Isoform", "PDB Ids List"]])
71# An explicitly chosen structure, after checking chain and residue coverage:
72structure = gget.pdb("1TUP", resource="mmcif")
73if structure is not None:
74 Path("1TUP.cif").write_text(structure)
75```
77Do not extract a PDB accession by splitting free-text BLAST descriptions.
78Check chain sequence, residue numbering, coverage, ligands, experimental method,
79and structure quality. Predicted structure confidence is not experimental
80validation. The gget AlphaFold wrapper is deprecated and is not part of this recipe.

Comparative sequences and structures

Choose orthologs from gget.bgee(..., type="orthologs"); verify species and one-to-many orthology before comparing. Save flat FASTA records, not nested lists of the output from seq.

import gget
from pathlib import Path

orthologs = gget.bgee("ENSG00000169174", type="orthologs")  # human PCSK9
print(orthologs[["gene_id", "gene_name", "species"]])
# Select a confirmed mouse ortholog from the response, rather than guessing an ID.
mouse = orthologs.loc[orthologs["species"].eq("musculus")]
if len(mouse) != 1:
    raise ValueError("Choose the intended mouse ortholog explicitly")
human_lines = gget.seq("ENSG00000169174", translate=True)
mouse_lines = gget.seq(mouse.iloc[0]["gene_id"], translate=True)
if not human_lines or not mouse_lines:
    raise RuntimeError("Sequence retrieval failed")
Path("orthologs.fasta").write_text("\n".join(human_lines + mouse_lines) + "\n")
gget.muscle("orthologs.fasta", out="orthologs.afa")  # returns None

# G2P connects a specified protein to existing isoforms and structures.
structure_map = gget.g2p("TP53", uniprot_id="P04637", resource="map")
if structure_map is not None:
    print(structure_map[["UniProt Isoform", "PDB Ids List"]])
# An explicitly chosen structure, after checking chain and residue coverage:
structure = gget.pdb("1TUP", resource="mmcif")
if structure is not None:
    Path("1TUP.cif").write_text(structure)

Do not extract a PDB accession by splitting free-text BLAST descriptions. Check chain sequence, residue numbering, coverage, ligands, experimental method, and structure quality. Predicted structure confidence is not experimental validation. The gget AlphaFold wrapper is deprecated and is not part of this recipe.

Raw lines 44 to 81
82## Cancer and drug associations
84```python
85import gget
87gene_id = "ENSG00000146648" # EGFR, human
88associations = gget.opentargets(gene_id, resource="diseases", limit=10)
89print(associations[["disease.id", "disease.name", "score"]])
90drugs = gget.opentargets(gene_id, resource="drugs", limit=10)
91if not drugs.empty:
92 print(drugs[["drug.name", "drug.drugType", "drug.maximumClinicalStage"]])
93tractability = gget.opentargets(gene_id, resource="tractability")
94print(tractability)
96expression = gget.opentargets(gene_id, resource="expression", limit=100)
97if not expression.empty:
98 print(expression[["median", "unit", "datasourceId", "datatypeId"]])
99interactions = gget.opentargets(gene_id, resource="interactions", limit=10)
100print(interactions.reindex(columns=["targetB.id", "targetB.approvedSymbol", "score"]))
101```
103These are bounded exploratory slices. gget does not traverse Open Targets pages;
104local filters cannot retrieve records outside the fetched page. A filter applied
105after `limit=10` searches only those ten rows. The disease score does not validate
106a target, and an associated drug is not a treatment recommendation. Do not label
107candidate targets “validated” from these queries alone.
109cBioPortal and COSMIC are separate input routes:
111```bash
112# Optional dependencies; then discover and select appropriate studies.
113gget setup cbio
114gget cbio search breast
115# Illustrative: downloads study data and writes a heatmap.
116gget cbio plot -s msk_impact_2017 -g EGFR TP53 -st tissue -vt mutation_occurrences
117# Requires a previously downloaded, licensed COSMIC TSV and matching project.
118gget cosmic EGFR --cosmic_project cancer --cosmic_tsv_path cosmic_data.tsv -l 10
119```
121Record study/sample coverage, assembly, mutation definitions, and denominators.
122A missing file or adapter failure is not a zero-mutation result.

Cancer and drug associations

import gget

gene_id = "ENSG00000146648"  # EGFR, human
associations = gget.opentargets(gene_id, resource="diseases", limit=10)
print(associations[["disease.id", "disease.name", "score"]])
drugs = gget.opentargets(gene_id, resource="drugs", limit=10)
if not drugs.empty:
    print(drugs[["drug.name", "drug.drugType", "drug.maximumClinicalStage"]])
tractability = gget.opentargets(gene_id, resource="tractability")
print(tractability)

expression = gget.opentargets(gene_id, resource="expression", limit=100)
if not expression.empty:
    print(expression[["median", "unit", "datasourceId", "datatypeId"]])
interactions = gget.opentargets(gene_id, resource="interactions", limit=10)
print(interactions.reindex(columns=["targetB.id", "targetB.approvedSymbol", "score"]))

These are bounded exploratory slices. gget does not traverse Open Targets pages; local filters cannot retrieve records outside the fetched page. A filter applied after limit=10 searches only those ten rows. The disease score does not validate a target, and an associated drug is not a treatment recommendation. Do not label candidate targets “validated” from these queries alone.

cBioPortal and COSMIC are separate input routes:

# Optional dependencies; then discover and select appropriate studies.
gget setup cbio
gget cbio search breast
# Illustrative: downloads study data and writes a heatmap.
gget cbio plot -s msk_impact_2017 -g EGFR TP53 -st tissue -vt mutation_occurrences
# Requires a previously downloaded, licensed COSMIC TSV and matching project.
gget cosmic EGFR --cosmic_project cancer --cosmic_tsv_path cosmic_data.tsv -l 10

Record study/sample coverage, assembly, mutation definitions, and denominators. A missing file or adapter failure is not a zero-mutation result.

Raw lines 82 to 123
124## Expression and enrichment
126```python
127import gget
129bulk = gget.archs4("TP53", which="tissue", species="human")
130print(bulk[["id", "median"]].head())
131correlated = gget.archs4("TP53", which="correlation", gene_count=20)
132print(correlated[["gene_symbol", "pearson_correlation"]])
133```
135For a differential-expression list, supply the genes actually tested as the
136background; record mapped/unmapped counts and use an organism-appropriate full
137library identifier. The following uploads the lists to Enrichr and is illustrative:
139```python
140import gget
141from pathlib import Path
143selected = Path("selected_gene_symbols.txt").read_text().splitlines()
144tested = Path("tested_gene_symbols.txt").read_text().splitlines()
145if not set(selected).issubset(tested):
146 raise ValueError("Selected genes must belong to the tested universe")
147result = gget.enrichr(selected, database="GO_Biological_Process_2021",
148 background_list=tested, species="human", plot=False)
149if result is None:
150 raise RuntimeError("Enrichment failed")
151result.to_csv("enrichment.csv", index=False)
152significant = result.loc[result["adj_p_val"] < 0.05]
153print(significant[["path_name", "adj_p_val", "overlapping_genes"]])
154```
156A coexpression-selected list needs a background from the genes eligible for that
157selection. Enrichr returns rows irrespective of your significance threshold;
158empty/error responses do not prove absence of enrichment. For fly/yeast/worm/fish,
159use a species-specific full library and omit custom backgrounds.

Expression and enrichment

import gget

bulk = gget.archs4("TP53", which="tissue", species="human")
print(bulk[["id", "median"]].head())
correlated = gget.archs4("TP53", which="correlation", gene_count=20)
print(correlated[["gene_symbol", "pearson_correlation"]])

For a differential-expression list, supply the genes actually tested as the background; record mapped/unmapped counts and use an organism-appropriate full library identifier. The following uploads the lists to Enrichr and is illustrative:

import gget
from pathlib import Path

selected = Path("selected_gene_symbols.txt").read_text().splitlines()
tested = Path("tested_gene_symbols.txt").read_text().splitlines()
if not set(selected).issubset(tested):
    raise ValueError("Selected genes must belong to the tested universe")
result = gget.enrichr(selected, database="GO_Biological_Process_2021",
                      background_list=tested, species="human", plot=False)
if result is None:
    raise RuntimeError("Enrichment failed")
result.to_csv("enrichment.csv", index=False)
significant = result.loc[result["adj_p_val"] < 0.05]
print(significant[["path_name", "adj_p_val", "overlapping_genes"]])

A coexpression-selected list needs a background from the genes eligible for that selection. Enrichr returns rows irrespective of your significance threshold; empty/error responses do not prove absence of enrichment. For fly/yeast/worm/fish, use a species-specific full library and omit custom backgrounds.

Raw lines 124 to 160
161## Scoped single-cell exploration
163Install `gget[cellxgene]==0.30.8` in a compatible Python 3.12/3.13 environment.
164Choose a retained Census snapshot and an explicit dataset ID first; placeholders
165below deliberately require input selection. This example is not a full scRNA-seq
166analysis or a tested large download.
168```python
169import gget
171census_version = "2025-11-08" # Example LTS; confirm availability before querying.
172dataset_id = "REPLACE_WITH_SELECTED_DATASET_UUID"
173metadata = gget.cellxgene(dataset_id=dataset_id, species="homo_sapiens",
174 census_version=census_version, meta_only=True,
175 column_names=["dataset_id", "donor_id", "cell_type", "is_primary_data"])
176print(f"Selected cells: {len(metadata)}") # gene filtering does not affect this table
178adata = gget.cellxgene(gene=["ACE2", "TMPRSS2"], dataset_id=dataset_id,
179 species="homo_sapiens", census_version=census_version)
180print(adata.shape)
181print(adata.var[["feature_id", "feature_name"]])
182# var_names may be Ensembl IDs, not symbols. Match feature_name explicitly.
183for symbol in ["ACE2", "TMPRSS2"]:
184 selected = adata[:, adata.var["feature_name"].eq(symbol).to_numpy()]
185 if selected.n_vars == 1 and selected.n_obs:
186 print(symbol, "raw nonzero fraction", float((selected.X > 0).sum() / selected.n_obs))
187```
189Do not filter cells at `min_genes=200` after retrieving two/four genes: that
190removes every cell. Do not normalize a selected marker panel as if it were a
191whole-transcriptome library. For QC/normalization, retrieve the required full
192feature universe or valid precomputed whole-cell metrics, and account for assay,
193dataset, donor, primary-data duplication, and batch before comparing expression.

Scoped single-cell exploration

Install gget[cellxgene]==0.30.8 in a compatible Python 3.12/3.13 environment. Choose a retained Census snapshot and an explicit dataset ID first; placeholders below deliberately require input selection. This example is not a full scRNA-seq analysis or a tested large download.

import gget

census_version = "2025-11-08"  # Example LTS; confirm availability before querying.
dataset_id = "REPLACE_WITH_SELECTED_DATASET_UUID"
metadata = gget.cellxgene(dataset_id=dataset_id, species="homo_sapiens",
                         census_version=census_version, meta_only=True,
                         column_names=["dataset_id", "donor_id", "cell_type", "is_primary_data"])
print(f"Selected cells: {len(metadata)}")  # gene filtering does not affect this table

adata = gget.cellxgene(gene=["ACE2", "TMPRSS2"], dataset_id=dataset_id,
                      species="homo_sapiens", census_version=census_version)
print(adata.shape)
print(adata.var[["feature_id", "feature_name"]])
# var_names may be Ensembl IDs, not symbols. Match feature_name explicitly.
for symbol in ["ACE2", "TMPRSS2"]:
    selected = adata[:, adata.var["feature_name"].eq(symbol).to_numpy()]
    if selected.n_vars == 1 and selected.n_obs:
        print(symbol, "raw nonzero fraction", float((selected.X > 0).sum() / selected.n_obs))

Do not filter cells at min_genes=200 after retrieving two/four genes: that removes every cell. Do not normalize a selected marker panel as if it were a whole-transcriptome library. For QC/normalization, retrieve the required full feature universe or valid precomputed whole-cell metrics, and account for assay, dataset, donor, primary-data duplication, and batch before comparing expression.

Raw lines 161 to 194
195## Reference-file preparation
197```bash
198# Historical pinned example; verify the assembly and release suit the study.
199gget ref homo_sapiens -r 110 -w gtf,cdna -d -od reference -o reference_manifest.json
200# Python ref returns links/metadata; downloading is a CLI capability.
201```
203Use a dedicated output directory, record checksums, and build downstream indexes
204with the downloaded filenames actually present. Do not mix the pinned release
205with unrecorded latest annotations. `search` accepts a release, whereas `info`
206and `seq` query current REST data.

Reference-file preparation

# Historical pinned example; verify the assembly and release suit the study.
gget ref homo_sapiens -r 110 -w gtf,cdna -d -od reference -o reference_manifest.json
# Python ref returns links/metadata; downloading is a CLI capability.

Use a dedicated output directory, record checksums, and build downstream indexes with the downloaded filenames actually present. Do not mix the pinned release with unrecorded latest annotations. search accepts a release, whereas info and seq query current REST data.

Raw lines 195 to 207
208## Applying a coding variant
210This local synthetic example was executed with 0.30.8:
212```python
213import gget
215cds = "ATCGCTAAGCT"
216assert cds[3] == "G" # HGVS c.4 is 1-based
217mutated = gget.mutate(cds, "c.4G>T", verbose=False)
218assert mutated == ["ATCTCTAAGCT"]
219```
221For real variants, first obtain the exact transcript-version CDS, confirm the
222reference base and reading frame, then apply the variant. Genomic gene sequences,
223UTRs, introns, negative-strand coordinates, and different isoforms cannot be used
224interchangeably. A sequence edit or structure comparison alone is not evidence of
225pathogenicity, frequency, or functional effect.

Applying a coding variant

This local synthetic example was executed with 0.30.8:

import gget

cds = "ATCGCTAAGCT"
assert cds[3] == "G"  # HGVS c.4 is 1-based
mutated = gget.mutate(cds, "c.4G>T", verbose=False)
assert mutated == ["ATCTCTAAGCT"]

For real variants, first obtain the exact transcript-version CDS, confirm the reference base and reading frame, then apply the variant. Genomic gene sequences, UTRs, introns, negative-strand coordinates, and different isoforms cannot be used interchangeably. A sequence edit or structure comparison alone is not evidence of pathogenicity, frequency, or functional effect.

Raw lines 208 to 225