
Opentargets Database
- 1.3k installs
- 2.6k repo stars
- Updated July 7, 2026
- google-deepmind/science-skills
opentargets-database is a data science skill that lets developers query the Open Targets Platform GraphQL API for genetics, disease associations, druggability, and clinical evidence from agents or Python scripts.
About
opentargets-database is a Google DeepMind science-skills module for querying the Open Targets Platform GraphQL API, which aggregates multi-modal evidence from GWAS and eQTL genetics, pathways, animal models, and clinical trials to rank target-disease associations and surface known drugs. Developers run scripts/query_opentargets.py for API communication, response formatting, and automatic truncation of large payloads to save agent context tokens. Built-in subcommands include get-gwas-studies with an EFO disease identifier for federated genetic evidence linking variants to diseases and druggable targets. Reach for opentargets-database when bioinformatics or computational biology workflows need druggability scores, target rankings, or disease association evidence inside Claude or terminal sessions—not for general SQL database administration. The Python script pattern keeps repeated GraphQL queries reproducible and context-safe for long API responses during drug-discovery research pipelines in agent, notebook, or script sessions.
- 8 built-in subcommands for GWAS studies, credible sets, L2G predictions, druggability, target-disease associations and m
- Automatically truncates large API responses to save context window tokens
- Supports --limit and --page-size global options for precise result control
- Returns multi-modal evidence from genetics, pathways, animal models and clinical trials
- Python script with ready-to-use CLI commands for agentic research workflows
Opentargets Database by the numbers
- 1,268 all-time installs (skills.sh)
- +168 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #258 of 2,064 Data Science & ML skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/google-deepmind/science-skills --skill opentargets-databaseAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.3k |
|---|---|
| repo stars | ★ 2.6k |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 7, 2026 |
| Repository | google-deepmind/science-skills ↗ |
How do you query Open Targets genetics data programmatically?
Query the Open Targets Platform for genetics, disease associations, druggability, and clinical evidence directly from agents or scripts.
Who is it for?
Computational biologists and data engineers who need Open Targets genetics and druggability evidence inside agent or Python workflows.
Skip if: Developers managing unrelated SQL databases or teams without biomedical target-discovery use cases.
When should I use this skill?
The user asks to query Open Targets, fetch GWAS studies by EFO ID, rank target-disease associations, or check druggability from agents.
What you get
Formatted Open Targets API responses with target-disease rankings, GWAS study data, and druggability evidence truncated for agent context.
- Formatted Open Targets query results
- GWAS study extracts
- Target-disease association rankings
By the numbers
- Bundled Python script scripts/query_opentargets.py with specialized subcommands
- GraphQL API aggregates GWAS/eQTL, pathways, animal models, and clinical trials
Files
Open Targets Database Skill
Overview
This skill provides access to the Open Targets Platform GraphQL API. It aggregates multi-modal evidence from genetics (GWAS/eQTL), pathways, animal models, and clinical trials to rank target-disease associations and identify druggable genes.
Prerequisites
1. `uv`: Read the uv skill and follow its Setup instructions to ensure uv is installed and on PATH. 2. User Notification: If LICENSE_NOTIFICATION.txt does not already exist in this skill directory then (1) prominently notify the user to check the terms at https://platform-docs.opentargets.org/licence, then (2) create the file recording the notification text and timestamp.
Core Rules
- Use the Wrapper: ALWAYS execute the provided helper scripts to query the
database rather than accessing the database directly. The scripts automatically enforce fair use and implement retry logic.
- Output Flag: The
--outputflag is always required as output can be
very large. Use jq or write your own code to process this JSON file.
- Notification: If this skill is used, ensure this is mentioned in the
output.
Quick Reference
Always use the provided Python script scripts/query_opentargets.py to quickly query the database. It handles API communication, retries, formatting, and automatically truncates overly large responses. NEVER write your own curl or similar requests.
Usage:
uv run scripts/query_opentargets.py --output /tmp/opentargets_results.json [OPTIONS] COMMAND [ARGS]...Common Options:
-
--output PATH: Required. Path to write the JSON output file. -
--limit N: Limit the number of items returned in arrays (default is 50).
Use a smaller number like 10 when doing preliminary exploration.
-
--page-size N: Set the API pagination size (default is 200). Increase if
you need more results (e.g., a study with many credible sets).
Available Commands:
- `get-gwas-studies` `efo_id`: Fetches all GWAS studies associated with
a specific disease ontology EFO ID (e.g. EFO_0000685).
- `get-study-credible-sets` `study_id`: Fetches all credible sets for a
given study ID (e.g. FINNGEN_R12_RX_CROHN_2NDLINE). Returns confidence, finemapping method, variant, and p-value info.
- `get-qtl-credible-sets` `variant_id`: Retrieves QTL credible sets for
a specific variant ID (e.g. 19_44908822_C_T).
- `get-l2g` `variant_id [--study-id ID]`: Returns Locus-to-Gene (L2G)
predictions/scores for a locus to identify the most likely causal gene. Only variant_id is required; use --study-id to filter to a specific study. Accepts chr prefix (e.g. chr1_113834946_A_G).
- `get-target-druggability` `ensembl_id`: Provides tractability data
(small molecule, antibody, etc.) and clinical trial safety info for a gene/target.
- `get-associated-targets` `efo_id`: Find all target genes associated
with a specific disease EFO ID.
- `get-associated-diseases` `ensembl_id`: Find all diseases associated
with a specific target Ensembl ID.
- `search-disease` `query_string`: Search for a disease by name to find
its EFO ID and other metadata.
- `get-credible-sets-near-target` `ensembl_id [--window N]`: Fetches
credible sets for a target and filters them to those within a genomic window around the target. Useful for finding variants "nearby" a gene.
- `custom-query` `query [--variables '{}']`: Run a raw GraphQL query for
any other Open Targets data.
L2G Query Usage
The get-l2g command has two modes:
- Variant only (
get-l2g <variant_id>): Returns L2G predictions from
all credible sets across all studies where that variant is the lead variant. This can return a large number of results (e.g., hundreds). Use this when the user wants a broad view of which gene is most likely causal at a locus, or when no specific study is mentioned.
- Variant + study (
get-l2g <variant_id> --study-id <study_id>): Returns
L2G predictions only for credible sets from that specific study. Use this when the user asks about a specific GWAS study or when you need to narrow down the results.
Incomplete results warning: The variant-only mode can return hundreds of
credible sets. The default --page-size is 200, so if the API reports acounthigher than the number ofrowsreturned, **you are seeing incomplete
results**. Always compare count to the actual number of rows. If theydiffer, either increase --page-size or inform the user that only a subsetwas retrieved.
Querying by Region
To find studies with variants "nearby" a gene, use get-credible-sets-near-target, which improves upon the base API by performing a flexible search based on genomic position: uv run scripts/query_opentargets.py --output /tmp/results.json get-credible-sets-near-target ENSG00000156515 --window 500000
Note that the Open Targets GraphQL schema includes a regions parameter for credibleSets, however it performs an exact match against pre-computed region strings (e.g., chr10:68769984-69903496) and there is some missing data. Use get-credible-sets-near-target as it allows a genomic range overlap search.
This fetches credible sets associated with the target and filters them in Python based on the variant's genomic position.
Advanced GraphQL Queries
If you need to query endpoints or fields not exposed by the built-in subcommands, use the custom-query subcommand.
Before writing a custom query: Read the reference documentation to understand the API schema, types, and see example queries. See references/OpenTargets_GraphQL_Guide.md for full schema details, endpoints, and examples.
Example: Finding drugs for a disease
uv run scripts/query_opentargets.py custom-query \
query drugsForDisease($id: String!) {
disease(efoId: $id) {
name
drugAndClinicalCandidates {
count
rows {
maxClinicalStage
drug {
id
name
}
}
}
}
}' \
--variables '{"id": "EFO_1001006"}'
--output '/tmp/opentargets_result.json'Confidence Star Ratings
The Open Targets Platform assigns a confidence level to each credible set based on the fine-mapping method and quality checks. These correspond to star ratings displayed in the platform UI:
| Stars | Confidence String (API value) |
|---|---|
| ★★★★ (4 stars) | SuSiE fine-mapped credible set with in-sample LD |
| ★★★ (3 stars) | SuSiE fine-mapped credible set with out-of-sample LD |
| ★★ (2 stars) | `PICS fine-mapped credible set extracted from summary |
: : statistics : | ★ (1 star) | PICS fine-mapped credible set based on reported top hit | | None | Unknown confidence` |
When users ask about "N-star confidence", match their request to the corresponding string in the confidence field of the API response.
Tips and Common Mistakes
- ID Formats:
- Disease IDs must be in EFO format (e.g.
EFO_0000685). - Target IDs must be Ensembl IDs (e.g.
ENSG00000169083), not HGNC
symbols. If you only have a gene symbol, you may need to map it first using a custom GraphQL search query.
- Variant IDs are formatted as
chromosome_position_ref_alt(e.g.,
1_154426264_C_T). A chr prefix (e.g. chr1_154426264_C_T) is automatically stripped by the tool.
- Study IDs can be GWAS Catalog IDs (e.g.
GCST90204201) or
project-specific IDs (e.g. FINNGEN_R12_RX_CROHN_2NDLINE).
- Truncation: The tool truncates arrays longer than
--limitto protect
the context window. If you see "_truncated", you can run the query again with a higher limit if you specifically need more data, but be cautious with large limit values. Always use the --output flag to save the result to a file and avoid terminal output truncation.
- Pagination and incomplete results: The
--page-sizeoption (default:
200) controls how many items are fetched from the API. Always check the `count` field in the response and compare it to the number of `rows` actually returned. If count > number of rows, you have incomplete data — either increase --page-size to fetch more, or inform the user that only a partial result set was returned. This is especially important for get-l2g without --study-id, which can return hundreds of credible sets.
Open Targets GraphQL API Guide
Overview
The Open Targets Platform GraphQL API provides access to aggregated multi-modal evidence from genetics (GWAS/eQTL), pathways, animal models, and clinical trials. This data is used to rank target-disease associations, identify druggable genes, and discover known drugs.
Querying the API
To interact with the Open Targets API, use the provided Python script scripts/query_opentargets.py. This script handles API communication, formatting, and automatically truncates large responses to save context window tokens.
Built-in Commands
For common tasks, use the specialized subcommands provided by the script:
-
get-gwas-studies <efo_id>: Fetch GWAS studies for a disease. -
get-study-credible-sets <study_id>: Fetch 95% credible sets for a study. -
get-qtl-credible-sets <variant_id>: Fetch QTL credible sets for a variant. -
get-l2g <variant_id> [--study-id <study_id>]: Get Locus-to-Gene (L2G)
predictions.
-
get-target-druggability <ensembl_id>: Get tractability and safety data for
a target.
-
get-associated-targets <efo_id>: Find target genes associated with a
disease.
-
get-associated-diseases <ensembl_id>: Find diseases associated with a
target.
-
search-disease <query_string>: Search for a disease to find its EFO ID.
Global Options:
-
--limit N: Limits the number of items returned in arrays (default: 50). -
--page-size N: Sets API pagination size (default: 200).
Custom GraphQL Queries
For complex queries or fields not covered by the built-in commands, use the custom-query subcommand:
uv run scripts/query_opentargets.py custom-query \
'query targetInfo($id: String!) {
target(ensemblId: $id) {
approvedSymbol
biotype
}
}' \
--variables '{"id": "ENSG00000169083"}'Core Entities & Identifiers
When writing custom GraphQL queries, you will primarily interact with the following core entities defined in the schema:
1. Target (Gene/Protein)
- Identifier: Ensembl ID (e.g.,
ENSG00000169083). **Do not use HGNC
symbols directly**; you must map them to Ensembl IDs first.
- Root Queries:
target(ensemblId: String!), `targets(ensemblIds:
[String!]!)`
- Key Fields:
-
id: Ensembl ID. -
approvedSymbol,approvedName: Standard HGNC symbol and name. -
biotype: Type of gene (e.g., protein_coding). -
associatedDiseases(...): Target-disease associations with scores. -
knownDrugs(...): Approved/investigational drugs targeting this gene. -
tractability: Feasibility of targeting with therapeutic modalities.
2. Disease (or Phenotype)
- Identifier: Experimental Factor Ontology (EFO) ID (e.g.,
EFO_0000685). - Root Queries:
disease(efoId: String!),diseases(efoIds: [String!]!) - Key Fields:
-
id: EFO ID. -
name,description: Disease name and summary. -
synonyms: Alternative names. -
associatedTargets(...): Targets associated with this disease, sortable
by score.
-
knownDrugs(...): Drugs indicated for this disease or currently in
clinical trials.
-
evidences(...): Specific pieces of evidence supporting target-disease
associations.
3. Drug (or Clinical Candidate)
- Identifier: ChEMBL ID (e.g.,
CHEMBL112). - Root Queries:
drug(chemblId: String!),drugs(chemblIds: [String!]!) - Key Fields:
-
id: ChEMBL ID. -
name,drugType: Generic name and molecule type. -
isApproved,maximumClinicalTrialPhase: Clinical status. -
mechanismsOfAction: How the drug interacts with its target. -
indications: Diseases the drug is indicated for. -
adverseEvents(...): Significant adverse events from FAERS.
4. Variant
- Identifier: Format
CHROM_POS_REF_ALT(e.g.,1_154426264_C_T). Note:
A chr prefix is automatically stripped by the CLI tool, but standard queries expect it without the prefix.
- Root Query:
variant(variantId: String!) - Key Fields:
-
id: Variant ID. -
chromosome,position,referenceAllele,alternateAllele: Genomic
coordinates.
-
rsIds: dbSNP identifiers. -
credibleSets(...): GWAS/molQTL credible sets containing this variant.
5. Study (GWAS/molQTL)
- Identifier: Study ID (e.g., GWAS Catalog ID
GCST90204201or project
ID).
- Root Query:
study(studyId: String) - Key Fields:
-
id: Study ID. -
studyType: Type of study (gwas,eqtl,pqtl, etc.). -
traitFromSource: The trait analysed in the study. -
credibleSets(...): 95% credible sets for this study.
Common Query Patterns
Finding Drugs for a Disease
To find drugs associated with a specific disease, use the knownDrugs field on the disease entity. This is more direct than searching for evidence records.
query diseaseDrugs($id: String!) {
disease(efoId: $id) {
name
drugAndClinicalCandidates {
count
rows {
maxClinicalStage
drug {
id
name
}
}
}
}
}Pagination
Many relation fields (like associatedDiseases, evidences, credibleSets) require a page argument to handle large datasets.
query getAssocDiseases($id: String!) {
target(ensemblId: $id) {
associatedDiseases(page: {index: 0, size: 10}) {
count
rows {
score
disease {
id
name
}
}
}
}
}Search and ID Mapping
If you only have a string (like a gene symbol or disease name), use the search or mapIds queries to find the correct canonical IDs.
query searchEntity($query: String!) {
search(
queryString: $query,
entityNames: ["target", "disease"],
page: {index: 0, size: 5}
) {
hits {
id
entity
name
description
}
}
}Best Practices & Tips for Agents
1. Check the `count`: Always check the count field when querying paginated lists (rows). If the total count is larger than the number of rows returned, you are only seeing a partial result. Increase --page-size or adjust your query's size parameter if more data is needed. 2. Locus-to-Gene (L2G) Nuances: When querying L2G predictions for a variant without specifying a study ID, you will get predictions across all credible sets where the variant is the lead. This often returns hundreds of rows. Use --study-id to narrow it down if the user is interested in a specific GWAS study. 3. Confidence Ratings: Open Targets assigns "star ratings" based on the fine-mapping method used for credible sets (e.g., 4 stars = SuSiE fine-mapped credible set with in-sample LD). Match these exact strings when users ask for specific confidence tiers. 4. Avoid Excessive Limits: The CLI tool defaults to a limit of 50 to protect context windows. Start with small limits or sizes (e.g., size: 10) when exploring the schema or doing preliminary searches, then increase if needed. 5. Use Subcommands First: Whenever possible, use the specialized subcommands (e.g., get-l2g, get-associated-targets) instead of writing custom raw GraphQL queries, as they are pre-optimized and easier to invoke.
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Queries the Open Targets Platform GraphQL API.
This script provides a command-line interface to query various endpoints of the
Open Targets GraphQL API, including GWAS studies, QTL credible sets, L2G
predictions, target druggability, and disease/target associations.
"""
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "scienceskillscommon",
# ]
# [tool.uv.sources]
# scienceskillscommon = { path = "../../scienceskillscommon" }
# ///
import argparse
import json
import re
import sys
from typing import Any
from science_skills.skills.scienceskillscommon import http_client
BASE_URL = "https://api.platform.opentargets.org/api/v4/graphql"
_CLIENT = http_client.HttpClient(BASE_URL, qps=1.0)
def normalize_variant_id(variant_id: str) -> str:
"""Normalize variant ID by stripping 'chr' prefix if present."""
return re.sub(r"^chr", "", variant_id, flags=re.IGNORECASE)
def truncate_data(data: Any, limit: int = 50) -> Any:
"""Recursively truncates lists within a dictionary or list to a given limit.
This function is designed to limit the size of potentially large lists within
the JSON response from the OpenTargets API, making the output more manageable.
Specifically handles the "rows" field within dictionaries that also have a
"count" field, common in OpenTargets GraphQL responses.
Args:
data: The data structure (dict or list) to potentially truncate.
limit: The maximum number of items to keep in any list.
Returns:
The truncated data structure.
"""
if isinstance(data, list):
if len(data) > limit:
result = [truncate_data(item, limit) for item in data[:limit]]
result.append({"_truncated": f"(Showing {limit} of {len(data)} items)"})
return result
return [truncate_data(item, limit) for item in data]
elif isinstance(data, dict):
result = {}
for k, v in data.items():
if k == "rows" and isinstance(v, list) and "count" in data:
# specific to Open Targets GraphQL
count = data.get("count", len(v))
if len(v) > limit:
result[k] = [truncate_data(item, limit) for item in v[:limit]]
result[k].append({"_truncated": f"(Showing {limit} of {count} rows)"})
else:
result[k] = [truncate_data(item, limit) for item in v]
else:
result[k] = truncate_data(v, limit)
return result
else:
return data
def execute_query(
query: str,
variables: dict[str, Any],
output_file: str,
limit: int = 50,
page_size: int = 200,
):
"""Executes a GraphQL query against the Open Targets API.
This function sends a POST request to the Open Targets GraphQL API. It
automatically injects pagination variables if the query supports it and
pagination is not already specified. The response is checked for errors,
truncated to a manageable size, and then written to the specified output file
as JSON.
Args:
query: The GraphQL query string.
variables: A dictionary of variables to pass with the query.
output_file: The path to the file where the JSON output will be written.
limit: The maximum number of items to keep in lists within the response
(used by truncate_data). Defaults to 50.
page_size: The size of each page for API pagination. If provided and the
query supports "$page", pagination variables will be added. Defaults to
200.
"""
# Inject pagination into variables the query supports it and not already set
if "page" not in variables and page_size and "$page" in query:
variables["page"] = {"index": 0, "size": page_size}
data = _CLIENT.fetch_json(
BASE_URL,
method="POST",
json_body={"query": query, "variables": variables},
)
if "errors" in data:
print(
f"GraphQL Errors: {json.dumps(data['errors'], indent=2)}",
file=sys.stderr,
)
sys.exit(1)
truncated_data = truncate_data(data.get("data", {}), limit)
with open(output_file, "w", encoding="utf-8") as f:
f.write(json.dumps(truncated_data, indent=2))
def main():
parser = argparse.ArgumentParser(
description="Query Open Targets Platform GraphQL API"
)
parser.add_argument(
"--limit",
type=int,
default=50,
help="Limit list sizes in response (default: 50)",
)
parser.add_argument(
"--page-size",
type=int,
default=200,
help=(
"API pagination size (default: 200). Set higher if results are"
" truncated."
),
)
parser.add_argument(
"--output",
required=True,
help="Path to write the JSON output file",
)
subparsers = parser.add_subparsers(dest="command", required=True)
# get-gwas-studies
p_gwas = subparsers.add_parser(
"get-gwas-studies", help="Get GWAS studies for a specific disease EFO ID"
)
p_gwas.add_argument("efo_id", help="Disease EFO ID (e.g., EFO_0000685)")
# get-qtl-credible-sets
p_qtl = subparsers.add_parser(
"get-qtl-credible-sets",
help="Get QTL credible sets for a specific variant",
)
p_qtl.add_argument("variant_id", help="Variant ID (e.g., 19_44908822_C_T)")
# get-l2g
p_l2g = subparsers.add_parser(
"get-l2g",
help=(
"Get L2G prioritisation scores for a variant, optionally filtered by"
" study"
),
)
p_l2g.add_argument(
"variant_id",
help="Lead variant ID (e.g., 1_113834946_A_G or chr1_113834946_A_G)",
)
p_l2g.add_argument(
"--study-id",
help="Optional study ID to filter results (e.g., GCST90204201)",
default=None,
)
# get-target-druggability
p_drug = subparsers.add_parser(
"get-target-druggability",
help="Get druggability and safety info for a target",
)
p_drug.add_argument(
"ensembl_id", help="Target Ensembl ID (e.g., ENSG00000169083)"
)
# get-associated-targets
p_assoc_tgt = subparsers.add_parser(
"get-associated-targets",
help="Get targets associated with a disease EFO ID",
)
p_assoc_tgt.add_argument("efo_id", help="Disease EFO ID (e.g., EFO_0000349)")
# get-associated-diseases
p_assoc_dis = subparsers.add_parser(
"get-associated-diseases",
help="Get diseases associated with a target Ensembl ID",
)
p_assoc_dis.add_argument(
"ensembl_id", help="Target Ensembl ID (e.g., ENSG00000127318)"
)
# get-study-credible-sets
p_study_cs = subparsers.add_parser(
"get-study-credible-sets",
help="Get credible sets for a GWAS or other study by study ID",
)
p_study_cs.add_argument(
"study_id",
help="Study ID (e.g., FINNGEN_R12_RX_CROHN_2NDLINE or GCST90204201)",
)
# search-disease
p_search_dis = subparsers.add_parser(
"search-disease",
help="Search for a disease by name to find its EFO ID and other metadata",
)
p_search_dis.add_argument(
"query_string",
help="Disease name or phenotype string to search for (e.g., 'asthma')",
)
# get-credible-sets-near-target
p_near = subparsers.add_parser(
"get-credible-sets-near-target",
help="Get credible sets near target by filtering coordinates",
)
p_near.add_argument(
"ensembl_id", help="Target Ensembl ID (e.g., ENSG00000156515)"
)
p_near.add_argument(
"--window",
type=int,
default=500_000,
help="Window size in bp around the target (default: 500000)",
)
# custom-query
p_custom = subparsers.add_parser(
"custom-query", help="Execute a custom GraphQL query"
)
p_custom.add_argument("query", help="GraphQL query string")
p_custom.add_argument(
"--variables", help="JSON string of variables", default="{}"
)
args = parser.parse_args()
if args.command == "get-gwas-studies":
query = """
query getGWASStudies($efoId: String!) {
studies(diseaseIds: [$efoId]) {
count
rows {
id
projectId
traitFromSource
publicationFirstAuthor
publicationDate
publicationJournal
nSamples
cohorts
pubmedId
ldPopulationStructure { ldPopulation relativeSampleSize }
}
}
}
"""
variables = {"efoId": args.efo_id}
elif args.command == "get-qtl-credible-sets":
query = """
query getQTLCredibleSets($variantId: String!) {
variant(variantId: $variantId) {
id
qtlCredibleSets: credibleSets(
studyTypes: [scsqtl, sceqtl, scpqtl, sctuqtl, sqtl, eqtl, pqtl, tuqtl]
) {
count
rows {
studyLocusId pValueMantissa pValueExponent beta finemappingMethod confidence
variant { id chromosome }
study {
id studyType condition
target { id approvedSymbol }
biosample { biosampleId biosampleName }
}
locus(variantIds: [$variantId]) {
rows { posteriorProbability }
}
}
}
}
}
"""
variables = {"variantId": normalize_variant_id(args.variant_id)}
elif args.command == "get-l2g":
variant_id = normalize_variant_id(args.variant_id)
query = """
query getL2G($variantIds: [String!], $studyIds: [String!], $page: Pagination) {
credibleSets(variantIds: $variantIds, studyIds: $studyIds, page: $page) {
count
rows {
studyLocusId
confidence
study { id studyType traitFromSource }
variant { id }
l2GPredictions {
rows {
score
target { id approvedSymbol }
}
}
}
}
}
"""
variables = {"variantIds": [variant_id]}
if args.study_id:
variables["studyIds"] = [args.study_id]
elif args.command == "get-target-druggability":
query = """
query getTargetAnnotation($ensemblId: String!) {
target(ensemblId: $ensemblId) {
id
approvedSymbol
tractability { modality label value }
safetyLiabilities {
event eventId
biosamples { cellFormat cellLabel tissueLabel }
effects { dosing direction }
studies { name type description }
datasource
}
geneticConstraint { constraintType exp obs score oe }
}
}
"""
variables = {"ensemblId": args.ensembl_id}
elif args.command == "get-associated-targets":
query = """
query getAssociatedTargets($efoId: String!) {
disease(efoId: $efoId) {
id
name
associatedTargets {
count
rows {
target { id approvedSymbol }
score
}
}
}
}
"""
variables = {"efoId": args.efo_id}
elif args.command == "get-associated-diseases":
query = """
query getAssociatedDiseases($ensemblId: String!) {
target(ensemblId: $ensemblId) {
id
approvedSymbol
associatedDiseases {
count
rows {
disease { id name }
datasourceScores { id score }
}
}
}
}
"""
variables = {"ensemblId": args.ensembl_id}
elif args.command == "get-study-credible-sets":
query = """
query getStudyCredibleSets($studyIds: [String!], $page: Pagination) {
credibleSets(studyIds: $studyIds, page: $page) {
count
rows {
studyLocusId
confidence
finemappingMethod
pValueMantissa
pValueExponent
beta
credibleSetIndex
region
variant { id chromosome position }
study { id studyType traitFromSource }
}
}
}
"""
variables = {"studyIds": [args.study_id]}
elif args.command == "search-disease":
query = """
query searchDisease($queryString: String!, $page: Pagination) {
search(queryString: $queryString, entityNames: ["disease"], page: $page) {
hits {
id
name
description
entity
}
}
}
"""
variables = {"queryString": args.query_string}
elif args.command == "get-credible-sets-near-target":
query = """
query getTargetCredibleSets($ensemblId: String!, $page: Pagination) {
target(ensemblId: $ensemblId) {
approvedSymbol
genomicLocation { chromosome start end }
credibleSets(page: $page) {
count
rows {
studyLocusId
confidence
region
chromosome
position
variant { id chromosome position }
study { id studyType traitFromSource }
}
}
}
}
"""
variables = {"ensemblId": args.ensembl_id}
if "page" not in variables and args.page_size and "$page" in query:
variables["page"] = {"index": 0, "size": args.page_size}
data = _CLIENT.fetch_json(
BASE_URL,
method="POST",
json_body={"query": query, "variables": variables},
)
if "errors" in data:
print(
f"GraphQL Errors: {json.dumps(data['errors'], indent=2)}",
file=sys.stderr,
)
sys.exit(1)
target_data = data.get("data", {}).get("target", {})
if not target_data:
print("Error: Target not found", file=sys.stderr)
sys.exit(1)
loc = target_data.get("genomicLocation", {})
target_chrom = loc.get("chromosome")
t_start = loc.get("start")
t_end = loc.get("end")
if t_start is None or t_end is None:
print(
"Warning: Target location not found, cannot filter by region.",
file=sys.stderr,
)
min_pos = 0
max_pos = sys.maxsize
else:
window = args.window
min_pos = max(0, t_start - window)
max_pos = t_end + window
cs_data = target_data.get("credibleSets", {})
rows = cs_data.get("rows", [])
filtered_rows = []
for row in rows:
v_pos = row.get("position") or row.get("variant", {}).get("position")
v_chrom = row.get("chromosome") or row.get("variant", {}).get(
"chromosome"
)
if (
v_pos is not None
and v_chrom == target_chrom
and min_pos <= v_pos <= max_pos
):
filtered_rows.append(row)
# Update data structure
cs_data["total_count"] = cs_data.get("count")
cs_data["rows"] = filtered_rows
cs_data["filtered_count"] = len(filtered_rows)
truncated_data = truncate_data(data.get("data", {}), args.limit)
with open(args.output, "w", encoding="utf-8") as f:
f.write(json.dumps(truncated_data, indent=2))
sys.exit(0)
elif args.command == "custom-query":
query = args.query
try:
variables = json.loads(args.variables)
except json.JSONDecodeError:
print("Error: --variables must be a valid JSON string", file=sys.stderr)
sys.exit(1)
else:
available_commands = ", ".join(subparsers.choices.keys())
print(
f"Error: Unknown command: {args.command}. Available commands:"
f" {available_commands}",
file=sys.stderr,
)
sys.exit(1)
execute_query(query, variables, args.output, args.limit, args.page_size)
if __name__ == "__main__":
main()
Related skills
How it compares
Pick opentargets-database over generic GraphQL skills when queries target drug-discovery genetics and druggability rankings on Open Targets Platform.
FAQ
How does opentargets-database query the API?
opentargets-database uses scripts/query_opentargets.py to call the Open Targets GraphQL API, format results, and truncate large responses to preserve agent context window tokens.
What evidence does Open Targets aggregate?
The Open Targets Platform GraphQL API combines GWAS and eQTL genetics, pathways, animal models, and clinical trial data to rank target-disease associations and identify druggable genes.
What is the get-gwas-studies command for?
The query_opentargets.py get-gwas-studies subcommand fetches federated genetic evidence for a disease when passed an EFO identifier such as an efo_id.
Is Opentargets Database safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.