Exemple #1
0
def workflow_validate(ctx, file):
    """Validate given REANA specification file."""
    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
    try:
        load_reana_spec(click.format_filename(file))
        click.echo(
            click.style(
                'File {filename} is a valid REANA specification file.'.format(
                    filename=click.format_filename(file)),
                fg='green'))

    except ValidationError as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(click.style(
            '{0} is not a valid REANA specification:\n{1}'.format(
                click.format_filename(file), e.message),
            fg='red'),
                   err=True)
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(click.style(
            'Something went wrong when trying to validate {}'.format(file),
            fg='red'),
                   err=True)
Exemple #2
0
def workflow_validate(ctx, file, environments, pull):  # noqa: D301
    """Validate workflow specification file.

    The `validate` command allows to check syntax and validate the reana.yaml
    workflow specification file.

    Examples: \n
    \t $ reana-client validate -f reana.yaml
    """
    logging.debug("command: {}".format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug("{param}: {value}".format(param=p, value=ctx.params[p]))
    try:
        load_reana_spec(
            click.format_filename(file),
            skip_validate_environments=not environments,
            pull_environment_image=pull,
        )

    except ValidationError as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        display_message(
            "{0} is not a valid REANA specification:\n{1}".format(
                click.format_filename(file), e.message),
            msg_type="error",
        )
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        display_message(
            "Something went wrong when trying to validate {}".format(file),
            msg_type="error",
        )
Exemple #3
0
def workflow_validate(ctx, file):  # noqa: D301
    """Validate workflow specification file.

    The `validate` command allows to check syntax and validate the reana.yaml
    workflow specification file.

    Examples: \n
    \t $ reana-client validate -f reana.yaml
    """
    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
    try:
        load_reana_spec(click.format_filename(file))
        click.echo(
            click.style(
                'File {filename} is a valid REANA specification file.'.format(
                    filename=click.format_filename(file)),
                fg='green'))

    except ValidationError as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(click.style(
            '{0} is not a valid REANA specification:\n{1}'.format(
                click.format_filename(file), e.message),
            fg='red'),
                   err=True)
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(click.style(
            'Something went wrong when trying to validate {}'.format(file),
            fg='red'),
                   err=True)
Exemple #4
0
def workflow_validate(
    ctx, file, environments, pull, server_capabilities, access_token
):  # noqa: D301
    """Validate workflow specification file.

    The ``validate`` command allows to check syntax and validate the reana.yaml
    workflow specification file.

    Examples: \n
    \t $ reana-client validate -f reana.yaml
    """
    if server_capabilities:
        if access_token:
            check_connection(lambda: None)()
        else:
            display_message(ERROR_MESSAGES["missing_access_token"], msg_type="error")
            ctx.exit(1)
    logging.debug("command: {}".format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug("{param}: {value}".format(param=p, value=ctx.params[p]))
    try:
        load_reana_spec(
            click.format_filename(file),
            access_token=access_token,
            skip_validate_environments=not environments,
            pull_environment_image=pull,
            server_capabilities=server_capabilities,
        )

    except (ValidationError, REANAValidationError) as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        display_message(
            "{0} is not a valid REANA specification:\n{1}".format(
                click.format_filename(file), e.message
            ),
            msg_type="error",
        )
        sys.exit(1)
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        display_message(
            "Something went wrong when trying to validate {}".format(file),
            msg_type="error",
        )
        sys.exit(1)
Exemple #5
0
def download_files(ctx, workflow, filenames,
                   output_directory, access_token):  # noqa: D301
    """Download workspace files.

    The `download` command allows to download workspace files. By default, the
    files specified in the workflow specification as outputs are downloaded.
    You can also specify the individual files you would like to download, see
    examples below. Note that downloading directories is not yet supported.

    Examples: \n
    \t $ reana-client download # download all output files \n
    \t $ reana-client download mydata.tmp outputs/myplot.png
    """
    from reana_client.api.client import download_file

    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))

    if not filenames:
        reana_spec = load_reana_spec(os.path.join(get_workflow_root(),
                                     'reana.yaml'),
                                     False)
        if 'outputs' in reana_spec:
            filenames = reana_spec['outputs'].get('files') or []

    if workflow:
        for file_name in filenames:
            try:
                binary_file = download_file(workflow,
                                            file_name,
                                            access_token)

                logging.info('{0} binary file downloaded ... writing to {1}'.
                             format(file_name, output_directory))

                outputs_file_path = os.path.join(output_directory, file_name)
                if not os.path.exists(os.path.dirname(outputs_file_path)):
                    os.makedirs(os.path.dirname(outputs_file_path))

                with open(outputs_file_path, 'wb') as f:
                    f.write(binary_file)
                click.secho(
                    'File {0} downloaded to {1}.'.format(
                        file_name, output_directory),
                    fg='green')
            except OSError as e:
                logging.debug(traceback.format_exc())
                logging.debug(str(e))
                click.echo(
                    click.style('File {0} could not be written.'.
                                format(file_name),
                                fg='red'), err=True)
            except Exception as e:
                logging.debug(traceback.format_exc())
                logging.debug(str(e))
                click.echo(click.style('File {0} could not be downloaded: {1}'.
                                       format(file_name, e), fg='red'),
                           err=True)
