# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function

import sys

import click
import rhea

from polyaxon_cli.cli.getters.experiment import (
    get_experiment_job_or_local,
    get_project_experiment_or_local
)
from polyaxon_cli.cli.upload import upload
from polyaxon_cli.client import PolyaxonClient
from polyaxon_cli.client.exceptions import PolyaxonHTTPError, PolyaxonShouldExitError
from polyaxon_cli.logger import clean_outputs
from polyaxon_cli.managers.experiment import ExperimentManager
from polyaxon_cli.managers.experiment_job import ExperimentJobManager
from polyaxon_cli.utils import cache
from polyaxon_cli.utils.formatting import (
    Printer,
    dict_tabulate,
    get_meta_response,
    get_resources,
    list_dicts_to_tabulate
)
from polyaxon_cli.utils.log_handler import get_logs_handler
from polyaxon_cli.utils.validation import validate_tags
from polyaxon_client.exceptions import PolyaxonClientException


def get_experiment_details(experiment):  # pylint:disable=redefined-outer-name
    if experiment.description:
        Printer.print_header("Experiment description:")
        click.echo('{}\n'.format(experiment.description))

    if experiment.resources:
        get_resources(experiment.resources.to_dict(), header="Experiment resources:")

    if experiment.declarations:
        Printer.print_header("Experiment declarations:")
        dict_tabulate(experiment.declarations)

    if experiment.last_metric:
        Printer.print_header("Experiment last metrics:")
        dict_tabulate(experiment.last_metric)

    response = experiment.to_light_dict(
        humanize_values=True,
        exclude_attrs=[
            'uuid', 'config', 'project', 'experiments', 'description',
            'declarations', 'last_metric', 'resources', 'jobs', 'run_env'
        ])

    Printer.print_header("Experiment info:")
    dict_tabulate(Printer.add_status_color(response))


@click.group()
@click.option('--project', '-p', type=str, help="The project name, e.g. 'mnist' or 'adam/mnist'.")
@click.option('--experiment', '-xp', type=int, help="The experiment id number.")
@click.pass_context
@clean_outputs
def experiment(ctx, project, experiment):  # pylint:disable=redefined-outer-name
    """Commands for experiments."""
    ctx.obj = ctx.obj or {}
    ctx.obj['project'] = project
    ctx.obj['experiment'] = experiment


@experiment.command()
@click.option('--job', '-j', type=int, help="The job id.")
@click.pass_context
@clean_outputs
def get(ctx, job):
    """Get experiment or experiment job.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples for getting an experiment:

    \b
    ```bash
    $ polyaxon experiment get  # if experiment is cached
    ```

    \b
    ```bash
    $ polyaxon experiment --experiment=1 get
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 1 --project=cats-vs-dogs get
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 1 -p alain/cats-vs-dogs get
    ```

    Examples for getting an experiment job:

    \b
    ```bash
    $ polyaxon experiment get -j 1  # if experiment is cached
    ```

    \b
    ```bash
    $ polyaxon experiment --experiment=1 get --job=10
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 1 --project=cats-vs-dogs get -j 2
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 1 -p alain/cats-vs-dogs get -j 2
    ```
    """

    def get_experiment():
        try:
            response = PolyaxonClient().experiment.get_experiment(user, project_name, _experiment)
            cache.cache(config_manager=ExperimentManager, response=response)
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could not load experiment `{}` info.'.format(_experiment))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

        get_experiment_details(response)

    def get_experiment_job():
        try:
            response = PolyaxonClient().experiment_job.get_job(user,
                                                               project_name,
                                                               _experiment,
                                                               _job)
            cache.cache(config_manager=ExperimentJobManager, response=response)
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could not get job `{}`.'.format(_job))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

        if response.resources:
            get_resources(response.resources.to_dict(), header="Job resources:")

        response = Printer.add_status_color(response.to_light_dict(
            humanize_values=True,
            exclude_attrs=['uuid', 'definition', 'experiment', 'unique_name', 'resources']
        ))
        Printer.print_header("Job info:")
        dict_tabulate(response)

    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))

    if job:
        _job = get_experiment_job_or_local(job)
        get_experiment_job()
    else:
        get_experiment()


