diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index beedbf5..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -include LICENSE -include README.md -recursive-include share * -include copy_voila_template.py -include requirements*.txt diff --git a/README.md b/README.md index 3550202..b1afc67 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ # Voilà template for Materials Cloud + [![PyPI - Version](https://img.shields.io/pypi/v/voila-materialscloud-template?color=4CC61E)](https://pypi.org/project/voila-materialscloud-template/) [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/materialscloud-org/voila-materialscloud-template/main?urlpath=%2Fvoila%2Frender%2Fexample-notebooks%2Fexample.ipynb) This is the Voilà template for Materials Cloud, implements the standard header and CSS. Three templates are provided: -* `materialscloud-tool` - highlights the [WORK](https://www.materialscloud.org/work)/Tools section in the header/breadcrumbs. -* `materialscloud-discover` - highlights the [DISCOVER](https://www.materialscloud.org/discover) section in the header/breadcrumbs. -* `materialscloud-iframe` - just adds a simple "Hosted on Materials Cloud" note at the bottom. + +- `materialscloud-tool` - highlights the [WORK](https://www.materialscloud.org/work)/Tools section in the header/breadcrumbs. +- `materialscloud-discover` - highlights the [DISCOVER](https://www.materialscloud.org/discover) section in the header/breadcrumbs. +- `materialscloud-iframe` - just adds a simple "Hosted on Materials Cloud" note at the bottom. ## Installation @@ -24,6 +26,7 @@ The main way is to use the `voila --template` option, e.g.: ```bash voila --template=materialscloud-tool example.ipynb ``` + Alternatively, you can write a `voila.json` file containing ```json @@ -51,7 +54,7 @@ Option 1: pip install -e .[dev] ``` -Note: this will copy the templates to the jupyter folder, and they need to be modified directly there or re-copied if new tests are required. +Note: this will copy the templates to the jupyter folder, and they need to be modified directly there or re-copied for changes to take effect. Option 2: @@ -69,10 +72,11 @@ Note: maybe there is an easier setup, e.g. with live-reload or similar. ### Making a new release To release a new version, just make a new release on Github with the correct version tag, without updating any versions manually. This will start the GitHub action that will -* update version numbers in the repo and commits it; -* tags this new commit with the version, overwriting the tag that was made by the Github release; -* pushes commit & tag to Github; -* publishes new version on PYPI. + +- update version numbers in the repo and commits it; +- tags this new commit with the version, overwriting the tag that was made by the Github release; +- pushes commit & tag to Github; +- publishes new version on PYPI. ## License diff --git a/copy_voila_template.py b/copy_voila_template.py deleted file mode 100755 index 003c521..0000000 --- a/copy_voila_template.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -import os -import json -from pathlib import Path -import shutil -import sys -from typing import Tuple - - -def get_voila_templates_dir() -> Tuple[Path, Path]: - """Find absolute path to Jupyter's data dir that contains Voilà templates""" - jupyter_dirs = os.popen("jupyter --paths --json") - try: - jupyter_dirs = json.loads(jupyter_dirs.read()) - except json.JSONDecodeError as exc: - raise RuntimeError( - "Could not decode shell command 'jupyter --paths --json' as JSON." - f"Original exception:\n{exc}" - ) - - for data_dir in jupyter_dirs.get("data", []): - data_dir = Path(data_dir) - nbconvert_templates_dir = data_dir / "nbconvert/templates/" - voila_templates_dir = data_dir / "voila/templates/" - if voila_templates_dir.exists(): - break - else: - for data_dir in jupyter_dirs.get("data", []): - if ".local" in data_dir: - data_dir = Path(data_dir) - # Create "voila/templates/" in this virtualenv-specific config folder - voila_templates_dir = data_dir / "voila/templates/" - voila_templates_dir.mkdir(parents=True, exist_ok=True) - # Create "nbconvert/templates/" in this virtualenv-specific config folder - nbconvert_templates_dir = data_dir / "nbconvert/templates/" - nbconvert_templates_dir.mkdir(parents=True, exist_ok=True) - break - else: - raise RuntimeError( - f"No valid Voilà 'templates' folder found amongst: {jupyter_dirs.get('data', [])!r}. " - "Also could not find '.local' in any of data directories." - ) - - return voila_templates_dir.resolve(), nbconvert_templates_dir.resolve() - - -def copy_template(name: str): - """Copy a Voilà template to Jupyter's first (and best) data dir""" - src_voila = Path(__file__).parent.joinpath(f'share/jupyter/voila/templates/{name}').resolve() - src_nbconvert = Path(__file__).parent.joinpath(f'share/jupyter/nbconvert/templates/{name}').resolve() - - for src in (src_voila, src_nbconvert): - if not src.exists(): - raise RuntimeError(f"Can not find provided template {name!r} at {src} !") - - dest_voila, dest_nbconvert = get_voila_templates_dir() - - for dest in (dest_voila, dest_nbconvert): - if dest.joinpath(name).exists(): - print( - f"Template {name!r} has already been copied into {dest}, " - "will first remove it, then copy it anew !" - ) - shutil.rmtree(str(dest / name)) - print(f"Successfully removed {dest / name} !") - - for src, dest in zip((src_voila, src_nbconvert), (dest_voila, dest_nbconvert)): - print(f"Will now copy {src} to {dest / name}.") - shutil.copytree(src, dest / name, symlinks=False) - print(f"Successfully copied {name!r} to {dest} !") - - -if __name__ == "__main__": - if len(sys.argv) > 1: - template = sys.argv[1] - else: - print("No template supplied to be copied!") - sys.exit(0) - - try: - copy_template(template) - except Exception as exc: # pylint: disable=broad-except - sys.exit(f"ERROR while copying template: {exc}") - else: - sys.exit(0) diff --git a/docker/Dockerfile b/docker/Dockerfile index 1d639dc..6b8fddf 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,10 +2,7 @@ FROM python:3.9 WORKDIR /home/voila -COPY requirements.txt . -RUN pip install -r requirements.txt - -COPY requirements_dev.txt . -RUN pip install -r requirements_dev.txt +COPY pyproject.toml LICENSE.txt README.md ./ +RUN pip install .[dev] EXPOSE 8866 \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..db9acb1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,43 @@ +[build-system] +requires = ["hatchling >=1.5"] +build-backend = "hatchling.build" + +[project] +name = "voila-materialscloud-template" +version = "0.4.1" +description = 'Voilà template for Materials Cloud.' +authors = [{ name = "The Materials Cloud team" }] +urls = { Source = 'https://github.com/materialscloud-org/voila-materialscloud-template' } +license = { file = 'LICENSE.txt' } +readme = "README.md" +keywords = ['voila', 'jupyter', 'materialscloud'] +classifiers = [ + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", +] + +requires-python = ">=3.8" +dependencies = ["voila~=0.4.4", "jupyter-core~=5.3.1"] + +[project.optional-dependencies] +dev = [ + "invoke~=2.2", + "ipywidgets~=8.1", + "pylint~=2.17", + "jupyterlab~=4.0", + "widget-periodictable~=4.1", +] + +[tool.hatch.build.targets.sdist] +artifacts = ["share"] + +[tool.hatch.build.targets.wheel] +packages = ["share"] + +# copy the templates to the correct location +[tool.hatch.build.targets.wheel.shared-data] +"share/jupyter" = "share/jupyter" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 64a0e1b..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -voila~=0.4.4 -jupyter-core~=5.3.1 \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index a6d1714..0000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,5 +0,0 @@ -invoke~=2.2 -ipywidgets~=8.1 -pylint~=2.17 -jupyterlab~=4.0 -widget-periodictable~=4.1 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index b8cac62..0000000 --- a/setup.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[bdist_wheel] -universal = 1 - -[metadata] -license_files = [LICENSE] - -[flake8] -max-line-length=200 diff --git a/setup.py b/setup.py deleted file mode 100644 index 97a257a..0000000 --- a/setup.py +++ /dev/null @@ -1,65 +0,0 @@ -from pathlib import Path -from subprocess import check_call - -from setuptools import setup -from setuptools.command.develop import develop -from setuptools.command.install import install - -def post_install(): - """Copy materialscloud templates' files to Jupyter config location""" - for template in ("materialscloud", "materialscloud-iframe", "materialscloud-tool", "materialscloud-discover"): - check_call(['./copy_voila_template.py', template], cwd=TOP_DIR) - -class ExtraInstall(install): - """Post-installation for installation (install) mode.""" - - def run(self): - """Install application and copy template files to Jupyter location afterwards.""" - install.run(self) - post_install() - - -class ExtraDevelop(develop): - """Post-installation for editable (develop) mode.""" - - def run(self): - """Install application and copy template files to Jupyter location afterwards.""" - develop.run(self) - post_install() - - -TOP_DIR = Path(__file__).parent.resolve() - -with open(TOP_DIR.joinpath("README.md")) as handle: - README = handle.read() - -with open(TOP_DIR.joinpath("requirements.txt")) as handle: - REQUIREMENTS_BASE = [f"{_.strip()}" for _ in handle.readlines() if " " not in _] - -with open(TOP_DIR.joinpath("requirements_dev.txt")) as handle: - REQUIREMENTS_DEV = [f"{_.strip()}" for _ in handle.readlines() if " " not in _] - - -setup( - name='voila-materialscloud-template', - version='0.4.1', - packages=[], - author='Dou Du and Casper Welzel Andersen', - author_email='dou.du@epfl.ch', - url='https://github.com/materialscloud-org/voila-materialscloud-template', - license='BSD', - description='Voilà template for Materials Cloud that implements the Materials Cloud header and CSS.', - long_description=README, - long_description_content_type='text/markdown', - keywords='voila jupyter materialscloud', - cmdclass={ - 'develop': ExtraDevelop, - 'install': ExtraInstall, - }, - setup_requires=[ - 'setuptools>=42.0.0', - 'jupyter-core~=5.3.1', - ], - install_requires=REQUIREMENTS_BASE, - extras_require={'dev': REQUIREMENTS_DEV} -)