ZOAU Python APIs

When you install the ZOAU Python language pack, you get access to the ZOAU Python application program interfaces (APIs). To learn more about installing the ZOAU language pack, see Installing and configuring ZOAU.

The Python APIs include several classes and modules. For detailed API reference information, see classes, datasets, jobs, mvscmd, opercmd, zoau_io, and zsystem.

New Python API functionality available in the latest release of ZOAU is described as follows.


Python API changes in ZOAU v1.3

ZOAU v1.3 introduces new capabilities and includes numerous improvements to existing classes, modules, and functions. Some changes are not compatible with previous versions of ZOAU, so if you plan to migrate to ZOAU v1.3 from a prior version, you must understand and perform several steps. To learn more, see Migrating to ZOAU v1.3 from v1.2.x or earlier.


New capabilities in datasets

The datasets module adds the following capabilities. To review the full datasets API, see Python API datasets module.

Listing data sets


In the list_datasets() function, the name_only argument is removed so that the function now only returns a single type. Example:

>>> datasets.list_datasets('ZOAUSER.TEST.*')
[zoautil_py.datasets.Dataset object with name:ZOAUSER.TEST.A,
zoautil_py.datasets.Dataset object with name:ZOAUSER.TEST.B,
zoautil_py.datasets.Dataset object with name:ZOAUSER.TEST.C,
zoautil_py.datasets.Dataset object with name:ZOAUSER.TEST.D]


The new function list_dataset_names() accepts the argument pattern: str to return a list of dataset names as strings rather than as Dataset objects. It also provides the optional migrated: bool method to list migrated datasets. Example:

>>> datasets.list_dataset_names('ZOAUSER.TEST.*', migrated=True)
['ZOAUSER.TEST.A', 'ZOAUSER.TEST.B', 'ZOAUSER.TEST.C', 'ZOAUSER.TEST.D',
'ZOAUSER.TEST.MIGRATED']


For details, see zoautil_py.datasets.list_datasets() and zoautil_py.datasets.list_dataset_names()



Printing dataset attributes


Printing dataset objects with print(Dataset) now returns a string that lists all dataset attributes in a dictionary format. Example:

>>> print(my_dataset)
"{'name': 'ZOAUSER.TEST.PDS', 'organization': 'PO', 'record_format': 'FB',
'volume': '339005', 'block_size': 27920, 'record_length': 80,
'total_space': 5666400, 'used_space': 17816,
'last_referenced': datetime.datetime(2023, 11, 9, 0, 0)}"


Printing dataset objects within another structure, such as lists, now returns a string representation with the object description and dataset name. Example:

>>> mydataset.__repr__()
'zoautil_py.datasets.Dataset object with name:ZOAUSER.TEST.PDS'



New capabilities in jobs

The jobs module adds the following capabilities. To review the full jobs API, see Python API jobs module.


Checking the existence of a job


The new function zoautil_py.jobs.exists() determines whether a job exists on the system and returns True if a job with the given ID is found. Example:

# Job J0778714 is currently running on the system.
>>> jobs.exists('J0778714')
True
# Job J0799999 does not exist.
>>> jobs.exists('J0799999')
False


For details, see zoautil_py.jobs.exists().



Submitting jobs and returning only the job ID


Use the new function zoautil.jobs.submit_return_job_id() to return only the submitted job ID as a string rather than fetching the job information into a Job object. Note that this function verifies only that the job is queued; it does not verify any other steps. For details, see zoautil_py.jobs.submit_return_job_id().



Returning basic and extended fields when listing jobs


By default, the previous jobs.listing() method retrieved all fields available from the ZOAU jls utility. However, because the work required to retrieve the programname field can impact performance, attributes in the job class are now categorized to provide more control over the information returned. Specifically, the programname field, along with the corresponding Python API job class attribute program_name, are moved to an extended job field category that does not get retrieved by default. To learn more, see Fetching single jobs.

Basic and extended fields are as follows:

Basic job fields

