1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
MLLP using asyncio
==================
.. versionadded:: 0.4.1
.. note::
`hl7.mllp` package is currently experimental and subject to change.
It aims to replace txHL7.
python-hl7 includes classes for building HL7 clients and
servers using asyncio. The underlying protocol for these
clients and servers is MLLP.
The `hl7.mllp` package is designed the same as
the `asyncio.streams` package. `Examples in that documentation
<https://docs.python.org/3/library/asyncio-stream.html>`_
may be of assistance in writing production senders and
receivers.
HL7 Sender
----------
.. code:: python
# Using the third party `aiorun` instead of the `asyncio.run()` to avoid
# boilerplate.
import aiorun
import hl7
from hl7.mllp import open_hl7_connection
async def main():
message = 'MSH|^~\&|GHH LAB|ELAB-3|GHH OE|BLDG4|200202150930||ORU^R01|CNTRL-3456|P|2.4\r'
message += 'PID|||555-44-4444||EVERYWOMAN^EVE^E^^^^L|JONES|196203520|F|||153 FERNWOOD DR.^^STATESVILLE^OH^35292||(206)3345232|(206)752-121||||AC555444444||67-A4335^OH^20030520\r'
message += 'OBR|1|845439^GHH OE|1045813^GHH LAB|1554-5^GLUCOSE|||200202150730||||||||555-55-5555^PRIMARY^PATRICIA P^^^^MD^^LEVEL SEVEN HEALTHCARE, INC.|||||||||F||||||444-44-4444^HIPPOCRATES^HOWARD H^^^^MD\r'
message += 'OBX|1|SN|1554-5^GLUCOSE^POST 12H CFST:MCNC:PT:SER/PLAS:QN||^182|mg/dl|70_105|H|||F\r'
# Open the connection to the HL7 receiver.
# Using wait_for is optional, but recommended so
# a dead receiver won't block you for long
hl7_reader, hl7_writer = await asyncio.wait_for(
open_hl7_connection("127.0.0.1", 2575),
timeout=10,
)
hl7_message = hl7.parse(message)
# Write the HL7 message, and then wait for the writer
# to drain to actually send the message
hl7_writer.writemessage(hl7_message)
await hl7_writer.drain()
print(f'Sent message\n {hl7_message}'.replace('\r', '\n'))
# Now wait for the ACK message from the receiever
hl7_ack = await asyncio.wait_for(
hl7_reader.readmessage(),
timeout=10
)
print(f'Received ACK\n {hl7_ack}'.replace('\r', '\n'))
aiorun.run(main(), stop_on_unhandled_errors=True)
HL7 Receiver
------------
.. code:: python
# Using the third party `aiorun` instead of the `asyncio.run()` to avoid
# boilerplate.
import aiorun
import hl7
from hl7.mllp import start_hl7_server
async def process_hl7_messages(hl7_reader, hl7_writer):
"""This will be called every time a socket connects
with us.
"""
peername = hl7_writer.get_extra_info("peername")
print(f"Connection established {peername}")
try:
# We're going to keep listening until the writer
# is closed. Only writers have closed status.
while not hl7_writer.is_closing():
hl7_message = await hl7_reader.readmessage()
print(f'Received message\n {hl7_message}'.replace('\r', '\n'))
# Now let's send the ACK and wait for the
# writer to drain
hl7_writer.writemessage(hl7_message.create_ack())
await hl7_writer.drain()
except asyncio.IncompleteReadError:
# Oops, something went wrong, if the writer is not
# closed or closing, close it.
if not hl7_writer.is_closing():
hl7_writer.close()
await hl7_writer.wait_closed()
print(f"Connection closed {peername}")
async def main():
try:
# Start the server in a with clause to make sure we
# close it
async with await start_hl7_server(
process_hl7_messages, port=2575
) as hl7_server:
# And now we server forever. Or until we are
# cancelled...
await hl7_server.serve_forever()
except asyncio.CancelledError:
# Cancelled errors are expected
pass
except Exception:
print("Error occurred in main")
aiorun.run(main(), stop_on_unhandled_errors=True)
|