Manipulating InterSystems IRIS Globals the Pythonic Way with iris-global-reference
InterSystems IRIS globals are one of the platform's core strengths: they store hierarchical data in a direct, ordered, and efficient structure. But when working from Python, manipulating globals can sometimes feel closer to a low-level API than to the natural habits of the language.

The iris-global-reference project provides a Python layer on top of IRIS globals. Its goal is simple: make access to globals more readable, more idiomatic, and easier to integrate into modern Python code, without hiding the underlying hierarchical model.
Suggested tags: InterSystems IRIS, Python, Embedded Python, Globals, JSON
Why This Project?
In ObjectScript, globals are natural:
set ^demo("players",1)="Babe Ruth"
set ^demo("players",2)="Cy Young"
In Python, we often want to write something closer to a dictionary:
team["players", "1"] = "Babe Ruth"
print(team["players"]["1"])
This is exactly what iris-global-reference provides with the GlobalReference class.
The project targets several use cases:
- manipulate IRIS globals with a Pythonic syntax;
- easily traverse a global tree;
- convert globals to Python dictionaries or JSON;
- import dictionaries or JSON into IRIS;
- use the same API in Embedded Python or from a remote connection;
- wrap common operations such as
set,get,kill,$ORDER,$QUERY, and transactions.
Installation
The package is available with pip:
pip install iris-global-reference
To use it directly from an IRIS Python terminal, you can also install it into the instance Python directory:
pip install iris-global-reference --target=<mgr_dir>/python
First Example
Here is a minimal example using a ^demo global:
from iris_global import GlobalReference
team = GlobalReference("^demo")
team.kill()
team.set((), "Baseball")
team["name"] = "Boston Red Sox"
team.set(("players", "1"), "Babe Ruth")
team.set(["players", "2"], "Cy Young")
team["players", "3"] = "Ted Williams"
print(team.get(()))
print(team["name"])
print(team["players"]["1"])
The same reference accepts multiple subscript forms: string, list, or tuple. This lets you use the API in whichever style best fits the calling code.
An API Close to Python Dictionaries
GlobalReference exposes explicit methods:
team.set(("players", "1"), "Babe Ruth")
print(team.get(("players", "1")))
team.kill(("players", "1"))
But it also supports familiar Python operations:
team["players", "1"] = "Babe Ruth"
if ("players", "1") in team:
print(team["players"]["1"])
del team["players", "1"]
This syntax is useful for writing more natural application code while staying aligned with the global data model.
Traversing a Global
The project provides several iteration methods:
for key in team.keys():
print(key)
for value in team.values():
print(value)
for key, value in team.items():
print(key, value)
You can also control the traversal:
for subscript in team.subscripts(("players",), children_only=True):
print(subscript, team.get(subscript))
For developers familiar with ObjectScript, order() and query() provide behavior close to $ORDER and $QUERY:
print(team.order(("players", "")))
print(team.query(("players",)))
Exporting a Global to a Dictionary or JSON
One of the project benefits is making round trips between IRIS globals and Python structures easier.
data = team.to_dict()
print(data)
Example result:
{
None: "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young",
"3": "Ted Williams"
}
}
The None key represents the value of the current node. This is necessary because an IRIS global node can have both a value and descendants, while a Python dictionary usually represents either a value or a nested dictionary.
The same content can be exported to JSON:
json_data = team.to_json()
print(json_data)
In JSON, the current node value is represented by default with the _ key:
{
"_": "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young",
"3": "Ted Williams"
}
}
Import works the other way around:
team.from_dict({
None: "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young"
}
})
And for JSON:
team.from_json("""
{
"_": "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young"
}
}
""")
Embedded Python or Remote Connection
The API can be used from Embedded Python without providing a connection:
from iris_global import GlobalReference
team = GlobalReference("^demo")
team["name"] = "Boston Red Sox"
It can also be used from an external Python program with a native IRIS connection:
import iris
from iris_global import GlobalReference
conn = iris.connect("localhost", 1972, "USER", "SuperUser", "SYS")
team = GlobalReference("^demo", connection=conn)
team["name"] = "Boston Red Sox"
print(team["name"])
The project targets the native connection provided by iris.connect(...).
Transactions
Transactions are exposed through a Python context manager:
from iris_global import GlobalReference
team = GlobalReference("^demo")
with team.transaction():
team["name"] = "Boston Red Sox"
team["players", "1"] = "Babe Ruth"
If the block completes successfully, the transaction is committed. If an exception is raised, it is rolled back.
The class can also be used directly with with:
with GlobalReference("^demo") as team:
team["name"] = "Boston Red Sox"
Experimental Array Support
IRIS globals do not have a native array concept in the JSON or Python sense. To support importing and exporting lists, the project uses a serialization convention.
For example:
gref = GlobalReference("^demo")
gref.from_dict({
"name": "example",
"numbers": [1, 2, 3]
})
print(gref.to_dict())
The array is stored in the global with an internal prefix, __array__ by default, then rebuilt as a Python list during export. This part is still experimental, but it already makes exchanges with JSON-like structures more convenient.
Displaying Content Like ZWRITE
For debugging or quickly checking the stored structure, the zw() method returns an output close to ZWRITE:
print(team.zw())
Example:
^demo="Baseball"
^demo("name")="Boston Red Sox"
^demo("players","1")="Babe Ruth"
^demo("players","2")="Cy Young"
This is useful when you want to compare the Python result with what you would write or inspect from ObjectScript.
Quick Comparison with Native APIs
The goal of the project is not to replace the native IRIS APIs, but to add a convenience layer for cases where you are mostly writing Python.
For example, with iris-global-reference:
global_reference.set(("name", 1), "Boston Red Sox")
value = global_reference.get(("name", 1))
With a native API, the argument order and subscript handling can be different. This library standardizes usage around a Python convention: the node path first, then the value.
When Should You Use This Project?
iris-global-reference is especially useful if you:
- develop with Embedded Python and InterSystems IRIS;
- write Python scripts that need to read or populate globals;
- want to expose global data as JSON;
- want to manipulate IRIS hierarchical structures with Python dictionaries;
- want to prototype quickly without writing a lot of ObjectScript;
- need a more readable API for common global operations.
Roadmap
The current roadmap includes:
- more advanced array support;
- more complete binary data support;
- IRIS types such as listbuild, vector, PVA, or bit;
- support for multidimensional variables.
Testing the Project
The repository contains a test suite. To run it:
python -m pytest
Conclusion
iris-global-reference is a small library, but it solves a concrete problem: making IRIS globals more pleasant to manipulate from Python.
It preserves the fundamental operations of the IRIS model while adding an experience close to Python dictionaries, practical JSON conversions, iterators, and usage from both Embedded Python and remote connections.
For developers working at the intersection of InterSystems IRIS and Python, it is a simple tool to try and an easy one to integrate into scripts, prototypes, or more structured applications.
Links:
Comments
until the OEX review is approved by admin