@experiment.command()
@click.pass_context
@clean_outputs
def delete(ctx):
    """Delete experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Example:

    \b
    ```bash
    $ polyaxon experiment delete
    ```
    """
    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    if not click.confirm("Are sure you want to delete experiment `{}`".format(_experiment)):
        click.echo('Existing without deleting experiment.')
        sys.exit(1)

    try:
        response = PolyaxonClient().experiment.delete_experiment(
            user, project_name, _experiment)
        # Purge caching
        ExperimentManager.purge()
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not delete experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)

    if response.status_code == 204:
        Printer.print_success("Experiment `{}` was delete successfully".format(_experiment))


@experiment.command()
@click.option('--name', type=str,
              help='Name of the experiment, must be unique within the project, could be none.')
@click.option('--description', type=str, help='Description of the experiment.')
@click.option('--tags', type=str, help='Tags of the experiment, comma separated values.')
@click.pass_context
@clean_outputs
def update(ctx, name, description, tags):
    """Update experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment -xp 2 update --description="new description for my experiments"
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 2 update --tags="foo, bar" --name="unique-name"
    ```
    """
    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    update_dict = {}

    if name:
        update_dict['name'] = name

    if description:
        update_dict['description'] = description

    tags = validate_tags(tags)
    if tags:
        update_dict['tags'] = tags

    if not update_dict:
        Printer.print_warning('No argument was provided to update the experiment.')
        sys.exit(0)

    try:
        response = PolyaxonClient().experiment.update_experiment(
            user, project_name, _experiment, update_dict)
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not update experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)

    Printer.print_success("Experiment updated.")
    get_experiment_details(response)


@experiment.command()
@click.option('--yes', '-y', is_flag=True, default=False,
              help="Automatic yes to prompts. "
                   "Assume \"yes\" as answer to all prompts and run non-interactively.")
@click.pass_context
@clean_outputs
def stop(ctx, yes):
    """Stop experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment stop
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 2 stop
    ```
    """
    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    if not yes and not click.confirm("Are sure you want to stop "
                                     "experiment `{}`".format(_experiment)):
        click.echo('Existing without stopping experiment.')
        sys.exit(0)

    try:
        PolyaxonClient().experiment.stop(user, project_name, _experiment)
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not stop experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)

    Printer.print_success("Experiment is being stopped.")


@experiment.command()
@click.option('--copy', '-c', is_flag=True, default=False,
              help="To copy the experiment before restarting.")
@click.option('--file', '-f', multiple=True, type=click.Path(exists=True),
              help="The polyaxon files to update with.")
@click.option('-u', is_flag=True, default=False,
              help="To upload the repo before restarting.")
@click.pass_context
@clean_outputs
def restart(ctx, copy, file, u):  # pylint:disable=redefined-builtin
    """Restart experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment --experiment=1 restart
    ```
    """
    config = None
    update_code = None
    if file:
        config = rhea.read(file)

    # Check if we need to upload
    if u:
        ctx.invoke(upload, sync=False)
        update_code = True

    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    try:
        if copy:
            response = PolyaxonClient().experiment.copy(
                user, project_name, _experiment, config=config, update_code=update_code)
            Printer.print_success('Experiment was copied with id {}'.format(response.id))
        else:
            response = PolyaxonClient().experiment.restart(
                user, project_name, _experiment, config=config, update_code=update_code)
            Printer.print_success('Experiment was restarted with id {}'.format(response.id))
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not restart experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)


@experiment.command()
@click.option('--file', '-f', multiple=True, type=click.Path(exists=True),
              help="The polyaxon files to update with.")
@click.option('-u', is_flag=True, default=False,
              help="To upload the repo before resuming.")