Exemple #6
0
def download_files(ctx, workflow, filenames, output_directory, access_token):
    """Download workflow workspace file(s)."""
    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))

    if not access_token:
        click.echo(click.style(ERROR_MESSAGES['missing_access_token'],
                               fg='red'),
                   err=True)
        sys.exit(1)

    if not filenames:
        reana_spec = load_reana_spec(
            os.path.join(get_workflow_root(), 'reana.yaml'), False)
        if 'outputs' in reana_spec:
            filenames = reana_spec['outputs'].get('files') or []

    if workflow:
        for file_name in filenames:
            try:
                binary_file = download_file(workflow, file_name, access_token)

                logging.info(
                    '{0} binary file downloaded ... writing to {1}'.format(
                        file_name, output_directory))

                outputs_file_path = os.path.join(output_directory, file_name)
                if not os.path.exists(os.path.dirname(outputs_file_path)):
                    os.makedirs(os.path.dirname(outputs_file_path))

                with open(outputs_file_path, 'wb') as f:
                    f.write(binary_file)
                click.secho('File {0} downloaded to {1}.'.format(
                    file_name, output_directory),
                            fg='green')
            except OSError as e:
                logging.debug(traceback.format_exc())
                logging.debug(str(e))
                click.echo(click.style(
                    'File {0} could not be written.'.format(file_name),
                    fg='red'),
                           err=True)
            except Exception as e:
                logging.debug(traceback.format_exc())
                logging.debug(str(e))
                click.echo(click.style(
                    'File {0} could not be downloaded: {1}'.format(
                        file_name, e),
                    fg='red'),
                           err=True)
Exemple #7
0
def workflow_create(ctx, file, name, skip_validation,
                    access_token):  # noqa: D301
    """Create a new workflow.

    The `create` command allows to create a new workflow from reana.yaml
    specifications file. The file is expected to be located in the current
    working directory, or supplied via command-line -f option, see examples
    below.

    Examples: \n
    \t $ reana-client create\n
    \t $ reana-client create -w myanalysis\n
    \t $ reana-client create -w myanalysis -f myreana.yaml\n
    """
    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))

    # Check that name is not an UUIDv4.
    # Otherwise it would mess up `--workflow` flag usage because no distinction
    # could be made between the name and actual UUID of workflow.
    if is_uuid_v4(name):
        click.echo(click.style('Workflow name cannot be a valid UUIDv4',
                               fg='red'),
                   err=True)
    if not access_token:
        click.echo(click.style(ERROR_MESSAGES['missing_access_token'],
                               fg='red'),
                   err=True)
        sys.exit(1)
    try:
        reana_specification = load_reana_spec(click.format_filename(file),
                                              skip_validation)
        logging.info('Connecting to {0}'.format(
            current_rs_api_client.swagger_spec.api_url))
        response = create_workflow(reana_specification, name, access_token)
        click.echo(click.style(response['workflow_name'], fg='green'))
        # check if command is called from wrapper command
        if 'invoked_by_subcommand' in ctx.parent.__dict__:
            ctx.parent.workflow_name = response['workflow_name']
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(click.style('Workflow could not be created: \n{}'.format(
            str(e)),
                               fg='red'),
                   err=True)
        if 'invoked_by_subcommand' in ctx.parent.__dict__:
            sys.exit(1)
