llmfy-guardrails is the guardrails plugin for llmfy: PIIGuard, a text-based PII detector/masker (PIIType, PIIStrategy, PIIDetection/PIIDetectionResult), independent of the LLM/flow layers in the core package.
How to install
# Using UV
uv add llmfy-guardrails
# Using pip
pip install llmfy-guardrails
Installing llmfy-guardrails pulls in llmfy (for the shared LLMfyException hierarchy) and pydantic automatically.
PII Guard — PERSON_NAME / ADDRESS detection
Most PIITypes are regex-based and work with no extra install. PIIType.PERSON_NAME/PIIType.ADDRESS are the exception — they're backed by an optional spaCy NER model, loaded lazily on first use:
# Using UV
uv add "llmfy-guardrails[spacy]"
uv add https://github.com/irufano/spacy_ner_pii/releases/download/v0.1.0/xx_ent_pii_sm-0.1.0-py3-none-any.whl
# Using pip
pip install "llmfy-guardrails[spacy]"
pip install https://github.com/irufano/spacy_ner_pii/releases/download/v0.1.0/xx_ent_pii_sm-0.1.0-py3-none-any.whl
xx_ent_pii_sm isn't published to PyPI, so it can't be pulled in as a normal extra — install it manually from the release wheel above.
Note that PIIGuard() defaults to detecting every PIIType, including these two — pass exclude_types=[PIIType.PERSON_NAME, PIIType.ADDRESS] if you don't want this dependency.
How to use
from llmfy_guardrails import PIIGuard, PIIStrategy, PIIType
guard = PIIGuard(exclude_types=[PIIType.PERSON_NAME, PIIType.ADDRESS]) # strategy=TOKENIZE (default)
result = guard.detect("Contact john.doe@example.com or call (555) 123-4567.")
print(result.processed_text) # "Contact [EMAIL_1] or call [PHONE_NUMBER_1]."
restored = guard.restore(result.processed_text, result.detections)
print(restored) # "Contact john.doe@example.com or call (555) 123-4567."
See llmfy_guardrails/example/pii_example.py for a full walkthrough of every strategy (TOKENIZE, MASK, REDACT, PARTIAL), custom types, and the NER-backed types.
Develop as Contributor
Commit message format
Commit subjects follow Conventional Commits:
<type>: <short summary>
[optional body]
typeis one of:feat,fix,refactor,chore,ci,docs,test.- For a breaking change, prefix the subject with
[breaking-changes], e.g.[breaking-changes] refactor: consolidate detection logic. - Keep the summary in the imperative mood (e.g. "add", not "added"/"adds").
- The release workflow copies each commit's subject and body verbatim into the GitHub release changelog, so write both to be read standalone (see
.github/workflows/release.yml).
Version bump rules (automatic tagging)
Every push to main is scanned by .github/workflows/auto-tag.yml, which tags a new release automatically — no manual git tag needed. The bump is decided per commit subject, in this precedence order (highest across all new commits wins):
| Commit subject | Bump |
|---|---|
[breaking-changes] <type>: ... or <type>!: ... / <type>(scope)!: ... |
MAJOR |
feat: ... (no breaking marker) |
MINOR |
fix: ... (no breaking marker) |
PATCH |
refactor:, chore:, ci:, docs:, test: alone |
no release (bundled into the next qualifying commit) |
A breaking marker always forces MAJOR regardless of type — use it deliberately when a feat or fix must ship as a major version, e.g. [breaking-changes] feat: ... or feat!: ..., both equivalent.
Build package
uv build
Manual / backfill release
Tagging is automatic (see above). To manually cut or re-run a release, use the workflow_dispatch trigger on release.yml (GitHub Actions UI → "Release & Publish" → "Run workflow", tag input vX.Y.Z) instead of pushing a tag by hand.
After deploy on local
After CI creates or moves the tag, your local tag ref may be stale. To sync:
git fetch --tags --force
The --force flag is needed because git fetch --tags alone won't update tags that already exist locally.
Package Development on local
uv sync --group dev
Check Lints
uvx ruff check --statistics . 2>&1 | tail -60
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llmfy_guardrails-0.1.0.tar.gz.
File metadata
- Download URL: llmfy_guardrails-0.1.0.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9f8cc1a3f913f9efdbcb90a4aa5d918b0bcd35831a7878172dc2f2740cde6e4
|
|
| MD5 |
4b1fbc66992d738604fc0dbdfcfd62e7
|
|
| BLAKE2b-256 |
c940e504a4aab8e86599eab3bf072e65a5d8475b3d3849a8f580804e393e6d34
|
File details
Details for the file llmfy_guardrails-0.1.0-py3-none-any.whl.
File metadata
- Download URL: llmfy_guardrails-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
094e022b551f9771328e73a57365db22f202607df5cdf5788f8951148491b10d
|
|
| MD5 |
21c6ed4a914330f9e09c46dd845775de
|
|
| BLAKE2b-256 |
0a84e9c91288746665234e132df4913a0fedc170f1c6422f80722b25e2002671
|