@click.pass_context
@clean_outputs
def resume(ctx, file, u):  # pylint:disable=redefined-builtin
    """Resume experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment --experiment=1 resume
    ```
    """
    config = None
    update_code = None
    if file:
        config = rhea.read(file)

    # Check if we need to upload
    if u:
        ctx.invoke(upload, sync=False)
        update_code = True

    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    try:
        response = PolyaxonClient().experiment.resume(
            user, project_name, _experiment, config=config, update_code=update_code)
        Printer.print_success('Experiment was resumed with id {}'.format(response.id))
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not resume experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)


@experiment.command()
@click.option('--page', type=int, help="To paginate through the list of jobs.")
@click.pass_context
@clean_outputs
def jobs(ctx, page):
    """List jobs for experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment --experiment=1 jobs
    ```
    """
    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    page = page or 1
    try:
        response = PolyaxonClient().experiment.list_jobs(
            user, project_name, _experiment, page=page)
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not get jobs for experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)

    meta = get_meta_response(response)
    if meta:
        Printer.print_header('Jobs for experiment `{}`.'.format(_experiment))
        Printer.print_header('Navigation:')
        dict_tabulate(meta)
    else:
        Printer.print_header('No jobs found for experiment `{}`.'.format(_experiment))

    objects = [Printer.add_status_color(o.to_light_dict(humanize_values=True))
               for o in response['results']]
    objects = list_dicts_to_tabulate(objects)
    if objects:
        Printer.print_header("Jobs:")
        objects.pop('experiment', None)
        dict_tabulate(objects, is_list_dict=True)


@experiment.command()
@click.option('--job', '-j', type=int, help="The job id.")
@click.option('--page', type=int, help="To paginate through the list of statuses.")
@click.pass_context
@clean_outputs
def statuses(ctx, job, page):
    """Get experiment or experiment job statuses.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples getting experiment statuses:

    \b
    ```bash
    $ polyaxon experiment statuses
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 1 statuses
    ```

    Examples getting experiment job statuses:

    \b
    ```bash
    $ polyaxon experiment statuses -j 3
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 1 statuses --job 1
    ```
    """

    def get_experiment_statuses():
        try:
            response = PolyaxonClient().experiment.get_statuses(
                user, project_name, _experiment, page=page)
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could get status for experiment `{}`.'.format(_experiment))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

        meta = get_meta_response(response)
        if meta:
            Printer.print_header('Statuses for experiment `{}`.'.format(_experiment))
            Printer.print_header('Navigation:')
            dict_tabulate(meta)
        else:
            Printer.print_header('No statuses found for experiment `{}`.'.format(_experiment))

        objects = list_dicts_to_tabulate(
            [Printer.add_status_color(o.to_light_dict(humanize_values=True), status_key='status')
             for o in response['results']])
        if objects:
            Printer.print_header("Statuses:")
            objects.pop('experiment', None)
            dict_tabulate(objects, is_list_dict=True)

    def get_experiment_job_statuses():
        try:
            response = PolyaxonClient().experiment_job.get_statuses(user,
                                                                    project_name,
                                                                    _experiment,
                                                                    _job,
                                                                    page=page)
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could not get status for job `{}`.'.format(job))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

        meta = get_meta_response(response)
        if meta:
            Printer.print_header('Statuses for Job `{}`.'.format(_job))
            Printer.print_header('Navigation:')
            dict_tabulate(meta)
        else:
            Printer.print_header('No statuses found for job `{}`.'.format(_job))

        objects = list_dicts_to_tabulate(
            [Printer.add_status_color(o.to_light_dict(humanize_values=True), status_key='status')
             for o in response['results']])
        if objects:
            Printer.print_header("Statuses:")
            objects.pop('job', None)
            dict_tabulate(objects, is_list_dict=True)

    page = page or 1

    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))

    if job:
        _job = get_experiment_job_or_local(job)
        get_experiment_job_statuses()
    else:
        get_experiment_statuses()


