Copy file(s) from device(s) -> local machine.

    @param ctx: The click context paramter, for receiving the object dictionary
              | being manipulated by other previous functions. Needed by any
              | function with the @click.pass_context decorator.
    @type ctx: click.Context
    @param source: the source filepath or dirpath
    @type source: str
    @param destination: the destination filepath or dirpath
    @type destination: str
    @param progress: bool set to True if we should request a progress callback
                   | from the Jaide object. Always set to False when
                   | we're copying to/from multiple devices.
    @type progress: bool

    @returns: None. Functions part of click relating to the command group
            | 'main' do not return anything. Click handles passing context
            | between the functions and maintaing command order and chaining.

def pull(ctx, source, destination, progress):
    """ Copy file(s) from device(s) -> local machine.

    @param ctx: The click context paramter, for receiving the object dictionary
              | being manipulated by other previous functions. Needed by any
              | function with the @click.pass_context decorator.
    @type ctx: click.Context
    @param source: the source filepath or dirpath
    @type source: str
    @param destination: the destination filepath or dirpath
    @type destination: str
    @param progress: bool set to True if we should request a progress callback
                   | from the Jaide object. Always set to False when
                   | we're copying to/from multiple devices.
    @type progress: bool

    @returns: None. Functions part of click relating to the command group
            | 'main' do not return anything. Click handles passing context
            | between the functions and maintaing command order and chaining.
    """
    mp_pool = multiprocessing.Pool(multiprocessing.cpu_count() * 2)
    multi = True if len(ctx.obj['hosts']) > 1 else False
    for ip in ctx.obj['hosts']:
        mp_pool.apply_async(wrap.open_connection, args=(ip,
                            ctx.obj['conn']['username'],
                            ctx.obj['conn']['password'],
                            wrap.pull, [source, destination, progress, multi],
                            ctx.obj['out'],
                            ctx.obj['conn']['connect_timeout'],
                            ctx.obj['conn']['session_timeout'],
                            ctx.obj['conn']['port']), callback=write_out)
    mp_pool.close()
    mp_pool.join()