Skip to content

Commit

Permalink
reworked the merging of promoted addons so that duplicated GUIDs are not
Browse files Browse the repository at this point in the history
reflected in the resultset
  • Loading branch information
crankycoder committed Jan 20, 2019
1 parent 350b2fc commit c2ff484
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 30 deletions.
61 changes: 46 additions & 15 deletions taar/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,40 @@ def getResource(self):
PROXY_MANAGER = ResourceProxy()


def clean_promoted_guids(raw_promoted_guids):
""" Verify that the promoted GUIDs are formatted correctly,
otherwise strip it down into an empty list.
"""
valid = True

for row in raw_promoted_guids:
if len(row) != 2:
valid = False
break

if not (
isinstance(row[0], str)
and (isinstance(row[1], int) or isinstance(row[1], float))
):
valid = False
break

if valid:
return raw_promoted_guids
return []


def merge_promoted_guids(promoted_guids, recommended_guids):
guids = set()
final = []
tmp = sorted(promoted_guids + [x for x in recommended_guids], key=lambda x: x[1], reverse=True)
for guid, weight in tmp:
if guid not in guids:
final.append((guid, weight))
guids.add(guid)
return final


def configure_plugin(app): # noqa: C901
"""
This is a factory function that configures all the routes for
Expand All @@ -41,7 +75,10 @@ def recommendations(hashed_client_id):
# Use the module global PROXY_MANAGER
global PROXY_MANAGER

promoted_guids = []
extra_data = {}
extra_data["options"] = {}
extra_data["options"]["promoted"] = []

try:
if request.method == "POST":
json_data = request.data
Expand All @@ -53,17 +90,11 @@ def recommendations(hashed_client_id):

if json_data != "":
post_data = json.loads(json_data)
promoted_guids = post_data.get("options", {}).get("promoted", [])

# Promoted GUIDs need to be sorted. Any TAAR
# generated weights will always be between 0 and 1.0.
# Any integer weight that is passed in for a promoted
# GUID will be greater than any machine generated
# GUID.
promoted_guids.sort(key=lambda x: x[1], reverse=True)
promoted_guids = [x[0] for x in promoted_guids]
else:
promoted_guids = []
raw_promoted_guids = post_data.get("options", {}).get(
"promoted", []
)
promoted_guids = clean_promoted_guids(raw_promoted_guids)
extra_data["options"]["promoted"] = promoted_guids

except Exception as e:
jdata = {}
Expand All @@ -76,8 +107,6 @@ def recommendations(hashed_client_id):
# Coerce the uuid.UUID type into a string
client_id = str(hashed_client_id)

extra_data = {"branch": 'intervention_a'}

locale = request.args.get("locale", None)
if locale is not None:
extra_data["locale"] = locale
Expand All @@ -104,10 +133,12 @@ def recommendations(hashed_client_id):
client_id=client_id, limit=TAAR_MAX_RESULTS, extra_data=extra_data
)

promoted_guids = extra_data.get("options", {}).get("promoted", [])
recommendations = merge_promoted_guids(promoted_guids, recommendations)

# Strip out weights from TAAR results to maintain compatibility
# with TAAR 1.0
jdata = {"results": [x[0] for x in recommendations]}
jdata["results"] = (promoted_guids + jdata["results"])[:TAAR_MAX_RESULTS]

response = app.response_class(
response=json.dumps(jdata), status=200, mimetype="application/json"
Expand Down
2 changes: 1 addition & 1 deletion taar/recommenders/recommendation_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


def hasher(client_id):
return hashlib.new('sha256', client_id.encode('utf8')).hexdigest()
return hashlib.new("sha256", client_id.encode("utf8")).hexdigest()


TEST_CLIENT_IDS = [
Expand Down
26 changes: 12 additions & 14 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,10 @@ class StaticRecommendationManager(FakeRecommendationManager):
# Recommenders must return a list of 2-tuple results
# with (GUID, weight)
def recommend(self, client_id, limit, extra_data={}):
branch_id = extra_data.get("branch", "control")
data = {"branch": branch_id}
result = [
("%(branch)s-addon-1" % data, 1.0),
("%(branch)s-addon-2" % data, 1.0),
("%(branch)s-addon-N" % data, 1.0),
("test-addon-1", 1.0),
("test-addon-2", 1.0),
("test-addon-N", 1.0),
]
return result

Expand Down Expand Up @@ -201,12 +199,12 @@ def test_platform_recommendation(client, platform_recommendation_manager):
assert response.data == b'{"results": []}'


def test_default_intervention(client, static_recommendation_manager):
def test_simple_request(client, static_recommendation_manager):
url = url_for("recommendations", hashed_client_id=hasher(uuid.uuid4()))
response = client.post(url)
assert response.status_code == 200
assert response.headers["Content-Type"] == "application/json"
expected = b'{"results": ["intervention_a-addon-1", "intervention_a-addon-2", "intervention_a-addon-N"]}'
expected = b'{"results": ["test-addon-1", "test-addon-2", "test-addon-N"]}'
assert response.data == expected


Expand All @@ -229,9 +227,9 @@ def test_mixed_and_promoted_and_taar_adodns(client, static_recommendation_manage
"guid1",
"guid55",
"guid2",
"intervention_a-addon-1",
"intervention_a-addon-2",
"intervention_a-addon-N",
"test-addon-1",
"test-addon-2",
"test-addon-N",
]
}
assert res.json == expected
Expand All @@ -246,18 +244,18 @@ def test_overlapping_mixed_and_promoted_and_taar_adodns(client, static_recommend
res = client.post(
url,
json=dict(
{"options": {"promoted": [["intervention_a-addon-1", 10], ["guid2", 5], ["guid55", 8]]}}
{"options": {"promoted": [["test-addon-1", 10], ["guid2", 5], ["guid55", 8]]}}
),
follow_redirects=True,
)
# The result should order the GUIDs in descending order of weight
expected = {
"results": [
"intervention_a-addon-1",
"test-addon-1",
"guid55",
"guid2",
"intervention_a-addon-2",
"intervention_a-addon-N",
"test-addon-2",
"test-addon-N",
]
}
assert res.json == expected

0 comments on commit c2ff484

Please sign in to comment.