microservices/matching_service/src/routes/matching.py (109 lines of code) (raw):
"""
Copyright 2022 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
""" Matching endpoints"""
from fastapi import APIRouter, HTTPException, status
import requests
from common.models import Document
from common.utils.logging_handler import Logger
from common.config import STATUS_IN_PROGRESS, STATUS_SUCCESS, STATUS_ERROR
from typing import Optional, List
from utils.json_matching.match_json import compare_json
# disabling for linting to pass
# pylint: disable = broad-except
import copy
import traceback
router = APIRouter()
SUCCESS_RESPONSE = {"status": STATUS_SUCCESS}
FAILED_RESPONSE = {"status": STATUS_ERROR}
def get_matching_score(af_dict: dict, sd_dict: dict):
"""
Makes call to json matching function and returns the result
Args: af_dict: Dictionary of Application form
sd_dict: Dictionary of Supporting Document
Returns: Updated supporting document entity and avg matching score
"""
print("Application form: ", af_dict["entities"])
print("Supporting document: ", sd_dict["entities"])
matching = compare_json(af_dict["entities"], sd_dict["entities"],
sd_dict["document_class"], af_dict["document_class"],
af_dict["context"])
Logger.info(matching)
print("Matching Output: ", matching)
if matching:
return (matching[:len(matching) - 1], matching[-1]["Avg Matching Score"])
else:
return None
def update_matching_status(case_id: str,
uid: str,
status: str,
entity: Optional[List[dict]] = None,
matching_score: Optional[float] = None):
"""
Makes api calls to DSM service to update document status for matching
"""
Logger.info(f"Updating Matching status for case_id {case_id} and uid {uid}")
if status == STATUS_SUCCESS:
base_url = "http://document-status-service/document_status_service/"\
"v1/update_matching_status"
req_url = f"{base_url}?case_id={case_id}&uid={uid}&status={status}"\
f"&entity={entity}&matching_score={matching_score}"
return requests.post(req_url, json=entity)
else:
base_url = "http://document-status-service/document_status_service/"\
"v1/update_matching_status"
req_url = f"{base_url}?case_id={case_id}&uid={uid}&status={status}"
return requests.post(req_url)
@router.post("/match_document")
async def match_document(case_id: str, uid: str):
"""
matching the document with case id , uid
Args:
case_id (str): Case id of the file ,
uid (str): unique id for each document
Returns:
200 : Matching score successfully updated
404 : If Application form for the document is not found
500 : HTTPException: Internal Server Error if something fail
"""
try:
#Get Application form data with the same caseid
af_doc = Document.collection.filter(case_id=case_id).filter(
active="active").filter(document_type="application_form").get()
if af_doc and af_doc.entities is not None:
Logger.info(f"Matching document with case_id {case_id}"\
" and uid {uid} with the corresponding Application form")
#Get Supporting Document data from DB
sd_doc = Document.find_by_uid(uid)
sd_dict = copy.deepcopy(sd_doc.to_dict())
af_dict = copy.deepcopy(af_doc.to_dict())
#getting json matching result
matching_result = get_matching_score(af_dict, sd_dict)
Logger.info(matching_result)
print("matching_result:")
print(matching_result)
#If the matching result is not null update the status in DB
if matching_result:
updated_entity = matching_result[0]
overall_score = matching_result[1]
#Updating document status
dsm_status = update_matching_status(
case_id,
uid,
STATUS_SUCCESS,
entity=updated_entity,
matching_score=overall_score)
print(f"dsm_status = {dsm_status}")
if dsm_status.status_code == status.HTTP_200_OK:
Logger.info(
f"Matching document with case_id {case_id} and "\
f"uid {uid} was successful"
)
return {"status": STATUS_SUCCESS, "score": overall_score}
else:
Logger.error(
f"Matching document with case_id {case_id} and "\
f"uid {uid} Failed. Doc status not updated"
)
raise HTTPException(
status_code=500,
detail="Document Matching failed.Status failed to update")
else:
Logger.error(f"Matching document with case_id {case_id} and uid {uid}"\
f" Failed. Error in geting Matching score")
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,detail="Document Matching failed"\
"Error in getting matching score")
else:
Logger.error(f"Matching with case_id {case_id} and uid {uid}: "\
f"Application form with entities not found with given case_id: {case_id}")
raise HTTPException(
status_code=404, detail="No supporting Application entities found")
except HTTPException as e:
dsm_status = update_matching_status(case_id, uid, STATUS_ERROR)
Logger.error(
f"HTTPException while matching document with case_id {case_id} and uid {uid}"
)
print(e)
Logger.error(e)
Logger.error(traceback.format_exc().replace("\n", " "))
raise e
except Exception as e:
print("ERROR: match_document error:")
dsm_status = update_matching_status(case_id, uid, STATUS_ERROR)
Logger.error(
f"Error while matching document with case_id {case_id} and uid {uid}")
Logger.error(e)
err = traceback.format_exc().replace("\n", " ")
Logger.error(err)
print(err)
raise HTTPException(status_code=500, detail=str(e)) from e