CareflowDocumentation

Examples and Instructions

Last Updated: June 25, 2026


The sample/ folder contains a complete, runnable example model. It builds on top of the Careflow Broker base image, receives sample data via a callback, and (optionally) writes results to S3.

plaintext
sample/
├── Dockerfile              # builds FROM careflowhealth/careflow-broker:latest
├── main.py                 # minimal callback example
├── main_test.py            # callback example with multi-bucket S3 usage
├── README.txt              # integration & build instructions
└── local_dev/
    ├── config.yaml         # set environment: 'local' for local sample-file runs
    ├── docker-compose.yaml # mounts config + sample data
    └── sample_data_payload.json

Setting up Docker

1. Pull the Careflow Broker base image

docker pull careflowhealth/careflow-broker:latest

2. Build your model image

The sample Dockerfile derives from the base image and copies in your model code:

dockerfile
FROM careflowhealth/careflow-broker:latest
COPY main.py /careflow/main.py
CMD ["python3", "main.py"]

Build it (no Azure Artifacts PAT is required; the Careflow dependencies are pre-bundled in the base image):

dockerfile
cd sample/
docker build --tag careflowhealth/test-ai-model:latest .

3. Run the container (local development)

Use local_dev/docker-compose.yaml, which mounts config.yaml and the sample data file into /careflow/config/. For local sample-file runs, set environment: 'local' in config.yaml before starting the container:

dockerfile
cd sample/local_dev/
# Update the volume paths in docker-compose.yaml to match your local filesystem first
docker compose up

The config.yaml must be mounted for the container to start – the Careflow library requires it at import time. When deployed via the Careflow Orchestrator, the config.yaml is generated and mounted automatically; you do not provide it yourself.

4. Check the Logs

dockerfile
docker ps
docker logs -f <container_name_or_id>

5. Access the Container

dockerfile
docker exec -it <container_name_or_id> /bin/bash

6. Verify the Careflow library version inside the container

dockerfile
docker exec -it <container_name_or_id> python3 -c "import careflow; print(careflow.__version__)"

Instructions

Minimal local model (main.py)

python
from careflow import logger, start, config, s3

def test_server_with_callback():
    logger.info(config.get())
    def callback(data):
        logger.info(f"Received data: {data}")
        # implement data processing here
        # publish results via careflow.send(...) or write to S3 via careflow.s3

    start(callback)

if __name__ == '__main__':
    test_server_with_callback()

In local mode, start(callback) reads the sample data file config/<SUB_TOPIC>.json and feeds it into the callback once every local.TIMER seconds. For the sample, SUB_TOPIC: sample_data_payload, so the file is sample_data_payload.json:

json
{
  "data_payload": "test data payload sent from JSON file for local dev testing"
}

Use Case: Local Testing with a Templated Sample Feed

When you need to simulate a stream of varying values (rather than a single static payload), start(callback, sample_parser) supports placeholder substitution in the sample data file. The sample_parser argument supplies the values to substitute on each interval.

The file names below (start.py, FHIR sample, etc.) are illustrative — they are not shipped in the repo. They demonstrate the templating capability of SampleService.

Setup

  • Set environment: 'local' in config.yaml.
  • Set the interval via local.TIMER (e.g. local.TIMER: 1 feeds a new value every second). Set local.LOOP: true to repeat the parser list from the start once exhausted.
  • The sample data file (config/<SUB_TOPIC>.json) is a JSON template containing placeholders.

Supported placeholders (handled by SampleService):

PlaceholderReplaced with
%NOW%Current UTC timestamp (ISO 8601, e.g. 2024-08-08T11:21:54Z)
%NOW_SECOND%Current Unix epoch seconds
%<KEY>%The value of the named key from the current sample_parser entry
%IF(<KEY><op><n>)%...%ENDIF%The enclosed block, only if the condition is true (operators: < > == <= >= !=)

If a parser value is a {"min": x, "max": y} dict, a random integer in that range is substituted.

Example (start.py)

python
import careflow
def callback(data):
    careflow.logger.info(f"Received data: {data}")
    if len(data) > 0:
        spo2 = float(data[0]['valueQuantity']['value'])
        pulse = float(data[1]['valueQuantity']['value'])
        careflow.send({"data": spo2 + pulse})
# sample_parser is a list of dicts; one entry is consumed per interval
parser = [
    {"SPO2": 98, "PULSE": 72},
    {"SPO2": 88, "PULSE": 110},
]   
careflow.start(callback, parser)

In the sample data template, %SPO2% / %PULSE% are replaced from each parser entry, %NOW% is replaced with the timestamp, and an %IF(SPO2<90)%...%ENDIF% block can conditionally inject an “abnormal” interpretation.

Process Overview

  1. Ensure environment and local.TIMER are configured.
  2. The callback is where the sample data is fed and processed — once per interval.
  3. Use careflow.send(...) to transmit processed results.