From eac83563af5c8223c1f374ad797677f181c97cdd Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 13 Apr 2017 14:40:28 +0300 Subject: [PATCH 1/6] `request`: tolerate absolute URLs --- valohai_cli/api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/valohai_cli/api.py b/valohai_cli/api.py index c567b05f..20711f39 100644 --- a/valohai_cli/api.py +++ b/valohai_cli/api.py @@ -101,4 +101,6 @@ def request(method, url, **kwargs): :rtype: requests.Response """ session = _get_current_api_session() + if url.startswith(session.base_url): + url = url[len(session.base_url):] return session.request(method, url, **kwargs) From 759b1ba57d0d00db3f9690bf6be453378adae39c Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 13 Apr 2017 14:26:36 +0300 Subject: [PATCH 2/6] Show project view URL in `proj stat` (if available) --- valohai_cli/commands/project/status.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/valohai_cli/commands/project/status.py b/valohai_cli/commands/project/status.py index 3f5c381b..89094bd2 100644 --- a/valohai_cli/commands/project/status.py +++ b/valohai_cli/commands/project/status.py @@ -15,7 +15,10 @@ def status(summary, incomplete): project = get_project(require=True) project_data = request('get', '/api/v0/projects/{id}/'.format(id=project.id)).json() - click.secho('# Project %s\n' % click.style(project.name, underline=True), bold=True) + click.secho('# Project %s' % click.style(project.name, underline=True), bold=True) + if 'urls' in project_data: + click.secho(' %s' % project_data['urls']['display']) + click.secho('') if summary: print_execution_summary(project_data) From 66f6d3fb6cf3d376b4f6e3a0c739a09f30fbfcea Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 13 Apr 2017 14:26:47 +0300 Subject: [PATCH 3/6] Don't print execution summary if there are no executions --- valohai_cli/commands/project/status.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/valohai_cli/commands/project/status.py b/valohai_cli/commands/project/status.py index 89094bd2..15660c56 100644 --- a/valohai_cli/commands/project/status.py +++ b/valohai_cli/commands/project/status.py @@ -45,6 +45,9 @@ def print_execution_summary(project_data): if not execution_summary: return total = execution_summary.pop('count') + if not total: + click.secho('No executions yet.', fg='cyan') + return click.secho('## Summary of %d executions\n' % total, bold=True) print_table( [ From 19218e986ce43a842cccc247af5d33e2b396147c Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 13 Apr 2017 15:15:35 +0300 Subject: [PATCH 4/6] Update fixture data to match current situation --- tests/fixture_data.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/fixture_data.py b/tests/fixture_data.py index 4c734127..e50b1f37 100644 --- a/tests/fixture_data.py +++ b/tests/fixture_data.py @@ -14,6 +14,9 @@ 'owner': 1, 'ctime': '2016-12-16T12:25:52.718310Z', 'mtime': '2017-01-20T14:35:02.196871Z', + 'urls': { + 'display': 'https://app.valohai.com/p/nyan/nyan/', + } } execution_id = str(uuid.uuid4()) @@ -35,9 +38,9 @@ 'step': 'run training', 'url': 'https://app.valohai.com/api/v0/executions/{id}/'.format(id=execution_id), 'urls': { - 'copy': '/api/v0/executions/34/copy/', - 'display': '/p/test/mnist/execution/34/', - 'stop': '/api/v0/executions/34/stop/', + 'copy': 'https://app.valohai.com/api/v0/executions/34/copy/', + 'display': 'https://app.valohai.com/p/test/mnist/execution/34/', + 'stop': 'https://app.valohai.com/api/v0/executions/34/stop/', }, 'events': [ { From 680679ed2b05bd5131016d13f66f73249e51a102 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 13 Apr 2017 15:15:45 +0300 Subject: [PATCH 5/6] Add generic monkeypatch call stub --- tests/utils.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/utils.py b/tests/utils.py index 4b5d54c5..d9b28e2d 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -10,3 +10,14 @@ def get_project_data(n_projects): for i in range(n_projects) ], } + + +def make_call_stub(retval=None): + calls = [] + + def call_stub(*args, **kwargs): + calls.append({'args': args, 'kwargs': kwargs}) + return retval + + call_stub.calls = calls + return call_stub From 501ef0ea6b43a91379b0cc944c97883cc2bebd18 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 13 Apr 2017 15:31:36 +0300 Subject: [PATCH 6/6] Add `exec open` and `proj open` utilities --- tests/commands/execution/test_open.py | 13 +++++++++++++ tests/commands/project/test_open.py | 17 +++++++++++++++++ valohai_cli/commands/execution/open.py | 14 ++++++++++++++ valohai_cli/commands/project/open.py | 15 +++++++++++++++ valohai_cli/utils.py | 11 +++++++++++ 5 files changed, 70 insertions(+) create mode 100644 tests/commands/execution/test_open.py create mode 100644 tests/commands/project/test_open.py create mode 100644 valohai_cli/commands/execution/open.py create mode 100644 valohai_cli/commands/project/open.py diff --git a/tests/commands/execution/test_open.py b/tests/commands/execution/test_open.py new file mode 100644 index 00000000..7427db34 --- /dev/null +++ b/tests/commands/execution/test_open.py @@ -0,0 +1,13 @@ +import webbrowser + +from tests.commands.execution.utils import get_execution_data_mock +from tests.utils import make_call_stub +from valohai_cli.commands.execution.open import open + + +def test_open(monkeypatch, runner, logged_in_and_linked): + call_stub = make_call_stub() + monkeypatch.setattr(webbrowser, 'open', call_stub) + with get_execution_data_mock(): + runner.invoke(open, ['7'], catch_exceptions=False) + assert call_stub.calls diff --git a/tests/commands/project/test_open.py b/tests/commands/project/test_open.py new file mode 100644 index 00000000..86a6932c --- /dev/null +++ b/tests/commands/project/test_open.py @@ -0,0 +1,17 @@ +import webbrowser + +import requests_mock + +from tests.fixture_data import PROJECT_DATA +from tests.utils import make_call_stub +from valohai_cli.commands.project.open import open + + +def test_open(monkeypatch, runner, logged_in_and_linked): + call_stub = make_call_stub() + monkeypatch.setattr(webbrowser, 'open', call_stub) + with requests_mock.mock() as m: + project_data = dict(PROJECT_DATA) + m.get('https://app.valohai.com/api/v0/projects/{id}/'.format(id=project_data['id']), json=project_data) + runner.invoke(open, catch_exceptions=False) + assert call_stub.calls diff --git a/valohai_cli/commands/execution/open.py b/valohai_cli/commands/execution/open.py new file mode 100644 index 00000000..e33ba255 --- /dev/null +++ b/valohai_cli/commands/execution/open.py @@ -0,0 +1,14 @@ +import click + +from valohai_cli.ctx import get_project +from valohai_cli.utils import open_browser + + +@click.command() +@click.argument('counter') +def open(counter): + """ + Open an execution in a web browser. + """ + execution = get_project(require=True).get_execution_from_counter(counter=counter, detail=True) + open_browser(execution) diff --git a/valohai_cli/commands/project/open.py b/valohai_cli/commands/project/open.py new file mode 100644 index 00000000..e7f6fbf6 --- /dev/null +++ b/valohai_cli/commands/project/open.py @@ -0,0 +1,15 @@ +import click + +from valohai_cli.api import request +from valohai_cli.ctx import get_project +from valohai_cli.utils import open_browser + + +@click.command() +def open(): + """ + Open the project's view in a web browser. + """ + project = get_project(require=True) + project_data = request('get', '/api/v0/projects/{id}/'.format(id=project.id)).json() + open_browser(project_data) diff --git a/valohai_cli/utils.py b/valohai_cli/utils.py index 2ba7af42..a23ea723 100644 --- a/valohai_cli/utils.py +++ b/valohai_cli/utils.py @@ -3,7 +3,9 @@ import random import re import string +import webbrowser +import click import six @@ -109,3 +111,12 @@ def find_scripts(directory): interpreter = extension_to_interpreter.get(os.path.splitext(filename.lower())[1]) if interpreter: yield (interpreter, os.path.basename(filename)) + + +def open_browser(object, url_name='display'): + if 'urls' not in object: + return False + url = object['urls'][url_name] + click.echo('Opening {} ...'.format(click.style(url, bold=True))) + webbrowser.open(url) + return True