Skip to content

Commit fdaa65a

Browse files
authored
Merge pull request #96 from bugout-dev/key_blacklist_zomglings
Made a change to how blacklist_fn works
2 parents 9d2f207 + 1555e3b commit fdaa65a

5 files changed

Lines changed: 105 additions & 51 deletions

File tree

python/README.md

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,25 +126,49 @@ set `MY_APP_NO_CONSENT=1`, then again no reports will get sent back.
126126
On the other hand, if the user has set `MY_APP_CONSENT=true` and left `MY_APP_NO_CONSENT` unset or
127127
set to a value other than `1`, Humbug will send you any reports you have configured.
128128

129-
### Blacklist
129+
### Blacklisting parameters in feature reports
130130

131-
There is a possibility to provide custom functions or use predefined at `blacklist.filter_parameters_by_key` for blacklist functionality.
131+
Arguments to functions and other callables can sometimes contain sensitive information which you may
132+
not want to include in Humbug reports.
132133

133-
Just add a list of keys you want to remove from the `feature_report` result and specify the function:
134+
Blacklist functions allow you to specify which parameters from an argument list to filter out of your
135+
feature reports.
136+
137+
#### `blacklist.generate_filter_parameters_by_key_fn`
138+
139+
If you would just like to filter out all paramters with a given name, you can use the `blacklist.generate_filter_parameters_by_key_fn`.
140+
141+
For example, to ignore all parameters named `token` (case insensitive), you would instantiate your
142+
`HumbugReporter` as follows:
134143

135144
```python
136-
reporter = Reporter(
137-
...
138-
blacklist_keys=["private"],
139-
blacklist_fn=blacklist.filter_parameters_by_key,
145+
reporter = HumbugReporter(
146+
...,
147+
blacklist_fn=blacklist.generate_filter_parameters_by_key_fn(["token"]),
148+
)
149+
```
150+
151+
#### Custom blacklist functions
152+
153+
You could also implement a custom blacklist function to remove all parameters that contained the substring
154+
`token` (case insensitive):
155+
156+
```python
157+
def blacklist_token_parameters_fn(params: Dict[str, Any]) -> Dict[str, Any]:
158+
admissible_params = {k:v for k, v in params.items() if "token" not in k}
159+
return admissible_params
160+
161+
reporter = HumbugReporter(
162+
...,
163+
blacklist_fn=blacklist_token_parameters_fn
140164
)
141165
```
142166

143-
### Example: activeloopai/Hub
167+
### Case study: activeloopai/deeplake
144168

