Spaces:
Running on Zero
Running on Zero
Download src/sequences.py from khairi/KCNG-Explorer: direct link, hf CLI and curl.
- Browser
- Download file 1.48 kB
-
https://huggingface.co/spaces/khairi/KCNG-Explorer/resolve/main/src/sequences.py
- Command line
-
hf download hf://spaces/khairi/KCNG-Explorer/src/sequences.py
-
curl -L -o sequences.py https://huggingface.co/spaces/khairi/KCNG-Explorer/resolve/main/src/sequences.py
1.48 kB
| """FASTA parsing and UniProt sequence fetching.""" | |
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| from io import StringIO | |
| import requests | |
| from Bio import SeqIO | |
| UNIPROT_FASTA_URL = "https://rest.uniprot.org/uniprotkb/{accession}.fasta" | |
| class ProteinRecord: | |
| id: str | |
| description: str | |
| sequence: str | |
| def parse_fasta(text: str) -> list[ProteinRecord]: | |
| records = SeqIO.parse(StringIO(text), "fasta") | |
| return [ | |
| ProteinRecord(id=r.id, description=r.description, sequence=str(r.seq).upper()) | |
| for r in records | |
| ] | |
| def extract_accession(record_id: str) -> str: | |
| """Pull the accession out of a FASTA record id. | |
| UniProt headers follow the `db|accession|entry_name` convention (e.g. | |
| `sp|Q9UK17|KCNG1_HUMAN`), so the accession is the middle field. Anything | |
| else (a plain accession, a custom id, ...) is returned as-is. | |
| """ | |
| parts = record_id.split("|") | |
| if len(parts) == 3: | |
| return parts[1] | |
| return record_id | |
| def fetch_uniprot_sequence(accession: str, timeout: float = 10.0) -> ProteinRecord: | |
| """Fetch a single sequence from UniProt by accession (e.g. "Q9Y2W7").""" | |
| url = UNIPROT_FASTA_URL.format(accession=accession.strip()) | |
| response = requests.get(url, timeout=timeout) | |
| response.raise_for_status() | |
| records = parse_fasta(response.text) | |
| if not records: | |
| raise ValueError(f"No sequence returned for accession {accession!r}") | |
| return records[0] | |