Skip to content

Commit

Permalink
add magics commands
Browse files Browse the repository at this point in the history
  • Loading branch information
giannisdoukas committed Jun 28, 2020
1 parent 3e4f404 commit e65bc71
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 8 deletions.
3 changes: 3 additions & 0 deletions cwlkernel/CWLKernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ def do_complete(self, code: str, cursor_pos: int):
self.log.debug(f'suggestions: {suggestions["matches"]}')
return {**suggestions, 'status': 'ok'}

def send_text_to_stdout(self, text: str):
self.send_response(self.iopub_socket, 'stream', {'name': 'stdout', 'text': text})


if __name__ == '__main__':
from ipykernel.kernelapp import IPKernelApp
Expand Down
45 changes: 42 additions & 3 deletions cwlkernel/kernel_magics.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import json
import os
import random
Expand Down Expand Up @@ -104,7 +105,15 @@ def execute(kernel: CWLKernel, execute_argument_string: str):


@CWLKernel.register_magic
def display_data(kernel: CWLKernel, data_name: str):
def display_data(kernel: CWLKernel, data_name: str) -> None:
"""
Display the data generated by workflow.
Usage % display_data [data id]
@param kernel: the kernel instance
@param data_name: the data id
@return None
"""
if not isinstance(data_name, str) or len(data_name.split()) == 0:
kernel._send_error_response(
'ERROR: you must select an output to display. Correct format:\n % display_data [output name]'
Expand Down Expand Up @@ -245,6 +254,9 @@ def logs(kernel: CWLKernel, limit=None):

@CWLKernel.register_magic
def data(kernel: CWLKernel, *args):
"""
Display all the data which are registered in the kernel session.
"""
data = "<ul>\n" + '\n'.join(
[f'\t<li><a href="file://{d}" target="_empty">{d}</a></li>' for d in kernel.get_past_results()]) + "\n</ul>"
kernel.send_response(
Expand Down Expand Up @@ -286,8 +298,35 @@ def viewTool(kernel: CWLKernel, workflow_id: str):


@CWLKernel.register_magic
def magics(kernel: CWLKernel, *args):
kernel._send_json_response(list(kernel._magic_commands.keys()))
def magics(kernel: CWLKernel, arg: str):
arg = arg.split()
parser = argparse.ArgumentParser()
parser.add_argument('magic', default=None, nargs='?')
arg = parser.parse_args(arg)
if arg.magic is None:
commands = ['\t- ' + cmd for cmd in kernel._magic_commands.keys()]
commands.sort()
commands = os.linesep.join(commands)
kernel.send_text_to_stdout(
f'List of Available Magic commands\n{commands}'
)
else:
try:
full_doc: str = globals()[arg.magic].__doc__.splitlines()
doc = []
for line_number, line in enumerate(full_doc):
line = line.strip()
if line.startswith('@'):
break
elif len(line) > 0:
doc.append(line)
doc = os.linesep.join(doc)

kernel.send_text_to_stdout(doc)
except Exception:
kernel.send_text_to_stdout(
'The function does not provide documentation'
)


# import user's magic commands
Expand Down
63 changes: 58 additions & 5 deletions examples/introduction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"source": [
"#!/usr/bin/env cwl-runner\n",
"\n",
"cwlVersion: v1.0\n",
"cwlVersion: v1.1\n",
"class: CommandLineTool\n",
"baseCommand: echo\n",
"id: echo\n",
Expand Down Expand Up @@ -89,19 +89,20 @@
"data": {
"application/json": {
"example_output": {
"basename": "f811c63eed22dec4eec6f02280820eabf16fa779",
"basename": "2e0a23bee9af60260156f18c56053610387aefc3",
"checksum": "sha1$47a013e660d408619d894b20806b1d5086aab03b",
"class": "File",
"http://commonwl.org/cwltool#generation": 0,
"id": "example_output",
"location": "file:///private/tmp/CWLKERNEL_DATA/runtime_data/f811c63eed22dec4eec6f02280820eabf16fa779",
"location": "file:///private/tmp/CWLKERNEL_DATA/fde9200f-dffd-4493-9ff5-03ea5f0cd4dd/runtime_data/2e0a23bee9af60260156f18c56053610387aefc3",
"nameext": "",
"nameroot": "f811c63eed22dec4eec6f02280820eabf16fa779",
"nameroot": "2e0a23bee9af60260156f18c56053610387aefc3",
"result_counter": 0,
"size": 13
}
},
"text/plain": [
"<IPython.core.display.JSON object>"
"{\"example_output\": {\"location\": \"file:///private/tmp/CWLKERNEL_DATA/fde9200f-dffd-4493-9ff5-03ea5f0cd4dd/runtime_data/2e0a23bee9af60260156f18c56053610387aefc3\", \"basename\": \"2e0a23bee9af60260156f18c56053610387aefc3\", \"nameroot\": \"2e0a23bee9af60260156f18c56053610387aefc3\", \"nameext\": \"\", \"class\": \"File\", \"checksum\": \"sha1$47a013e660d408619d894b20806b1d5086aab03b\", \"size\": 13, \"http://commonwl.org/cwltool#generation\": 0, \"id\": \"example_output\", \"result_counter\": 0}}"
]
},
"metadata": {
Expand All @@ -122,6 +123,58 @@
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"List of Available Magic commands\n",
"\t- data\n",
"\t- display_data\n",
"\t- display_data_csv\n",
"\t- display_data_image\n",
"\t- execute\n",
"\t- githubImport\n",
"\t- logs\n",
"\t- magics\n",
"\t- newWorkflow\n",
"\t- newWorkflowAddInput\n",
"\t- newWorkflowAddOutputSource\n",
"\t- newWorkflowAddStep\n",
"\t- newWorkflowAddStepIn\n",
"\t- newWorkflowBuild\n",
"\t- sample_csv\n",
"\t- snippet\n",
"\t- viewTool"
]
}
],
"source": [
"% magics"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Display the data generated by workflow.\n",
"Usage % display_data [data id]"
]
}
],
"source": [
"% magics display_data"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
Expand Down
32 changes: 32 additions & 0 deletions tests/test_CWLKernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,38 @@ def test_import_users_magic_commands(self):
)
os.environ.pop('CWLKERNEL_MAGIC_COMMANDS_DIRECTORY')

def test_magics_magic_command(self):
kernel = CWLKernel()
# cancel send_response
responses = []
kernel.send_response = lambda *args, **kwargs: responses.append((args, kwargs))

commands = [f'\t- {cmd}' for cmd in kernel._magic_commands.keys()]
commands.sort()


self.assertDictEqual(
{'status': 'ok', 'execution_count': 0, 'payload': [], 'user_expressions': {}},
kernel.do_execute(f"""% magics""")
)
self.assertEqual(
'List of Available Magic commands\n' + os.linesep.join(commands),
responses[-1][0][2]['text']
)

self.assertDictEqual(
{'status': 'ok', 'execution_count': 0, 'payload': [], 'user_expressions': {}},
kernel.do_execute(f"""% magics data""")
)
from cwlkernel.kernel_magics import data as data_magic_command
import inspect
self.assertEqual(
inspect.getdoc(data_magic_command),
responses[-1][0][2]['text']
)
self.assertIn(' '.join('Display all the data which are registered in the kernel session.'.split()),
' '.join(responses[-1][0][2]['text'].split()))


if __name__ == '__main__':
unittest.main()

0 comments on commit e65bc71

Please sign in to comment.