Python examples¶
These examples use the 0.11.0 APIs, including the pygarble.gibberish and
pygarble.screening modules; see Installation. Each example
includes its own imports and data. Reuse a configured detector across calls.
Redact a batch without gibberish checks¶
from pygarble.screening import Scanner
scanner = Scanner(categories=["secrets", "pii"], max_input_length=10_000)
texts = ["mail jane@example.com", "key AKIAIOSFODNN7EXAMPLE", "hello"]
reports = scanner.scan_batch(texts)
assert [report.flagged for report in reports] == [True, True, False]
redacted = [scanner.redact(text).text for text in texts]
assert redacted == ["mail [EMAIL]", "key [AWS_ACCESS_KEY_ID]", "hello"]
assert scanner.scan("qxzjkwpv bnmqwer zzxqv").flagged is False
For a large input stream, scanner.iter_scan(iterable) yields reports
one at a time. It does not split a document or materialize the input iterable.
Configure native screening rules¶
from pygarble.screening import Scanner
scanner = Scanner(
categories=["pii", "profanity"],
locales=["uk"],
profanity_allowlist=["damn"],
)
assert scanner.scan("NI AB123456C").kinds() == ("nino",)
assert scanner.scan("damn").findings == ()
locales selects native PII packs. Optional phone-number backends have
their own region option. See Standalone screening and optional backends for complete
backend examples and PII, Profanity and Secrets for rules.
Validate a required English field¶
from typing import Optional
from pygarble.gibberish import EnsembleDetector
detector = EnsembleDetector(max_input_length=10_000)
def validate_english_field(text: str) -> Optional[str]:
if not text.strip():
return "Enter some English text."
if len(text) > 10_000:
return "Use at most 10,000 characters."
if detector.predict(text):
return "Please review this text; it does not pass the English checks."
return None
assert validate_english_field("Hello world") is None
assert validate_english_field("") == "Enter some English text."
assert validate_english_field("asdfghjkl") is not None
Use this policy for fields that expect English. Non-English text may be meaningful and still fail these checks. Rare words and names may also require review.
Partition a dataset for review¶
from pygarble.gibberish import EnsembleDetector
texts = ["Hello world", "asdfghjkl", "Please review this text"]
detector = EnsembleDetector()
decisions = detector.predict(texts)
flagged = [text for text, bad in zip(texts, decisions) if bad]
remaining = [text for text, bad in zip(texts, decisions) if not bad]
assert flagged == ["asdfghjkl"]
assert len(remaining) == 2
For larger sources, submit lists in caller-controlled chunks. The returned lists are materialized, and input validation covers each submitted batch.
Export explanations as JSON¶
import json
from dataclasses import asdict
from pygarble.gibberish import GarbleDetector, Strategy
text = "Please review qxzjkwpvm before delivery."
result = GarbleDetector(Strategy.LOCAL_ANOMALY).analyze(text)
assert result.garbled is True
assert any(text[s.start:s.end] == "qxzjkwpvm" for s in result.spans)
payload = json.dumps(asdict(result), ensure_ascii=False)
assert json.loads(payload)["status"] == "garbled"
asdict includes spans under each signal. result.spans is a convenience
property combining those spans, not an additional serialized dataclass field.
Offsets use Python string indices, not byte offsets; the end is exclusive.
Check encoding independently of language¶
from pygarble.gibberish import EnsembleDetector
detector = EnsembleDetector(profile="corruption")
texts = ["नमस्ते दुनिया", "Café au lait", "Café au lait", "hello\x00world"]
assert detector.predict(texts) == [False, False, True, True]
This detects selected artifacts; it does not repair encoding or certify that all possible encoding problems have been found.
Configure members independently¶
from pygarble.gibberish import EnsembleDetector, Strategy
detector = EnsembleDetector(
strategies=[Strategy.MARKOV_CHAIN, Strategy.WORD_ANOMALY],
voting="weighted",
weights=[0.7, 0.3],
threshold=0.5,
strategy_kwargs={
Strategy.MARKOV_CHAIN: {"min_length": 4},
Strategy.WORD_ANOMALY: {"min_word_length": 6},
},
allowlist=["syzygy"],
)
assert detector.predict("syzygy") is False
A custom strategy list defaults to majority voting unless overridden. Validate thresholds and weights against representative inputs; they are policy choices, not calibrated confidence levels.