pyprod: Creating IRIS Interoperability Productions Programmatically with Python
In the previous article, we used pyprod to create production components while relying on the UI for production configuration. That same production can now be defined entirely in Python:
from intersystems_pyprod import Production, ServiceItem, ProcessItem, OperationItem
iris_package_name = "HelloWorld"
class MyProduction(Production):
services = [
ServiceItem(
"MyServiceName",
"HelloWorld.MyService",
host_settings={"target": "MyProcessName"},
)
]
processes = [
ProcessItem(
"MyProcessName",
"HelloWorld.MyProcess",
host_settings={"target": "MyOperationName"},
)
]
operations = [
OperationItem("MyOperationName", "HelloWorld.MyOperation")
]
Key parts of the code
-
The Production class
MyProductionsubclassesProduction, which tells pyprod that this class represents an interoperability production. Production-level settings such asactor_pool_size,testing_enabled, etc. can be set as class attributes. -
services, processes and operations lists
When pyprod finds one of these attributes, it expects a list ofServiceItem,ProcessItem, orOperationItemobjects. Each item represents one config entry that will be registered in the production backend, along with its unique instance settings. -
ServiceItem, ProcessItem and OperationItem
These classes declare the business host class to add as a production component along with its instance-specific settings. Both Python and ObjectScript classes can be added this way. -
host_settings
This dictionary sets the properties defined asIRISPropertyon the python host class or thePropertyof an ObjectScript class. This is the programmatic equivalent of entering values in the Production Configuration page.
More options are available - adapter_settings, scheduling, pool size, enable/disable flags, and others - documented in the API Reference.
Load to IRIS
To load this production into IRIS, point the CLI tool at the Python script containing it. The production definition can be at the end of the same file as your business host classes, or in a separate file:
$ intersystems_pyprod /path/to/MyProduction.pyLoad-time validation
When you run the CLI command to load the production into IRIS, pyprod validates it on two levels. First, unknown attributes on the Production subclass emit a warning (catching typos as well). Second, all host_settings and adapter_settings key names are checked against the actual class definitions, with a warning emitted for any unrecognised property, catching configuration mistakes before the production runs.
Controlling the production programmatically
Once the production is loaded, you can start, inspect, and stop it using the director module from a Python shell or script
>>> from intersystems_pyprod import director
>>> director.start_production()
1
>>> director.get_production_status()
(1, 'HelloWorld.MyProduction', '1')
>>> director.stop_production()
1
You can also inspect messages that have passed through any host:
>>> messages = director.get_host_messages("MyServiceName", 100)
>>> messages[0]
{
'id': '156',
'time_created': '2026-06-02 19:34:10.545',
'source': 'MyProcessName',
'target': 'MyServiceName',
'status': 9,
'session_id': 153,
'body_class': 'HelloWorld.MyResponse',
'body_id': '27'
}
The full list of methods available in the director module is documented in the API Reference.
You can find an example of creating an adapterless business service here, and see how to test it using the director module in test_bo_method_1() here.
Comments
Great, this is a good design, congratulations!
I love it.
Do you plan to support brownfield productions too, meaning scaffold an existing IRIS production into Python source so it can be put under source control?
Thank you ! Had a lot of feedback from product/integration teams.
I’ll discuss with the product team whether there are requirements for supporting existing productions or linking them to pyprod, and get back to you.
Awesome work Geet!
Thank you !
I remembered when we talked about your initiative at Ready 2025, and I showed you how Apache Camel did it, and I thought it looked similar. Apache Camel is the best at programmatic integration on the market. But I liked the way you did it with your library. Great job!
Apache camel looks like this:
import org.apache.camel.builder.RouteBuilder;
public class FileRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
// Step 1: Consume text files from the input folder
from("file:data/input?noop=true") // noop=true leaves source files unchanged
.log("Processing file: ${header.CamelFileName}")
// Step 2: Route based on file content (EIP Content Based Router)
.choice()
.when(body().contains("URGENT"))
.log("Routing to critical queue...")
.to("file:data/output/critical")
.otherwise()
.log("Routing to regular queue...")
.to("file:data/output/regular")
.end(); // Close choice block
}
}Thank you, Yuri! I remember that conversation at Ready 2025 as well, and it was very helpful feedback. Seeing how Apache Camel approached programmatic integration gave us a useful reference point while thinking through this library, especially in terms of what kind of code-first integration experience developers appreciate. Thankfully, IRIS/ObjectScript productions also provide a solid foundation for what a good interface should look like in this context, which helps guide and constrain the design.