# genesis/api_clients/chembl_api.py import os import requests from typing import List, Dict, Optional CHEMBL_BASE = "https://www.ebi.ac.uk/chembl/api/data" def _fetch_paginated(endpoint: str, params: dict) -> List[dict]: """ Handles paginated ChEMBL API responses. """ results = [] url = f"{CHEMBL_BASE}/{endpoint}" while url: r = requests.get(url, params=params) r.raise_for_status() data = r.json() page_items = data.get(endpoint, []) results.extend(page_items) url = data.get("page_meta", {}).get("next") params = {} # clear params after first page to avoid duplication return results def search_molecule_by_name(name: str, max_results: int = 10) -> List[dict]: """ Search molecules in ChEMBL by name or synonym. """ params = {"molecule_synonyms__icontains": name, "limit": max_results} return _fetch_paginated("molecule", params) def get_molecule_details(chembl_id: str) -> dict: """ Retrieve detailed information for a molecule by ChEMBL ID. """ r = requests.get(f"{CHEMBL_BASE}/molecule/{chembl_id}") r.raise_for_status() return r.json() def get_molecule_bioactivities(chembl_id: str, max_results: int = 50) -> List[dict]: """ Retrieve bioactivity records for a given molecule. """ params = {"molecule_chembl_id": chembl_id, "limit": max_results} return _fetch_paginated("activity", params) def search_target_by_name(name: str, max_results: int = 10) -> List[dict]: """ Search for biological targets by name. """ params = {"target_synonym__icontains": name, "limit": max_results} return _fetch_paginated("target", params) def get_target_details(chembl_id: str) -> dict: """ Retrieve detailed target information by ChEMBL ID. """ r = requests.get(f"{CHEMBL_BASE}/target/{chembl_id}") r.raise_for_status() return r.json() def search_assays_by_target(target_chembl_id: str, max_results: int = 50) -> List[dict]: """ Retrieve assays related to a specific target. """ params = {"target_chembl_id": target_chembl_id, "limit": max_results} return _fetch_paginated("assay", params) def get_drugs_in_clinical_phase(phase: int, max_results: int = 20) -> List[dict]: """ Retrieve drugs by clinical trial phase. """ params = {"max_phase": phase, "limit": max_results} return _fetch_paginated("molecule", params) def get_molecule_image_url(chembl_id: str) -> str: """ Generate a URL to the 2D structure image of a molecule. """ return f"https://www.ebi.ac.uk/chembl/api/data/image/{chembl_id}.svg"