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

WIP support external mapper repository #62

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11-bullseye
FROM python:3.12-bullseye
RUN pip install pipenv
RUN mkdir /app
WORKDIR /app
Expand Down
4 changes: 2 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sentry-sdk = "==1.14.0"
aiocontextvars = "==0.2.2"
coloredlogs = ">=15.0.1"
aidbox-python-sdk = "==0.1.3"
fhirpathpy = "~=1.0"
fhirpathpy = "*"
pytest-aiohttp = "==1.0.4"
pytest-cov = "==4.0.0"
pytest = "==7.2.2"
Expand All @@ -41,4 +41,4 @@ pytest-asyncio = "*"
aiohttp-cors = "~=0.7.0"

[requires]
python_version = "3.11"
python_version = "3.12"
2,063 changes: 1,137 additions & 926 deletions Pipfile.lock

Large diffs are not rendered by default.

50 changes: 36 additions & 14 deletions app/fhir_server/operations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json

from aiohttp import web
from aiohttp import ClientSession, web
from fhirpy.lib import AsyncFHIRClient

from app.converter.fce_to_fhir import from_first_class_extension
Expand All @@ -16,7 +16,7 @@
resolve_expression,
)
from ..sdc.utils import parameter_to_env, validate_context
from ..utils import get_extract_services
from ..utils import get_extract_services, get_mapper_repository

routes = web.RouteTableDef()

Expand Down Expand Up @@ -56,7 +56,12 @@ async def get_questionnaire_context_handler(request: web.BaseRequest):
@routes.post("/Questionnaire/$extract")
async def extract_questionnaire_handler(request: web.BaseRequest):
resource = await request.json()
client = request.app["client"]
original_client = request.app["client"]
client = AsyncFHIRClient(
original_client.url,
authorization=request.headers["Authorization"],
extra_headers=original_client.extra_headers,
)

if resource["resourceType"] == "QuestionnaireResponse":
env = {}
Expand All @@ -76,7 +81,7 @@ async def extract_questionnaire_handler(request: web.BaseRequest):
if ext["url"]
== "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-targetStructureMap"
]
jute_templates = []
templates = []

for structure_map_extension in structure_map_extensions:
structure_map_id = structure_map_extension["valueCanonical"].split("/")[-1]
Expand All @@ -92,7 +97,21 @@ async def extract_questionnaire_handler(request: web.BaseRequest):
"valueString",
]
)
jute_templates.append(json.loads(template_string))
templates.append(json.loads(template_string))

mapper_extensions = [
ext["valueReference"]["reference"]
for ext in questionnaire["extension"]
if ext["url"] == "http://beda.software/fhir-extensions/questionnaire-mapper"
]

mapper_service_url = get_mapper_repository(request.app)
async with ClientSession() as session:
for mapper_ref in mapper_extensions:
query = f"{mapper_service_url}/{mapper_ref}"
async with session.get(query) as result:
data = await result.text()
templates.append(json.loads(data))

context = {
"Questionnaire": to_first_class_extension(questionnaire),
Expand All @@ -101,9 +120,7 @@ async def extract_questionnaire_handler(request: web.BaseRequest):
}

await constraint_check(client, context)
extraction_result = await extract(
client, jute_templates, context, get_extract_services(request.app)
)
extraction_result = await extract(client, templates, context, get_extract_services(request.app))
return web.json_response(extraction_result)


Expand All @@ -114,7 +131,7 @@ async def extract_questionnaire_instance_operation(request: web.BaseRequest):
fhir_questionnaire = (
await client.resources("Questionnaire").search(_id=request.match_info["id"]).get()
)
jute_templates = []
templates = []
structure_map_extensions = [
ext
for ext in fhir_questionnaire["extension"]
Expand All @@ -138,7 +155,7 @@ async def extract_questionnaire_instance_operation(request: web.BaseRequest):
"valueString",
]
)
jute_templates.append(json.loads(template_string))
templates.append(json.loads(template_string))

if resource["resourceType"] == "QuestionnaireResponse":
questionnaire_response = client.resource("QuestionnaireResponse", **resource)
Expand All @@ -148,7 +165,7 @@ async def extract_questionnaire_instance_operation(request: web.BaseRequest):
}
await constraint_check(client, context)
return web.json_response(
await extract(client, jute_templates, context, get_extract_services(request.app))
await extract(client, templates, context, get_extract_services(request.app))
)

if resource["resourceType"] == "Parameters":
Expand Down Expand Up @@ -178,7 +195,7 @@ async def extract_questionnaire_instance_operation(request: web.BaseRequest):
}
await constraint_check(client, context)
return web.json_response(
await extract(client, jute_templates, context, get_extract_services(request.app))
await extract(client, templates, context, get_extract_services(request.app))
)

raise ConstraintCheckOperationOutcome(
Expand Down Expand Up @@ -216,11 +233,16 @@ async def populate_questionnaire_handler(request: web.BaseRequest):

@routes.post("/Questionnaire/{id}/$populate")
async def populate_questionnaire_instance(request: web.BaseRequest):
client = request.app["client"]
original_client = request.app["client"]
client = AsyncFHIRClient(
original_client.url,
authorization=request.headers["Authorization"],
extra_headers=original_client.extra_headers,
)
questionnaire = (
await client.resources("Questionnaire").search(_id=request.match_info["id"]).get()
)
env = parameter_to_env(request["resource"])
env = parameter_to_env(await request.json())
converted = to_first_class_extension(questionnaire)
env["Questionnaire"] = converted
populated_resource = await populate(client, converted, env)
Expand Down
1 change: 1 addition & 0 deletions app/fhir_server/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ def __init__(self, **custom_settings):
BASE_URL=os.getenv("BASE_URL", "http://devbox:8080/fhir"),
AUTH_TOKEN=os.getenv("AUTH_TOKEN"),
FHIRPATH_MAPPING_SERVICE=os.getenv("FHIRPATH_MAPPING_SERVICE"),
MAPPER_REPOSITORY=os.getenv("MAPPER_REPOSITORY"),
)
5 changes: 5 additions & 0 deletions app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ def get_extract_services(app):
jute_service = app["settings"].JUTE_SERVICE
fhir_mapping_service = app["settings"].FHIRPATH_MAPPING_SERVICE
return {"JUTE": jute_service, "FHIRPath": fhir_mapping_service}


def get_mapper_repository(app):
mapper_repository = app["settings"].MAPPER_REPOSITORY or app["setting"].BASE_URL
return mapper_repository
Loading