annotating-variants
Annotates VCF variants and normalizes HGVS nomenclature with public, license-free annotators…
Combine OpenMed clinical NLP with Microsoft Presidio, spaCy, or LangChain through OpenMed's built-in interop adapter registry (openmed.interop). Covers the lazy adapter registry (available_adapters, get_adapter, adapter_spec), the presidio/spacy/langchain pip extras, and the
$ npx -y skills add maziyarpanahi/openmed --skill bridging-presidio-and-spacy --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/bridging-presidio-and-spacyContext preview
The summary Claude sees to decide when to auto-load this skill.
Combine OpenMed clinical NLP with Microsoft Presidio, spaCy, or LangChain through OpenMed's built-in interop adapter registry (openmed.interop). Covers the lazy adapter registry (available_adapters, get_adapter, adapter_spec), the presidio/spacy/langchain pip extras, and the
name: bridging-presidio-and-spacy description: "Combine OpenMed clinical NLP with Microsoft Presidio, spaCy, or LangChain through OpenMed's built-in interop adapter registry (openmed.interop). Covers the lazy adapter registry (available_adapters, get_adapter, adapter_spec), the presidio/spacy/langchain pip extras, and the verified callables — Presidio to_canonical/from_canonical/merge_with_openmed, the spaCy openmed_deid pipeline factory, and the LangChain create_redaction_runnable. Use when the user wants to add Presidio recognizers, embed OpenMed PII detection in a spaCy pipeline, or use OpenMed de-identification as a LangChain runnable. Pairs adjacent to the OpenMed PII skills." license: Apache-2.0 metadata: project: OpenMed category: fhir-interop pairs: adjacent version: "1.0"
OpenMed interoperates with the dominant PII/NLP ecosystems through a single, **lazy** adapter registry: `openmed.interop`. Adapters live behind explicit imports, so importing `openmed` never drags in Presidio, spaCy, or LangChain — each is an optional extra you install only when you need that bridge.
Reach for a bridge when:
on top (or to feed OpenMed spans back into Presidio's anonymizer);
LLM (the on-device guardrail in front of a cloud model);
instead of rewriting the pipeline around `openmed.deidentify`.
import openmed.interop as interop
interop.available_adapters()
# ('cda', 'hl7v2', 'langchain', 'presidio', 'spacy')
spec = interop.adapter_spec("presidio")
# AdapterSpec(name='presidio', module='openmed.interop.presidio',
# extra='presidio', description='Presidio RecognizerResult adapter')
mod = interop.get_adapter("presidio") # imports openmed.interop.presidio
# Attribute access also works lazily:
openmed.interop.presidio # same module, imported on first touch`available_adapters()` and `adapter_spec()` never import the adapter module, so they are safe to call for discovery even without the extra installed. `get_adapter(name)` (and attribute access) triggers the import — and the adapter's own optional dependency.
Install only the extra you need:
pip install "openmed[presidio]" # Presidio RecognizerResult adapter pip install "openmed[spacy]" # spaCy openmed_deid component pip install "openmed[langchain]" # LangChain redaction runnable # cda and hl7v2 adapters ship in core (no extra) — see their own skills
Module `openmed.interop.presidio` converts between Presidio `RecognizerResult`s and OpenMed canonical `PIIEntity`s, and merges both detectors through OpenMed's semantic-unit merger.
from openmed.interop.presidio import (
to_canonical, # RecognizerResult(s) -> [PIIEntity]
from_canonical, # [PIIEntity] -> [RecognizerResult] (needs presidio extra)
merge_with_openmed, # combine OpenMed + Presidio spans, resolve overlaps
PresidioAdapterConfig,
)
import openmed
text = "Dr. Smith called patient at 617-555-0123 on 2024-03-02."
# Presidio gives you RecognizerResults; OpenMed gives PIIEntities.
openmed_spans = openmed.extract_pii(text).entities
presidio_results = analyzer.analyze(text=text, language="en") # your Presidio analyzer
merged = merge_with_openmed(
openmed_spans, presidio_results, text=text,
config=PresidioAdapterConfig(preserve_presidio_labels=True),
)
# -> de-duplicated [PIIEntity]; overlaps resolved by score, length, OpenMed-originWhy merge instead of union: `merge_with_openmed` runs both detectors' spans through `merge_entities_with_semantic_units`, so overlapping/adjacent detections collapse into one correct span (e.g. `PHONE` from Presidio vs a partial OpenMed hit) rather than producing double redactions. Label mapping is built in (Presidio `PHONE_NUMBER` ↔ OpenMed `PHONE`, `US_SSN` ↔ `SSN`, etc.).
To push OpenMed spans into Presidio's **anonymizer**, convert back:
results = from_canonical(openmed_spans) # [RecognizerResult] anonymized = anonymizer.anonymize(text=text, analyzer_results=results)
Module `openmed.interop.spacy_component` registers a spaCy pipeline factory named **`openmed_deid`**. Add it to a pipeline and OpenMed PII spans land on the `Doc`.
import spacy
import openmed.interop.spacy_component # registers the @Language.factory
nlp = spacy.blank("en")
nlp.add_pipe("openmed_deid", config={
"confidence_threshold": 0.5,
"lang": "en",
"target": "openmed_pii", # doc.spans key
"merge_ents": False, # set True to also write doc.ents
"alignment_mode": "expand", # char->token alignment: strict|contract|expand
})
doc = nlp("Patient John Doe, MRN 12345, seen today.")
for span in doc.spans["openmed_pii"]:
print(span.label_, span.text)
# raw char-offset spans also available on doc._.openmed_pii`merge_ents=True` writes the spans into `doc.ents`, resolving overlaps with spaCy's `filter_spans`. Use `OpenMedDeidComponent` / `OpenMedDeidConfig` directly if you construct the component outside `add_pipe`.
Module `openmed.interop.langchain` exposes a `Runnable`-shaped redactor you drop *in front of* an LLM step so PHI never leaves the device.
from openmed.interop.langchain import (
create_redaction_runnable, LangChainRedactionConfig,
)
redactor = create_redaction_runnable(
config=LangChainRedactionConfig(method="mask", policy="hipaa_safe_harbor"),
input_key="text", # redact this key in a dict payload (optional)Local-first healthcare AI: clinical NER and HIPAA PII de-identification on hardware you control. 2,200+ medical models, 35 model-backed PII languages, and Python, MLX, Android and browser runtimes. Apache-2.0 SDK.
Repo: maziyarpanahi/openmed
Annotates VCF variants and normalizes HGVS nomenclature with public, license-free annotators…
Choose the first OpenMed workflow skill for an intake, privacy, extraction, exchange, or…
Package multiple FHIR R4 resources produced from OpenMed output into a single valid…
Adversarially scan already-de-identified clinical text for residual identifiers and emit a…
Produce a signed, reproducible, no-PHI audit trail for an OpenMed de-identification run via…
Generates and verifies 21 CFR Part 11-style audit trails — who/what/when, electronic…