Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Unit tests

on:
- push
- pull_request

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
- uses: mamba-org/setup-micromamba@v2
with:
environment-file: environment.yml
init-shell: >-
bash
cache-environment: false
create-args: python=${{ matrix.python-version }}
post-cleanup: 'all'
- name: Install xcengine
shell: bash -el {0}
run: |
python --version
pip install --no-deps --editable .
- name: Run pytest
shell: bash -el {0}
run: |
pytest --cov=xcengine --cov-branch --cov-report=xml
- uses: codecov/codecov-action@v5
with:
verbose: true
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Unit tests](https://github.com/xcube-dev/xcengine/actions/workflows/tests.yaml/badge.svg)](https://github.com/xcube-dev/xcengine/actions/workflows/tests.yaml)

# xcengine: turn Jupyter notebooks into Application Packages

xcengine provides tools to convert a Jupyter notebook into one of several
Expand Down
4 changes: 3 additions & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ channels:
- conda-forge
dependencies:
# Python
- python >=3.10
- python >=3.11
# Required
- click
- docker-py
- ipython # Used by nbconvert to transform IPython syntax to pure Python
- nbconvert
- nbformat
- pystac
- pyyaml
- xcube # See note below
# test dependencies
- pytest
- pytest-cov

# Note: xcube is not required for the conversion itself, but is required
# to run generated scripts outside containers ("create" mode).
13 changes: 8 additions & 5 deletions xcengine/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def make_cwl_params(self):
def from_code(cls, code: str) -> "NotebookParameters":
# TODO run whole notebook up to params cell, not just the params cell!
# (Because it might use imports etc. from earlier in the notebook.)
# This will need some tweaking of the parameter extraction -- see
# comment therein.
return cls(cls.extract_variables(code))

@classmethod
Expand All @@ -60,10 +62,11 @@ def from_yaml_file(cls, path: str | os.PathLike) -> "NotebookParameters":

@classmethod
def extract_variables(cls, code: str) -> dict[str, tuple[type, Any]]:
_old_locals = set(locals().keys())
exec(code)
newvars = locals().keys() - _old_locals - {"_old_locals"}
return {k: cls.make_param_tuple(locals()[k]) for k in newvars}
# TODO: just working on a single code block is insufficient:
# We should execute everything up to the params cell, but only extract
# variables defined in the params cell.
exec(code, globals(), locals_ := {})
return {k: cls.make_param_tuple(locals_[k]) for k in (locals_.keys())}

@staticmethod
def make_param_tuple(value: Any) -> tuple[type, Any]:
Expand Down Expand Up @@ -98,7 +101,7 @@ def get_cwl_workflow_input(self, var_name: str) -> dict[str, Any]:

def get_cwl_commandline_input(self, var_name: str) -> dict[str, Any]:
return self.get_cwl_workflow_input(var_name) | {
"inputBinding": {"prefix": f"--{var_name.replace("_", "-")}"}
"inputBinding": {"prefix": f'--{var_name.replace("_", "-")}'}
}

def to_yaml(self) -> str:
Expand Down