Hybrid Scripting: Running Python from JCL and JCL from Python on z/OS
Hamidali Kottaparamban
Senior Solutions Architect | Mainframe Modernization Expert
Mainframes (specifically those running the z/OS operating system) are renowned for their robust job scheduling capabilities, often driven by Job Control Language (JCL). On the other hand, Python is a modern, versatile language, increasingly popular in data science and automation. Interestingly, these two worlds can be bridged, allowing seamless interaction between Python and JCL on z/OS.
Submitting JCL from Python
If you have the zoautil_py package installed within your z/OS Unix System Services (USS) environment, submitting JCL from Python becomes surprisingly easy. Let's look at an example:
from zoautil_py import jobs, datasets
jcl_template = """
//Z35240T JOB (ACCT#1) 'JCL FROM PYTHON',
// CLASS=X,
// MSGCLASS=X
//*
//STEP1 EXEC PGM=SORT
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SORTIN DD PATH='/z/z35240/files/mydatafile.dat'
//SORTOUT DD DSN=Z35240.SORTOUT1,
// DISP=(NEW,CATLG),
// SPACE=(TRK,(10,10)),
// DCB=(RECFM=FB,LREC=80,BLKSIZE=800),
// UNIT=3390
//*
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(1,50,,30X)
/*
//*
"""
mypds = datasets.hlq() + "TEMP.JCLS"
this_job = mypds + "(TESTJOB)"
datasets.write(dataset=this_job, content=jcl_template)
job_info = jobs.submit(this_job)
print(f"JobId : {job_info.id}")
print(f"Job Name : {job_info.name}")
print(f"Job Owner : {job_info.owner}")
job_info.wait()
job_info.refresh()
print(f"Job Status : {job_info.status}")
print(f"Job RC : {job_info.rc}")
In this code, we demonstrate how to:
Power of 'zoautil_py': This package empowers us to interact with z/OS resources—datasets, jobs, and more—programmatically from Python, simplifying management.
Running Python from JCL
Let's flip the script! Here are a few techniques to run Python directly from JCL:
1. BPXBATCH: Use the BPXBATCH program to directly execute a shell script (.sh). This shell script can contain your command to run python - python /z/z35240/files/python_script.py
//STEP1???EXEC PGM=BPXBATCH
//STDERR??DD?SYSOUT=*?
//STDOUT??DD?SYSOUT=*
//STDPARM??DD?*
sh /z/z35240/files/runpyfromjcl.sh
/*
2. Direct Echo and Pipe: Here we just echo the python script file to the USS shell to execute.
//STEP1 EXEC PGM=BPXBATCH
//STDERR DD SYSOUT=*
//STDOUT DD SYSOUT=*
//STDPARM DD *
sh echo "python /z/z35240/files/python_script.py" | sh
/*
3. Inline Commands ('dcat'): Create a PDS member and put your call to python script as we usually do in terminal. This is a slight variation from our method 1. We just place the script call in a PDS member and use the dcat command to fetch this member and pipe its contents to a shell for further execution.
领英推荐
//STEP1???EXEC PGM=BPXBATCH
//STDERR??DD?SYSOUT=*?
//STDOUT??DD?SYSOUT=*
//STDPARM??DD?*
SH dcat "Z35240.SOURCE.SCRIPTS(CALLPY)" | sh
/*
4. Direct Echo and Pipe: This gets interesting now. Ditch those USS files altogether. Create a PDS member containing your Python script. Use the dcat command to fetch this member and pipe its contents to Python for execution.
//STEP1???EXEC PGM=BPXBATCH
//STDERR??DD?SYSOUT=*?
//STDOUT??DD?SYSOUT=*
//STDPARM??DD?*
SH dcat "Z35240.SOURCE.SCRIPTS(PYSCRPT)" | python
/*
In this case "Z35240.SOURCE.SCRIPTS(PYSCRPT)" has my full python script as sample below.
from datetime import datetime
print(f'Test Script Runtime : {datetime.now()}')
Real-World Applications
Why integrate Python and JCL? Here are a few compelling use cases:
Further Exploration
I encourage the community to do further experiments! Remember, running Python on z/OS provides access to a rich array of Python libraries. Consider more complex scenarios of interactions between JCL and Python to fully unlock the potential of this hybrid approach!
Let me know your comments!
References:
Legacy Modernization & Automation Specialist
6 个月Thanks for the article. I tried to execute python from JCL using option 4 (Direct Echo and Pipe) but all I got is one line output "-c dcat "myuserid.SOURCE.SCRIPTS(PYSCRPT)" | python" in STDOUT.
Student at University of Tehran
6 个月Perfect
Good at 0's and 1's
7 个月Is there a way where can we can do similar functionalitu from rexx using bpwunix but zoautil.so is not found error is received where it works fine with jcl
Project leader DB2 13 for z/OS migration Project Leader at Atos
8 个月I tried your Submitting JCL from Python sample, but this is not working: from zoautil_py import jobs, datasets Response: Q047220:/u/Q047220:$> python subjcl.py????????????????????? Traceback (most recent call last):??????????????????????? ?File "/u/Q047220/subjcl.py", line 29, in <module>??????????????? TypeError: write() missing 1 required positional argument: 'dataset_name'???? Q047220:/u/Q047220:$>????????? Any hints/tips??????????????????????
Engineering Manager @ Cognizant || Ex-Principal Global Services || Ex-capgemini
11 个月Great one Hamid !!! Will certainly try and let you know