@experiment.command()
@click.option('--job', '-j', type=int, help="The job id.")
@click.option('--gpu', '-g', is_flag=True, help="List experiment GPU resources.")
@click.pass_context
@clean_outputs
def resources(ctx, job, gpu):
    """Get experiment or experiment job resources.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples for getting experiment resources:

    \b
    ```bash
    $ polyaxon experiment -xp 19 resources
    ```

    For GPU resources

    \b
    ```bash
    $ polyaxon experiment -xp 19 resources --gpu
    ```

    Examples for getting experiment job resources:

    \b
    ```bash
    $ polyaxon experiment -xp 19 resources -j 1
    ```

    For GPU resources

    \b
    ```bash
    $ polyaxon experiment -xp 19 resources -j 1 --gpu
    ```
    """

    def get_experiment_resources():
        try:
            message_handler = Printer.gpu_resources if gpu else Printer.resources
            PolyaxonClient().experiment.resources(
                user, project_name, _experiment, message_handler=message_handler)
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could not get resources for experiment `{}`.'.format(_experiment))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    def get_experiment_job_resources():
        try:
            message_handler = Printer.gpu_resources if gpu else Printer.resources
            PolyaxonClient().experiment_job.resources(user,
                                                      project_name,
                                                      _experiment,
                                                      _job,
                                                      message_handler=message_handler)
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could not get resources for job `{}`.'.format(_job))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))

    if job:
        _job = get_experiment_job_or_local(job)
        get_experiment_job_resources()
    else:
        get_experiment_resources()


@experiment.command()
@click.option('--job', '-j', type=int, help="The job id.")
@click.option('--past', '-p', is_flag=True, help="Show the past logs.")
@click.option('--follow', '-f', is_flag=True, default=False,
              help="Stream logs after showing past logs.")
@click.option('--hide_time', is_flag=True, default=False,
              help="Whether or not to hide timestamps from the log stream.")
@click.pass_context
@clean_outputs
def logs(ctx, job, past, follow, hide_time):
    """Get experiment or experiment job logs.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples for getting experiment logs:

    \b
    ```bash
    $ polyaxon experiment logs
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 10 -p mnist logs
    ```

    Examples for getting experiment job logs:

    \b
    ```bash
    $ polyaxon experiment -xp 1 -j 1 logs
    ```
    """

    def get_experiment_logs():
        if past:
            try:
                response = PolyaxonClient().experiment.logs(
                    user, project_name, _experiment, stream=False)
                get_logs_handler(handle_job_info=True,
                                 show_timestamp=not hide_time,
                                 stream=False)(response.content.decode().split('\n'))
                print()

                if not follow:
                    return
            except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
                if not follow:
                    Printer.print_error(
                        'Could not get logs for experiment `{}`.'.format(_experiment))
                    Printer.print_error(
                        'Error message `{}`.'.format(e))
                    sys.exit(1)

        try:
            PolyaxonClient().experiment.logs(
                user,
                project_name,
                _experiment,
                message_handler=get_logs_handler(handle_job_info=True,
                                                 show_timestamp=not hide_time))
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could not get logs for experiment `{}`.'.format(_experiment))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    def get_experiment_job_logs():
        if past:
            try:
                response = PolyaxonClient().experiment_job.logs(
                    user,
                    project_name,
                    _experiment,
                    _job,
                    stream=False)
                get_logs_handler(handle_job_info=True,
                                 show_timestamp=not hide_time,
                                 stream=False)(response.content.decode().split('\n'))
                print()

                if not follow:
                    return
            except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
                if not follow:
                    Printer.print_error(
                        'Could not get logs for experiment `{}`.'.format(_experiment))
                    Printer.print_error(
                        'Error message `{}`.'.format(e))
                    sys.exit(1)

        try:
            PolyaxonClient().experiment_job.logs(
                user,
                project_name,
                _experiment,
                _job,
                message_handler=get_logs_handler(handle_job_info=True,
                                                 show_timestamp=not hide_time))
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            Printer.print_error('Could not get logs for job `{}`.'.format(_job))
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))

    if job:
        _job = get_experiment_job_or_local(job)
        get_experiment_job_logs()
    else:
        get_experiment_logs()


