<commit_before># -*- coding: utf-8 -*-
'''
The client module is used to create a client connection to the publisher
The data structure needs to be:
    {'enc': 'clear',
     'load': {'fun': '<mod.callable>',
              'arg':, ('arg1', 'arg2', ...),
              'tgt': '<glob or id>',
              'key': '<read in the key file>'}
'''

# The components here are simple, and they need to be and stay simple, we
# want a client to have 3 external concerns, and maybe a forth configurable
# option.
# The concerns are:
# 1. Who executes the command?
# 2. What is the function being run?
# 3. What arguments need to be passed to the function?
# 4. How long do we wait for all of the replies?
#
# Import python libs
from __future__ import absolute_import, print_function
import os
import time
import logging
from datetime import datetime

# Import salt libs
import salt.config
import salt.cache
import salt.payload
import salt.transport
import salt.loader
import salt.utils
import salt.utils.args
import salt.utils.event
import salt.utils.minions
import salt.utils.verify
import salt.utils.jid
import salt.syspaths as syspaths
from salt.exceptions import (
    EauthAuthenticationError, SaltInvocationError, SaltReqTimeoutError,
    SaltClientError, PublishError
)

# Import third party libs
import salt.ext.six as six
# pylint: disable=import-error
try:
    import zmq
    HAS_ZMQ = True
except ImportError:
    HAS_ZMQ = False

# Try to import range from https://github.com/ytoolshed/range
HAS_RANGE = False
try:
    import seco.range
    HAS_RANGE = True
except ImportError:
    pass
# pylint: enable=import-error

# Import tornado
import tornado.gen  # pylint: disable=F0401

log = logging.getLogger(__name__)


def get_local_client(
        c_path=os.path.join(syspaths.CONFIG_DIR, 'master'),
        mopts=None,
        skip_perm_errors=False,
        io_loop=None):
    '''
    .. versionadded:: 2014.7.0

    Read in the config and return the correct LocalClient object based on
    the configured transport

    :param IOLoop io_loop: io_loop used for events.
                           Pass in an io_loop if you want asynchronous
                           operation for obtaining events. Eg use of
                           set_event_handler() API. Otherwise, operation
                           will be synchronous.
    '''
    if mopts:
        opts = mopts
    else:
        # Late import to prevent circular import
        import salt.config
        opts = salt.config.client_config(c_path)
    if opts['transport'] == 'raet':
        import salt.client.raet
        return salt.client.raet.LocalClient(mopts=opts)
    # TODO: AIO core is separate from transport
    elif opts['transport'] in ('zeromq', 'tcp'):
        return LocalClient(
            mopts=opts,
            skip_perm_errors=skip_perm_errors,
            io_loop=io_loop)


class LocalClient(object):
    '''
    The interface used by the :command:`salt` CLI tool on the Salt Master

    ``LocalClient`` is used to send a command to Salt minions to execute
    :ref:`execution modules <all-salt.modules>` and return the results to the
    Salt Master.

    Importing and using ``LocalClient`` must be done on the same machine as the
    Salt Master and it must be done using the same user that the Salt Master is
    running as. (Unless :conf_master:`external_auth` is configured and
    authentication credentials are included in the execution).

    .. code-block:: python

        import salt.client

        local = salt.client.LocalClient()
        local.cmd('*', 'test.fib', [10])
    '''<commit_msg>Add a note to LocalClient docs about IOLoops (#35501)<commit_after># -*- coding: utf-8 -*-
'''
The client module is used to create a client connection to the publisher
The data structure needs to be:
    {'enc': 'clear',
     'load': {'fun': '<mod.callable>',
              'arg':, ('arg1', 'arg2', ...),
              'tgt': '<glob or id>',
              'key': '<read in the key file>'}
'''

# The components here are simple, and they need to be and stay simple, we
# want a client to have 3 external concerns, and maybe a forth configurable
# option.
# The concerns are:
# 1. Who executes the command?
# 2. What is the function being run?
# 3. What arguments need to be passed to the function?
# 4. How long do we wait for all of the replies?
#
# Import python libs
from __future__ import absolute_import, print_function
import os
import time
import logging
from datetime import datetime

# Import salt libs
import salt.config
import salt.cache
import salt.payload
import salt.transport
import salt.loader
import salt.utils
import salt.utils.args
import salt.utils.event
import salt.utils.minions
import salt.utils.verify
import salt.utils.jid
import salt.syspaths as syspaths
from salt.exceptions import (
    EauthAuthenticationError, SaltInvocationError, SaltReqTimeoutError,
    SaltClientError, PublishError
)

# Import third party libs
import salt.ext.six as six
# pylint: disable=import-error
try:
    import zmq
    HAS_ZMQ = True
except ImportError:
    HAS_ZMQ = False

# Try to import range from https://github.com/ytoolshed/range
HAS_RANGE = False
try:
    import seco.range
    HAS_RANGE = True
except ImportError:
    pass
# pylint: enable=import-error

# Import tornado
import tornado.gen  # pylint: disable=F0401

log = logging.getLogger(__name__)


def get_local_client(
        c_path=os.path.join(syspaths.CONFIG_DIR, 'master'),
        mopts=None,
        skip_perm_errors=False,
        io_loop=None):
    '''
    .. versionadded:: 2014.7.0

    Read in the config and return the correct LocalClient object based on
    the configured transport

    :param IOLoop io_loop: io_loop used for events.
                           Pass in an io_loop if you want asynchronous
                           operation for obtaining events. Eg use of
                           set_event_handler() API. Otherwise, operation
                           will be synchronous.
    '''
    if mopts:
        opts = mopts
    else:
        # Late import to prevent circular import
        import salt.config
        opts = salt.config.client_config(c_path)
    if opts['transport'] == 'raet':
        import salt.client.raet
        return salt.client.raet.LocalClient(mopts=opts)
    # TODO: AIO core is separate from transport
    elif opts['transport'] in ('zeromq', 'tcp'):
        return LocalClient(
            mopts=opts,
            skip_perm_errors=skip_perm_errors,
            io_loop=io_loop)


class LocalClient(object):
    '''
    The interface used by the :command:`salt` CLI tool on the Salt Master

    ``LocalClient`` is used to send a command to Salt minions to execute
    :ref:`execution modules <all-salt.modules>` and return the results to the
    Salt Master.

    Importing and using ``LocalClient`` must be done on the same machine as the
    Salt Master and it must be done using the same user that the Salt Master is
    running as. (Unless :conf_master:`external_auth` is configured and
    authentication credentials are included in the execution).

    ..note::

        The LocalClient uses a Tornado IOLoop, this can create issues when
        using the LocalClient inside an existing IOLoop. If creating the
        LocalClient in partnership with another IOLoop either create the
        IOLoop before creating the LocalClient, or when creating the IOLoop
        use ioloop.current() which will return the ioloop created by
        LocalClient.

    .. code-block:: python

        import salt.client

        local = salt.client.LocalClient()
        local.cmd('*', 'test.fib', [10])
    '''
{'fraction_non_alphanumeric': 0.08182533438237609, 'fraction_numerical': 0.005900865460267506, 'mean_word_length': 2.7926404773744404, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '82521', 'n_tokens_mistral': 2180, 'n_tokens_neox': 2095, 'n_words': 829}