Skip to content

Commit bae10c2

Browse files
committed
add jython migration documentation
1 parent 0e26551 commit bae10c2

2 files changed

Lines changed: 125 additions & 0 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
`regi-python` is the Python bridge over the REGI Java libraries.
44

5+
The client-facing Python API is documented in [docs/PYTHON_API.md](docs/PYTHON_API.md).
6+
For script migration guidance, see [docs/JYTHON_TO_JPYPE_MIGRATION.md](docs/JYTHON_TO_JPYPE_MIGRATION.md).
7+
58
## What Lives Where
69

710
- `regi-headless/src/main/python/regi_python/`

docs/JYTHON_TO_JPYPE_MIGRATION.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Migrating REGI Headless District Jython Scripts to `regi_python`
2+
3+
This guide captures the script migration pattern used in the district-scripts history,
4+
moving from old Python 2 Jython-style top-level scripts to the current JPype-based `regi_python` bridge.
5+
6+
## Core Migration Pattern
7+
8+
Old scripts typically:
9+
10+
- imported Java classes at module import time
11+
- accessed global `registry` and calculation objects at top level
12+
- executed the calculation immediately when the file was loaded
13+
- relied on shell wrappers such as `RunHeadlessJython.bat` or `.sh`
14+
15+
New scripts should:
16+
17+
- import `regi_session` and `run_headless` from `regi_python`
18+
- move Java imports inside a callback that runs after the JVM starts
19+
- wrap the calculation logic in a function such as `run_calculations(registry)`
20+
- keep `registry.getCalculation(...)` and Java method calls unchanged
21+
- end with `if __name__ == "__main__": with regi_session(): run_headless(run_calculations)`
22+
23+
## Before And After
24+
25+
### Before
26+
27+
```python
28+
from java.util import Calendar
29+
from java.util import TimeZone
30+
31+
gateCalc = registry.getCalculation(1.0, "Gate Flow")
32+
timeZone = TimeZone.getTimeZone("US/Central")
33+
startCal = Calendar.getInstance(timeZone)
34+
endCal = Calendar.getInstance(timeZone)
35+
gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total")
36+
```
37+
38+
### After
39+
40+
```python
41+
from regi_python import regi_session, run_headless
42+
43+
44+
def run_calculations(registry):
45+
from java.util import Calendar
46+
from java.util import TimeZone
47+
48+
gateCalc = registry.getCalculation(1.0, "Gate Flow")
49+
timeZone = TimeZone.getTimeZone("US/Central")
50+
startCal = Calendar.getInstance(timeZone)
51+
endCal = Calendar.getInstance(timeZone)
52+
gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total")
53+
54+
55+
if __name__ == "__main__":
56+
with regi_session():
57+
run_headless(run_calculations)
58+
```
59+
60+
## Translation Rules
61+
62+
### 1. Move Java imports inside the callback
63+
64+
JPype-backed imports should happen after the JVM starts.
65+
Put them inside `run_calculations(registry)` or a nested helper only called from that callback.
66+
67+
This is the biggest behavioral difference from Jython scripts.
68+
69+
### 2. Keep the registry lookup pattern
70+
71+
The migration does not change the scriptable REGI API. Calls like these stay the same:
72+
73+
- `registry.getNames(1.0)`
74+
- `registry.getCalculation(1.0, "Inflow")`
75+
- `registry.getCalculation(1.0, "Gate Flow")`
76+
77+
The change is only the Python wrapper around those calls.
78+
79+
### 3. Convert top-level execution into a callback
80+
81+
Scripts must be converted from immediate execution to a `run_calculations()` function.
82+
That keeps import side effects out of the module.
83+
84+
### 4. Replace Python 2 `print` statements
85+
86+
Old scripts often contain lines like:
87+
88+
```python
89+
print "Error Computing Flow Group"
90+
```
91+
92+
Update these to Python 3 syntax:
93+
94+
```python
95+
print("Error Computing Flow Group")
96+
```
97+
98+
### 5. Keep optional Java-side logging calls
99+
100+
Calls such as `LoggingOptions.setDbMessageLevel(2)` and `LoggingOptions.setMetricsEnabled(True)` still belong in the script if the district workflow depends on them. They do not move to `regi_python`; they simply live inside the callback now.
101+
102+
### 6. Remove the shell wrapper
103+
104+
The old `RunHeadlessJython` launchers are no longer needed. The Python file itself becomes the entry point:
105+
106+
```python
107+
if __name__ == "__main__":
108+
with regi_session():
109+
run_headless(run_calculations)
110+
```
111+
112+
## Project-Specific Examples
113+
114+
The current district scripts show the same migration shape across several script families:
115+
116+
- `SWF/InflowCalcComputedInflow.py`
117+
- `SWF/InflowCalcComputeEvapAsFlow.py`
118+
- `SWF/GateSettings.py`
119+
- `SWT/GateFlowGroup1.py`
120+
- `SWL/Big3-GateFlow.py`
121+
122+
The differences between them are the calculation names, location lists, and optional logging or flow-group loops. The migration pattern itself is the same.

0 commit comments

Comments
 (0)