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.
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') # 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 .
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)