Skip to content

Commit

Permalink
rm ipython2cwl imports from code
Browse files Browse the repository at this point in the history
  • Loading branch information
giannisdoukas committed Jun 22, 2020
1 parent 5344058 commit 5aefe01
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 33 deletions.
23 changes: 20 additions & 3 deletions ipython2cwl/cwltool.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
import tempfile
from collections import namedtuple
from pathlib import Path
from typing import Dict
from typing import Dict, Any

import astor
import yaml

from .iotypes import CWLFilePathInput, CWLBooleanInput, CWLIntInput, CWLStringInput, CWLFilePathOutput
from .requirements_manager import RequirementsManager

with open(os.sep.join([os.path.abspath(os.path.dirname(__file__)), 'template.dockerfile'])) as f:
with open(os.sep.join([os.path.abspath(os.path.dirname(__file__)), 'templates', 'template.dockerfile'])) as f:
DOCKERFILE_TEMPLATE = f.read()
with open(os.sep.join([os.path.abspath(os.path.dirname(__file__)), 'template.setup.py'])) as f:
with open(os.sep.join([os.path.abspath(os.path.dirname(__file__)), 'templates', 'template.setup'])) as f:
SETUP_TEMPLATE = f.read()


Expand Down Expand Up @@ -82,6 +82,23 @@ def visit_AnnAssign(self, node):
pass
return node

def visit_Import(self, node: ast.Import):
names = []
for name in node.names: # type: ast.alias
if name.name == 'ipython2cwl' or name.name.startswith('ipython2cwl.'):
continue
names.append(name)
if len(names) > 0:
node.names = names
return node
else:
return None

def visit_ImportFrom(self, node: ast.ImportFrom) -> Any:
if node.module == 'ipython2cwl' or node.module.startswith('ipython2cwl.'):
return None
return node


class AnnotatedIPython2CWLToolConverter:
"""
Expand Down
35 changes: 7 additions & 28 deletions ipython2cwl/ipython2cwl.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import argparse
import os
from pathlib import Path
from typing import List, Optional

import nbformat
from pip._internal.operations import freeze

with open(os.sep.join([os.path.abspath(os.path.dirname(__file__)), 'template.dockerfile'])) as f:
DOCKERFILE_TEMPLATE = f.read()


def directory_type(directory_argument: str):
"""Function to be used as a directory type for argparse argument."""
directory = Path(directory_argument)
if not directory.is_dir():
raise RuntimeError('directory does not exists')
return str(directory.absolute())
from .cwltool import AnnotatedIPython2CWLToolConverter


def main(argv: Optional[List[str]] = None):
Expand All @@ -24,28 +12,19 @@ def main(argv: Optional[List[str]] = None):
argv = sys.argv
parser = argparse.ArgumentParser()
parser.add_argument('jn', type=argparse.FileType('r'), nargs=1)
parser.add_argument('-o', '--output-dir', type=directory_type, required=True)
parser.add_argument('-o', '--output', type=Path, required=True)
args = parser.parse_args(argv[1:])
notebook = nbformat.read(args.jn[0], as_version=4)
output_dir = args.output_dir
output: Path = args.output
args.jn[0].close()
script_code = '\n'.join(
[f"\n\n# --------- cell - {i} ---------\n\n{cell.source}" for i, cell in
enumerate(filter(lambda c: c.cell_type == 'code', notebook.cells), start=1)]
)
print(script_code)
requirements = list(freeze.freeze())
with open(os.sep.join([output_dir, 'app.py']), 'w') as f:
f.write(script_code)
with open(os.sep.join([output_dir, 'requirements.txt']), 'w') as f:
f.write('\n'.join(requirements))
with open(os.sep.join([output_dir, 'Dockerfile']), 'w') as f:
f.write(
DOCKERFILE_TEMPLATE.format(
python_version=notebook.metadata.language_info.version,
source_code_directory=output_dir
)
)

converter = AnnotatedIPython2CWLToolConverter(script_code)
converter.compile(output)

return 0


Expand Down
File renamed without changes.
12 changes: 12 additions & 0 deletions ipython2cwl/templates/template.setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from setuptools import setup

name = 'JupyterAsATool'

setup(
name=name,
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
],
scripts=['notebookTool']
)
8 changes: 6 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ def get_version(rel_path):
setup(
name=name,
version=get_version(f"{name}/__init__.py"),
packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
packages=['ipython2cwl'],
package_dir={'ipython2cwl': 'ipython2cwl'},
package_data={'ipython2cwl': ['ipython2cwl/templates/*']},
author='Yannis Doukas',
author_email='giannisdoukas2311@gmail.com',
description='Convert IPython Jupyter Notebooks to CWL tool',
Expand All @@ -47,7 +49,9 @@ def get_version(rel_path):
"Programming Language :: Python :: 3.8",
],
entry_points={
'console_scripts': ['jupyter-jn2cwl=ipython2cwl.ipython2cwl:main'],
'console_scripts': [
'jupyter-jn2cwl=ipython2cwl.ipython2cwl:main',
],
},
install_requires=[
'nbformat>=5.0.6',
Expand Down
46 changes: 46 additions & 0 deletions tests/test_cwltool.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,52 @@ def test_AnnotatedIPython2CWLToolConverter_wrap_script_to_method(self):
locals()['main']('new message')
self.assertEqual('new message', globals()['printed_message'])

def test_AnnotatedIPython2CWLToolConverter_wrap_script_to_method_removes_ipython2cwl_imports(self):
annotated_python_scripts = [
os.linesep.join([
'import ipython2cwl',
'print("hello world")'
]),
os.linesep.join([
'import ipython2cwl as foo',
'print("hello world")'
]),
os.linesep.join([
'import ipython2cwl.iotypes',
'print("hello world")'
]),
os.linesep.join([
'from ipython2cwl import iotypes',
'print("hello world")'
]),
os.linesep.join([
'from ipython2cwl.iotypes import CWLFilePathInput',
'print("hello world")'
]),
os.linesep.join([
'from ipython2cwl.iotypes import CWLFilePathInput, CWLBooleanInput',
'print("hello world")'
]),
os.linesep.join([
'import typing, ipython2cwl',
'print("hello world")'
])
]
for script in annotated_python_scripts:
conv = AnnotatedIPython2CWLToolConverter(script)
new_script = conv._wrap_script_to_method(conv._tree, conv._variables)
print('-' * 10)
print(script)
print('-' * 2)
print(new_script)
print('-' * 10)
self.assertNotIn('ipython2cwl', new_script)

self.assertIn('typing', os.linesep.join([
'import typing, ipython2cwl'
'print("hello world")'
]))

def test_AnnotatedIPython2CWLToolConverter_output_file_annotation(self):
import tempfile
root_dir = tempfile.mkdtemp()
Expand Down

0 comments on commit 5aefe01

Please sign in to comment.