-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support PII detection in http request
Signed-off-by: Huamin Chen <[email protected]>
- Loading branch information
Showing
11 changed files
with
779 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
"""PII detection module for vLLM router.""" | ||
|
||
import logging | ||
from typing import Optional | ||
|
||
from .analyzers.base import PIIAnalyzer | ||
from .analyzers.factory import create_analyzer | ||
from .config import PIIConfig | ||
from .middleware import check_pii | ||
from .types import PIIAction, PIITarget, PIIType | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
# Global analyzer instance | ||
_analyzer: Optional[PIIAnalyzer] = None | ||
|
||
|
||
async def initialize_pii_detection( | ||
analyzer_type: str = "presidio", config: Optional[dict] = None | ||
) -> None: | ||
""" | ||
Initialize PII detection with the specified analyzer. | ||
Args: | ||
analyzer_type: Type of analyzer to use | ||
config: Optional configuration for the analyzer | ||
""" | ||
global _analyzer | ||
|
||
try: | ||
_analyzer = await create_analyzer(analyzer_type, config) | ||
logger.info(f"Initialized PII detection with {analyzer_type} analyzer") | ||
except Exception as e: | ||
logger.error(f"Failed to initialize PII detection: {e}") | ||
raise | ||
|
||
|
||
async def shutdown_pii_detection() -> None: | ||
"""Shutdown PII detection.""" | ||
global _analyzer | ||
|
||
if _analyzer: | ||
await _analyzer.shutdown() | ||
_analyzer = None | ||
logger.info("Shut down PII detection") | ||
|
||
|
||
def get_pii_analyzer() -> Optional[PIIAnalyzer]: | ||
"""Get the current PII analyzer instance.""" | ||
return _analyzer | ||
|
||
|
||
def is_pii_detection_enabled() -> bool: | ||
"""Check if PII detection is enabled.""" | ||
return _analyzer is not None | ||
|
||
|
||
__all__ = [ | ||
"PIIAction", | ||
"PIITarget", | ||
"PIIType", | ||
"PIIConfig", | ||
"check_pii", | ||
"initialize_pii_detection", | ||
"shutdown_pii_detection", | ||
"get_pii_analyzer", | ||
"is_pii_detection_enabled", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
"""PII analyzers package.""" | ||
|
||
from .base import PIIAnalysisResult, PIIAnalyzer, PIILocation | ||
from .factory import create_analyzer | ||
from .presidio import PresidioAnalyzer | ||
|
||
__all__ = [ | ||
"PIIAnalyzer", | ||
"PIIAnalysisResult", | ||
"PIILocation", | ||
"create_analyzer", | ||
"PresidioAnalyzer", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
"""Base interface for PII analyzers.""" | ||
|
||
import abc | ||
from dataclasses import dataclass | ||
from typing import Dict, List, Optional, Set | ||
|
||
from ..types import PIIType | ||
|
||
|
||
@dataclass | ||
class PIILocation: | ||
"""Location of PII in text.""" | ||
|
||
start: int # Start index in text | ||
end: int # End index in text | ||
pii_type: PIIType # Type of PII found | ||
value: str # The actual PII text found | ||
score: float # Confidence score of the detection | ||
|
||
|
||
@dataclass | ||
class PIIAnalysisResult: | ||
"""Result of PII analysis.""" | ||
|
||
has_pii: bool # Whether PII was found | ||
detected_types: Set[PIIType] # Types of PII found | ||
pii_locations: Optional[List[PIILocation]] = None # Locations of PII in text | ||
|
||
|
||
class PIIAnalyzer(abc.ABC): | ||
"""Base class for PII analyzers.""" | ||
|
||
def __init__(self, config: Optional[Dict] = None): | ||
"""Initialize the analyzer with optional config.""" | ||
self.config = config or {} | ||
|
||
@abc.abstractmethod | ||
async def analyze( | ||
self, | ||
text: str, | ||
pii_types: Optional[Set[PIIType]] = None, | ||
score_threshold: float = 0.5, | ||
) -> PIIAnalysisResult: | ||
""" | ||
Analyze text for PII. | ||
Args: | ||
text: Text to analyze | ||
pii_types: Types of PII to look for. If None, look for all types. | ||
score_threshold: Minimum confidence score to consider a match | ||
Returns: | ||
PIIAnalysisResult containing analysis results | ||
""" | ||
raise NotImplementedError | ||
|
||
@abc.abstractmethod | ||
async def initialize(self) -> None: | ||
"""Initialize the analyzer. Called once before first use.""" | ||
raise NotImplementedError | ||
|
||
@abc.abstractmethod | ||
async def shutdown(self) -> None: | ||
"""Shutdown the analyzer. Called when service is shutting down.""" | ||
raise NotImplementedError |
Oops, something went wrong.