Skip to content

Commit

Permalink
Merge branch 'doc' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
giannisdoukas committed Jul 1, 2020
2 parents dba30a6 + d3476b7 commit 6e91265
Show file tree
Hide file tree
Showing 3 changed files with 303 additions and 36 deletions.
41 changes: 36 additions & 5 deletions cwlkernel/CWLKernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,29 @@ def __init__(self, **kwargs):
if self.log is None: # pylint: disable=access-member-before-definition
self.log = logging.getLogger()

@property
def workflow_repository(self) -> WorkflowRepository:
return self._workflow_repository

@property
def results_manager(self) -> ResultsManager:
return self._results_manager

@property
def workflow_composer(self) -> CWLWorkflow:
return self._workflow_composer

@workflow_composer.setter
def workflow_composer(self, composer=Optional[CWLWorkflow]):
self._workflow_composer = composer

@classmethod
def register_magic(cls, magic: Callable):
"""
Registers magic commands. That method should be used as a decorator to register custom magic commands.
@param magic: The magic command to register
@return: the magic function
"""
cls._magic_commands[magic.__name__] = magic
cls._auto_complete_engine.add_magic_command(magic.__name__)
return magic
Expand Down Expand Up @@ -102,7 +123,7 @@ def do_execute(self, code: str, silent=False, store_history: bool = True,
except Exception as e:
status = 'error'
traceback.print_exc()
self._send_error_response(f'{type(e).__name__}: {e}')
self.send_error_response(f'{type(e).__name__}: {e}')
finally:
return {
'status': status,
Expand Down Expand Up @@ -133,10 +154,20 @@ def _do_execute_magic_command(self, commands: str):
args = " ".join(command[1:])
self._magic_commands[command_name](self, args)

def _send_error_response(self, text):
def send_error_response(self, text) -> None:
"""
Sends a response to the jupyter notebook's stderr.
@param text: The message to display
@return: None
"""
self.send_response(self.iopub_socket, 'stream', {'name': 'stderr', 'text': text})

def _send_json_response(self, json_data: Union[Dict, List]):
def send_json_response(self, json_data: Union[Dict, List]) -> None:
"""
Display a Dict or a List object as a JSON. The object must be json dumpable to use that function.
@param json_data: Data to print in Jupyter Notebook
@return: None
"""
self.send_response(
self.iopub_socket,
'display_data',
Expand Down Expand Up @@ -184,7 +215,7 @@ def _preprocess_data(self, data: Dict) -> Dict:
data[key_id].pop('$data')
if has_change is True:
self.send_text_to_stdout('set data to:\n')
self._send_json_response(data)
self.send_json_response(data)
return data

def _clear_data(self):
Expand Down Expand Up @@ -216,7 +247,7 @@ def _execute_workflow(self, code_path: Path) -> Optional[Exception]:
output_directory_for_that_run,
metadata=results[output]
)
self._send_json_response(results)
self.send_json_response(results)
if exception is not None:
self.log.debug(f'execution error: {exception}')
self.send_response(self.iopub_socket, 'stream', {'name': 'stderr', 'text': str(exception)})
Expand Down
69 changes: 41 additions & 28 deletions cwlkernel/kernel_magics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@
import os
import random
from io import StringIO
from pathlib import Path

from ruamel.yaml import YAML

from .CWLKernel import CONF as CWLKernel_CONF
from .CWLKernel import CWLKernel
from .cwlrepository.CWLComponent import CWLWorkflow, WorkflowComponent, WorkflowComponentFactory
from .cwlrepository.CWLComponent import CWLWorkflow, WorkflowComponentFactory


@CWLKernel.register_magic
def newWorkflowBuild(kernel: CWLKernel, *args):
kernel._send_json_response(kernel._workflow_composer.to_dict())
kernel._workflow_repository.register_tool(kernel._workflow_composer)
kernel._workflow_composer = None
kernel.send_json_response(kernel.workflow_composer.to_dict())
kernel.workflow_repository.register_tool(kernel.workflow_composer)
kernel.workflow_composer = None


@CWLKernel.register_magic
Expand All @@ -25,7 +26,7 @@ def newWorkflowAddInput(kernel: CWLKernel, args: str):
step_id, step_in_id = args[0].split()
input_description = '\n'.join(args[1:])
input_description = y.safe_load(StringIO(input_description))
kernel._workflow_composer.add_input(
kernel.workflow_composer.add_input(
workflow_input=input_description,
step_id=step_id.strip(),
in_step_id=step_in_id.strip())
Expand All @@ -39,29 +40,41 @@ def newWorkflowAddStepIn(kernel: CWLKernel, args: str):
import yaml as y
input_description = y.safe_load(StringIO(input_description))
for input_id, description in input_description.items():
kernel._workflow_composer.add_step_in_out(description, input_id, *step_in_args)
kernel.workflow_composer.add_step_in_out(description, input_id, *step_in_args)


@CWLKernel.register_magic
def newWorkflowAddStep(kernel: CWLKernel, ids: str):
tool_id, step_id = ids.split()
tool = kernel._workflow_repository.get_by_id(tool_id)
kernel._workflow_composer.add(tool, step_id)
tool = kernel.workflow_repository.get_by_id(tool_id)
kernel.workflow_composer.add(tool, step_id)


@CWLKernel.register_magic
def newWorkflowAddOutputSource(kernel: CWLKernel, args: str):
reference, type_of = args.split()
kernel._workflow_composer.add_output_source(reference, type_of)
kernel.workflow_composer.add_output_source(reference, type_of)


@CWLKernel.register_magic
def newWorkflow(kernel: CWLKernel, workflow_id: str):
kernel._workflow_composer = CWLWorkflow(workflow_id)
kernel.workflow_composer = CWLWorkflow(workflow_id)


@CWLKernel.register_magic
def snippet(kernel: CWLKernel, command: str):
"""
Submit a cwl workflow incrementally. Usage:
% snippet add
[...]
% snippet add
[...]
% snippet build
@param kernel:
@param command:
@return:
"""
command = command.splitlines()
command[0] = command[0].strip()
y = YAML(typ='rt')
Expand All @@ -73,19 +86,19 @@ def snippet(kernel: CWLKernel, command: str):
snippet = '\n'.join(command[1:])
kernel._snippet_builder.append(snippet)
workflow = kernel._snippet_builder.build()
kernel._workflow_repository.register_tool(workflow)
kernel.workflow_repository.register_tool(workflow)
current_code = y.load(StringIO(kernel._snippet_builder.get_current_code()))
kernel._snippet_builder.clear()
else:
raise ValueError()
kernel._send_json_response(current_code)
kernel.send_json_response(current_code)


@CWLKernel.register_magic
def execute(kernel: CWLKernel, execute_argument_string: str):
execute_argument_string = execute_argument_string.splitlines()
cwl_id = execute_argument_string[0].strip()
cwl_component_path: WorkflowComponent = kernel._workflow_repository.get_tools_path_by_id(cwl_id)
cwl_component_path: Path = kernel.workflow_repository.get_tools_path_by_id(cwl_id)
kernel._set_data('\n'.join(execute_argument_string[1:]))
kernel._execute_workflow(cwl_component_path)
kernel._clear_data()
Expand All @@ -102,11 +115,11 @@ def display_data(kernel: CWLKernel, data_name: str) -> None:
@return None
"""
if not isinstance(data_name, str) or len(data_name.split()) == 0:
kernel._send_error_response(
kernel.send_error_response(
'ERROR: you must select an output to display. Correct format:\n % display_data [output name]'
)
return
result = kernel._results_manager.get_last_result_by_id(data_name)
result = kernel.results_manager.get_last_result_by_id(data_name)
if result is None:
kernel.send_response(kernel.iopub_socket, 'stream', {'name': 'stderr', 'text': 'Result not found'})
return
Expand All @@ -119,13 +132,13 @@ def display_data(kernel: CWLKernel, data_name: str) -> None:
def display_data_csv(kernel: CWLKernel, data_name: str):
import pandas as pd
if not isinstance(data_name, str) or len(data_name.split()) == 0:
kernel._send_error_response(
kernel.send_error_response(
'ERROR: you must select an output to display. Correct format:\n % display_data_csv [output name]'
)
return
result = kernel._results_manager.get_last_result_by_id(data_name)
result = kernel.results_manager.get_last_result_by_id(data_name)
if result is None:
kernel._send_error_response('Result not found')
kernel.send_error_response('Result not found')
return

df = pd.read_csv(result, header=None)
Expand All @@ -149,14 +162,14 @@ def sample_csv(kernel: CWLKernel, args: str):
data_name, sample_percent = args.split()
sample_percent = float(sample_percent)
except Exception:
kernel._send_error_response(
kernel.send_error_response(
'ERROR: you must select an output to display. Correct format:\n '
'% sample_csv [output name] [percent size (0.5)]'
)
return
result = kernel._results_manager.get_last_result_by_id(data_name)
result = kernel.results_manager.get_last_result_by_id(data_name)
if result is None:
kernel._send_error_response('Result not found')
kernel.send_error_response('Result not found')
return

df = pd.read_csv(result, header=None, skiprows=lambda i: i > 0 and random.random() > sample_percent)
Expand All @@ -177,13 +190,13 @@ def sample_csv(kernel: CWLKernel, args: str):
def display_data_image(kernel: CWLKernel, data_name: str):
import base64
if not isinstance(data_name, str) or len(data_name.split()) == 0:
kernel._send_error_response(
kernel.send_error_response(
'ERROR: you must select an output to display. Correct format:\n % display_data [output name]'
)
return
result = kernel._results_manager.get_last_result_by_id(data_name)
result = kernel.results_manager.get_last_result_by_id(data_name)
if result is None:
kernel._send_error_response('Result not found')
kernel.send_error_response('Result not found')
return

kernel.log.debug(result)
Expand Down Expand Up @@ -270,18 +283,18 @@ def githubImport(kernel: CWLKernel, url: str):
with open(cwl_file) as f:
file_data = f.read()
cwl_component = cwl_factory.get_workflow_component(file_data)
kernel._workflow_repository.register_tool(cwl_component)
kernel.workflow_repository.register_tool(cwl_component)
kernel.send_response(kernel.iopub_socket, 'stream',
{'name': 'stdout', 'text': f"tool '{cwl_component.id}' registered\n"})


@CWLKernel.register_magic
def viewTool(kernel: CWLKernel, workflow_id: str):
workflow = kernel._workflow_repository.__repo__.get_by_id(workflow_id)
workflow = kernel.workflow_repository.__repo__.get_by_id(workflow_id)
if workflow is not None:
kernel._send_json_response(workflow.to_dict())
kernel.send_json_response(workflow.to_dict())
else:
kernel._send_error_response(f"Tool '{workflow_id}' is not registered")
kernel.send_error_response(f"Tool '{workflow_id}' is not registered")


@CWLKernel.register_magic
Expand Down
Loading

0 comments on commit 6e91265

Please sign in to comment.