jls field name Python API job class attribute name
owner owner
name name
id job_id
status status
ccode return_code
jobclass job_class
serviceclass service_class
priority priority
asid asid
creationdate creation_datetime (merged)
creationtime creation_datetime (merged)
queueposition queue_position
jobtype job_type

Extended job fields

jls field name Python API job class attribute name
programname program_name


Fetching single jobs


Use the jobs.fetch() function to fetch a Job object for a given job ID.

In the following example, the job_id attribute is a string, and the include_extended attribute is set with the default boolean value of False, which retrieves everything but program_name:

jobs.fetch(job_id: Union[str, None] = None,
           include_extended: bool = False, **kwargs) -> Job:


The following examples show the result of fetching a job.

In this example of default fetch behavior, the program_name attribute name is not retrieved with other job information, and so is assigned a value of None:

>>> print(jobs.fetch('J0778714'))
{'job_id': 'J0778714', 'name': 'ZOAUSERSL', 'job_class': 'A', 'asid': 0,
'priority': 1, 'queue_position': 10569, 'owner': 'ZOAUSER',
'program_name': None, 'return_code': '0000', 'status': 'CC',
'service_class': None, 'purged': False,
'creation_datetime': datetime.datetime(2023, 11, 12, 14, 57, 31), 'job_type': 'JOB'}


In this next example, the parameter include_extended is set to True, which retrieves the program_name value (BPXBATCH) along with other available information:

>>> print(jobs.fetch('J0778714', include_extended=True))
{'job_id': 'J0778714', 'name': 'ZOAUSERSL', 'job_class': 'A', 'asid': 0,
'priority': 1, 'queue_position': 10569, 'owner': 'ZOAUSER',
'program_name': 'BPXBATCH', 'return_code': '0000', 'status': 'CC',
'service_class': None, 'purged': False,
'creation_datetime': datetime.datetime(2023, 11, 12, 14, 57, 31), 'job_type': 'JOB'}


To limit the maximum number of times to query the job for information, use the fetch_max_retries parameter.

For details, see zoautil_py.jobs.fetch().



Fetching multiple jobs


Use the jobs.fetch_multiple() function to fetch a list of jobs that match the given filters. Example:

def fetch_multiple(
    job_id: Union[str, None] = None,
    job_owner: Union[str, None] = None,
    job_name: Union[str, None] = None,
    include_extended: bool = False,
    **kwargs,
) -> list[Job]:


The following example fetches multiple jobs submitted by a single user with the ID 'ZOAUser':

>>> jobs.fetch_multiple(job_owner='ZOAUSER')
[zoautil_py.jobs.Job object with ID:J0778714,
 zoautil_py.jobs.Job object with ID:J0778774]


Additional parameters are available. For details, see zoautil_py.jobs.fetch_multiple().



Fetching job information as a JSON dictionary


Unlike the fetch_multiple() method, which returns most or all fields from the jls utility, the new jobs.fetch_multiple_as_json() method returns fields based on a custom query or a default set. Because this new method bypasses the Job class constructor and returns a dictionary extracted from the JSON output of jls, using jobs.fetch_multiple_as_json() can help you fine-tune your results and improve performance. Example:


def fetch_multiple_as_json(
    job_id: Union[str, None] = None,
    job_owner: Union[str, None] = None,
    job_name: Union[str, None] = None,
    included_fields: Union[List[str], None] = BASIC_JOB_FIELDS[0:5],
    **kwargs,
) -> dict:


The returned JSON dictionary includes pairs of parameters and values that match your custom query or the default set. In the following example, the default set is returned. Note that the jls field name is used for each name-value pair:

>>> jobs.fetch_multiple_as_json(job_id='J0778714')
{'J0778714': {'owner': 'ZOAUSER', 'name': 'ZOAUSERSL', 'id': 'J0778714',
'status': 'CC', 'ccode': '0000'}}


This next example shows the result of fetching only the job name and class. Notice that the return type is a dictionary, not a Job object:

