Phenosnap Phenotype Extractor
by @kaichop
Extract clinical phenotypes and medication entities from user-provided text using PhenoSnap, producing a timestamped JSON output.
clawhub install phenoskill📖 About This Skill
name: phenosnap-phenotype-extractor description: Extract clinical phenotypes and medication entities from user-provided text using PhenoSnap, producing a timestamped JSON output. user-invocable: true metadata: {"openclaw":{"requires":{"bins":["python3"],"anyBins":["git","curl","powershell"],"env":["HPO_OBO_PATH"]},"primaryEnv":"HPO_OBO_PATH"}}
When to use
Use this skill when the user provides their own:Examples that should trigger:
When NOT to use
Do not use this skill when:Safety & privacy
Requirements / setup
python3 available on PATH.{baseDir}/resources/hp.obo
- Override path via environment variable: HPO_OBO_PATH
- This skill does not auto-download hp.obo. You must supply it.Recommended (best practice):
pip.Inputs & outputs
{baseDir}/artifacts/phenosnap_inputs/input_.txt
{baseDir}/artifacts/phenosnap_outputs/phenotypes_.json
{baseDir}/third_party/phenosnap_main.zip
- {baseDir}/third_party/get-pip.pyDetection heuristic (activation check)
Trigger if the user message contains any of:symptom(s), phenotype(s), Dx, diagnosis, PMH, Hx, history of, or a symptom-like listmeds, medications, taking, prescribed, plus patterns like:\b\d+(\.\d+)?\s?(mg|mcg|g|ml|units)\b
- frequencies: qd, q.d., bid, b.i.d., tid, t.i.d., qhs, qAM, qPM, daily, weeklyDo not trigger for purely informational questions without user-provided phenotype/medication content.
Procedure
0) Create required directories
Create if missing:{baseDir}/PhenoSnap/{baseDir}/artifacts/phenosnap_inputs/{baseDir}/artifacts/phenosnap_outputs/{baseDir}/resources/{baseDir}/third_party/1) Confirm / redact sensitive identifiers
1) Scan the user message for identifiers (email/phone/address/MRN/name fields). 2) If strongly identifying PHI is present (name + DOB/address/MRN): - Ask the user to confirm proceeding and recommend removing identifiers. 3) Produce a redacted version of the user text: - Replace emails with[REDACTED_EMAIL]
- Replace phone numbers with [REDACTED_PHONE]
- Replace long numeric IDs with [REDACTED_ID]
- Replace address-like patterns with [REDACTED_ADDRESS]
- Replace explicit “Name: …” fields with Name: [REDACTED_NAME]2) Ensure PhenoSnap exists locally
Target location:{baseDir}/PhenoSnap/2A) If {baseDir}/PhenoSnap/ exists and contains extract_phenotypes.py
Proceed to dependency self-test.2B) If {baseDir}/PhenoSnap/ does NOT exist (or missing extract_phenotypes.py)
Prefer git; fallback to zip.#### If git is available
Run:
git clone https://github.com/WGLab/PhenoSnap.git "{baseDir}/PhenoSnap"#### If git is NOT available
Download zip:
https://github.com/WGLab/PhenoSnap/archive/refs/heads/main.zip{baseDir}/third_party/phenosnap_main.zipDownload method (pick first available):
curl exists:curl -L "https://github.com/WGLab/PhenoSnap/archive/refs/heads/main.zip" -o "{baseDir}/third_party/phenosnap_main.zip"
Invoke-WebRequest -Uri "https://github.com/WGLab/PhenoSnap/archive/refs/heads/main.zip" -OutFile "{baseDir}/third_party/phenosnap_main.zip"Unzip (choose by OS/tools):
Expand-Archive -Path "{baseDir}/third_party/phenosnap_main.zip" -DestinationPath "{baseDir}/third_party/phenosnap_unzip" -Force
unzip -o "{baseDir}/third_party/phenosnap_main.zip" -d "{baseDir}/third_party/phenosnap_unzip"If neither unzip nor Expand-Archive is available, use Python:
python3 -c "import zipfile; z=zipfile.ZipFile(r'{baseDir}/third_party/phenosnap_main.zip'); z.extractall(r'{baseDir}/third_party/phenosnap_unzip')"Then rename/move the extracted folder to {baseDir}/PhenoSnap/:
{baseDir}/third_party/phenosnap_unzip/PhenoSnap-main{baseDir}/PhenoSnap/Final check:
{baseDir}/PhenoSnap/extract_phenotypes.py exists.{baseDir}/PhenoSnap/ and {baseDir}/third_party/phenosnap_unzip/.3) Dependency self-test and auto-install
Run from inside{baseDir}/PhenoSnap/.3A) Smoke test importability
Run:python3 -c "import importlib.util; spec=importlib.util.spec_from_file_location('extract_phenotypes','extract_phenotypes.py'); m=importlib.util.module_from_spec(spec); spec.loader.exec_module(m); print('ok')"If it prints ok, proceed.
3B) If smoke test fails with missing module (ModuleNotFoundError / ImportError)
#### Step 1: Ensure pip exists for python3 Check:python3 -m pip --versionIf that fails, try:
python3 -m ensurepip --upgradeCheck again:
python3 -m pip --versionIf still failing, bootstrap pip via get-pip.py:
https://bootstrap.pypa.io/get-pip.py to {baseDir}/third_party/get-pip.pycurl -L "https://bootstrap.pypa.io/get-pip.py" -o "{baseDir}/third_party/get-pip.py"
- or PowerShell:
- Invoke-WebRequest -Uri "https://bootstrap.pypa.io/get-pip.py" -OutFile "{baseDir}/third_party/get-pip.py"
python3 "{baseDir}/third_party/get-pip.py"
python3 -m pip --versionIf pip still cannot be used, stop and report the error output.
#### Step 2: Install PhenoSnap dependencies
From {baseDir}/PhenoSnap/, run:
python3 -m pip install -r requirements.txt#### Step 3: Re-run smoke test once Re-run:
python3 -c "import importlib.util; spec=importlib.util.spec_from_file_location('extract_phenotypes','extract_phenotypes.py'); m=importlib.util.module_from_spec(spec); spec.loader.exec_module(m); print('ok')"If still failing, stop and return:
4) Prepare HPO OBO path
Resolve HPO OBO path in this order: 1) If env varHPO_OBO_PATH is set and file exists, use that.
2) Else use {baseDir}/resources/hp.obo if it exists.If the resolved file does not exist:
hp.obo at {baseDir}/resources/hp.obo or set HPO_OBO_PATH to its full path.5) Write input file (redacted)
YYYYMMDD_HHMMSS (local time).{baseDir}/artifacts/phenosnap_inputs/input_.txt 6) Run extraction
From{baseDir}/PhenoSnap/, run:
python3 extract_phenotypes.py --input-file "{baseDir}/artifacts/phenosnap_inputs/input_.txt" --hpo-obo "" --output "{baseDir}/artifacts/phenosnap_outputs/phenotypes_.json" --format json Validate:
If validation fails:
7) Respond to user
Return a concise confirmation:Troubleshooting
{baseDir}/PhenoSnap/extract_phenotypes.py exists.python3 -m venv .venv then activate and rerun skill.
{baseDir}/resources/hp.obo or set HPO_OBO_PATH.Examples
Example 1 (phenotypes + meds)
User:Action:
phenotypes_.json Example 2 (meds only)
User:Action:
Example 3 (should NOT trigger)
User:Action: