Custom Receivers¶
txHL7 ships with a simple example of a twisted.receiver.LoggingReceiver, but for most cases, you will want to execute some custom actions when a message is received. To do this, you will need to define your own receiver, which implements txHL7.receiver.IHL7Receiver.
txHL7.receiver.IHL7Receiver only requires a few methods to be implemented (and if you look further down this document, you will find the even easier AbstractHL7Receiver):
- parseMessage provides the parsing logic to transform the pipe-delimited message into something more useful. It will return an instance of txHL7.receiver.MessageContainer. The MessageContainer is important, because it implements how build an HL7 ACK message.
- handleMessage receives the parsed txHL7.receiver.MessageContainer and is where you should put your business logic. It must return a twisted.internet.defer.Deferred instance.
- Internally txHL7 treats data as unicode, and getCodec provides the codec to use to decode the bytestring into unicode.
If you wish to use python-hl7 to parse the message, txHL7.receiver.AbstractHL7Receiver makes your job even easier. You just need to implement handleMessage and optionally getCodec.
Example Receiver¶
A simple example:
from txHL7.receiver import AbstractHL7Receiver
from twisted.internet import defer
class ExampleReceiver(AbstractHL7Receiver):
def handleMessage(self, container):
message = container.message
# Our business logic
mrn = message.segment('PID')[3][0]
# Do something with mrn
# We succeeded, so ACK back (default is AA)
return defer.succeed(container.ack())
def getCodec(self):
# Our messages are encoded in Windows-1252
# WARNING this is an example and is not universally true! You will
# need to figure out the encoding you are receiving.
return 'cp1252'
We can launch this receiver with:
twistd --nodaemon mllp --receiver example.ExampleReceiver
Deferring to a Thread¶
Remember that twisted is non-blocking. Blocking operations should ideally be executed outside the main loop. One way to accomplish this is to defer to a thread in twisted [1].
Warning
It is up to you to ensure that your application is thread-safe.
Here is an example that calls a blocking operation in importMessage, which is defered to a thread in handleMessage. We additionally, show catching an error are returning a reject message:
from txHL7.receiver import AbstractHL7Receiver
from twisted.internet import threads
class ThreadedReceiver(AbstractHL7Receiver):
def saveMessage(self, message):
try:
self.database.insert(message)
return message.ack()
except:
# reject the message
return message.ack(ack_code='AR')
def handleMessage(self, message):
return threads.deferToThread(self.saveMessage, message)
[1] | https://twistedmatrix.com/documents/current/core/howto/threading.html |