Skip to content

Commit 3b2839e

Browse files
authored
use version 1.1.0 of integration interface (#67)
1 parent 80dbc9a commit 3b2839e

30 files changed

+201
-167
lines changed

.cookiecutterrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ default_context:
3535
project_slug: 'osparc-python-runner'
3636
project_type: 'computational'
3737
release_date: '2020'
38-
version: '1.3.0'
38+
version: '2.0.0'

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.3.0
1+
2.0.0

VERSION_INTEGRATION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.0
1+
1.1.0

docker-compose-meta.yml

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,21 @@ services:
1717
input data file", "type": "data:*/*"}, "input_5": {"displayOrder": 5, "label":
1818
"Additional input data - optional", "description": "Any additional input
1919
data file", "type": "data:*/*"}}}'
20-
io.simcore.integration-version: '{"integration-version": "1.0.0"}'
20+
io.simcore.integration-version: '{"integration-version": "1.1.0"}'
2121
io.simcore.key: '{"key": "simcore/services/comp/osparc-python-runner"}'
2222
io.simcore.name: '{"name": "oSparc Python Runner"}'
2323
io.simcore.outputs: '{"outputs": {"output_1": {"displayOrder": 1, "label":
2424
"Output data", "description": "The data produced by the script and saved
25-
under OUTPUT_FOLDER/output_1 as output_1.zip", "type": "data:*/*", "fileToKeyMap":
26-
{"output_1.zip": "output_1"}}, "output_2": {"displayOrder": 2, "label":
25+
under OUTPUT_FOLDER/output_1 as output_1.zip", "type": "data:*/*"}, "output_2":
26+
{"displayOrder": 2, "label": "Output data", "description": "The data produced
27+
by the script and saved under OUTPUT_FOLDER/output_2 as output_2.zip", "type":
28+
"data:*/*"}, "output_3": {"displayOrder": 3, "label": "Output data", "description":
29+
"The data produced by the script and saved under OUTPUT_FOLDER/output_3
30+
as output_3.zip", "type": "data:*/*"}, "output_4": {"displayOrder": 4, "label":
2731
"Output data", "description": "The data produced by the script and saved
28-
under OUTPUT_FOLDER/output_2 as output_2.zip", "type": "data:*/*", "fileToKeyMap":
29-
{"output_2.zip": "output_2"}}, "output_3": {"displayOrder": 3, "label":
30-
"Output data", "description": "The data produced by the script and saved
31-
under OUTPUT_FOLDER/output_3 as output_3.zip", "type": "data:*/*", "fileToKeyMap":
32-
{"output_3.zip": "output_3"}}, "output_4": {"displayOrder": 4, "label":
33-
"Output data", "description": "The data produced by the script and saved
34-
under OUTPUT_FOLDER/output_4 as output_4.zip", "type": "data:*/*", "fileToKeyMap":
35-
{"output_4.zip": "output_4"}}}}'
32+
under OUTPUT_FOLDER/output_4 as output_4.zip", "type": "data:*/*"}}}'
3633
io.simcore.type: '{"type": "computational"}'
37-
io.simcore.version: '{"version": "1.3.0"}'
34+
io.simcore.version: '{"version": "2.0.0"}'
3835
org.label-schema.build-date: ${BUILD_DATE}
3936
org.label-schema.schema-version: '1.0'
4037
org.label-schema.vcs-ref: ${VCS_REF}

metadata/metadata.yml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: oSparc Python Runner
22
key: simcore/services/comp/osparc-python-runner
33
type: computational
4-
integration-version: 1.0.0
5-
version: 1.3.0
4+
integration-version: 1.1.0
5+
version: 2.0.0
66
description: oSparc Python Runner
77
contact: anderegg@itis.swiss
88
authors:
@@ -44,26 +44,18 @@ outputs:
4444
label: Output data
4545
description: The data produced by the script and saved under OUTPUT_FOLDER/output_1 as output_1.zip
4646
type: data:*/*
47-
fileToKeyMap:
48-
output_1.zip: output_1
4947
output_2:
5048
displayOrder: 2
5149
label: Output data
5250
description: The data produced by the script and saved under OUTPUT_FOLDER/output_2 as output_2.zip
5351
type: data:*/*
54-
fileToKeyMap:
55-
output_2.zip: output_2
5652
output_3:
5753
displayOrder: 3
5854
label: Output data
5955
description: The data produced by the script and saved under OUTPUT_FOLDER/output_3 as output_3.zip
6056
type: data:*/*
61-
fileToKeyMap:
62-
output_3.zip: output_3
6357
output_4:
6458
displayOrder: 4
6559
label: Output data
6660
description: The data produced by the script and saved under OUTPUT_FOLDER/output_4 as output_4.zip
6761
type: data:*/*
68-
fileToKeyMap:
69-
output_4.zip: output_4

requirements.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ black
88
coverage
99
docker
1010
jsonschema
11+
pylint
1112
pytest
1213
pytest-cookies
1314
pytest-cov

requirements.txt

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
#
55
# pip-compile --output-file=requirements.txt
66
#
7-
arrow==1.2.2
7+
arrow==1.2.3
88
# via jinja2-time
9-
attrs==21.4.0
9+
astroid==2.12.9
10+
# via pylint
11+
attrs==22.1.0
1012
# via
1113
# jsonschema
1214
# pytest
@@ -18,54 +20,70 @@ bump2version==1.0.1
1820
# via bumpversion
1921
bumpversion==0.6.0
2022
# via -r requirements.in
21-
certifi==2021.10.8
23+
certifi==2022.9.14
2224
# via requests
23-
chardet==4.0.0
25+
chardet==5.0.0
2426
# via binaryornot
25-
charset-normalizer==2.0.12
27+
charset-normalizer==2.1.1
2628
# via requests
27-
click==8.1.0
29+
click==8.1.3
2830
# via
2931
# black
3032
# cookiecutter
3133
cookiecutter==2.1.1
3234
# via pytest-cookies
33-
coverage[toml]==6.3.2
35+
coverage[toml]==6.4.4
3436
# via
3537
# -r requirements.in
3638
# pytest-cov
39+
dill==0.3.5.1
40+
# via pylint
3741
docker==6.0.0
3842
# via -r requirements.in
39-
idna==3.3
43+
idna==3.4
4044
# via requests
45+
importlib-resources==5.9.0
46+
# via jsonschema
4147
iniconfig==1.1.1
4248
# via pytest
43-
jinja2==3.1.1
49+
isort==5.10.1
50+
# via pylint
51+
jinja2==3.1.2
4452
# via
4553
# cookiecutter
4654
# jinja2-time
4755
jinja2-time==0.2.0
4856
# via cookiecutter
4957
jsonschema==4.16.0
5058
# via -r requirements.in
59+
lazy-object-proxy==1.7.1
60+
# via astroid
5161
markupsafe==2.1.1
5262
# via jinja2
63+
mccabe==0.7.0
64+
# via pylint
5365
mypy-extensions==0.4.3
5466
# via black
5567
packaging==21.3
5668
# via
5769
# docker
5870
# pytest
5971
# pytest-sugar
60-
pathspec==0.9.0
61-
# via black
62-
platformdirs==2.5.1
72+
pathspec==0.10.1
6373
# via black
74+
pkgutil-resolve-name==1.3.10
75+
# via jsonschema
76+
platformdirs==2.5.2
77+
# via
78+
# black
79+
# pylint
6480
pluggy==1.0.0
6581
# via pytest
6682
py==1.11.0
6783
# via pytest
68-
pyparsing==3.0.7
84+
pylint==2.15.2
85+
# via -r requirements.in
86+
pyparsing==3.0.9
6987
# via packaging
7088
pyrsistent==0.18.1
7189
# via jsonschema
@@ -89,30 +107,42 @@ pytest-sugar==0.9.5
89107
# via -r requirements.in
90108
python-dateutil==2.8.2
91109
# via arrow
92-
python-slugify==6.1.1
110+
python-slugify==6.1.2
93111
# via cookiecutter
94112
pyyaml==6.0
95113
# via
96114
# -r requirements.in
97115
# cookiecutter
98-
requests==2.27.1
116+
requests==2.28.1
99117
# via
100118
# cookiecutter
101119
# docker
102120
six==1.16.0
103121
# via python-dateutil
104-
termcolor==1.1.0
122+
termcolor==2.0.1
105123
# via pytest-sugar
106124
text-unidecode==1.3
107125
# via python-slugify
108126
tomli==2.0.1
109127
# via
110128
# black
111129
# coverage
130+
# pylint
112131
# pytest
113-
urllib3==1.26.9
132+
tomlkit==0.11.4
133+
# via pylint
134+
typing-extensions==4.3.0
135+
# via
136+
# astroid
137+
# black
138+
# pylint
139+
urllib3==1.26.12
114140
# via
115141
# docker
116142
# requests
117-
websocket-client==1.3.2
143+
websocket-client==1.4.1
118144
# via docker
145+
wrapt==1.14.1
146+
# via astroid
147+
zipp==3.8.1
148+
# via importlib-resources

service.cli/run

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ INPUT_4=$INPUT_FOLDER/input_4
1919
export INPUT_4
2020
INPUT_5=$INPUT_FOLDER/input_5
2121
export INPUT_5
22+
OUTPUT_1=$OUTPUT_FOLDER/output_1
23+
export OUTPUT_1
24+
OUTPUT_2=$OUTPUT_FOLDER/output_2
25+
export OUTPUT_2
26+
OUTPUT_3=$OUTPUT_FOLDER/output_3
27+
export OUTPUT_3
28+
OUTPUT_4=$OUTPUT_FOLDER/output_4
29+
export OUTPUT_4
2230

2331
exec execute.sh
2432

src/osparc_python_runner/main.py

Lines changed: 23 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
11
import json
22
import logging
33
import os
4-
import shutil
54
import subprocess
65
import sys
76
from pathlib import Path
8-
from typing import Dict
97

108
logging.basicConfig(level=logging.INFO)
119
logger = logging.getLogger("osparc-python-main")
1210

1311

14-
ENVIRONS = ["INPUT_FOLDER", "OUTPUT_FOLDER"]
15-
try:
16-
INPUT_FOLDER, OUTPUT_FOLDER = [Path(os.environ[v]) for v in ENVIRONS]
17-
except KeyError:
18-
raise ValueError("Required env vars {ENVIRONS} were not set")
19-
20-
# NOTE: sync with schema in metadata!!
21-
NUM_INPUTS = 5
22-
NUM_OUTPUTS = 4
23-
OUTPUT_SUBFOLDER_ENV_TEMPLATE = "OUTPUT_{}"
24-
OUTPUT_SUBFOLDER_TEMPLATE = "output_{}"
25-
OUTPUT_FILE_TEMPLATE = "output_{}.zip"
12+
INPUT_1 = Path(os.environ["INPUT_1"])
2613

2714

2815
def _find_user_code_entrypoint(code_dir: Path) -> Path:
@@ -58,59 +45,44 @@ def _ensure_pip_requirements(code_dir: Path) -> Path:
5845
f"pipreqs --savepath={requirements} --force {code_dir}".split(),
5946
shell=False,
6047
check=True,
61-
cwd=INPUT_FOLDER,
48+
cwd=INPUT_1,
6249
)
6350

6451
# TODO log subprocess.run
6552

6653
else:
6754
requirements = requirements[0]
68-
logger.info(f"Found: {requirements}")
55+
logger.info("Found: %s", requirements)
6956
return requirements
7057

7158

72-
# TODO: Next version of integration will take care of this and maybe the ENVs as well
73-
def _ensure_output_subfolders_exist() -> Dict[str, str]:
74-
output_envs = {}
75-
for n in range(1, NUM_OUTPUTS + 1):
76-
output_sub_folder_env = f"OUTPUT_{n}"
77-
output_sub_folder = OUTPUT_FOLDER / OUTPUT_SUBFOLDER_TEMPLATE.format(n)
78-
# NOTE: exist_ok for forward compatibility in case they are already created
79-
output_sub_folder.mkdir(parents=True, exist_ok=True)
80-
output_envs[output_sub_folder_env] = f"{output_sub_folder}"
81-
logger.info(
82-
"Output ENVs available: %s",
83-
json.dumps(output_envs, indent=2),
84-
)
85-
return output_envs
86-
87-
88-
def _ensure_input_environment() -> Dict[str, str]:
89-
input_envs = {
90-
f"INPUT_{n}": os.environ[f"INPUT_{n}"] for n in range(1, NUM_INPUTS + 1)
91-
}
92-
logger.info(
93-
"Input ENVs available: %s",
94-
json.dumps(input_envs, indent=2),
95-
)
96-
return input_envs
59+
def _show_io_environments() -> None:
60+
for io_type in ["input", "output"]:
61+
logger.info(
62+
"%s ENVs available: %s",
63+
io_type.capitalize(),
64+
json.dumps(
65+
list(
66+
filter(
67+
lambda x, io_type=io_type: f"{io_type.upper()}_" in x,
68+
os.environ,
69+
)
70+
),
71+
indent=2,
72+
),
73+
)
9774

9875

9976
def setup():
100-
input_envs = _ensure_input_environment()
101-
output_envs = _ensure_output_subfolders_exist()
77+
_show_io_environments()
10278
logger.info("Available data:")
10379
os.system("ls -tlah")
10480

105-
user_code_entrypoint = _find_user_code_entrypoint(INPUT_FOLDER)
106-
requirements_txt = _ensure_pip_requirements(INPUT_FOLDER)
81+
user_code_entrypoint = _find_user_code_entrypoint(INPUT_1)
82+
requirements_txt = _ensure_pip_requirements(INPUT_1)
10783

10884
logger.info("Preparing launch script ...")
10985
venv_dir = Path.home() / ".venv"
110-
bash_input_env_export = [f"export {env}={path}" for env, path in input_envs.items()]
111-
bash_output_env_export = [
112-
f"export {env}='{path}'" for env, path in output_envs.items()
113-
]
11486
script = [
11587
"#!/bin/sh",
11688
"set -o errexit",
@@ -120,30 +92,16 @@ def setup():
12092
f'python3 -m venv --system-site-packages --symlinks --upgrade "{venv_dir}"',
12193
f'"{venv_dir}/bin/pip" install -U pip wheel setuptools',
12294
f'"{venv_dir}/bin/pip" install -r "{requirements_txt}"',
123-
"\n".join(bash_input_env_export),
124-
"\n".join(bash_output_env_export),
12595
f'echo "Executing code {user_code_entrypoint.name}..."',
12696
f'"{venv_dir}/bin/python3" "{user_code_entrypoint}"',
12797
'echo "DONE ..."',
12898
]
12999
main_script_path = Path("main.sh")
130-
main_script_path.write_text("\n".join(script))
100+
main_script_path.write_text("\n".join(script), encoding="utf-8")
131101

132102

133103
def teardown():
134-
logger.info("Zipping output...")
135-
for n in range(1, NUM_OUTPUTS + 1):
136-
output_path = OUTPUT_FOLDER / f"output_{n}"
137-
archive_file_path = OUTPUT_FOLDER / OUTPUT_FILE_TEMPLATE.format(n)
138-
logger.info("Zipping %s into %s...", output_path, archive_file_path)
139-
shutil.make_archive(
140-
f"{(archive_file_path.parent / archive_file_path.stem)}",
141-
format="zip",
142-
root_dir=output_path,
143-
logger=logger,
144-
)
145-
logger.info("Zipping %s into %s done", output_path, archive_file_path)
146-
logger.info("Zipping done.")
104+
logger.info("Completed")
147105

148106

149107
if __name__ == "__main__":

0 commit comments

Comments
 (0)