Skip to content

Commit

Permalink
Add Additional Logging for new endpoint (#3779)
Browse files Browse the repository at this point in the history
* add logs to contention level logs for expanded classification endpoint only

* adjusted prep_incoming_text and get, added tests

* consolidated logging and added conditionals to prevent unwanted logging

* adds tests for logging processed text

* broke out code into helper function
  • Loading branch information
tyler-spangler6 authored Dec 2, 2024
1 parent 89bbf65 commit 9164fd1
Show file tree
Hide file tree
Showing 4 changed files with 524 additions and 20 deletions.
59 changes: 45 additions & 14 deletions domain-cc/cc-app/src/python_src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,30 @@ def log_as_json(log: dict):
logging.info(json.dumps(log))


def log_expanded_contention_text(
logging_dict: dict, contention_text: str, log_contention_text: str
):
"""
Updates the logging dictionary with the contention text updates from the expanded classification method
"""
processed_text = expanded_lookup_table.prep_incoming_text(contention_text)
# only log these items if the expanded lookup returns a classification code
if expanded_lookup_table.get(contention_text)["classification_code"]:
if log_contention_text == "unmapped contention text":
log_contention_text = f"unmapped contention text {[processed_text]}"
logging_dict.update(
{
"processed_contention_text": processed_text,
"contention_text": log_contention_text,
}
)
# log none as the processed text if it is not in the LUT and leave unmapped contention text as is
else:
logging_dict.update({"processed_contention_text": None})

return logging_dict


def log_contention_stats(
contention: Contention,
classified_contention: ClassifiedContention,
Expand All @@ -108,20 +132,27 @@ def log_contention_stats(

is_multi_contention = len(claim.contentions) > 1

log_as_json(
{
"vagov_claim_id": sanitize_log(claim.claim_id),
"claim_type": sanitize_log(log_contention_type),
"classification_code": classification_code,
"classification_name": classification_name,
"contention_text": log_contention_text,
"diagnostic_code": sanitize_log(contention.diagnostic_code),
"is_in_dropdown": is_in_dropdown,
"is_lookup_table_match": classification_code is not None,
"is_multi_contention": is_multi_contention,
"endpoint": request.url.path,
}
)
logging_dict = {
"vagov_claim_id": sanitize_log(claim.claim_id),
"claim_type": sanitize_log(log_contention_type),
"classification_code": classification_code,
"classification_name": classification_name,
"contention_text": log_contention_text,
"diagnostic_code": sanitize_log(contention.diagnostic_code),
"is_in_dropdown": is_in_dropdown,
"is_lookup_table_match": classification_code is not None,
"is_multi_contention": is_multi_contention,
"endpoint": request.url.path,
}

if request.url.path == "/expanded-contention-classification":
logging_dict = log_expanded_contention_text(
logging_dict, contention.contention_text, log_contention_text
)

# log_as_json(logging_dict)
# else:
log_as_json(logging_dict)


def log_claim_stats_v2(
Expand Down
20 changes: 14 additions & 6 deletions domain-cc/cc-app/src/python_src/util/expanded_lookup_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,19 @@ def _build_lut(self):

return classification_code_mappings

def prep_incoming_text(self, input_str: str):
"""
Prepares the incoming text for lookup by removing common words and punctuation
"""
input_str = input_str.strip().lower()

for term in ["due to", "secondary to", "because of"]:
if term in input_str:
input_str = input_str.split(term)[0]
input_str = self._removal_pipeline(input_str)

return input_str

def get(self, input_str: str, default_value=LUT_DEFAULT_VALUE):
"""
Processes input string using same method as the LUT and performs the lookup
Expand All @@ -132,19 +145,14 @@ def get(self, input_str: str, default_value=LUT_DEFAULT_VALUE):
This also process the parenthetical terms in the mappings
"""
# There is only one case of using due to in the mappings (need to figure out a better way than hard coding it)
input_str = input_str.strip().lower()
if input_str == "loss of teeth due to bone loss":
return {
"classification_code": 8967,
"classification_name": "Dental and Oral",
}

for term in ["due to", "secondary to", "because of"]:
if term in input_str:
input_str = input_str.split(term)[0]
input_str = self.prep_incoming_text(input_str)

input_str = self._removal_pipeline(input_str)
input_str_lookup = frozenset(input_str.split())
classification = self.contention_text_lookup_table.get(
input_str_lookup, default_value
Expand Down
20 changes: 20 additions & 0 deletions domain-cc/cc-app/tests/test_expanded_lookup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from unittest.mock import patch

from fastapi.testclient import TestClient
from src.python_src.util.expanded_lookup_config import COMMON_WORDS, FILE_READ_HELPER
from src.python_src.util.expanded_lookup_table import ExpandedLookupTable
Expand Down Expand Up @@ -118,6 +120,24 @@ def test_removed_parentheses():
assert TEST_LUT.get(test_str) == expected


@patch(
"src.python_src.util.expanded_lookup_table.ExpandedLookupTable._removal_pipeline"
)
def test_prep_incoming_text_cause(mock_removal_pipeline):
test_str = "acl tear, due to something"
TEST_LUT.prep_incoming_text(test_str)
mock_removal_pipeline.assert_called_once_with("acl tear, ")


@patch(
"src.python_src.util.expanded_lookup_table.ExpandedLookupTable._removal_pipeline"
)
def test_prep_incoming_text_non_cause(mock_removal_pipeline):
test_str = "acl tear in my right knee"
TEST_LUT.prep_incoming_text(test_str)
mock_removal_pipeline.assert_called_once_with(test_str)


def test_lookup_cause_included():
test_str = [
"migraines (headaches), due to something",
Expand Down
Loading

0 comments on commit 9164fd1

Please sign in to comment.