Source code for tools.system_interface

# =========================================================================

# Module: tools/system_interface.py

# Author: Henry R. Winterbottom

# Email: henry.winterbottom@noaa.gov

# This program is free software: you can redistribute it and/or modify
# it under the terms of the respective public license published by the
# Free Software Foundation and included with the repository within
# which this application is contained.

# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# =========================================================================

"""
Module
------

    system_interface.py

Description
-----------

    This module contains functions to perform various system-level
    tasks.

Functions
---------

    _get_stack()

        This function defines the calling application stack frame.

    app_path(app)

        This function invokes the POSIX UNIX command function to retrieve
        the path to the application specified upon entry.

    chown(path, user, group=None)

        This function changes the ownership credentials for the
        specified file path.

    get_app_path(app)

        This function collects the path for the specified application;
        if the path cannot be determined, NoneType is returned.

    get_pid()

        This function returns the current process integer
        identification.

    sleep(seconds=0)

        This function allows specific calling applications to suspend
        execution for a specified number of seconds.

    task_exit()

        This function (gracefully) exits the respective application
        and returns a status code of 0 (i.e., success).

    user()

        This method returns the login name of the user.

Author(s)
---------

    Henry R. Winterbottom; 03 December 2022

History
-------

    2022-12-03: Henry Winterbottom -- Initial implementation.

"""

# ----

# pylint: disable=consider-using-with
# pylint: disable=redefined-outer-name
# pylint: disable=unused-variable

# ----

__author__ = "Henry R. Winterbottom"
__maintainer__ = "Henry R. Winterbottom"
__email__ = "henry.winterbottom@noaa.gov"

# ----

import getpass
import inspect
import os
import shutil
import subprocess
import sys
import time
from typing import List, Union

from utils.logger_interface import Logger

# ----

# Define all available functions.
__all__ = ["app_path", "chown", "get_app_path", "get_pid", "sleep", "task_exit", "user"]

# ----

logger = Logger(caller_name=__name__)

# ----


def _get_stack() -> List:
    """
    Description
    -----------

    This function defines the calling application stack frame.

    Returns
    -------

    stack: List

        A Python list containing the calling application stack frame.

    """

    # Collect the calling application stack frame.
    stack = inspect.stack()

    return stack


# ----


[docs]def app_path(app: str) -> Union[str, None]: """ Description ----------- This function invokes the POSIX UNIX command function to retrieve the path to the application specified upon entry. Parameters ---------- app: str A Python string specifying the name of the application for which the path is to be determined. Returns ------- path: Union[str, None] A Python string specifying the path determined for the application name specified upon entry; if no path for the respective application name can be determined NoneType is returned. """ # Query the run-time environment in order to collect the path for # the application name specified upon entry. cmd = ["command", "-V", app] proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE) (out, err) = proc.communicate() # Collect the run-time environment path from the query for the # application name specified upon entry. if len(out) > 0: path = out.rstrip().decode("utf-8").split()[2] else: path = None return path
# ----
[docs]def chown(path: str, user: str, group: str = None) -> None: """ Description ----------- This function changes the ownership credentials for the specified file path. Parameters ---------- path: str A Python string specifying the file path for which to change the ownership credentials. user: str A Python string specifying the host name for the user to be used for the file path ownership credentials. Keywords -------- group: str A Python string specifying the host group name to be user for the path owner credentials. """ # Change the ownership credentials for the specified file path in # accordance with the parameter values provided upon entry. shutil.chown(path=path, user=user, group=group)
# ----
[docs]def get_app_path(app: str) -> Union[str, None]: """ Description ----------- This function collects the path for the specified application; if the path cannot be determined, NoneType is returned. Parameters ---------- app: str A Python string specifying the name of the application for which to return the respective path. Returns ------- app_path: Union[str, None] A Python string specifying the path to the application name provided upon entry; if the application path cannot be determined, this value is NoneType. """ # Collect the application path. app_path = shutil.which(app) return app_path
# ----
[docs]def get_pid() -> int: """ Description ----------- This function returns the current process integer identification. Returns ------- pid: int A Python integer specifying the current process integer identification. """ # Collect the current process integer identifier. pid = os.getpid() return pid
# ----
[docs]def sleep(seconds: int = 0) -> None: """ Description ----------- This function allows specific calling applications to suspend execution for a specified number of seconds. Keywords -------- seconds: int, optional A Python integer specifying the number of seconds for which to suspend execution. """ # Suspend execution for the specified number of seconds. time.sleep(seconds)
# ----
[docs]def task_exit() -> None: """ Description ----------- This function (gracefully) exits the respective application and returns a status code of 0 (i.e., success). """ # Define the calling application stack frame. stack = _get_stack() # Define calling application attributes. [module, lineno] = (stack[2][1], stack[2][2]) # Gracefully exit task. msg = f"Task exit called from file {module} line number {lineno}." logger.warn(msg=msg) sys.exit(0)
# ----
[docs]def user() -> str: """ Description ----------- This method returns the login name of the user. Returns ------- username: str A Python string specifying the login name of the user. """ # Query the POSIX UNIX environment to determine the user invoking # this function. username = getpass.getuser() return username