Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAI-29: Claim bundle evaluation websocket endpoint #2

Merged
merged 4 commits into from
Jan 19, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions claim_ai/consumers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .claim_consumer import ClaimConsumer
70 changes: 70 additions & 0 deletions claim_ai/consumers/claim_consumer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import inspect
import json
import zlib
import time
import asyncio
import threading
import concurrent.futures
import functools

from channels.exceptions import StopConsumer

from ..evaluation import ClaimBundleEvaluation
from channels.generic.websocket import WebsocketConsumer, AsyncConsumer


import traceback


class ClaimConsumer(AsyncConsumer):

async def websocket_connect(self, event):
self.bundle_query = {}
self.pool_executor = concurrent.futures.ProcessPoolExecutor(max_workers=10)
await self.send({
"type": "websocket.accept",
})

async def websocket_receive(self, event):
payload = self._get_content(event)
if payload['type'] == 'claim.bundle.payload':
index = self._assign_event_index(payload)
await self._bundle_evaluation(payload['content'], index)
elif payload['type'] == 'claim.bundle.acceptance':
# TODO: confirm evaluation receive and remove it from query
print("Payload received")
pass

def _get_content(self, event):
bytes_data = event.get('bytes', None)
if bytes_data:
try:
bytes_data = zlib.decompress(bytes_data)
except Exception as e:
pass
bundle = json.loads(bytes_data.decode("utf-8"))
return bundle

def _assign_event_index(self, event):
event_index = len(self.bundle_query.keys())
self.bundle_query[event_index] = event
return event_index

async def _bundle_evaluation(self, content, event_index):
await self._send_acceptance(event_index)
await self._send_evaluation(content, event_index)

async def _send_acceptance(self, event_index):
accept_response = { 'type': 'claim.bundle.acceptance', 'content': 'Accepted', 'index': event_index}
await self.send({
'text': json.dumps(accept_response),
'type': 'websocket.send'
})

async def _send_evaluation(self, bundle, event_index):
evaluation_result = ClaimBundleEvaluation.evaluate_bundle(bundle)
evaluation_response = {'type': 'claim.bundle.payload', 'content': evaluation_result, 'index': event_index}
await self.send({
'type': 'websocket.send',
'text': json.dumps(evaluation_response)
})
1 change: 1 addition & 0 deletions claim_ai/evaluation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .bundle_evaluation import ClaimBundleEvaluation
24 changes: 24 additions & 0 deletions claim_ai/evaluation/bundle_evaluation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from ..test_response_bundle import adjudication_bundle


class ClaimBundleEvaluation:

@classmethod
def evaluate_bundle(cls, claim_bundle):
entries = claim_bundle['entry']
evaluation_result = []
for next_claim in entries:
evaluation_result.append(cls._evaluate(next_claim))

return cls._build_response_bundle(evaluation_result)

@classmethod
def _build_response_bundle(cls, evaluation_resutl):
# TODO: Add real build here
return adjudication_bundle

@classmethod
def _evaluate(cls, claim):
# TODO: Call AI Evaluation here
return True

7 changes: 7 additions & 0 deletions claim_ai/routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.urls import re_path, path

from . import consumers

websocket_urlpatterns = [
re_path(r'ws/Claim/(?P<process_id>\w+)/$', consumers.ClaimConsumer.as_asgi()),
]
91 changes: 91 additions & 0 deletions claim_ai/test_response_bundle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
adjudication_bundle = {
'resourceType': 'AdjudicationBundle',
'entry': [
{
"resourceType": "ClaimResponse",
"created": "2020-11-15",
"id": "C670E61A-36F1-4F70-A5D2-6CE2C20457F6",
"item": [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I let some comments after this, but is easier to follow based on the updated ClaimsResponse structure described in the specification: https://openimis.atlassian.net/wiki/spaces/OP/pages/1790345259/openIMIS-AI+-+6.+Specification#Build-FHIR-ClaimResponse

{
"adjudication": [
dborowiecki marked this conversation as resolved.
Show resolved Hide resolved
{
"amount": {
"currency": "$",
"value": 13.0
},
"category": {
"coding": [
{
"code": "-2",
}
],
"text": "AI"
},
"reason": {
"coding": [
{
"code": 1
}
],
"text": "accepted"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code 1 is for 'rejected'.

},
"value": 1.0
}
],
"extension": [
{
"url": "Medication",
"valueReference": {
"reference": "Medication/4DAFEF84-7AFA-47C6-BB51-B6D5511A8AF9"
}
}
],
"itemSequence": 1,
"noteNumber": [
1
]
},
{
"adjudication": [
{
"amount": {
"currency": "$",
"value": 400.0
},
"category": {
"coding": [
{
"code": "-2",
}
],
"text": "AI"
},
"reason": {
"coding": [
{
"code": 0
}
],
"text": "rejected"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code 0 is for 'accepted'. This is based on the AI Model output.

},
"value": 1.0
}
],
"extension": [
{
"url": "ActivityDefinition",
"valueReference": {
"reference": "Medication/48DB6423-E696-45D9-B76E-CA1B7C57D738"
}
}
],
"itemSequence": 2,
"noteNumber": [
2
]
}
],
"use": "claim"
}
]
}