Skip to content

Controlled keywords are persisted inconsistently by Experiment create/update routes #617

@bencap

Description

@bencap

During experiment creation, we attempt to persist keywords by first validating the list and then searching in a case-insensitive manner, see:

if item_create.keywords:
all_labels_none = all(k.keyword.label is None for k in item_create.keywords)
if all_labels_none is False:
# Users may choose part of keywords from dropdown menu. Remove not chosen keywords from the list.
filtered_keywords = list(filter(lambda k: k.keyword.label is not None, item_create.keywords))
try:
validate_keyword_list(filtered_keywords)
except ValidationError as e:
raise HTTPException(status_code=422, detail=str(e))
for upload_keyword in filtered_keywords:
try:
description = upload_keyword.description
controlled_keyword = search_keyword(db, upload_keyword.keyword.key, upload_keyword.keyword.label)
experiment_controlled_keyword = ExperimentControlledKeywordAssociation(
controlled_keyword=controlled_keyword,
description=description,
)
keywords.append(experiment_controlled_keyword)
except ValueError as e:
raise HTTPException(status_code=422, detail=str(e))

During experiment updates, we validate keywords but then attempt to set them using a class method on the DB object which is case-sensitive:

if item_update.keywords:
all_labels_none = all(k.keyword.label is None for k in item_update.keywords)
if all_labels_none is False:
# Users may choose part of keywords from dropdown menu. Remove not chosen keywords from the list.
filtered_keywords = list(filter(lambda k: k.keyword.label is not None, item_update.keywords))
try:
validate_keyword_list(filtered_keywords)
except ValidationError as e:
raise HTTPException(status_code=422, detail=str(e))
try:
await item.set_keywords(db, filtered_keywords)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Invalid keywords: {str(e)}")

I think the case in-sensitive approach does make sense, but we should update keywords in the same manner during object creation and updating, and also more robustly test these routes on differently cased keywords to ensure the behavior is consistent in both routes.

Sub-issues

Metadata

Metadata

Assignees

Labels

app: backendTask implementation touches the backendtype: bugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions