A library for parsing HL7 (version 2.x) messages in XML format into Python objects
You can install this library using pip:
pip install python-xml-hl7
or from the git repository:
git clone https://github.com/weynelucas/python-xml-hl7.git
cd python-xml-hl7
python setup.py install
As an example, let’s create a HL7 message:
message = """
<ORU_R01>
<MSH><MSH.1>|</MSH.1><MSH.2>^~\\&</MSH.2><MSH.3>hospital</MSH.3><MSH.7>20180703111743</MSH.7><MSH.9><MSH.9.1>ORU</MSH.9.1><MSH.9.2>R01</MSH.9.2></MSH.9><MSH.12>2.3.1</MSH.12></MSH>
<PID><PID.2>shenzhen</PID.2><PID.3>1</PID.3><PID.5>libang</PID.5><PID.7>20091010</PID.7><PID.8>M</PID.8></PID>
<PV1><PV1.2>U</PV1.2><PV1.18>adult</PV1.18><PV1.44>20180726181346</PV1.44></PV1>
<OBR><OBR.7>20180703111743</OBR.7></OBR>
<OBX><OBX.2>NM</OBX.2><OBX.3>SPO2</OBX.3><OBX.5>96</OBX.5><OBX.6>%</OBX.6><OBX.7>90-100</OBX.7></OBX>
<OBX><OBX.2>NM</OBX.2><OBX.3>PR</OBX.3><OBX.5>68</OBX.5><OBX.6>bpm</OBX.6><OBX.7>50-120</OBX.7></OBX>
<OBX><OBX.2>NM</OBX.2><OBX.3>SYS</OBX.3><OBX.5>131</OBX.5><OBX.6>mmHg</OBX.6><OBX.7>90-160</OBX.7><OBX.14>20180703111713</OBX.14></OBX>
<OBX><OBX.2>NM</OBX.2><OBX.3>DIA</OBX.3><OBX.5>85</OBX.5><OBX.6>mmHg</OBX.6><OBX.7>50-90</OBX.7><OBX.14>20180703111713</OBX.14></OBX>
<OBX><OBX.2>NM</OBX.2><OBX.3>MAP</OBX.3><OBX.5>100</OBX.5><OBX.6>mmHg</OBX.6><OBX.7>60-110</OBX.7><OBX.14>20180703111713</OBX.14></OBX>
<OBX><OBX.2>NM</OBX.2><OBX.3>NIBP_PR</OBX.3><OBX.5>73</OBX.5><OBX.6>bpm</OBX.6><OBX.7>50-120</OBX.7><OBX.14>20180703111713</OBX.14></OBX>
</ORU_R01>
"""
Call hl7.xml.parse()
command to convert the string message
from hl7.xml import parse
h = parse(message)
This command returns a Message
instance, wrapping a series of Segment
objects. Is possible iterate over segments or match for specific ones:
>>> list(h) # List all message segments
[<hl7.xml.containers.MSH>,
<hl7.xml.containers.PID>,
<hl7.xml.containers.PV1>,
<hl7.xml.containers.OBR>,
<hl7.xml.containers.OBX: SPO2>,
<hl7.xml.containers.OBX: PR>,
<hl7.xml.containers.OBX: SYS>,
<hl7.xml.containers.OBX: DIA>,
<hl7.xml.containers.OBX: MAP>,
<hl7.xml.containers.OBX: NIBP_PR>]
>>> h[0] # Get 1st message segment
<hl7.xml.containers.MSH>
>>> h['OBX'] # Find all OBX segments
[<hl7.xml.containers.OBX: SPO2>,
<hl7.xml.containers.OBX: PR>,
<hl7.xml.containers.OBX: SYS>,
<hl7.xml.containers.OBX: DIA>,
<hl7.xml.containers.OBX: MAP>,
<hl7.xml.containers.OBX: NIBP_PR>]
A Segment
instance wraps a serie of Field
objects, you can iterate over them:
>>> list(h[2]) # List all fields for 3rd message segment (PV1)
[<hl7.xml.containers.Field: PV1.2>,
<hl7.xml.containers.Field: PV1.18>,
<hl7.xml.containers.Field: PV1.44>]
>>> list(h[5]) # List all fields for 6th message segment (OBX)
[<hl7.xml.containers.Field: OBX.2>,
<hl7.xml.containers.Field: OBX.3>,
<hl7.xml.containers.Field: OBX.5>,
<hl7.xml.containers.Field: OBX.6>,
<hl7.xml.containers.Field: OBX.7>]
>>> h[5][0].value
'NM'
>>> h[5][2].value
'62'
There are different types of Segment
, they are: MSH
, PID
, PV1
, OBR
and OBX
. Each of them has helper methods to retrieve data from its respective HL7 segment without iterate over his Field
objects
>>> msh = h['MSH'][0]
>>> (msh.field_separator,
msh.encoding_chars,
msh.sending_application,
msh.datetime,
msh.version,
msh.message_type)
('|', '^~\\&', 'hospital', datetime.datetime(2018, 7, 3, 11, 17, 43), '2.3.1', ('ORU', 'R01'))
>>> pid = h['PID'][0]
>>> (pid.id,
pid.id_list,
pid.name,
pid.birthdate,
pid.gender)
('shenzhen', '1', 'libang', datetime.datetime(2009, 10, 10, 0, 0), 'M')
>>> pv1 = h['PV1'][0]
>>> (pv1.patient_class,
pv1.patient_class_display,
pv1.patient_type,
pv1.patient_type_display,
pv1.assigned_patient_location,
pv1.admit_datetime)
('U', 'Unknown', 'adult', 'Adult', None, datetime.datetime(2018, 7, 26, 18, 13, 46))
>>> obr = h['OBR'][0]
>>> obr.datetime
datetime.datetime(2018, 7, 3, 11, 17, 43)
>>> obx = h['OBX'][3] # 4th OBX instance
>>> (obx.identifier,
obx.value_type,
obx.value,
obx.units,
obx.reference_range,
obx.datetime)
('DIA', 'NM', 85, 'mmHg', (50, 90), datetime.datetime(2018, 7, 3, 11, 17, 13))
To find a OBX
segment or value inside a Message
by its identifier, use get_obx
and get_obx_value
methods:
>>> h.get_obx('DIA')
<hl7.xml.containers.OBX: DIA>
>>> h.get_obx('DIA').value
85
>>> h.get_obx_value('SPO2')
96
python-xml-hl7
provides a simple network (TCP/IP) client, wich reads HL7 messages from Alfamed patient monitors like VITA 200e
from hl7.xml.client import AlfamedClient
client = AlfamedClient('169.254.215.35') # Default communication port is 9100
client.read_message() # By default, HL7 messages are converted into Message objects
client.read_message(parse_message=False) # Returns the original HL7 message as string
AlfamedClient
objects instantiated with invalid host addresses will raises AttributeError
You can run tests locally using unittest
module
cd python-xml-hl7
python -m unittest tests
If all the tests pass you will see a success message like this:
.................
----------------------------------------------------------------------
Ran 17 tests in 0.007s
OK
- Specification for XML encoding rules of HL7 v2 messages can be found here
- For any suggestion, feature or bug fix, you can report an issue here. Or submit a pull request
- For handle HL7 messages in original stream format, use solutions like python-hl7 or HL7apy
- 1.0.0 - First release
- 1.1.0 - Find
OBX
segments withget_obx
andget_obx_value
- 1.2.0 - String representation for client and container objects
- 1.3.0 - Add Travis and Codecov support