Module base
Functions
def extract_HPO_terms_from_phenopacket(phenopacket: dict, ignore_excluded: bool = True) ‑> str-
Expand source code
def extract_HPO_terms_from_phenopacket( phenopacket: dict, ignore_excluded: bool = True ) -> str: """Extract HPO terms of a given phenopacket Args: phenopacket (dict): Phenopacket containing phenotypic features ignore_excluded (bool, optional): Whether to ignore excluded phenotypic features. Defaults to True. Returns: str: String of HPO terms for the phenopacket in the format "HP:0000001 - Phenotype 1; HP:0000002 - Phenotype 2; ..." If feature is excluded, it will be marked as "HP:0000001 - Phenotype 1 (excluded)" """ # Check if key exists if "phenotypicFeatures" not in phenopacket: sams_entry = phenopacket["subject"]["id"] logger.warning(f"SAMS: No phenotypicFeatures found for {sams_entry}") return "" else: phenotypes = phenopacket["phenotypicFeatures"] # Get HPO terms from phenopacket pheno_strings = [] for feature in phenotypes: pheno_string = f"{feature['type']['id']} - {feature['type']['label']}" if feature.get("excluded", 0): if ignore_excluded: continue else: pheno_string += " (excluded)" pheno_strings.append(pheno_string) return "; ".join(pheno_strings)Extract HPO terms of a given phenopacket
Args
phenopacket:dict- Phenopacket containing phenotypic features
ignore_excluded:bool, optional- Whether to ignore excluded phenotypic features. Defaults to True.
Returns
str- String of HPO terms for the phenopacket in the format "HP:0000001 - Phenotype 1; HP:0000002 - Phenotype 2; …" If feature is excluded, it will be marked as "HP:0000001 - Phenotype 1 (excluded)"
def extract_disease_terms_from_phenopacket(phenopacket: dict, ignore_excluded: bool = True) ‑> str-
Expand source code
def extract_disease_terms_from_phenopacket( phenopacket: dict, ignore_excluded: bool = True ) -> str: """Extract disease terms (OMIM, ORPHANET)of a given phenopacket Args: phenopacket (dict): Phenopacket containing diseases ignore_excluded (bool, optional): Whether to ignore excluded diseases. Defaults to True. Returns: str: String of disease terms for the phenopacket in the format "OMIM:0000001 - Disease 1; OMIM:0000002 - Disease 2; ..." """ if "diseases" not in phenopacket: sams_entry = phenopacket["subject"]["id"] logger.warning(f"SAMS: No diseases found for {sams_entry}") return "" else: diseases = phenopacket["diseases"] # Get disease terms from phenopacket disease_strings = [] for disease in diseases: disease_string = f"{disease['term']['id']} - {disease['term']['label']}" if disease.get("excluded", 0): if ignore_excluded: continue else: disease_string += " (excluded)" disease_strings.append(disease_string) return "; ".join(disease_strings)Extract disease terms (OMIM, ORPHANET)of a given phenopacket
Args
phenopacket:dict- Phenopacket containing diseases
ignore_excluded:bool, optional- Whether to ignore excluded diseases. Defaults to True.
Returns
str- String of disease terms for the phenopacket in the format "OMIM:0000001 - Disease 1; OMIM:0000002 - Disease 2; …"
def filter_phenopacket_by_onset(phenopacket: dict, input_onset_timestamp: str) ‑> dict-
Expand source code
def filter_phenopacket_by_onset(phenopacket: dict, input_onset_timestamp: str) -> dict: """Filter phenopacket by onset timestamp Args: phenopacket (dict): Phenopacket containing phenotypic features input_onset_timestamp (str): Onset timestamp to filter by (e.g. "2026-02-12T00:00:00Z") If set to "earliest", it will filter by the earliest onset timestamp in the phenopacket, If set to "latest", it will filter by the latest onset timestamp in the phenopacket Returns: dict: Filtered phenopacket containing only phenotypic features with the given onset timestamp """ def compute_onset_timestamp(onset: str) -> str: if onset == "earliest": onset = min( feature["onset"]["timestamp"] for feature in phenopacket.get("phenotypicFeatures", []) ) elif onset == "latest": onset = max( feature["onset"]["timestamp"] for feature in phenopacket.get("phenotypicFeatures", []) ) return onset onset_timestamp = compute_onset_timestamp(input_onset_timestamp) filered_phenotypes = [] filtered_diseases = [] for feature in phenopacket.get("phenotypicFeatures", []): if feature["onset"]["timestamp"] == onset_timestamp: filered_phenotypes.append(feature) for disease in phenopacket.get("diseases", []): if disease["onset"]["timestamp"] == onset_timestamp: filtered_diseases.append(disease) phenopacket["phenotypicFeatures"] = filered_phenotypes phenopacket["diseases"] = filtered_diseases return phenopacketFilter phenopacket by onset timestamp
Args
phenopacket:dict- Phenopacket containing phenotypic features
input_onset_timestamp:str- Onset timestamp to filter by (e.g. "2026-02-12T00:00:00Z")
If set to "earliest", it will filter by the earliest onset timestamp in the phenopacket, If set to "latest", it will filter by the latest onset timestamp in the phenopacket
Returns
dict- Filtered phenopacket containing only phenotypic features with the given onset timestamp
Classes
class SAMSapi (sams_url: str = 'https://www.genecascade.org/sams-cgi',
session: requests.sessions.Session = <factory>,
phenopackets: dict = None)-
Expand source code
@dataclass class SAMSapi: sams_url: str = DEFAULT_SAMS_URL session: requests.Session = field(default_factory=requests.Session) phenopackets: dict = None def __post_init__(self): self.sams_url = self.sams_url.rstrip("/") @property def login_url(self): return f"{self.sams_url}/login.cgi" @property def export_phenopackets_url(self): return f"{self.sams_url}/ExportPhenopacket.cgi?export_all=1" @property def export_phenopacket_by_id_url(self): return f"{self.sams_url}/ExportPhenopacket.cgi?external_id={{patient_id}}" @property def loggedIn(self): return "SAMSI" in self.session.cookies def _login(self, username, password): data = {"email": username, "password": password} resp = self.session.post(self.login_url, data=data) resp.raise_for_status() def login_with_credentials_file(self, credentials_file: str): """Login to SAMS using credentials from a file Args: credentials_file (str): Path to the file containing the credentials (first line username, second line password) Returns: SAMS: Instance of SAMS """ with open(credentials_file) as f: username, password = [l.strip() for l in f.readlines()] self._login(username, password) def login_with_username(self, username: str, password: str): """Login to SAMS using username and password Args: username (str): Name of the user password (str): Password of the user Returns: SAMS: Instance of SAMS """ self._login(username, password) def get_phenopackets(self) -> List[dict]: """Load all phenopackets from SAMS for the current user Returns: List[dict]: List of phenopackets """ resp = self.session.get(self.export_phenopackets_url) resp.raise_for_status() all_data = resp.json() return all_data def get_phenopacket(self, patient_id: str) -> dict: """Get phenopacket for a specific patient Args: patient_id (str): ID of the patient Raises: RuntimeError: If the phenopacket for the patient could not be found Returns: dict: Phenopacket for the patient """ resp = self.session.get( self.export_phenopacket_by_id_url.format(patient_id=patient_id) ) resp.raise_for_status() patient_data = resp.json() if patient_data["subject"]["id"] != patient_id: raise RuntimeError( f"Failed to obtain phenopacket for external id {patient_id}" ) return patient_dataSAMSapi(sams_url: str = 'https://www.genecascade.org/sams-cgi', session: requests.sessions.Session =
, phenopackets: dict = None) Instance variables
prop export_phenopacket_by_id_url-
Expand source code
@property def export_phenopacket_by_id_url(self): return f"{self.sams_url}/ExportPhenopacket.cgi?external_id={{patient_id}}" prop export_phenopackets_url-
Expand source code
@property def export_phenopackets_url(self): return f"{self.sams_url}/ExportPhenopacket.cgi?export_all=1" prop loggedIn-
Expand source code
@property def loggedIn(self): return "SAMSI" in self.session.cookies prop login_url-
Expand source code
@property def login_url(self): return f"{self.sams_url}/login.cgi" var phenopackets : dict-
The type of the None singleton.
var sams_url : str-
The type of the None singleton.
var session : requests.sessions.Session-
The type of the None singleton.
Methods
def get_phenopacket(self, patient_id: str) ‑> dict-
Expand source code
def get_phenopacket(self, patient_id: str) -> dict: """Get phenopacket for a specific patient Args: patient_id (str): ID of the patient Raises: RuntimeError: If the phenopacket for the patient could not be found Returns: dict: Phenopacket for the patient """ resp = self.session.get( self.export_phenopacket_by_id_url.format(patient_id=patient_id) ) resp.raise_for_status() patient_data = resp.json() if patient_data["subject"]["id"] != patient_id: raise RuntimeError( f"Failed to obtain phenopacket for external id {patient_id}" ) return patient_dataGet phenopacket for a specific patient
Args
patient_id:str- ID of the patient
Raises
RuntimeError- If the phenopacket for the patient could not be found
Returns
dict- Phenopacket for the patient
def get_phenopackets(self) ‑> List[dict]-
Expand source code
def get_phenopackets(self) -> List[dict]: """Load all phenopackets from SAMS for the current user Returns: List[dict]: List of phenopackets """ resp = self.session.get(self.export_phenopackets_url) resp.raise_for_status() all_data = resp.json() return all_dataLoad all phenopackets from SAMS for the current user
Returns
List[dict]- List of phenopackets
def login_with_credentials_file(self, credentials_file: str)-
Expand source code
def login_with_credentials_file(self, credentials_file: str): """Login to SAMS using credentials from a file Args: credentials_file (str): Path to the file containing the credentials (first line username, second line password) Returns: SAMS: Instance of SAMS """ with open(credentials_file) as f: username, password = [l.strip() for l in f.readlines()] self._login(username, password)Login to SAMS using credentials from a file
Args
credentials_file:str- Path to the file containing the credentials (first line username, second line password)
Returns
SAMS- Instance of SAMS
def login_with_username(self, username: str, password: str)-
Expand source code
def login_with_username(self, username: str, password: str): """Login to SAMS using username and password Args: username (str): Name of the user password (str): Password of the user Returns: SAMS: Instance of SAMS """ self._login(username, password)Login to SAMS using username and password
Args
username:str- Name of the user
password:str- Password of the user
Returns
SAMS- Instance of SAMS