@experiment.command()
@click.pass_context
@clean_outputs
def outputs(ctx):
    """Download outputs for experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment -xp 1 outputs
    ```
    """
    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    try:
        PolyaxonClient().experiment.download_outputs(user, project_name, _experiment)
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not download outputs for experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)
    Printer.print_success('Files downloaded.')


@experiment.command()
@click.pass_context
@clean_outputs
def bookmark(ctx):
    """Bookmark experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment bookmark
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 2 bookmark
    ```
    """
    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    try:
        PolyaxonClient().experiment.bookmark(user, project_name, _experiment)
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not bookmark experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)

    Printer.print_success("Experiment is bookmarked.")


@experiment.command()
@click.pass_context
@clean_outputs
def unbookmark(ctx):
    """Unbookmark experiment.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon experiment unbookmark
    ```

    \b
    ```bash
    $ polyaxon experiment -xp 2 unbookmark
    ```
    """
    user, project_name, _experiment = get_project_experiment_or_local(ctx.obj.get('project'),
                                                                      ctx.obj.get('experiment'))
    try:
        PolyaxonClient().experiment.unbookmark(user, project_name, _experiment)
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not unbookmark experiment `{}`.'.format(_experiment))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)

    Printer.print_success("Experiment is unbookmarked.")