Exemple #8
0
def workflow_create(ctx, file, name, skip_validation,
                    access_token):  # noqa: D301
    """Create a new workflow.

    The `create` command allows to create a new workflow from reana.yaml
    specifications file. The file is expected to be located in the current
    working directory, or supplied via command-line -f option, see examples
    below.

    Examples: \n
    \t $ reana-client create\n
    \t $ reana-client create -w myanalysis\n
    \t $ reana-client create -w myanalysis -f myreana.yaml\n
    """
    from reana_client.api.client import create_workflow
    from reana_client.utils import get_api_url

    logging.debug("command: {}".format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug("{param}: {value}".format(param=p, value=ctx.params[p]))

    # Check that name is not an UUIDv4.
    # Otherwise it would mess up `--workflow` flag usage because no distinction
    # could be made between the name and actual UUID of workflow.
    if is_uuid_v4(name):
        click.echo(click.style("Workflow name cannot be a valid UUIDv4",
                               fg="red"),
                   err=True)
    try:
        reana_specification = load_reana_spec(click.format_filename(file),
                                              skip_validation)
        logging.info("Connecting to {0}".format(get_api_url()))
        response = create_workflow(reana_specification, name, access_token)
        click.echo(click.style(response["workflow_name"], fg="green"))
        # check if command is called from wrapper command
        if "invoked_by_subcommand" in ctx.parent.__dict__:
            ctx.parent.workflow_name = response["workflow_name"]
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(
            click.style("Cannot create workflow {}: \n{}".format(name, str(e)),
                        fg="red"),
            err=True,
        )
        if "invoked_by_subcommand" in ctx.parent.__dict__:
            sys.exit(1)
Exemple #9
0
def workflow_create(ctx, file, name, skip_validation, access_token):
    """Create a REANA compatible workflow from REANA spec file."""
    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))

    # Check that name is not an UUIDv4.
    # Otherwise it would mess up `--workflow` flag usage because no distinction
    # could be made between the name and actual UUID of workflow.
    if is_uuid_v4(name):
        click.echo(
            click.style('Workflow name cannot be a valid UUIDv4', fg='red'),
            err=True)
    if not access_token:
        click.echo(
            click.style(ERROR_MESSAGES['missing_access_token'],
                        fg='red'), err=True)
        sys.exit(1)
    try:
        reana_specification = load_reana_spec(click.format_filename(file),
                                              skip_validation)
        logging.info('Connecting to {0}'.format(
            current_rs_api_client.swagger_spec.api_url))
        response = create_workflow(reana_specification,
                                   name,
                                   access_token)
        click.echo(click.style(response['workflow_name'], fg='green'))
        # check if command is called from wrapper command
        if 'invoked_by_subcommand' in ctx.parent.__dict__:
            ctx.parent.workflow_name = response['workflow_name']
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(
            click.style('Workflow could not be created: \n{}'
                        .format(str(e)), fg='red'),
            err=True)
        if 'invoked_by_subcommand' in ctx.parent.__dict__:
            sys.exit(1)