145-
[This pull request](https://github.com/activeloopai/Hub/pull/624) shows how
169+
[This pull request](https://github.com/activeloopai/deeplake/pull/624) shows how
146170
[Activeloop](https://www.activeloop.ai/) integrated Humbug into their popular
147-
[`Hub`](https://github.com/activeloopai/Hub) tool.
171+
[`deeplake`](https://github.com/activeloopai/deeplake) tool.
148172

149173
This example shows how to use Humbug to record consent in a configuration file that the user
150174
can modify at will. It also shows how to add custom tags to your Humbug reports.

python/humbug/blacklist.py

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,57 @@
11
"""
22
Various implementations of the blacklist functionality.
33
"""
4-
from typing import Any, Dict, List, Optional
4+
from typing import Any, Callable, Dict, List, Optional
55

66

7-
def filter_parameters_by_key(
7+
def generate_filter_parameters_by_key_fn(
88
blacklist_keys: List[str],
9-
parameters: Dict[str, Any],
10-
) -> Dict[str, Any]:
9+
) -> Callable[[Dict[str, Any]], Dict[str, Any]]:
1110
"""
12-
Applies blacklist filter to provided parameters and to 2nd layer of
13-
inner dictionary parameter if exists.
11+
Generates a parameter filter function which filters out the parameters whose names are in the given
12+
list of blacklist_keys.
13+
14+
The comparison to blacklist_keys is case insensitive.
1415
"""
15-
whitelisted_parameters: Dict[str, Any] = {}
16-
17-
for key in parameters.keys():
18-
if key.lower() in blacklist_keys:
19-
continue
20-
21-
key_as_dict: Optional[Dict[str, Any]] = None
22-
for d in dir(parameters[key]):
23-
if d == "keys":
24-
key_as_dict = parameters[key]
25-
break
26-
elif d == "dict": # Pydantic models support
27-
key_as_dict = parameters[key].dict()
28-
break
29-
30-
if key_as_dict is not None:
31-
try:
32-
inner_dict: Dict[str, str] = {}
33-
for inner_key in key_as_dict.keys():
34-
if inner_key.lower() in blacklist_keys:
35-
continue
36-
inner_dict[inner_key] = str(key_as_dict[inner_key])
37-
whitelisted_parameters[key] = inner_dict
16+
17+
lowercase_blacklist_keys = [key.lower() for key in blacklist_keys]
18+
19+
def filter_parameters_by_key(
20+
parameters: Dict[str, Any],
21+
) -> Dict[str, Any]:
22+
"""
23+
Applies blacklist filter to provided parameters and to 2nd layer of
24+
inner dictionary parameter if exists.
25+
"""
26+
whitelisted_parameters: Dict[str, Any] = {}
27+
28+
for key in parameters.keys():
29+
if key.lower() in lowercase_blacklist_keys:
3830
continue
39-
except Exception:
40-
pass
4131

42-
whitelisted_parameters[key] = str(parameters[key])
32+
key_as_dict: Optional[Dict[str, Any]] = None
33+
for d in dir(parameters[key]):
34+
if d == "keys":
35+
key_as_dict = parameters[key]
36+
break
37+
elif d == "dict": # Pydantic models support
38+
key_as_dict = parameters[key].dict()
39+
break
40+
41+
if key_as_dict is not None:
42+
try:
43+
inner_dict: Dict[str, str] = {}
44+
for inner_key in key_as_dict.keys():
45+
if inner_key.lower() in lowercase_blacklist_keys:
46+
continue
47+
inner_dict[inner_key] = str(key_as_dict[inner_key])
48+
whitelisted_parameters[key] = inner_dict
49+
continue
50+
except Exception:
51+
pass
52+
53+
whitelisted_parameters[key] = str(parameters[key])
54+
55+
return whitelisted_parameters
4356

44-
return whitelisted_parameters
57+
return filter_parameters_by_key

python/humbug/report.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,7 @@ def __init__(
6060
mode: Modes = Modes.DEFAULT,
6161
url: Optional[str] = None,
6262
tags: Optional[List[str]] = None,
63-
blacklist_keys: List[str] = [],
64-
blacklist_fn: Optional[
65-
Callable[[List[str], Dict[str, Any]], Dict[str, Any]]
66-
] = None,
63+
blacklist_fn: Optional[Callable[[Dict[str, Any]], Dict[str, Any]]] = None,
6764
):
6865
if url is None:
6966
url = DEFAULT_URL
@@ -97,7 +94,6 @@ def __init__(
9794
if tags is not None:
9895
self.tags = tags
9996

100-
self.blacklist_keys = blacklist_keys
10197
self.blacklist_fn = blacklist_fn
10298

10399
def wait(self) -> None:
@@ -398,7 +394,7 @@ def feature_report(
398394
title = "Feature used: {name}".format(name=feature_name)
399395

400396
if apply_blacklist and self.blacklist_fn is not None:
401-
parameters = self.blacklist_fn(self.blacklist_keys, parameters)
397+
parameters = self.blacklist_fn(parameters)
402398

403399
parameters_content = "\n".join(
404400
[

python/humbug/test_blacklist.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from typing import Any, Dict
2+
import unittest
3+
4+
from . import blacklist
5+
6+
7+
class TestGenerateFilterParametersByKeyFunction(unittest.TestCase):
8+
"""
9+
Tests for blacklist.generate_filter_parameters_by_key_fn.
10+
"""
11+
12+
def test_exact_matches(self):
13+
params: Dict[str, Any] = {"good": 1, "bad": "lol"}
14+
blacklist_fn = blacklist.generate_filter_parameters_by_key_fn(["bad"])
15+
filtered_params = blacklist_fn(params)
16+
self.assertDictEqual(filtered_params, {"good": "1"})
17+
18+
def test_case_insensitive_matches(self):
19+
params: Dict[str, Any] = {"good": 1, "BAD": "lol"}
20+
blacklist_fn = blacklist.generate_filter_parameters_by_key_fn(["Bad"])
21+
filtered_params = blacklist_fn(params)
22+
self.assertDictEqual(filtered_params, {"good": "1"})

python/humbug/test_report.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ def setUp(self):
1111
name="TestReporter",
1212
consent=self.consent,
1313
tags=["humbug-unit-test"],
14-
blacklist_keys=["private"],
15-
blacklist_fn=blacklist.filter_parameters_by_key,
14+
blacklist_fn=blacklist.generate_filter_parameters_by_key_fn(["private"]),
1615
)
1716
self.reporter.publish = MagicMock()
1817

0 commit comments

Comments
 (0)