From 241c9e1264509be4c6ea62e8047b6b330c45ceb7 Mon Sep 17 00:00:00 2001 From: Michael Weinstein Date: Tue, 1 Dec 2020 23:56:01 -0800 Subject: [PATCH] Lab address now can take suite information. OBX8 takes an anbormality code per the new CDPH data standard. Added strict enforcement of strong cipher suites for connection to the gateway. --- templateSubmission.csv | 2 +- zymoTransmitSupport/config.py | 1 + zymoTransmitSupport/configClean.txt | 1 + zymoTransmitSupport/hl7Encoder/encoders.py | 6 ++++-- zymoTransmitSupport/hl7Encoder/generics.py | 4 ++-- .../hl7Encoder/observedResults.py | 8 ++++---- zymoTransmitSupport/inputOutput/connection.py | 20 +++++++++++++++++++ zymoTransmitSupport/supportData.py | 4 ++-- 8 files changed, 35 insertions(+), 11 deletions(-) diff --git a/templateSubmission.csv b/templateSubmission.csv index 8e1ef2a..fa0ff84 100644 --- a/templateSubmission.csv +++ b/templateSubmission.csv @@ -1,2 +1,2 @@ #PatientID,Patient Last Name,Patient First Name,Patient Middle Name,Patient Date of Birth,Patient Sex,Patient Street Address,Patient City,Patient State,Patient Zip,Patient Phone,Provider Last Name,Provider First Name,Provider Middle Name,Provider Street,Provider City,Provider State,Provider Zip,Provider Phone,Specimen ID,Collection Date,Collection Time,Received Date,Received Time,Specimen SNOMED Code,Test LOINC Code,Analysis Date,Analysis Time,Result,Reported Date,Reported Time,Notes,Race,Ethnicity,Accession ID,Test Ordered Date,Test Ordered Time,Test Equipment Code,Test Equipment Description,Test Equipment ID Number,Provider NPI -#1K94U,Weinstein,Andrew,P,8/15/2017,M,17062 Murphy Ave. #1,Irvine,CA,92614,888-882-9682,Rain,Leo,,13842 Tustin East Drive,Tustin,CA,92780,(818) 344-3434,1234567,6/8/2020,0:00,6/8/2020,13:00,258529004,94306-8,6/9/2020,11:00,Negative,6/10/2020,14:00,"Phone is pretty flexible for formatting, just be reasonable. Email address is also an acceptable entry there, if needed. Please stick to mm/dd/yyyy formatting for dates. Having a # at the start of a line will cause that line to be ignored as a comment or header.",unknown,unk,1A2B3C4D5E,6/8/2020,0:00,qPCR,Zymo Research Quick SARS-CoV-2 rRT-PCR Kit,R3011, +1K94U,Weinstein,Andrew,P,8/15/2017,M,17062 Murphy Ave. #1,Irvine,CA,92614,888-882-9682,Rain,Leo,,13842 Tustin East Drive,Tustin,CA,92780,(818) 344-3434,1234567,6/8/2020,0:00,6/8/2020,13:00,258529004,94306-8,6/9/2020,11:00,Negative,6/10/2020,14:00,"Phone is pretty flexible for formatting, just be reasonable. Email address is also an acceptable entry there, if needed. Please stick to mm/dd/yyyy formatting for dates. Having a # at the start of a line will cause that line to be ignored as a comment or header.",unknown,unk,1A2B3C4D5E,6/8/2020,0:00,qPCR,Zymo Research Quick SARS-CoV-2 rRT-PCR Kit,R3011, diff --git a/zymoTransmitSupport/config.py b/zymoTransmitSupport/config.py index 28074fd..d194053 100644 --- a/zymoTransmitSupport/config.py +++ b/zymoTransmitSupport/config.py @@ -56,6 +56,7 @@ class LabInfo: phone = configDict.setdefault("lab phone", "") email = configDict.setdefault("lab email", "") street = configDict.setdefault("lab street", "") + suite = configDict.setdefault("lab suite", "") city = configDict.setdefault("lab city", "") state = configDict.setdefault("lab state", "") zip = configDict.setdefault("lab zip", "") diff --git a/zymoTransmitSupport/configClean.txt b/zymoTransmitSupport/configClean.txt index fe37b6b..12f7121 100644 --- a/zymoTransmitSupport/configClean.txt +++ b/zymoTransmitSupport/configClean.txt @@ -12,6 +12,7 @@ Lab Name: Lab Phone: Lab Email: Lab Street: +Lab Suite: Lab City: Lab State: Lab Zip: diff --git a/zymoTransmitSupport/hl7Encoder/encoders.py b/zymoTransmitSupport/hl7Encoder/encoders.py index 0fea6f5..23594f5 100644 --- a/zymoTransmitSupport/hl7Encoder/encoders.py +++ b/zymoTransmitSupport/hl7Encoder/encoders.py @@ -125,7 +125,8 @@ def makeORCLine(result:inputOutput.resultReader.TestResult): config.LabInfo.street, config.LabInfo.city, config.LabInfo.state, - config.LabInfo.zip + config.LabInfo.zip, + otherDesignation=config.LabInfo.suite ) if "labPhone" in result.auxiliaryData: orderingFacilityPhone = orderHeader.OrderingFacilityPhone(result.auxiliaryData["labPhone"]) @@ -303,7 +304,8 @@ def makeObservationValueAndAbnormalityObjects(resultString:str): config.LabInfo.street, config.LabInfo.city, config.LabInfo.state, - config.LabInfo.zip + config.LabInfo.zip, + otherDesignation=config.LabInfo.suite ) if config.LabDirectorInfo.assigningAuthority: medicalDirectorAssignmentAuthority = observedResults.MedicalDirectorNumberAssignmentAuthority( diff --git a/zymoTransmitSupport/hl7Encoder/generics.py b/zymoTransmitSupport/hl7Encoder/generics.py index bb24031..ffacb61 100644 --- a/zymoTransmitSupport/hl7Encoder/generics.py +++ b/zymoTransmitSupport/hl7Encoder/generics.py @@ -252,9 +252,9 @@ class Address(Hl7Field): defaultAddressType = "H" - def __init__(self, streetAddress:str, city:str, state:str, zip:str, country:str="USA", addressType:str=None): + def __init__(self, streetAddress:str, city:str, state:str, zip:str, country:str="USA", addressType:str=None, otherDesignation:str=""): self.streetAddress = streetAddress - self.otherDesignation = "" + self.otherDesignation = otherDesignation self.city = city self.state = state self.zip = correctLostLeadingZeroZipcode(zip, state) diff --git a/zymoTransmitSupport/hl7Encoder/observedResults.py b/zymoTransmitSupport/hl7Encoder/observedResults.py index fa61285..1cbcfe2 100644 --- a/zymoTransmitSupport/hl7Encoder/observedResults.py +++ b/zymoTransmitSupport/hl7Encoder/observedResults.py @@ -67,13 +67,13 @@ def getAbnormalityObject(result:str): if not result in validResults: raise ValueError("Result type must be in: " %validResults) if result == "detected": - return generics.SystemCode(code="260373001", text="Detected", coding="SNOMED", codingSystemDateOrVersion="2.7") + return generics.SystemCode(code="A", text="Abnormal", coding="HL70078", codingSystemDateOrVersion="2.7") elif result == "indeterminate": - return generics.SystemCode(code="419984006", text="Inconclusive", coding="SNOMED", codingSystemDateOrVersion="2.7") + return generics.SystemCode(code="A", text="Abnormal", coding="HL70078", codingSystemDateOrVersion="2.7") elif result == "negative": - return generics.SystemCode(code="260415000", text="Not detected", coding="SNOMED", codingSystemDateOrVersion="2.7") + return generics.SystemCode(code="N", text="Normal", coding="HL70078", codingSystemDateOrVersion="2.7") elif result == "unsatisfactory": - return generics.SystemCode(code="125154007", text="Specimen unsatisfactory", coding="SNOMED", codingSystemDateOrVersion="2.7") + return generics.SystemCode(code="A", text="Abnormal", coding="HL70078", codingSystemDateOrVersion="2.7") elif result == "": return "" else: diff --git a/zymoTransmitSupport/inputOutput/connection.py b/zymoTransmitSupport/inputOutput/connection.py index eb13cab..51fcf84 100644 --- a/zymoTransmitSupport/inputOutput/connection.py +++ b/zymoTransmitSupport/inputOutput/connection.py @@ -1,10 +1,30 @@ import requests import os import zeep +import ssl +import requests.adapters +import requests.packages.urllib3 + +strongSSLCipherSuiteEnforcement = True +permittedCipherSuites = 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256' +defaultSSLRules = (ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1) + + +class TLSEnforcer(requests.adapters.HTTPAdapter): + def __init__(self, sslRules=defaultSSLRules, **kwargs): + self.sslRules = sslRules + super(TLSEnforcer, self).__init__(**kwargs) + + def init_poolmanager(self, *pool_args, **pool_kwargs): + sslSettings = requests.packages.urllib3.util.ssl_.create_urllib3_context(ciphers=permittedCipherSuites, cert_reqs=ssl.CERT_REQUIRED, options=self.sslRules) + self.poolmanager = requests.packages.urllib3.poolmanager.PoolManager(*pool_args, ssl_context=sslSettings, **pool_kwargs) + def getSOAPClient(wsdlURL:str, clientCertificatePath:str=None, dumpClientInfo:bool=False, testOnly:bool=False): session = requests.Session() + if strongSSLCipherSuiteEnforcement: + session.mount("https://", adapter=TLSEnforcer()) if clientCertificatePath: if not os.path.isfile(clientCertificatePath): raise FileNotFoundError("Unable to find client certificate path at %s" %clientCertificatePath) diff --git a/zymoTransmitSupport/supportData.py b/zymoTransmitSupport/supportData.py index 89edd5f..b887cca 100644 --- a/zymoTransmitSupport/supportData.py +++ b/zymoTransmitSupport/supportData.py @@ -1,4 +1,4 @@ -softwareVersion = "1.3.0" +softwareVersion = "1.4.0" -softwareDate = "20200805" \ No newline at end of file +softwareDate = "20201201" \ No newline at end of file