Skip to content

Commit

Permalink
cli: move client import inside functions
Browse files Browse the repository at this point in the history
* Client operations are expensive, moving the client
  imports inside the functions that use them reduces
  loading time as it only performs the import when it's
  really needed
  • Loading branch information
mvidalgarcia committed Jan 22, 2020
1 parent 6058e16 commit 0b425c0
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 44 deletions.
2 changes: 1 addition & 1 deletion reana_client/api/client.py
Expand Up @@ -252,7 +252,7 @@ def upload_file(workflow_id, file_, file_name, access_token):
:param file_name: name of a file that will be uploaded.
:param access_token: access token of the current user.
"""
from reana_client.cli import get_api_url
from reana_client.utils import get_api_url
try:
endpoint = \
current_rs_api_client.api.upload_file.operation.path_name.format(
Expand Down
9 changes: 2 additions & 7 deletions reana_client/cli/__init__.py
Expand Up @@ -11,7 +11,7 @@
import sys

import click
import urllib3
from urllib3 import disable_warnings

from reana_client.cli import workflow, files, ping, secrets

Expand Down Expand Up @@ -42,7 +42,7 @@ class ReanaCLI(click.Group):

def __init__(self, name=None, commands=None, **attrs):
"""Initialize REANA client commands."""
urllib3.disable_warnings()
disable_warnings()
click.Group.__init__(self, name, **attrs)
for group in ReanaCLI.cmd_groups:
for cmd in group.commands.items():
Expand Down Expand Up @@ -71,11 +71,6 @@ def format_commands(self, ctx, formatter):
formatter.write_dl(item['rows'])


def get_api_url():
"""Obtain REANA server API URL."""
return os.environ.get('REANA_SERVER_URL')


@click.command(cls=ReanaCLI)
@click.option(
'--loglevel',
Expand Down
8 changes: 4 additions & 4 deletions reana_client/cli/cwl_runner.py
Expand Up @@ -24,9 +24,6 @@
from cwltool.main import printdeps
from cwltool.workflow import findfiles

from reana_client.api.client import (create_workflow, current_rs_api_client,
get_workflow_logs, start_workflow,
upload_file)
from reana_client.cli.utils import add_access_token_options
from reana_client.config import default_user
from reana_client.utils import load_workflow_spec
Expand Down Expand Up @@ -72,7 +69,10 @@ def get_file_dependencies_obj(cwl_obj, basedir):
def cwl_runner(ctx, quiet, outdir, basedir, processfile, jobfile,
access_token):
"""Run CWL files in a standard format <workflow.cwl> <job.json>."""
from reana_client.api import get_api_url
from reana_client.utils import get_api_url
from reana_client.api.client import (create_workflow, get_workflow_logs,
start_workflow, upload_file)

logging.basicConfig(
format='[%(levelname)s] %(message)s',
stream=sys.stderr,
Expand Down
17 changes: 13 additions & 4 deletions reana_client/cli/files.py
Expand Up @@ -15,10 +15,6 @@

import click

from reana_client.api.client import (current_rs_api_client, delete_file,
download_file, get_workflow_disk_usage,
get_workflow_status, list_files, mv_files,
upload_to_server)
from reana_client.api.utils import get_path_from_operation_id
from reana_client.cli.utils import (add_access_token_options,
add_workflow_option, check_connection,
Expand Down Expand Up @@ -77,6 +73,8 @@ def get_files(ctx, workflow, _filter,
\t $ reana-client ls --workflow myanalysis.42
"""
import tablib
from reana_client.api.client import current_rs_api_client, list_files

logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
for p in ctx.params:
logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
Expand Down Expand Up @@ -161,6 +159,8 @@ def download_files(ctx, workflow, filenames,
\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]))
Expand Down Expand Up @@ -230,6 +230,8 @@ def upload_files(ctx, workflow, filenames, access_token): # noqa: D301
\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]))
Expand Down Expand Up @@ -319,6 +321,8 @@ def delete_files(ctx, workflow, filenames, access_token): # noqa: D301
\t $ reana-client rm -w myanalysis.42 data/mydata.csv \n
\t $ reana-client rm -w myanalysis.42 'code/\*'
"""
from reana_client.api.client import delete_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]))
Expand Down Expand Up @@ -374,6 +378,9 @@ def move_files(ctx, source, target, workflow, access_token): # noqa: D301
Examples:\n
\t $ reana-client mv data/input.txt input/input.txt
"""
from reana_client.api.client import (get_workflow_status, list_files,
mv_files)

logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
for p in ctx.params:
logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
Expand Down Expand Up @@ -441,6 +448,8 @@ def workflow_disk_usage(ctx, workflow, access_token, summarize, block_size): #
\t $ reana-client du -w myanalysis.42 -s \n
\t $ reana-client du -w myanalysis.42 --bytes
"""
from reana_client.api.client import get_workflow_disk_usage

logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
for p in ctx.params:
logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
Expand Down
4 changes: 2 additions & 2 deletions reana_client/cli/ping.py
Expand Up @@ -11,7 +11,6 @@
import traceback

import click
from reana_client.api.client import ping as rs_ping
from reana_client.cli.utils import check_connection
from reana_client.version import __version__

Expand All @@ -34,7 +33,8 @@ def ping(ctx): # noqa: D301
\t $ reana-client ping
"""
try:
from reana_client.cli import get_api_url
from reana_client.api.client import ping as rs_ping
from reana_client.utils import get_api_url
logging.info('Connecting to {0}'.format(get_api_url()))
response = rs_ping()
click.echo(click.style('Connected to {0} - Server is running.'
Expand Down
8 changes: 6 additions & 2 deletions reana_client/cli/secrets.py
Expand Up @@ -11,8 +11,6 @@
import traceback

import click
from reana_client.api.client import add_secrets, delete_secrets, \
list_secrets, current_rs_api_client
from reana_client.cli.utils import (add_access_token_options, check_connection,
NotRequiredIf)
from reana_client.config import ERROR_MESSAGES
Expand Down Expand Up @@ -65,6 +63,8 @@ def secrets_add(env, file, overwrite, access_token): # noqa: D301
\t --env PASSWORD=password \n
\t --file ~/.keytab
"""
from reana_client.api.client import add_secrets

secrets_ = {}
for literal in env:
secret = parse_secret_from_literal(literal)
Expand Down Expand Up @@ -108,6 +108,8 @@ def secrets_delete(secrets, access_token): # noqa: D301
Examples: \n
\t $ reana-client secrets-delete PASSWORD
"""
from reana_client.api.client import delete_secrets

try:
deleted_secrets = delete_secrets(secrets, access_token)
except REANASecretDoesNotExist as e:
Expand Down Expand Up @@ -142,6 +144,8 @@ def secrets_list(access_token): # noqa: D301
Examples: \n
\t $ reana-client secrets-list
"""
from reana_client.api.client import list_secrets

try:
secrets = list_secrets(access_token)
headers = ['name', 'type']
Expand Down
2 changes: 1 addition & 1 deletion reana_client/cli/utils.py
Expand Up @@ -47,7 +47,7 @@ def check_connection(func):
"""Check if connected to any REANA cluster."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
from reana_client.cli import get_api_url
from reana_client.utils import get_api_url
api_url = get_api_url()
if not api_url:
click.secho(
Expand Down
34 changes: 20 additions & 14 deletions reana_client/cli/workflow.py
Expand Up @@ -16,15 +16,6 @@

import click
from jsonschema.exceptions import ValidationError
from reana_client.api.client import (close_interactive_session,
create_workflow, current_rs_api_client,
delete_workflow, diff_workflows,
get_workflow_disk_usage,
get_workflow_logs,
get_workflow_parameters,
get_workflow_status, get_workflows,
open_interactive_session, start_workflow,
stop_workflow)
from reana_client.cli.files import get_files, upload_files
from reana_client.cli.utils import (add_access_token_options,
add_workflow_option, check_connection,
Expand Down Expand Up @@ -118,6 +109,8 @@ def workflow_workflows(ctx, sessions, _filter, output_format, access_token,
\t $ reana-client list --verbose --bytes
"""
import tablib
from reana_client.api.client import get_workflows

logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
for p in ctx.params:
logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
Expand Down Expand Up @@ -222,7 +215,8 @@ def workflow_create(ctx, file, name,
\t $ reana-client create -w myanalysis\n
\t $ reana-client create -w myanalysis -f myreana.yaml\n
"""
from reana_client.cli import get_api_url
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]))
Expand Down Expand Up @@ -306,7 +300,9 @@ def workflow_start(ctx, workflow, access_token,
\t $ reana-client start -w myanalysis.42 -p sleeptime=10 -p myparam=4 \n
\t $ reana-client start -w myanalysis.42 -p myparam1=myvalue1 -o CACHE=off
"""
from reana_client.cli import get_api_url
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]))
Expand Down Expand Up @@ -412,6 +408,7 @@ def workflow_status(ctx, workflow, _filter, output_format,
\t $ reana-client status -w myanalysis.42 -v --json
"""
import tablib
from reana_client.api.client import get_workflow_status

def render_progress(finished_jobs, total_jobs):
if total_jobs:
Expand Down Expand Up @@ -533,6 +530,7 @@ def workflow_logs(ctx, workflow, access_token, json_format): # noqa: D301
Examples: \n
\t $ reana-client logs -w myanalysis.42
"""
from reana_client.api.client import get_workflow_logs
logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
for p in ctx.params:
logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
Expand Down Expand Up @@ -647,6 +645,8 @@ def workflow_stop(ctx, workflow, force_stop, access_token): # noqa: D301
Example: \n
\t $ reana-client stop -w myanalysis.42 --force
"""
from reana_client.api.client import get_workflow_status, stop_workflow

if not force_stop:
click.secho('Graceful stop not implement yet. If you really want to '
'stop your workflow without waiting for jobs to finish'
Expand Down Expand Up @@ -779,7 +779,8 @@ def workflow_delete(ctx, workflow, all_runs, workspace,
\t $ reana-client delete -w myanalysis.42 \n
\t $ reana-client delete -w myanalysis.42 --include-records
"""
from reana_client.cli import get_api_url
from reana_client.api.client import delete_workflow, get_workflow_status
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]))
Expand Down Expand Up @@ -846,6 +847,7 @@ def workflow_diff(ctx, workflow_a, workflow_b, brief,
\t $ reana-client diff myanalysis.42 myotheranalysis.43 \n
\t $ reana-client diff myanalysis.42 myotheranalysis.43 --brief
"""
from reana_client.api.client import diff_workflows
logging.debug('command: {}'.format(ctx.command_path.replace(" ", ".")))
for p in ctx.params:
logging.debug('{param}: {value}'.format(param=p, value=ctx.params[p]))
Expand Down Expand Up @@ -923,6 +925,8 @@ def workflow_open_interactive_session(ctx, workflow, interactive_session_type,
Examples:\n
\t $ reana-client open -w myanalysis.42 jupyter
"""
from reana_client.api.client import open_interactive_session

if workflow:
try:
logging.info(
Expand Down Expand Up @@ -963,6 +967,8 @@ def workflow_close_interactive_session(workflow, access_token): # noqa: D301
Examples:\n
\t $ reana-client close -w myanalysis.42
"""
from reana_client.api.client import close_interactive_session

if workflow:
try:
logging.info(
Expand All @@ -976,5 +982,5 @@ def workflow_close_interactive_session(workflow, access_token): # noqa: D301
click.secho("Interactive session could not be closed: \n{}"
.format(str(e)), fg='red', err=True)
else:
click.secho("Workflow {} does not exist".format(workflow),
fg="red", err=True)
click.secho("Workflow {} does not exist".format(workflow),
fg="red", err=True)
5 changes: 5 additions & 0 deletions reana_client/utils.py
Expand Up @@ -351,3 +351,8 @@ def parse_secret_from_path(path):
.format(path),
fg='red'),
err=True)


def get_api_url():
"""Obtain REANA server API URL."""
return os.environ.get('REANA_SERVER_URL')
17 changes: 8 additions & 9 deletions tests/test_cli_workflows.py
Expand Up @@ -245,15 +245,14 @@ def test_create_workflow_from_json(create_yaml_workflow_schema):
"reana_client.api.client.current_rs_api_client",
make_mock_api_client('reana-server')(mock_response,
mock_http_response)):
result = create_workflow_from_json(
workflow_json=workflow_json['workflow'],
name=response['workflow_name'],
access_token=reana_token,
parameters=workflow_json['inputs'],
workflow_engine='serial'
)
assert response['workflow_name'] == result['workflow_name']
assert response['message'] == result['message']
result = create_workflow_from_json(
workflow_json=workflow_json['workflow'],
name=response['workflow_name'],
access_token=reana_token,
parameters=workflow_json['inputs'],
workflow_engine='serial')
assert response['workflow_name'] == result['workflow_name']
assert response['message'] == result['message']


@pytest.mark.parametrize("status", [
Expand Down

0 comments on commit 0b425c0

Please sign in to comment.