Early Access · beta. Help test and shape the 1.0 release. Where the project stands →

Developer guide

Receive and send HL7 over MLLP in Python

Receive and send HL7 v2 messages over MLLP with Python connections. Add routing and transforms, then test the interface.

The Minimal Lower Layer Protocol (MLLP) marks the start and end of each HL7 v2 message over TCP. Declare a connection, and MessageFoundry runs the listener and passes messages to your code.

1. Install the engine

MessageFoundry installs from PyPI. Create a virtual environment and install it — no C compiler needed for the default install.

terminal
python -m venv .venv
# macOS / Linux:   . .venv/bin/activate
# Windows (PS):    .venv\Scripts\Activate.ps1

pip install messagefoundry

2. Define an MLLP inbound and outbound connection

Add a Python module to your config directory. Give the inbound listener a name, port, and router. Give the outbound sender a downstream host and port.

config/lab_oru.py
from messagefoundry import MLLP, Send, inbound, outbound, router, handler

# receive HL7 v2 over MLLP on port 2575
inbound("IB_Lab_ORU", MLLP(port=2575), router="oru_router")

# send to a downstream system over MLLP
outbound("OB_EHR_ORU", MLLP(host="10.0.0.21", port=6661))

3. Route and transform each message

A router selects handlers by name. A handler transforms the message and sends it on. Address fields by HL7 path, such as MSH-9.1 or OBR-25. An empty router result leaves the message unrouted; a handler returning None filters it.

config/lab_oru.py
@router("oru_router")
def route(msg):
    if msg["MSH-9.1"] != "ORU":
        return []                    # UNROUTED — not a lab result
    return ["to_ehr"]

@handler("to_ehr")
def to_ehr(msg):
    if msg["OBR-25"] == "X":       # drop corrected-in-error
        return None                  # FILTERED
    return Send("OB_EHR_ORU", msg)

4. Run the engine

Point MessageFoundry at your config directory and a store database. It opens the MLLP listener, persists every message before it's acknowledged, and routes it through your code.

terminal
python -m messagefoundry serve --config config --db messagefoundry.db

# MLLP listening on 0.0.0.0:2575 — every message is stored, then routed

Validate the config before it ships with the commit gate: python -m messagefoundry check --config config.

5. Send a test HL7 message

Send a test HL7 v2 message to port 2575. Use an MLLP client or the repository’s send_mllp.py helper. An ORU result routes downstream; the engine records other messages as unrouted.

terminal
python samples/send_mllp.py samples/messages/oru_r01.hl7
# → ORU routed to OB_EHR_ORU; non-ORU logged UNROUTED

MLLP over TLS

MessageFoundry supports MLLP-over-TLS to encrypt traffic in transit. TLS is enabled by default for connections whose peer supports it. For older systems without TLS, you can choose plaintext MLLP per connection. Plaintext can support a HIPAA-compliant deployment within your organization’s secure network perimeter. See the certificate and TLS settings in the Configuration reference and Deployment & network-exposure guide.

Keep interfaces in one Python configuration repository for Test and Production. Review changes, compare versions, and unit-test the code. Compare channel-based engines →

FAQ

Frequently asked questions

What is MLLP?

MLLP stands for Minimal Lower Layer Protocol. It marks each HL7 v2 message’s start and end over TCP, so the receiver can separate messages.

Does MessageFoundry support MLLP over TLS?

Yes. TLS is enabled by default for connections whose peer supports it. For older endpoints, plaintext MLLP is also supported within your organization’s secure network perimeter. That setup can support a HIPAA-compliant deployment.

How do I receive HL7 over MLLP in Python?

Declare an inbound MLLP connection in a Python config module: inbound('IB_Lab', MLLP(port=2575), router='oru_router'). Write a router and handler to process messages. MessageFoundry runs the listener.