external_api.py•5.78 kB
#!/usr/bin/env python3
from typing import Any, Dict, cast
from urllib.parse import quote
import requests
def get_children_from_branch(
branch_iri: str, ontology_acronym: str, bioportal_api_key: str
) -> Dict[str, Any]:
"""
Fetch children terms from BioPortal for a given branch URI.
Args:
branch_iri: IRI of the branch to get children for
ontology_acronym: Ontology acronym (e.g., "HRAVS")
bioportal_api_key: BioPortal API key for authentication
Returns:
Dictionary containing raw BioPortal API response or error information
"""
try:
# URL encode the branch IRI for safe inclusion in URL
encoded_iri = quote(branch_iri, safe="")
# Build the BioPortal API URL
base_url = f"https://data.bioontology.org/ontologies/{ontology_acronym}/classes/{encoded_iri}/children"
# Set query parameters as shown in cURL example
params = {
"display_context": "false",
"display_links": "false",
"include_views": "false",
"pagesize": "999",
"include": "prefLabel",
}
# Set authorization header
headers = {"Authorization": f"apiKey token={bioportal_api_key}"}
# Make the API request
response = requests.get(base_url, headers=headers, params=params)
response.raise_for_status()
# Return the raw JSON response from BioPortal
return response.json()
except requests.exceptions.RequestException as e:
# Handle HTTP errors gracefully
return {"error": f"Failed to fetch children from BioPortal: {str(e)}"}
except (KeyError, ValueError) as e:
# Handle JSON parsing errors
return {"error": f"Failed to parse BioPortal response: {str(e)}"}
def search_instance_ids(
template_id: str, cedar_api_key: str, limit: int = 10, offset: int = 0
) -> Dict[str, Any]:
"""
Search for template instances with pagination support.
Args:
template_id: Template ID (UUID or full URL)
cedar_api_key: CEDAR API key for authentication
limit: Number of instances to fetch
offset: Starting position
Returns:
Dictionary containing:
- instance_ids: List of instance IDs for this page
- pagination: Pagination metadata
- error: Error message if failed
"""
try:
# Convert template ID to full URL format if needed
if not template_id.startswith("https://"):
template_url = f"https://repo.metadatacenter.org/templates/{template_id}"
else:
template_url = template_id
headers = {
"Accept": "application/json",
"Authorization": f"apiKey {cedar_api_key}",
}
# Build the search API URL
base_url = "https://resource.metadatacenter.org/search"
params = {
"version": "latest",
"limit": limit,
"is_based_on": template_url,
"offset": offset,
}
# Make the API request
response = requests.get(
base_url, headers=headers, params=cast(Any, params), timeout=30
)
response.raise_for_status()
search_data = response.json()
# Extract information
total_count = search_data.get("totalCount", 0)
resources = search_data.get("resources", [])
# Extract instance IDs from current page
instance_ids = []
for resource in resources:
instance_id = resource.get("@id")
if instance_id:
instance_ids.append(instance_id)
# Calculate pagination metadata
current_page = (offset // limit) + 1
total_pages = (
(total_count + limit - 1) // limit if limit > 0 else 0
) # Ceiling division
has_next = offset + limit < total_count
pagination_metadata = {
"limit": limit,
"offset": offset,
"total_count": total_count,
"current_page": current_page,
"total_pages": total_pages,
"has_next": has_next,
}
return {"instance_ids": instance_ids, "pagination": pagination_metadata}
except requests.exceptions.RequestException as e:
return {"error": f"Failed to search CEDAR instances: {str(e)}"}
except (KeyError, ValueError) as e:
return {"error": f"Failed to parse CEDAR search response: {str(e)}"}
def get_instance(instance_id: str, cedar_api_key: str) -> Dict[str, Any]:
"""
Fetch the full content of a CEDAR template instance.
Args:
instance_id: Full instance URL (e.g., "https://repo.metadatacenter.org/template-instances/{uuid}")
cedar_api_key: CEDAR API key for authentication
Returns:
Dictionary containing instance content or error information
"""
try:
# URL encode the instance ID for safe inclusion in URL
encoded_instance_id = quote(instance_id, safe="")
# Build the instance API URL
base_url = f"https://resource.metadatacenter.org/template-instances/{encoded_instance_id}"
# Set authorization header
headers = {
"Accept": "application/json",
"Authorization": f"apiKey {cedar_api_key}",
}
# Make the API request with timeout
response = requests.get(base_url, headers=headers, timeout=30)
response.raise_for_status()
# Return the raw JSON response from CEDAR
return response.json()
except requests.exceptions.RequestException as e:
return {"error": f"Failed to fetch CEDAR instance content: {str(e)}"}
except (KeyError, ValueError) as e:
return {"error": f"Failed to parse CEDAR instance response: {str(e)}"}