>>> jobs.fetch_multiple_as_json(job_id='J0778714',
                                included_fields=['name','jobclass'])
{'J0778714': {'name': 'ZOAUSERSL', 'jobclass': 'A', 'id': 'J0778714'}}
>>> type(jobs.fetch_multiple_as_json('J0778714'))
<class 'dict'>


For details, see zoautil_py.jobs.fetch_multiple_as_json().



Retrieving and updating all fields


A new class method Job.fetch_extended_fields() is available to retrieve and update all fields. For details, see zoautil_py.jobs.fetch_extended_fields().



Printing jobs


Printing job objects with print(Job) now returns a string that lists all the job attributes in a dictionary format. Example:

>>> myjob.__str__()
"{'job_id': 'J0659026', 'name': 'IBMUSERSL', 'job_class': 'A', 'asid': 0,
'priority': 1, 'queue_position': 1095, 'owner': 'IBMUSER',
'program_name': None, 'return_code': '0000', 'status': 'CC',
'service_class': None, 'purged': False,
'creation_datetime': datetime.datetime(2023, 11, 2, 15, 50, 50), 'job_type': 'JOB'}"


Printing job objects within another structure, such as lists, now returns a string representation with the object description and job ID. Example:

>>> myjob.__repr__()
'zoautil_py.jobs.Job object with ID:J0659026'



Canceling and purging jobs


You can use the new function zoautil_py.jobs.purge() to purge a job from the system, which produces the same result as calling zoautil_py.jobs.cancel(purge_job=True). If you're migrating to ZOAU v1.3 from a prior version, note that the the new jobs.purge() function and the updated jobs.cancel() function always return None, whereas the return code from jcan was previously used.

The 'zoautil_py.jobs.cancel' function includes a new purge_job boolean attribute that is set to False by default. It gets set to True when the new jobs.purge() function is used. Note that this variable is exclusive to the Python API and is not reflected on the system.

Both the new zoautil_py.jobs.purge() function and the existing zoautil_py.jobs.cancel() function now include a confirm_timeout parameter. If confirm_timeout retains its default setting of zero seconds (int = 0), the function does not attempt to confirm that the purge or cancel operation is successful. Example:

def cancel(
    job_id: str, purge_job: bool = False, confirm_timeout: int = 0, **kwargs
) -> None:


If a confirmation timeout is specified, the script waits until the job appears as purged or canceled on the system. If the timeout is reached and the job still exists on the system, a JobPurgeConfirmException or a JobCancelConfirmException is now raised to communicate that the purge or cancelation of the job cannot be confirmed. However, neither of these exceptions implies that the job will not be purged or canceled soon.

If the script attempts to cancel a job that is already canceled, a warning is now issued. If a given job ID is not found, a JobPurgeException or JobCancelException is now raised.

The following examples shows the new warnings and exceptions raised by zoautil_py.jobs.cancel() and zoautil_py.jobs.purge().

In this example, a warning is raised by zoautil_py.jobs.cancel():

>>> jobs.cancel('J0778713')
>>> jobs.cancel('J0778713')
/home/zoauser/env/lib/python3.10/site-packages/zoautil_py/jobs.py:558:
UserWarning: Cannot cancel job J0778713, job is already cancelled.
  warnings.warn(f"Cannot cancel job {job_id}, job is already cancelled.")


In this next example, an exception is raised by zoautil_py.jobs.purge():

>>> jobs.purge('J0778713')
>>> jobs.purge('J0778713')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/zoauser/env/lib/python3.10/site-packages/zoautil_py/jobs.py", line 649, in purge
    raise JobPurgeException(response)
zoautil_py.exceptions.JobPurgeException: [ZOAUResponse]
        rc: 8
        response_format: UTF-8
        stdout_response:
        stderr_response: BGYSC3802I Job not found.

        command: jcan P "*" "J0778713"


For details about canceling jobs, see zoautil_py.jobs.cancel(). For details about purging jobs, see zoautil_py.jobs.purge().