Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
with:
python-version: '3.11'

- name: Run tests
run: |
python -m pip install --upgrade pip
pip install -e '.[dev]'
pytest -q

- name: Build package
run: |
python -m pip install --upgrade pip build
Expand Down
34 changes: 34 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Tests

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

jobs:
pytest:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install package
run: |
python -m pip install --upgrade pip
pip install -e '.[dev]'

- name: Run tests
run: pytest -q
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
.pytest_cache
__pycache__

vault.json
*.vault.json
.venv
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ Under the hood:
1. **Detection** — a hybrid engine combines deterministic regex patterns
(emails, phones, credit cards with Luhn validation, SSNs, IPs, IBANs,
URLs, AWS/API keys) with Microsoft Presidio + spaCy NER for
contextual entities (people, organizations, locations).
contextual entities (people, organizations, locations). If Presidio
can't load, it falls back to a HuggingFace transformer model
(`pip install "shieldprompt[ner]"`).
2. **Masking** — each detected value is stored in an in-memory vault and
replaced with a stable token like `[PERSON_1]` or `[EMAIL_ADDRESS_2]`.
3. **Unmasking** — after the LLM responds, tokens are mapped back to the
Expand Down
9 changes: 5 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "shieldprompt"
version = "0.1.4"
version = "0.1.5"
description = "Privacy bridge for LLMs — mask PII before it leaves your machine."
readme = "README.md"
license = {text = "MIT"}
Expand All @@ -27,7 +27,7 @@ dependencies = [
]

[project.optional-dependencies]
ner = ["transformers>=4.30.0", "torch>=2.0.0", "span-marker>=1.5.0"]
ner = ["transformers>=4.30.0", "torch>=2.0.0"]
fastapi = ["fastapi>=0.100.0", "starlette>=0.27.0"]
all = ["shieldprompt[ner,fastapi]"]
dev = [
Expand All @@ -44,8 +44,9 @@ pii = "shieldprompt.cli:pii_main"
retrace = "shieldprompt.cli:retrace_main"

[project.urls]
Homepage = "https://github.com/shieldprompt/shieldprompt"
Documentation = "https://github.com/shieldprompt/shieldprompt#readme"
Homepage = "https://github.com/modelpath-dev/ShieldPrompt"
Documentation = "https://github.com/modelpath-dev/ShieldPrompt/blob/main/SETUP.md"
Issues = "https://github.com/modelpath-dev/ShieldPrompt/issues"

[tool.hatch.build.targets.wheel]
packages = ["src/shieldprompt"]
Expand Down
2 changes: 1 addition & 1 deletion src/shieldprompt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from .shield import Shield
from .vault import Vault, get_vault

__version__ = "0.1.4"
__version__ = "0.1.5"

__all__ = [
"Shield",
Expand Down
4 changes: 2 additions & 2 deletions src/shieldprompt/detector/hybrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class HybridDetector:
"""Combines regex (fast, deterministic) and NER (contextual) detection.

NER backend selection order:
1. Presidio (presidio-analyzer + spaCy en_core_web_lg) — preferred
1. Presidio (presidio-analyzer + spaCy en_core_web_sm) — preferred
2. HuggingFace transformer (dslim/bert-base-NER) — fallback
3. Regex only — if neither is installed
"""
Expand Down Expand Up @@ -81,7 +81,7 @@ def _init_ner_backend(
except ImportError:
logger.info(
"No NER backend installed — regex-only detection. "
"Install with: pip install shieldprompt[presidio] "
"Reinstall shieldprompt (Presidio is a core dependency) "
"or: pip install shieldprompt[ner]"
)
return None
Expand Down
4 changes: 1 addition & 3 deletions tests/test_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ async def echo_async(prompt: str) -> str:
assert "bob@test.com" not in prompt
return f"Got: {prompt}"

result = asyncio.get_event_loop().run_until_complete(
echo_async("Send to bob@test.com")
)
result = asyncio.run(echo_async("Send to bob@test.com"))
assert "bob@test.com" in result


Expand Down
5 changes: 0 additions & 5 deletions vault.json

This file was deleted.

Loading