While working with mainframe systems in todays world, it can make a lot of sense to try and integrate it with other languages or control it from the “outside”. This enabled me to simplify tasks such as automated testing, continous integration and deployment, and a few smaller tasks that would have taken way longer if they were done manually. In this post, I’ll show how I used Python to orchestrate jobs on a z/OS-system through FTP.

The documentation for using FTP with python is pretty straight forward. To connect to your z/OS-system, create an FTP-object and use the login-method if authentication is required:

from ftplib import FTP
ftp = FTP('my-zos.internal')
ftp.login('username', 'password')

Now we can change into a sensible PDS and upload the JCL-file that we want to execute through the same ftp-object that we created earlier:

ftp.cwd('LIB.JCL')

with open('super_job.jcl', 'rb') as f:
	content = f.read()
	ftp.storlines(f'STOR SUPERJOB', f)

The last part now is to interface with JES through FTP. JES allows us to trigger or schedule a job. The IBM-Documentation explains this pretty well. To interact with JES, we tell our FTP-connection that the next command will be for JES:

ftp.voidcmd('site file=JES')

Now we trigger the job and store the output of the job-run, all in a single command. With retrlines we retrieve the previously uploaded JCL-file, which then gets passed to JES (due to the command from before). JES then executes the job and returns the joblog to our FTP retrlines-command, which we can then store locally in our script through a callback.

joblog = []
def callback(line):
	joblog.append(line.strip())
	
ftp.retrlines("RETR 'LIB.JCL(SUPERJOB)'", callback)

joblog is now a list of all the lines in the joblog.

With this technique, you can now interact with z/OS through python. In my opinion this opens up a lot of possiblities that I didn’t know were possible before, and it helped me a lot in making my work more efficient!