Written by

Sales Engineer at InterSystems
Article Guillaume Rongier · May 12 7m read

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