
Initial Release
Submission for the 2026 InterSystems Technology Innovation Contest
Zero custom backend code · Direct integration with the official SysAdmin REST API · A modern IRIS management console deployable in under 3 minutes
The built-in InterSystems IRIS Management Portal is feature-complete but its interface is traditional and its key operational metrics are scattered across multiple menu levels, making it hard for operators to grasp instance health at a glance.
Built on top of the official SysAdmin REST API exposed in IRIS 2026.2 (/api/admin, following the version-shipped mainspec_v2.json OpenAPI 3.0 specification), LuminIRIS is a dark-themed, glassmorphism-style single-pane management console. Five management scenarios - system monitoring, web applications, user permissions, scheduled tasks, and security auditing - are reachable from one entry point. All data comes live from the official APIs with no secondary storage.
| # | Highlight | Description |
|---|---|---|
| 1 | Zero-backend portal, zero intrusion | 3 static files make up the complete portal; no tables created, no resident service processes - zero burden on production instances. The one server-side class is only the small Embedded Python dispatcher |
| 2 | Strict official-spec compliance | Every endpoint strictly maps to mainspec_v2.json (OpenAPI 3.0); request paths, response structures, and status codes all follow the official contract |
| 3 | JWT dual-token secure auth | access_token lives only 60 seconds, refresh_token approx. 15 minutes; the frontend silently refreshes every 50 seconds, auto-retries on 401, and revokes tokens on logout |
| 4 | Async task polling pattern | The audit endpoint returns 202 Accepted + Location; the frontend polls /v1/async-result until State=Finished, fully implementing the official async-task protocol |
| 5 | Modern glassmorphism UI | Deep-tech background, animated gradient glow, frosted-glass cards, animated progress bars, terminal-style log stream, status tags, responsive layout |
| 6 | Same-origin, environment-agnostic | API base is the relative path /api/admin, same-origin as the portal; no CORS configuration, zero changes when switching instances, ports, or upgrading major versions |
| 7 | Dual-standard delivery | Ships both a Docker image (one-click experience) and an IPM package (publishable to Open Exchange, one-command install for production) |
| 8 | Embedded Python console | An interactive Python terminal inside the portal that executes code directly in the IRIS process via ##class(%SYS.Python).Run, with full iris module access to globals/SQL - contest bonus +3 |
| 9 | Battle-tested + reproducible platform bug reports | Every integration issue on the live 2026.2 instance is logged with root cause/fix in Section 6; two deterministic Embedded Python defects (%SYS.Python.Run() broken status semantics in both directions) are formally reported with a one-command repro script in Section 7 / bug-repro/ for the contest bonus |
+----------------------------------------------------+
| Browser |
| +----------------------------------------------+ |
| | LuminIRIS SPA | |
| | index.html + style.css + main.js (3 files) | |
| | Glassmorphism UI . JWT client . Async poll | |
| +---------------------+------------------------+ |
+------------------------|---------------------------+
| HTTPS / same-origin / Authorization: Bearer
v
+----------------------------------------------------+
| InterSystems IRIS 2026.2 . Web Gateway :52773 |
| |
| /csp/user/luminiris/ Static portal assets |
| /api/admin/login JWT login / refresh / logout |
| /api/admin/info Instance info |
| /api/admin/v2/monitor/ Performance / resources |
| /api/admin/v2/web-apps Web applications |
| /api/admin/v2/security/* Users / roles / audit |
| /api/admin/v2/tasks Scheduled tasks |
| /api/admin/v2/processes Running processes |
| /api/admin/v1/async-result 202 async result poll |
| /luminiris/api/python/* Embedded Python (shipped class|
| Luminiris.PythonApi) |
| |
| (All monitoring data comes from official |
| IRIS built-in services; the only custom |
| server-side code is the small Python REST |
| dispatcher class Luminiris.PythonApi) |
+----------------------------------------------------+
| Module | Function | Official Endpoint |
|---|---|---|
| Auth | Login / auto-refresh / logout | POST /api/admin/login, /refresh, /logout |
| Overview | Instance version, namespaces, current user | GET /api/admin/info |
| Overview | Cache hit ratio, Global refs/sec, Set+Kill, disk reads/writes | GET /api/admin/v2/monitor/dashboard/main |
| Overview | System resource Seize dynamic bars | GET /api/admin/v2/monitor/dashboard/system-resources |
| Web & API | CSP/Web app names, namespace, auth methods, enabled status | GET /api/admin/v2/web-apps |
| Permissions | User list (full name, type, enabled/disabled) | GET /api/admin/v2/security/users |
| Permissions | Role tag cloud | GET /api/admin/v2/security/roles |
| Tasks | Scheduled tasks (type, namespace, next scheduled time) | GET /api/admin/v2/tasks |
| Tasks | Running processes (PID, namespace, routine, state) | GET /api/admin/v2/processes?maxRows=50 |
| Audit Logs | Security audit records (terminal-style log stream, 202 async fetch) | POST /api/admin/v2/security/audit/records -> GET /v1/async-result |
| Embedded Python | Python runtime info + interactive code execution inside IRIS | GET /luminiris/api/python/info, POST /luminiris/api/python/exec (%CSP.REST class Luminiris.PythonApi using ##class(%SYS.Python).Run) |
// access_token is valid for only 60s; the client silently swaps it for a
// new one using refresh_token every 50 seconds.
setInterval(() => fetch('/api/admin/refresh', {
method: 'POST',
body: JSON.stringify({ refresh_token })
}), 50_000);
Audit queries are long-running. The official API returns 202 Accepted with the result address in the Location response header, and the frontend polls until completion:
const res = await fetch('/api/admin/v2/security/audit/records',
{ method: 'POST', headers: authHeader() });
if (res.status === 202) {
const loc = res.headers.get('location'); // /api/admin/v1/async-result?id=...
// Poll until result.State === "Finished", then read result.Result
}
The official SysAdmin API does not expose a Python execution endpoint, so LuminIRIS ships one small ObjectScript class, Luminiris.PythonApi (extends %CSP.REST), deployed as a dedicated REST application at /luminiris/api. It invokes the IRIS Embedded Python engine directly via ##class(%SYS.Python).Run(...). This is the only custom server-side code in the project and it exists solely to surface the Embedded Python feature. Using a %CSP.REST class (instead of a raw .csp file) gives explicit, reliable URL mapping via an XData route table.
Two routes are exposed:
GET /luminiris/api/python/info - returns Python version, implementation, platform, the IRIS version via the iris module, and a list of installed data-science packages (numpy, pandas, sklearn, …).POST /luminiris/api/python/exec with JSON body {"code": "..."} - executes arbitrary Python code inside IRIS and returns captured stdout/stderr. User code is passed through a scratch global (^LUM.PYCODE) to avoid quoting issues; stdout is captured with io.StringIO and returned through ^LUM.PYOUT (runtime info uses ^LUM.PYINFO). The globals are deleted immediately after each call.Implementation note: results travel through globals via the native Python binding
iris.gref('^NAME')[None](theiris.globalspackage is an empty placeholder;iris.grefis the real API). This deliberately avoids ObjectScript sequential-file I/O, which would hijack the CSP output device.
From the browser, the operator gets a full interactive console:
import iris
print('IRIS version :', iris.cls('%SYSTEM.Version').GetVersion())
g = iris.gref('^LUM.DEMO') # read/write an IRIS global directly
g[None] = 'hello from Embedded Python'
print('global value:', g[None])
This demonstrates real Embedded Python usage (contest bonus: +3 points) - the Python code runs inside the IRIS process, has full access to the iris module to read/write globals, call ObjectScript, and run SQL, with zero external Python interpreter required.
End-to-end validation completed on a live InterSystems IRIS 2026.2 (Build 221U) instance:
| Module | Measured Data |
|---|---|
| Overview | Correctly identified version 2026.2 Build 221U; cache efficiency 90.83%; Global refs 316/sec |
| Web & API | Loaded 22 web applications |
| Permissions | 9 users, 37 roles |
| Tasks | 16 scheduled tasks, 28 running processes |
| Audit Logs | Async-task mode successfully returned 358 real audit records |
| Embedded Python | GET /python/info reported CPython 3.11.9 on Windows-10 / AMD64 with the iris module loaded; POST /python/exec ran print(2**10) returning 1024, and invalid code correctly returned a ZeroDivisionError traceback with status:"error" |
The Embedded Python integration was built and validated entirely against a live IRIS 2026.2 instance. Every issue below was reproduced, root-caused, and fixed; the final configuration in this repository is the result of this process. They are documented here to save other developers the same investigation time.
| # | Symptom | Root Cause | Fix |
|---|---|---|---|
| 1 | GET /python/info returned HTTP 200 with an empty body |
The first implementation passed results back through a sequential file (OPEN/USE/READ/CLOSE). The ObjectScript USE <device> command redirected the current output device, so the final Write ret.%ToJSON() went to the file instead of the HTTP response |
Removed all sequential-file I/O from the CSP method. Results now travel through IRIS globals, which never touch the output device |
| 2 | iris.globals.set(...) failed silently - “returned no data” |
iris.globals exists but is an empty placeholder package (dir(iris.globals) → []). The real native binding is iris.gref |
Discovered via dir(iris) inside ##class(%SYS.Python).Shell(); switched to iris.gref('^NAME')[None] = value for root-node access |
| 3 | %SYS.Python.Run() returned an opaque error #00 (no error text) even when the script ran perfectly - and later testing showed the inverse as well (success status when Python raised) |
The returned %Status is unreliable in both directions; Python-side exceptions are swallowed and not translated into the status text. Confirmed as two platform defects - see Section 7 |
The Python wrapper captures its own traceback.format_exc() into a global; ObjectScript judges success by actual output (a Traceback marker means error), not by the %Status |
| 4 | REST dispatch silently ignored: requests 404 / DispatchMap undefined |
%CSP.REST is only visible in the %SYS namespace. Compiling the class in USER and setting Namespace="USER" meant the route XData never loaded. Additionally Type=2 (REST application) is mandatory - without it DispatchClass is ignored |
Compile PythonApi.cls in %SYS and create the app with Namespace=%SYS, Type=2, DispatchClass=Luminiris.PythonApi (mirrors the built-in /api/admin) |
| 5 | REST app returned 401/403 regardless of configuration | The %SYS namespace enforces security: AutheEnabled=64 (unauthenticated) → 403; 4 or 0 → 401. Anonymous dispatch is impossible there |
AutheEnabled=32 (JWT) + JWTAuthEnabled=1; the portal calls the endpoint same-origin with the Bearer token it already holds from /api/admin/login |
| 6 | iris.system.version() → AttributeError: module 'iris_system' has no attribute 'version' |
The Python-side API surface differs from the ObjectScript class naming; the function does not exist under that path | Use the documented class bridge: iris.cls('%SYSTEM.Version').GetVersion(), with a nested fallback for portability |
| 7 | Status dot on the “ready” badge rendered as mojibake in the browser | The badge used a literal Unicode character (●, U+25CF) in main.js. On a Chinese-locale (GBK) Web Gateway the byte stream was interpreted with the wrong charset before the browser executed it |
Replaced every non-ASCII character in the three front-end files with ASCII Unicode escapes ("●" → "\u25CF", "—" → "\u2014"). The shipped front end is now 100% ASCII source, immune to gateway charset assumptions |
| 8 | Copied static files returned 404 under /csp/user/luminiris/ |
/csp/user had LockCSPName=1, which only serves explicitly registered CSP names; freshly copied physical files are rejected |
Set LockCSPName=0 (and AutheEnabled=65 for anonymous static access) in both setup.script and the bootstrap installer |
| 9 | Embedded Python failed on bare-metal Windows (%SYS.Python unavailable) |
IRIS 2026.2 on Windows neither ships nor installs Python, and the CPF helpers assumed in older guides ($System.Config.Set(), GetCPFParameter()) do not exist in 2026.2 |
Install Python 3.11 for all users, then edit iris.cpf [config] directly: PythonRuntimeLibrary=...python311.dll and PythonRuntimeLibraryVersion=3.11; restart IRIS (see Deployment prerequisites) |
| 10 | Audit query initially returned nothing usable | The audit endpoint is asynchronous: it answers 202 Accepted with a Location header instead of the records |
Implemented the official poll loop against /api/admin/v1/async-result until State=Finished; 358 records then loaded successfully |
Methodology note: when the Python binding behaved unexpectedly, the fastest diagnostic was the in-process shell (Do ##class(%SYS.Python).Shell()) plus dir(iris) - the discrepancy between documented/assumed APIs (iris.globals, iris.system.version) and the actual runtime surface was immediately visible.
For the contest item “Find a bug in Embedded Python”, two independently reproducible defects were found, verified on the live build (IRIS 2026.2 Build 221U + CPython 3.11.9 on Windows), and written up with full reproduction steps:
%SYS.Python.Run() returns an ERROR %Status (#00, no description) when the Python code executes successfully - e.g. Run("x=1") yields $system.Status.IsError(sc)=1.%SYS.Python.Run() returns a SUCCESS %Status when the Python code raises an exception, and the Python exception message/traceback is discarded - e.g. Run("raise Exception('boom')") yields IsError(sc)=0; the marker string appears nowhere in the status.A third, lower-severity observation (the empty iris.globals placeholder wrapper that raises a misleading NameError) is included as an additional finding.
Full reports (Title / Environment / Steps / Expected / Actual / Impact / Workaround) and a one-command reproduction script are in:
https://github.com/Brett-git-app/LuminIRIS/blob/main/bug-repro/BUG_REPORTS.md - formal bug reportshttps://github.com/Brett-git-app/LuminIRIS/blob/main/bug-repro/ep_bug_repro.isc - deterministic reproduction script (Get-Content ep_bug_repro.isc | iris session IRIS -U USER)Both Run() issues are deterministic and need no configuration beyond a working Embedded Python installation. The workarounds (self-capturing traceback into an iris.gref global; judging success from payload instead of the returned status) are already implemented in Luminiris.PythonApi.
The portal is pure static assets served directly by the IRIS Web Gateway. Two standard deployment methods are available - Docker and IPM. Choose either one.
Prerequisite: InterSystems IRIS 2026.2 or later (provides the official SysAdmin API
/api/admin).Embedded Python prerequisite (Python tab only): the five management modules need nothing extra. The optional Embedded Python console additionally requires a configured Python runtime:
- Docker / official Linux kits - no action needed; the
iris-communityimage ships with Embedded Python preconfigured (Python 3.x inside the image, verified against the documented containersys.path).- Bare-metal Windows - Windows does not ship Python and the IRIS installer does not add it. Install 64-bit Python 3.11 for all users, stop IRIS, then add to the
[config]section ofiris.cpfand restart:Verify withPythonRuntimeLibrary=C:\Program Files\Python311\python311.dll PythonRuntimeLibraryVersion=3.11Do ##class(%SYS.Python).Shell()(the banner must showPython 3.11.x ... on win32). Optional packages:python -m pip install --target "<install-dir>\mgr\python" numpy pandas.- Bare-metal Linux - install the Python 3 version supported by your IRIS release (e.g.
python3.10on Ubuntu 22.04); the IRIS installer links it automatically.
Base image is the official public image intersystemsdc/iris-community:2026.2 (same tag available at containers.intersystems.com/intersystems/iris-community:2026.2), no login required, pinned to the 2026.2 GA release in the Dockerfile. (Note: image tags use -em for Extended Maintenance releases, not “embedded Python” - Embedded Python is already built into every current community image.)
A1. Docker Compose (one command)
cd luminiris
docker compose up -d --build
A2. Native Docker commands
docker build -t luminiris:2.1.0 .
docker run -d \
--name luminiris \
-p 52773:52773 \
-p 1972:1972 \
-e IRIS_PASSWORD=SYS \
luminiris:2.1.0
During the image build, setup.script runs automatically: it installs the portal module via IPM (deploying the static assets), configures /csp/user to allow anonymous access to the static assets, compiles Luminiris.PythonApi in the %SYS namespace, and creates the /luminiris/api REST application (Type=2, JWT-secured exactly like /api/admin). Monitoring data endpoints remain JWT-protected (no security risk). After the container starts, IRIS is launched automatically by the official iris-main entrypoint.
IPM (InterSystems Package Manager, formerly zpm) is InterSystems’ official package manager. The project’s module.xml declares a ClassRoot (src/cls) and a CSP resource (src/csp, deployed to <install-dir>/csp/user/luminiris/). IPM itself cannot register web applications, so one extra code-driven step is required afterwards: run the bundled install.isc bootstrap (it is idempotent - it compiles Luminiris.PythonApi in %SYS, creates the JWT-secured /luminiris/api REST application, and enables anonymous access to the static pages; copying the already-deployed files again is harmless). See Method C for its one-line invocation, or run the equivalent terminal commands:
ZN "%SYS"
do $system.OBJ.Load("/your/path/luminiris/src/cls/Luminiris/PythonApi.cls","ck")
do $system.OBJ.Load("/your/path/luminiris/src/install/Luminiris.Installer.cls","ck")
do ##class(Luminiris.Installer).EnsureRestApp()
B1. Install from a local directory
Open an IRIS terminal:
# Linux iris session IRISWindows (default instance name)
iris session IRIS
Then run:
ZN "USER"
zpm "install /your/path/luminiris"
Windows example (place the project in an English-only path):
ZN "USER"
zpm "install C:\contest\luminiris"
If the instance does not yet have IPM enabled, first load the installer shipped with the version:
do $system.OBJ.Load($System.Util.InstallDirectory()_"dist/install/misc/zpm.xml","ck") zpm zpm:USER> repo -reset-defaults
B2. Install from Open Exchange (after publication)
Once the work is published to InterSystems Open Exchange, any instance can install it directly:
ZN "USER"
zpm "install luminiris"
B3. Uninstall
ZN "USER"
zpm "uninstall luminiris"
When IPM is not available, use the bundled minimal bootstrap script (loads a single Luminiris.Installer class, no other dependencies):
install.isc and change root on line 9 to the absolute path of this project directory (forward slashes work on both Windows and Linux):
set root = "C:/IRIS"
# Linux / macOS / Windows CMD
iris session IRIS -U USER < install.isc
# Windows PowerShell (does not support < redirection; use a pipe)
Get-Content install.isc | iris session IRIS -U USER
The script copies the 3 static files to <install-dir>/csp/user/luminiris/, compiles Luminiris.PythonApi in the %SYS namespace, creates the JWT-secured /luminiris/api REST application, and configures anonymous access to the static pages - all automatically.You can also call it manually from the IRIS terminal:
ZN "USER"
do $system.OBJ.Load("C:/IRIS/src/install/Luminiris.Installer.cls","ck")
do ##class(Luminiris.Installer).Install("C:/IRIS/src/csp")
B4. (Optional) Avoid the double-login under IPM
The IPM method does not modify the instance security configuration. When accessing the static page, you may first see the native IRIS auth prompt and then the portal login. To match the Docker experience (anonymous static pages, data protected by portal JWT), an administrator can run this once in the terminal:
ZN "%SYS"
set p("AutheEnabled")=65 // 1=Password + 64=Unauthenticated
do ##class(Security.Applications).Modify("/csp/user",.p)
After deployment, open in a browser:
http://<server-ip>:52773/csp/user/luminiris/index.html
http://localhost:52773/csp/user/luminiris/index.html
_SYSTEM / SYS (set by IRIS_PASSWORD, change as needed)_SYSTEM)After login you see real-time data for all five modules; tokens auto-refresh every 50 seconds, and you can manually refresh or log out from the top-right corner.
luminiris/
+-- module.xml # IPM package definition (ClassRoot + CSP resource)
+-- package.json # Package metadata
+-- Dockerfile # Built on the official iris-community image
+-- docker-compose.yml # One-click orchestration
+-- setup.script # ObjectScript run during image build (IPM install + REST/security config)
+-- install.isc # Minimal no-IPM bootstrap (change one path to run)
+-- .dockerignore
+-- README.md
+-- bug-repro/ # Embedded Python bug reports (contest bonus), see Section 7
+ +-- BUG_REPORTS.md # Formal reports: Run() status defects + iris.globals wrapper
+ +-- ep_bug_repro.isc # One-command deterministic reproduction script
+-- articles/ # Developer Community announcement articles (English)
+ +-- article-1-luminiris-console-overview.md # Project/architecture showcase
+ +-- article-2-embedded-python-rest-console.md # Embedded Python deep dive + bugs
+-- src/
+-- csp/ # * Portal source (static)
| +-- index.html # Page structure: login overlay + side nav + six modules
| +-- style.css # Dark glassmorphism theme, animations, responsive layout
| +-- main.js # JWT auth, API client, 202 async polling, Python console client
+-- cls/ # * ObjectScript classes (compiled into the namespace)
| +-- Luminiris/
| +-- PythonApi.cls # %CSP.REST dispatcher: Embedded Python info + exec
+-- install/
+-- Luminiris.Installer.cls # Optional bootstrap installer (not needed for IPM/Docker)
Deployment priority: Docker (Method A) -> IPM (Method B) -> bootstrap (Method C). The three methods do not conflict; Methods A and B never use the
Luminiris.Installerclass orinstall.isc(excluded from the image via.dockerignore).
/api/admin/login; tokens are kept in browser memory and expire when the page is closed./luminiris/api/python/*) are also JWT-protected with the same /api/admin token; executing Python in-process is an administrator-level capability, identical in power to the built-in Python shell (%SYS.Python.Shell()), so the portal must only be deployed for trusted admin users.IRIS_PASSWORD / default admin credentials to strong passwords.backdrop-filter, gradient animations, Flex/Grid responsive)