Skip to content

Commit cd28811

Browse files
authored
Add policyUUIDs to text scan endpoint
Add policyUUIDs to text scan endpoint
2 parents 62333c0 + 69d3400 commit cd28811

File tree

2 files changed

+106
-13
lines changed

2 files changed

+106
-13
lines changed

nightfall/api.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,24 @@ def __init__(self, key: Optional[str] = None, signing_secret: Optional[str] = No
5555
'Authorization': f'Bearer {self.key}',
5656
}
5757

58-
def scan_text(self, texts: List[str], detection_rules: Optional[List[DetectionRule]] = None,
58+
def scan_text(self, texts: List[str], policy_uuids: List[str] = None, detection_rules: Optional[List[DetectionRule]] = None,
5959
detection_rule_uuids: Optional[List[str]] = None, context_bytes: Optional[int] = None,
6060
default_redaction_config: Optional[RedactionConfig] = None) ->\
6161
Tuple[List[List[Finding]], List[str]]:
6262
"""Scan text with Nightfall.
6363
6464
This method takes the specified config and then makes
6565
one or more requests to the Nightfall API for scanning.
66-
At least one of detection_rule_uuids or detection_rules is required.
6766
67+
A caller must provide exactly one of the following:
68+
* a non-empty policy_uuids list (current maximum supported length = 1)
69+
* at least one of detection_rule_uuids or detection_rules
6870
6971
:param texts: List of strings to scan.
7072
:type texts: List[str]
73+
:param policy_uuids: List of policy UUIDs to scan each text with.
74+
These can be created in the Nightfall UI.
75+
:type policy_uuids: List[str] or None
7176
:param detection_rules: List of detection rules to scan each text with.
7277
:type detection_rules: List[DetectionRule] or None
7378
:param detection_rule_uuids: List of detection rule UUIDs to scan each text with.
@@ -81,22 +86,26 @@ def scan_text(self, texts: List[str], detection_rules: Optional[List[DetectionRu
8186
:returns: list of findings, list of redacted input texts
8287
"""
8388

84-
if not detection_rule_uuids and not detection_rules:
85-
raise NightfallUserError("at least one of detection_rule_uuids or detection_rules required", 40001)
89+
if not policy_uuids and not detection_rule_uuids and not detection_rules:
90+
raise NightfallUserError("at least one of policy_uuids, detection_rule_uuids, or detection_rules is required", 40001)
8691

87-
config = {}
92+
policy = {}
8893
if detection_rule_uuids:
89-
config["detectionRuleUUIDs"] = detection_rule_uuids
94+
policy["detectionRuleUUIDs"] = detection_rule_uuids
9095
if detection_rules:
91-
config["detectionRules"] = [d.as_dict() for d in detection_rules]
96+
policy["detectionRules"] = [d.as_dict() for d in detection_rules]
9297
if context_bytes:
93-
config["contextBytes"] = context_bytes
98+
policy["contextBytes"] = context_bytes
9499
if default_redaction_config:
95-
config["defaultRedactionConfig"] = default_redaction_config.as_dict()
100+
policy["defaultRedactionConfig"] = default_redaction_config.as_dict()
101+
96102
request_body = {
97-
"payload": texts,
98-
"config": config
103+
"payload": texts
99104
}
105+
if policy:
106+
request_body["policy"] = policy
107+
if policy_uuids:
108+
request_body["policyUUIDs"] = policy_uuids
100109
response = self._scan_text_v3(request_body)
101110

102111
_validate_response(response, 200)

tests/test_api.py

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def test_scan_text():
224224
[
225225
"4916-6734-7572-5015 is my credit card number, 489-36-8350 ssn"
226226
],
227-
"config":
227+
"policy":
228228
{
229229
"detectionRules":
230230
[
@@ -332,8 +332,92 @@ def test_scan_text():
332332
assert len(redactions) == 1
333333
assert redactions[0] == "491👀-👀👀👀👀-👀👀👀👀-👀👀👀👀 is my credit card number, [REDACTED] ssn"
334334

335+
@responses.activate
336+
def test_scan_text_with_policy_uuids():
337+
nightfall = Nightfall("NF-NOT_REAL")
338+
responses.add(responses.POST, 'https://api.nightfall.ai/v3/scan',
339+
json={
340+
"findings":
341+
[
342+
[
343+
{
344+
"finding": "4916-6734-7572-5015",
345+
"redactedFinding": "491👀-👀👀👀👀-👀👀👀👀-👀👀👀👀",
346+
"afterContext": " is my cre",
347+
"detector":
348+
{
349+
"name": "Credit Card Number",
350+
"uuid": "74c1815e-c0c3-4df5-8b1e-6cf98864a454"
351+
},
352+
"confidence": "VERY_LIKELY",
353+
"location":
354+
{
355+
"byteRange":
356+
{
357+
"start": 0,
358+
"end": 19
359+
},
360+
"codepointRange":
361+
{
362+
"start": 0,
363+
"end": 19
364+
}
365+
},
366+
"redactedLocation":
367+
{
368+
"byteRange":
369+
{
370+
"start": 0,
371+
"end": 19
372+
},
373+
"codepointRange":
374+
{
375+
"start": 0,
376+
"end": 19
377+
}
378+
},
379+
"matchedDetectionRuleUUIDs":
380+
["0d8efd7b-b87a-478b-984e-9cf5534a46bc"],
381+
"matchedDetectionRules":
382+
[]
383+
},
384+
]
385+
],
386+
"redactedPayload":
387+
[
388+
"491👀-👀👀👀👀-👀👀👀👀-👀👀👀👀 is my credit card number, [REDACTED] ssn"
389+
]
390+
})
391+
result, redactions = nightfall.scan_text(
392+
["4916-6734-7572-5015 is my credit card number, 489-36-8350 ssn"],
393+
policy_uuids=["2388f83f-cd31-4689-971b-4ee94f798281"]
394+
)
395+
396+
assert len(responses.calls) == 1
397+
assert responses.calls[0].request.headers.get("Authorization") == "Bearer NF-NOT_REAL"
398+
assert json.loads(responses.calls[0].request.body) == {
399+
"payload":
400+
[
401+
"4916-6734-7572-5015 is my credit card number, 489-36-8350 ssn"
402+
],
403+
"policyUUIDs": ["2388f83f-cd31-4689-971b-4ee94f798281"]
404+
}
405+
406+
assert len(result) == 1
407+
assert len(result[0]) == 1
408+
assert result[0][0] == Finding(
409+
"4916-6734-7572-5015",
410+
'491👀-👀👀👀👀-👀👀👀👀-👀👀👀👀',
411+
None, " is my cre",
412+
"Credit Card Number",
413+
result[0][0].detector_uuid,
414+
Confidence.VERY_LIKELY,
415+
Range(0, 19), Range(0, 19), "",
416+
["0d8efd7b-b87a-478b-984e-9cf5534a46bc"], [])
417+
assert len(redactions) == 1
418+
assert redactions[0] == "491👀-👀👀👀👀-👀👀👀👀-👀👀👀👀 is my credit card number, [REDACTED] ssn"
335419

336-
def test_scan_text_no_detection_rules():
420+
def test_scan_text_no_detection_rules_or_policy_uuids():
337421
nightfall = Nightfall("NF-NOT_REAL")
338422
with pytest.raises(NightfallUserError):
339423
nightfall.scan_text(texts=["will", "fail"])

0 commit comments

Comments
 (0)