Exemple #10
0
def workflow_restart(
    ctx, workflow, access_token, parameters, options, file
):  # noqa: D301
    """Restart previously run workflow.

    The ``restart`` command allows to restart a previous workflow on the same
    workspace.

    Note that workflow restarting can be used in a combination with operational
    options ``FROM`` and ``TARGET``. You can also pass a modified workflow
    specification with ``-f`` or ``--file`` flag.

    You can furthermore use modified input prameters using ``-p`` or
    ``--parameters`` flag and by setting additional operational options using
    ``-o`` or ``--options``.  The input parameters and operational options can be
    repetitive.

    Examples: \n
    \t $ reana-client restart -w myanalysis.42 -p sleeptime=10 -p myparam=4 \n
    \t $ reana-client restart -w myanalysis.42 -p myparam=myvalue\n
    \t $ reana-client restart -w myanalysis.42 -o TARGET=gendata\n
    \t $ reana-client restart -w myanalysis.42 -o FROM=fitdata
    """
    from reana_client.utils import get_api_url
    from reana_client.api.client import (
        get_workflow_parameters,
        get_workflow_status,
        start_workflow,
    )

    logging.debug("command: {}".format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug("{param}: {value}".format(param=p, value=ctx.params[p]))

    parsed_parameters = {
        "input_parameters": parameters,
        "operational_options": options,
        "restart": True,
    }
    if file:
        parsed_parameters["reana_specification"] = load_reana_spec(
            click.format_filename(file)
        )
    if workflow:
        if parameters or options:
            try:
                if "reana_specification" in parsed_parameters:
                    workflow_type = parsed_parameters["reana_specification"][
                        "workflow"
                    ]["type"]
                    original_parameters = (
                        parsed_parameters["reana_specification"]
                        .get("inputs", {})
                        .get("parameters", {})
                    )
                else:
                    response = get_workflow_parameters(workflow, access_token)
                    workflow_type = response["type"]
                    original_parameters = response["parameters"]

                parsed_parameters["operational_options"] = validate_operational_options(
                    workflow_type, parsed_parameters["operational_options"]
                )
                parsed_parameters["input_parameters"] = validate_input_parameters(
                    parsed_parameters["input_parameters"], original_parameters
                )

            except REANAValidationError as e:
                display_message(e.message, msg_type="error")
                sys.exit(1)
            except Exception as e:
                display_message(
                    "Could not apply given input parameters: "
                    "{0} \n{1}".format(parameters, str(e)),
                    msg_type="error",
                )
        try:
            logging.info("Connecting to {0}".format(get_api_url()))
            response = start_workflow(workflow, access_token, parsed_parameters)
            workflow = response["workflow_name"] + "." + str(response["run_number"])
            current_status = get_workflow_status(workflow, access_token).get("status")
            display_message(
                get_workflow_status_change_msg(workflow, current_status),
                msg_type="success",
            )
        except Exception as e:
            logging.debug(traceback.format_exc())
            logging.debug(str(e))
            display_message(
                "Cannot start workflow {}: \n{}".format(workflow, str(e)),
                msg_type="error",
            )
            if "invoked_by_subcommand" in ctx.parent.__dict__:
                sys.exit(1)
Exemple #11
0
def _load_reana_specification(reana_file_path: str) -> Dict:
    return load_reana_spec(
        format_filename(reana_file_path),
        access_token=REANA_ACCESS_TOKEN,
        skip_validation=True,
    )
Exemple #12
0
def upload_files(ctx, workflow, filenames, access_token):
    """Upload files and directories to workflow workspace."""
    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))

    if not access_token:
        click.echo(click.style(ERROR_MESSAGES['missing_access_token'],
                               fg='red'),
                   err=True)
        sys.exit(1)

    if not filenames:
        reana_spec = load_reana_spec(
            os.path.join(get_workflow_root(), 'reana.yaml'), False)
        if 'inputs' in reana_spec:
            filenames = []
            filenames += [
                os.path.join(get_workflow_root(), f)
                for f in reana_spec['inputs'].get('files') or []
            ]
            filenames += [
                os.path.join(get_workflow_root(), d)
                for d in reana_spec['inputs'].get('directories') or []
            ]

    if workflow:
        for filename in filenames:
            try:
                response = upload_to_server(workflow, filename, access_token)
                for file_ in response:
                    if file_.startswith('symlink:'):
                        click.echo(
                            click.style('Symlink resolved to {}. Uploaded'
                                        ' hard copy.'.format(
                                            file_[len('symlink:'):]),
                                        fg='green'))
                    else:
                        click.echo(
                            click.style(
                                'File {} was successfully uploaded.'.format(
                                    file_),
                                fg='green'))
            except FileNotFoundError as e:
                logging.debug(traceback.format_exc())
                logging.debug(str(e))
                click.echo(click.style(
                    'File {0} could not be uploaded: {0} does not exist.'.
                    format(filename),
                    fg='red'),
                           err=True)
                if 'invoked_by_subcommand' in ctx.parent.__dict__:
                    sys.exit(1)
            except FileUploadError as e:
                logging.debug(traceback.format_exc())
                logging.debug(str(e))
                click.echo(click.style(
                    'Something went wrong while uploading {0}.\n{1}'.format(
                        filename, str(e)),
                    fg='red'),
                           err=True)
                if 'invoked_by_subcommand' in ctx.parent.__dict__:
                    sys.exit(1)
            except Exception as e:
                logging.debug(traceback.format_exc())
                logging.debug(str(e))
                click.echo(click.style(
                    'Something went wrong while uploading {}'.format(filename),
                    fg='red'),
                           err=True)
                if 'invoked_by_subcommand' in ctx.parent.__dict__:
                    sys.exit(1)