[((59, 1, 59, 14), 'click.group', 'click.group', ({}, {}), '()', False, 'import click\n'), ((60, 1, 60, 98), 'click.option', 'click.option', (), '', False, 'import click\n'), ((61, 1, 61, 80), 'click.option', 'click.option', (), '', False, 'import click\n'), ((72, 1, 72, 58), 'click.option', 'click.option', (), '', False, 'import click\n'), ((204, 1, 205, 95), 'click.option', 'click.option', (), '', False, 'import click\n'), ((206, 1, 206, 79), 'click.option', 'click.option', (), '', False, 'import click\n'), ((207, 1, 207, 89), 'click.option', 'click.option', (), '', False, 'import click\n'), ((258, 1, 260, 88), 'click.option', 'click.option', (), '', False, 'import click\n'), ((298, 1, 299, 63), 'click.option', 'click.option', (), '', False, 'import click\n'), ((302, 1, 303, 59), 'click.option', 'click.option', (), '', False, 'import click\n'), ((348, 1, 349, 57), 'click.option', 'click.option', (), '', False, 'import click\n'), ((387, 1, 387, 79), 'click.option', 'click.option', (), '', False, 'import click\n'), ((431, 1, 431, 58), 'click.option', 'click.option', (), '', False, 'import click\n'), ((432, 1, 432, 83), 'click.option', 'click.option', (), '', False, 'import click\n'), ((531, 1, 531, 58), 'click.option', 'click.option', (), '', False, 'import click\n'), ((532, 1, 532, 81), 'click.option', 'click.option', (), '', False, 'import click\n'), ((603, 1, 603, 58), 'click.option', 'click.option', (), '', False, 'import click\n'), ((604, 1, 604, 71), 'click.option', 'click.option', (), '', False, 'import click\n'), ((605, 1, 606, 58), 'click.option', 'click.option', (), '', False, 'import click\n'), ((607, 1, 608, 76), 'click.option', 'click.option', (), '', False, 'import click\n'), ((55, 4, 55, 44), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(55, 25, 55, 43): '"""Experiment info:"""'}, {}), "('Experiment info:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((237, 11, 237, 30), 'polyaxon_cli.utils.validation.validate_tags', 'validate_tags', ({(237, 25, 237, 29): 'tags'}, {}), '(tags)', False, 'from polyaxon_cli.utils.validation import validate_tags\n'), ((253, 4, 253, 48), 'polyaxon_cli.utils.formatting.Printer.print_success', 'Printer.print_success', ({(253, 26, 253, 47): '"""Experiment updated."""'}, {}), "('Experiment updated.')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((294, 4, 294, 57), 'polyaxon_cli.utils.formatting.Printer.print_success', 'Printer.print_success', ({(294, 26, 294, 56): '"""Experiment is being stopped."""'}, {}), "('Experiment is being stopped.')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((413, 11, 413, 38), 'polyaxon_cli.utils.formatting.get_meta_response', 'get_meta_response', ({(413, 29, 413, 37): 'response'}, {}), '(response)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((423, 14, 423, 45), 'polyaxon_cli.utils.formatting.list_dicts_to_tabulate', 'list_dicts_to_tabulate', ({(423, 37, 423, 44): 'objects'}, {}), '(objects)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((738, 4, 738, 46), 'polyaxon_cli.utils.formatting.Printer.print_success', 'Printer.print_success', ({(738, 26, 738, 45): '"""Files downloaded."""'}, {}), "('Files downloaded.')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((770, 4, 770, 54), 'polyaxon_cli.utils.formatting.Printer.print_success', 'Printer.print_success', ({(770, 26, 770, 53): '"""Experiment is bookmarked."""'}, {}), "('Experiment is bookmarked.')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((802, 4, 802, 56), 'polyaxon_cli.utils.formatting.Printer.print_success', 'Printer.print_success', ({(802, 26, 802, 55): '"""Experiment is unbookmarked."""'}, {}), "('Experiment is unbookmarked.')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((34, 8, 34, 55), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(34, 29, 34, 54): '"""Experiment description:"""'}, {}), "('Experiment description:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((41, 8, 41, 56), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(41, 29, 41, 55): '"""Experiment declarations:"""'}, {}), "('Experiment declarations:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((42, 8, 42, 46), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', ({(42, 22, 42, 45): 'experiment.declarations'}, {}), '(experiment.declarations)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((45, 8, 45, 56), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(45, 29, 45, 55): '"""Experiment last metrics:"""'}, {}), "('Experiment last metrics:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((46, 8, 46, 45), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', ({(46, 22, 46, 44): 'experiment.last_metric'}, {}), '(experiment.last_metric)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((56, 18, 56, 52), 'polyaxon_cli.utils.formatting.Printer.add_status_color', 'Printer.add_status_color', ({(56, 43, 56, 51): 'response'}, {}), '(response)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((155, 8, 155, 41), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(155, 29, 155, 40): '"""Job info:"""'}, {}), "('Job info:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((156, 8, 156, 31), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', ({(156, 22, 156, 30): 'response'}, {}), '(response)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((162, 15, 162, 47), 'polyaxon_cli.cli.getters.experiment.get_experiment_job_or_local', 'get_experiment_job_or_local', ({(162, 43, 162, 46): 'job'}, {}), '(job)', False, 'from polyaxon_cli.cli.getters.experiment import get_experiment_job_or_local, get_project_experiment_or_local\n'), ((186, 8, 186, 59), 'click.echo', 'click.echo', ({(186, 19, 186, 58): '"""Existing without deleting experiment."""'}, {}), "('Existing without deleting experiment.')", False, 'import click\n'), ((187, 8, 187, 19), 'sys.exit', 'sys.exit', ({(187, 17, 187, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((193, 8, 193, 33), 'polyaxon_cli.managers.experiment.ExperimentManager.purge', 'ExperimentManager.purge', ({}, {}), '()', False, 'from polyaxon_cli.managers.experiment import ExperimentManager\n'), ((242, 8, 242, 83), 'polyaxon_cli.utils.formatting.Printer.print_warning', 'Printer.print_warning', ({(242, 30, 242, 82): '"""No argument was provided to update the experiment."""'}, {}), "('No argument was provided to update the experiment.')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((243, 8, 243, 19), 'sys.exit', 'sys.exit', ({(243, 17, 243, 18): '(0)'}, {}), '(0)', False, 'import sys\n'), ((284, 8, 284, 59), 'click.echo', 'click.echo', ({(284, 19, 284, 58): '"""Existing without stopping experiment."""'}, {}), "('Existing without stopping experiment.')", False, 'import click\n'), ((285, 8, 285, 19), 'sys.exit', 'sys.exit', ({(285, 17, 285, 18): '(0)'}, {}), '(0)', False, 'import sys\n'), ((321, 17, 321, 32), 'rhea.read', 'rhea.read', ({(321, 27, 321, 31): 'file'}, {}), '(file)', False, 'import rhea\n'), ((300, 50, 300, 73), 'click.Path', 'click.Path', (), '', False, 'import click\n'), ((367, 17, 367, 32), 'rhea.read', 'rhea.read', ({(367, 27, 367, 31): 'file'}, {}), '(file)', False, 'import rhea\n'), ((346, 50, 346, 73), 'click.Path', 'click.Path', (), '', False, 'import click\n'), ((416, 8, 416, 43), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(416, 29, 416, 42): '"""Navigation:"""'}, {}), "('Navigation:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((417, 8, 417, 27), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', ({(417, 22, 417, 26): 'meta'}, {}), '(meta)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((425, 8, 425, 37), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(425, 29, 425, 36): '"""Jobs:"""'}, {}), "('Jobs:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((427, 8, 427, 49), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', (), '', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((474, 15, 474, 42), 'polyaxon_cli.utils.formatting.get_meta_response', 'get_meta_response', ({(474, 33, 474, 41): 'response'}, {}), '(response)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((502, 15, 502, 42), 'polyaxon_cli.utils.formatting.get_meta_response', 'get_meta_response', ({(502, 33, 502, 41): 'response'}, {}), '(response)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((524, 15, 524, 47), 'polyaxon_cli.cli.getters.experiment.get_experiment_job_or_local', 'get_experiment_job_or_local', ({(524, 43, 524, 46): 'job'}, {}), '(job)', False, 'from polyaxon_cli.cli.getters.experiment import get_experiment_job_or_local, get_project_experiment_or_local\n'), ((596, 15, 596, 47), 'polyaxon_cli.cli.getters.experiment.get_experiment_job_or_local', 'get_experiment_job_or_local', ({(596, 43, 596, 46): 'job'}, {}), '(job)', False, 'from polyaxon_cli.cli.getters.experiment import get_experiment_job_or_local, get_project_experiment_or_local\n'), ((709, 15, 709, 47), 'polyaxon_cli.cli.getters.experiment.get_experiment_job_or_local', 'get_experiment_job_or_local', ({(709, 43, 709, 46): 'job'}, {}), '(job)', False, 'from polyaxon_cli.cli.getters.experiment import get_experiment_job_or_local, get_project_experiment_or_local\n'), ((128, 12, 128, 76), 'polyaxon_cli.utils.cache.cache', 'cache.cache', (), '', False, 'from polyaxon_cli.utils import cache\n'), ((142, 12, 142, 79), 'polyaxon_cli.utils.cache.cache', 'cache.cache', (), '', False, 'from polyaxon_cli.utils import cache\n'), ((197, 8, 197, 19), 'sys.exit', 'sys.exit', ({(197, 17, 197, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((251, 8, 251, 19), 'sys.exit', 'sys.exit', ({(251, 17, 251, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((292, 8, 292, 19), 'sys.exit', 'sys.exit', ({(292, 17, 292, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((342, 8, 342, 19), 'sys.exit', 'sys.exit', ({(342, 17, 342, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((383, 8, 383, 19), 'sys.exit', 'sys.exit', ({(383, 17, 383, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((411, 8, 411, 19), 'sys.exit', 'sys.exit', ({(411, 17, 411, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((477, 12, 477, 47), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(477, 33, 477, 46): '"""Navigation:"""'}, {}), "('Navigation:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((478, 12, 478, 31), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', ({(478, 26, 478, 30): 'meta'}, {}), '(meta)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((486, 12, 486, 45), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(486, 33, 486, 44): '"""Statuses:"""'}, {}), "('Statuses:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((488, 12, 488, 53), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', (), '', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((505, 12, 505, 47), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(505, 33, 505, 46): '"""Navigation:"""'}, {}), "('Navigation:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((506, 12, 506, 31), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', ({(506, 26, 506, 30): 'meta'}, {}), '(meta)', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((514, 12, 514, 45), 'polyaxon_cli.utils.formatting.Printer.print_header', 'Printer.print_header', ({(514, 33, 514, 44): '"""Statuses:"""'}, {}), "('Statuses:')", False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((516, 12, 516, 53), 'polyaxon_cli.utils.formatting.dict_tabulate', 'dict_tabulate', (), '', False, 'from polyaxon_cli.utils.formatting import Printer, dict_tabulate, get_meta_response, get_resources, list_dicts_to_tabulate\n'), ((737, 8, 737, 19), 'sys.exit', 'sys.exit', ({(737, 17, 737, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((768, 8, 768, 19), 'sys.exit', 'sys.exit', ({(768, 17, 768, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((800, 8, 800, 19), 'sys.exit', 'sys.exit', ({(800, 17, 800, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((132, 12, 132, 23), 'sys.exit', 'sys.exit', ({(132, 21, 132, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((146, 12, 146, 23), 'sys.exit', 'sys.exit', ({(146, 21, 146, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((472, 12, 472, 23), 'sys.exit', 'sys.exit', ({(472, 21, 472, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((500, 12, 500, 23), 'sys.exit', 'sys.exit', ({(500, 21, 500, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((577, 12, 577, 23), 'sys.exit', 'sys.exit', ({(577, 21, 577, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((590, 12, 590, 23), 'sys.exit', 'sys.exit', ({(590, 21, 590, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((666, 12, 666, 23), 'sys.exit', 'sys.exit', ({(666, 21, 666, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((703, 12, 703, 23), 'sys.exit', 'sys.exit', ({(703, 21, 703, 22): '(1)'}, {}), '(1)', False, 'import sys\n'), ((190, 19, 190, 35), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((246, 19, 246, 35), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((288, 8, 288, 24), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((377, 19, 377, 35), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((406, 19, 406, 35), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((641, 16, 643, 46), 'polyaxon_cli.utils.log_handler.get_logs_handler', 'get_logs_handler', (), '', False, 'from polyaxon_cli.utils.log_handler import get_logs_handler\n'), ((661, 32, 662, 78), 'polyaxon_cli.utils.log_handler.get_logs_handler', 'get_logs_handler', (), '', False, 'from polyaxon_cli.utils.log_handler import get_logs_handler\n'), ((677, 16, 679, 46), 'polyaxon_cli.utils.log_handler.get_logs_handler', 'get_logs_handler', (), '', False, 'from polyaxon_cli.utils.log_handler import get_logs_handler\n'), ((698, 32, 699, 78), 'polyaxon_cli.utils.log_handler.get_logs_handler', 'get_logs_handler', (), '', False, 'from polyaxon_cli.utils.log_handler import get_logs_handler\n'), ((733, 8, 733, 24), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((764, 8, 764, 24), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((796, 8, 796, 24), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((127, 23, 127, 39), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((138, 23, 138, 39), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((332, 23, 332, 39), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((336, 23, 336, 39), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((467, 23, 467, 39), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((492, 23, 492, 39), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((572, 12, 572, 28), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((582, 12, 582, 28), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((654, 20, 654, 31), 'sys.exit', 'sys.exit', ({(654, 29, 654, 30): '(1)'}, {}), '(1)', False, 'import sys\n'), ((657, 12, 657, 28), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((690, 20, 690, 31), 'sys.exit', 'sys.exit', ({(690, 29, 690, 30): '(1)'}, {}), '(1)', False, 'import sys\n'), ((693, 12, 693, 28), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((639, 27, 639, 43), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n'), ((671, 27, 671, 43), 'polyaxon_cli.client.PolyaxonClient', 'PolyaxonClient', ({}, {}), '()', False, 'from polyaxon_cli.client import PolyaxonClient\n')]