From d528c03e26222f48a0e943608925825547044ca1 Mon Sep 17 00:00:00 2001 From: Paul Bugni Date: Wed, 23 Jun 2021 10:21:04 -0700 Subject: [PATCH] Early work on CSV file upload API. Not functional - checking in to capture WIP. --- script_facade/api/fhir.py | 37 +++++++++++++++++++++++++++++++++++++ tests/test_api.py | 10 ++++++++++ tests/test_api/patients.csv | 2 ++ 3 files changed, 49 insertions(+) create mode 100644 tests/test_api/patients.csv diff --git a/script_facade/api/fhir.py b/script_facade/api/fhir.py index 85a38ef..3f059a8 100644 --- a/script_facade/api/fhir.py +++ b/script_facade/api/fhir.py @@ -1,4 +1,6 @@ +import csv from flask import Blueprint, request, current_app +import io import timeit from script_facade.client.client_106 import rx_history_query, patient_lookup_query @@ -57,3 +59,38 @@ def patient_search(fhir_version): patient_bundle = patient_lookup_query(patient_fname, patient_lname, patient_dob) return patient_bundle + + +@blueprint.route('/upload/patient/csv', methods=['POST']) +def upload_patient_csv(): + """Given a CSV file (via request.files) upload contents""" + + def decode_file(binary_data): + """Convert binary file data to file like string buffer + + Flask reads in multipart files as binary, which the csv lib can't + handle. + + :returns: StringIO buffer of utf-8 decoded strings for file like use + """ + buffer = io.StringIO() + last_pos = binary_data.tell() + while True: + line = binary_data.readline() + pos = binary_data.tell() + if pos == last_pos: + # Position stops progressing at EOF + break + last_pos = pos + buffer.write(line.decode('utf-8')) + + buffer.seek(0) + return buffer + + contents = request.files['file'] + csv.register_dialect('generic', skipinitialspace=True) + reader = csv.DictReader(decode_file(contents), dialect='generic') + for row in reader: + if 'provider_last_name' in row: + # Upsert provider + pass diff --git a/tests/test_api.py b/tests/test_api.py index 8c0c3be..c343365 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,3 +1,4 @@ +import os import pytest from conftest import load_json @@ -20,3 +21,12 @@ def test_medication_order(client, mocker, med_order_bundle): } ) assert response.status_code == 200 + + +def test_upload_patient(client, datadir): + file = open(os.path.join(datadir, 'patients.csv'), 'rb') + data = {'filename': 'patients.csv', 'file': file} + client.post( + '/upload/patient/csv', + content_type='multipart/form-data', + data=data) diff --git a/tests/test_api/patients.csv b/tests/test_api/patients.csv new file mode 100644 index 0000000..9e664d5 --- /dev/null +++ b/tests/test_api/patients.csv @@ -0,0 +1,2 @@ +first_name, last_name, birthdate +John, Hancock, 1737-01-23