Exemple #13
0
def workflow_restart(ctx, workflow, access_token, parameters, options,
                     file):  # noqa: D301
    """Restart previously run workflow.

    The `restart` command allows to restart a previous workflow on the same
    workspace.

    Note that workflow restarting can be used in a combination with operational
    options ``FROM`` and ``TARGET``. You can also pass a modified workflow
    specification with ``-f`` or `--file`` flag.

    You can furthermore use modified input prameters using `-p` or
    `--parameters` flag and by setting additional operational options using
    `-o` or `--options`.  The input parameters and operational options can be
    repetitive.

    Examples: \n
    \t $ reana-client restart -w myanalysis.42 -p sleeptime=10 -p myparam=4 \n
    \t $ reana-client restart -w myanalysis.42 -p myparam=myvalue\n
    \t $ reana-client restart -w myanalysis.42 -o TARGET=gendata\n
    \t $ reana-client restart -w myanalysis.42 -o FROM=fitdata
    """
    from reana_client.utils import get_api_url
    from reana_client.api.client import (get_workflow_parameters,
                                         get_workflow_status, start_workflow)
    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))

    parsed_parameters = {
        'input_parameters': parameters,
        'operational_options': options,
        'restart': True
    }
    if file:
        parsed_parameters['reana_specification'] = \
            load_reana_spec(click.format_filename(file))
    if workflow:
        if parameters or options:
            try:
                if 'reana_specification' in parsed_parameters:
                    workflow_type = \
                        parsed_parameters['reana_specification']['workflow'][
                            'type']
                    original_parameters = \
                        parsed_parameters['reana_specification'].get(
                            'inputs', {}).get('parameters', {})
                else:
                    response = get_workflow_parameters(workflow, access_token)
                    workflow_type = response['type']
                    original_parameters = response['parameters']

                parsed_parameters['operational_options'] = \
                    validate_operational_options(
                        workflow_type,
                        parsed_parameters['operational_options'])
                parsed_parameters['input_parameters'] = \
                    validate_input_parameters(
                        parsed_parameters['input_parameters'],
                        original_parameters)

            except REANAValidationError as e:
                click.secho(e.message, err=True, fg='red')
                sys.exit(1)
            except Exception as e:
                click.secho('Could not apply given input parameters: '
                            '{0} \n{1}'.format(parameters, str(e)),
                            err=True)
        try:
            logging.info('Connecting to {0}'.format(get_api_url()))
            response = start_workflow(workflow, access_token,
                                      parsed_parameters)
            workflow = response['workflow_name'] + '.' + \
                str(response['run_number'])
            current_status = get_workflow_status(workflow,
                                                 access_token).get('status')
            click.secho(get_workflow_status_change_msg(workflow,
                                                       current_status),
                        fg='green')
        except Exception as e:
            logging.debug(traceback.format_exc())
            logging.debug(str(e))
            click.echo(click.style('Cannot start workflow {}: \n{}'.format(
                workflow, str(e)),
                                   fg='red'),
                       err=True)
            if 'invoked_by_subcommand' in ctx.parent.__dict__:
                sys.exit(1)
Exemple #14
0
def upload_files(ctx, workflow, filenames, access_token):  # noqa: D301
    """Upload files and directories to workspace.

    The `upload` command allows to upload workflow input files and
    directories. The SOURCES argument can be repeated and specifies which files
    and directories are to be uploaded, see examples below. The default
    behaviour is to upload all input files and directories specified in the
    reana.yaml file.

    Examples: \n
    \t $ reana-client upload -w myanalysis.42 \n
    \t $ reana-client upload -w myanalysis.42 code/mycode.py
    """
    from reana_client.api.client import upload_to_server

    logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
    for p in ctx.params:
        logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))

    if not filenames:
        reana_spec = load_reana_spec(os.path.join(get_workflow_root(),
                                     'reana.yaml'),
                                     False)
        if 'inputs' in reana_spec:
            filenames = []
            filenames += [os.path.join(get_workflow_root(), f)
                          for f in reana_spec['inputs'].get('files') or []]
            filenames += [os.path.join(get_workflow_root(), d)
                          for d in reana_spec['inputs'].
                          get('directories') or []]

    if workflow:
        if filenames:
            for filename in filenames:
                try:
                    response = upload_to_server(workflow,
                                                filename,
                                                access_token)
                    for file_ in response:
                        if file_.startswith('symlink:'):
                            click.echo(
                                click.style('Symlink resolved to {}. Uploaded'
                                            ' hard copy.'.
                                            format(file_[len('symlink:'):]),
                                            fg='green'))
                        else:
                            click.echo(
                                click.style('File {} was successfully '
                                            'uploaded.'.format(file_),
                                            fg='green'))
                except FileNotFoundError as e:
                    logging.debug(traceback.format_exc())
                    logging.debug(str(e))
                    click.echo(
                        click.style(
                            'File {0} could not be uploaded: {0} does not'
                            ' exist.'.format(filename),
                            fg='red'),
                        err=True)
                    if 'invoked_by_subcommand' in ctx.parent.__dict__:
                        sys.exit(1)
                except FileUploadError as e:
                    logging.debug(traceback.format_exc())
                    logging.debug(str(e))
                    click.echo(
                        click.style(
                            'Something went wrong while uploading {0}.\n{1}'.
                            format(filename, str(e)),
                            fg='red'),
                        err=True)
                    if 'invoked_by_subcommand' in ctx.parent.__dict__:
                        sys.exit(1)
                except Exception as e:
                    logging.debug(traceback.format_exc())
                    logging.debug(str(e))
                    click.echo(
                        click.style(
                            'Something went wrong while uploading {}'.
                            format(filename),
                            fg='red'),
                        err=True)
                    if 'invoked_by_subcommand' in ctx.parent.__dict__:
                        sys.exit(1)