From fb937a3d19ea801b26a3943565286a93a2fef58c Mon Sep 17 00:00:00 2001 From: Markus Scheidgen <markus.scheidgen@gmail.com> Date: Wed, 13 Mar 2024 15:40:47 +0000 Subject: [PATCH] Upgraded Jupyterhub. Changelog: Fixed --- .gitlab-ci.yml | 16 +++ docs/howto/oasis/migrate.md | 24 ++++ gui/public/pyiron_logo.png | Bin 0 -> 74311 bytes gui/tests/artifacts.js | 148 ++++++++++---------- nomad/app/v1/routers/north.py | 5 +- nomad/config/north.py | 101 +++++++++++--- nomad/jupyterhub_config.py | 5 +- ops/kubernetes/nomad-prod-develop.yaml | 2 +- ops/kubernetes/nomad/Chart.lock | 6 +- ops/kubernetes/nomad/Chart.yaml | 2 +- ops/kubernetes/nomad/updatevalues.py | 74 ++++++++++ ops/kubernetes/nomad/values.yaml | 139 ++++++++++++------- ops/kubernetes/values.yaml | 2 +- pyproject.toml | 5 +- requirements-dev.txt | 171 ++++++++++++----------- requirements.txt | 173 ++++++++++++------------ scripts/check_helm_chart.sh | 17 +++ scripts/check_python_dependencies.sh | 33 +++-- scripts/generate_python_dependencies.sh | 15 +- scripts/update_helm_chart.sh | 10 ++ 20 files changed, 604 insertions(+), 344 deletions(-) create mode 100644 gui/public/pyiron_logo.png create mode 100644 ops/kubernetes/nomad/updatevalues.py create mode 100755 scripts/check_helm_chart.sh create mode 100755 scripts/update_helm_chart.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 11ca0c7eea..6da592a30a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -147,6 +147,22 @@ check python dependencies: - when: manual allow_failure: true +check helm chart: + stage: test + image: ${CI_REGISTRY_IMAGE}/dev_python:${DOCKER_TAG} + script: + - scripts/check_helm_chart.sh + after_script: + - > + if [ $CI_JOB_STATUS == 'failed' ]; then + echo 'Make sure that the helm chart values.yaml has been updated and committed by running' + echo './scripts/update_hem_chart.sh' + fi + rules: + - if: $CI_COMMIT_TAG + when: never + - when: on_success + check gui artifacts: stage: test image: ${CI_REGISTRY_IMAGE}/dev_python:${DOCKER_TAG} diff --git a/docs/howto/oasis/migrate.md b/docs/howto/oasis/migrate.md index 6ef3acfaf0..e893eab11f 100644 --- a/docs/howto/oasis/migrate.md +++ b/docs/howto/oasis/migrate.md @@ -66,6 +66,30 @@ For changing the minor or major version, please check the [migration steps](#mig ## Migration steps +### to 1.2.2 + +We upgraded the Jupyterhub version used for NORTH from 1.0.2 to 4.0.2. By default the +Jupyterhub database is persisted in the `nomad_oasis_north` container. If you want to +keep the database (e.g. to not loose any open tools), you will have to upgrade the database. +Update the NOMAD docker image version and restart the Oasis like this: + +``` +docker compose down +docker compose pull +docker copmose run north python -m jupyterhub upgrade +docker compose up -d +``` + +Alternatively, you can delete the `nomad_oasis_north` container and start with a fresh +database. Make sure that all north tools are stopped and removed. + +``` +docker compose down +docker rm nomad_oasis_north +docker compose pull +docker compose up -d +``` + ### to 1.2.0 - We introduced the plugin mechanism. There are now more options to control which schemas diff --git a/gui/public/pyiron_logo.png b/gui/public/pyiron_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3fb087817bdf45cd7fdcfc3f3d7687c47f5e279 GIT binary patch literal 74311 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 z
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 literal 0 HcmV?d00001 diff --git a/gui/tests/artifacts.js b/gui/tests/artifacts.js index bafe358be1..e985fbd18e 100644 --- a/gui/tests/artifacts.js +++ b/gui/tests/artifacts.js @@ -103273,58 +103273,56 @@ window.nomadArtifacts = { }, "northTools": { "jupyter": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/jupyterlab:prod", - "description": "### **Jupyter Notebook**: The Classic Notebook Interface\n\nThe Jupyter Notebook is the original web application for creating and sharing computational documents. It offers a simple, streamlined, document-centric experience.", "short_description": "Basic jupyter run with an empty notebook or on given notebook file.", + "description": "### **Jupyter Notebook**: The Classic Notebook Interface\n\nThe Jupyter Notebook is the original web application for creating and sharing computational documents. It offers a simple, streamlined, document-centric experience.", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/north/jupyter:latest", "cmd": null, - "with_path": true, + "image_pull_policy": "Always", + "privileged": false, "path_prefix": "lab/tree", - "mount_path": "/home/jovyan", - "icon": "jupyter_logo.svg", + "with_path": true, "file_extensions": [ "ipynb" ], + "mount_path": "/home/jovyan", + "icon": "jupyter_logo.svg", "maintainer": [ { "name": "Markus Scheidgen", "email": "markus.scheidgen@physik.hu-berlin.de" - }, - { - "name": "Some-one Else", - "email": "markus.scheidgen@physik.hu-berlin.de" } ], - "privileged": false, "external_mounts": [] }, "nionswift": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/nionswift-webtop", - "description": "Run Nion Swift to analyze data.", "short_description": "Run NionSwift to analyze data as well as prepare focus series reconstructions", + "description": "Run Nion Swift to analyze data.", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/nionswift-webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, + "with_path": false, + "file_extensions": [], "mount_path": "/config", "icon": null, - "file_extensions": [], "maintainer": [ { "name": "Sherjeel Shabih", "email": "sherjeel.shabih@hu-berlin.de" } ], - "privileged": true, "external_mounts": [] }, "nexustools": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/nexus-webtop", - "description": "Includes multiple NeXus tools for visualization and analysis.", "short_description": null, + "description": "Includes multiple NeXus tools for visualization and analysis.", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/nexus-webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, - "mount_path": "/config", - "icon": null, + "with_path": false, "file_extensions": [ "nxs", "nx", @@ -103335,28 +103333,31 @@ window.nomadArtifacts = { "hdf", "ipynb" ], + "mount_path": "/config", + "icon": null, "maintainer": [ { "name": "Sandor Brockhauser", "email": "sandor.brockhauser@physik.hu-berlin.de" } ], - "privileged": true, "external_mounts": [] }, "ellips": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/ellips-jupyter", - "description": "This example presents the capabilities of the NOMAD platform to store and standardize ellipsometry data. It shows the generation of a NeXus file according to the [NXellipsometry](https://manual.nexusformat.org/classes/contributed_definitions/NXellipsometry.html#nxellipsometry) application definition and a successive analysis of a SiO2 on Si Psi/Delta measurement.", "short_description": "An example for analyzing ellipsometric data.", + "description": "This example presents the capabilities of the NOMAD platform to store and standardize ellipsometry data. It shows the generation of a NeXus file according to the [NXellipsometry](https://manual.nexusformat.org/classes/contributed_definitions/NXellipsometry.html#nxellipsometry) application definition and a successive analysis of a SiO2 on Si Psi/Delta measurement.", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/ellips-jupyter", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": false, "path_prefix": "lab/tree", - "mount_path": "/home/jovyan", - "icon": "jupyter_logo.svg", + "with_path": false, "file_extensions": [ "ipynb", "nxs" ], + "mount_path": "/home/jovyan", + "icon": "jupyter_logo.svg", "maintainer": [ { "name": "Florian Dobener", @@ -103367,48 +103368,50 @@ window.nomadArtifacts = { "email": "emminger.carola@physik.hu-berlin.de" } ], - "privileged": false, "external_mounts": [] }, "mpes": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/north/mpes/webtop", - "description": "This example presents the capabilities of the NOMAD platform to store and standardize multi photoemission spectroscopy (MPES) experimental data. It contains three major examples:\n\n- Taking a pre-binned file, here stored in a h5 file, and converting it into the standardized MPES NeXus format. There exists a [NeXus application definition for MPES](https://manual.nexusformat.org/classes/contributed_definitions/NXmpes.html#nxmpes) which details the internal structure of such a file.\n- Binning of raw data (see [here](https://www.nature.com/articles/s41597-020-00769-8) for additional resources) into a h5 file and consecutively generating a NeXus file from it.\n- An analysis example using data in the NeXus format and employing the [pyARPES](https://github.com/chstan/arpes) analysis tool to reproduce the main findings of [this paper](https://arxiv.org/pdf/2107.07158.pdf).", "short_description": "An example for analyzing mpes data.", + "description": "This example presents the capabilities of the NOMAD platform to store and standardize multi photoemission spectroscopy (MPES) experimental data. It contains three major examples:\n\n- Taking a pre-binned file, here stored in a h5 file, and converting it into the standardized MPES NeXus format. There exists a [NeXus application definition for MPES](https://manual.nexusformat.org/classes/contributed_definitions/NXmpes.html#nxmpes) which details the internal structure of such a file.\n- Binning of raw data (see [here](https://www.nature.com/articles/s41597-020-00769-8) for additional resources) into a h5 file and consecutively generating a NeXus file from it.\n- An analysis example using data in the NeXus format and employing the [pyARPES](https://github.com/chstan/arpes) analysis tool to reproduce the main findings of [this paper](https://arxiv.org/pdf/2107.07158.pdf).", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/north/mpes/webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, - "mount_path": "/config", - "icon": null, + "with_path": false, "file_extensions": [ "ipynb", "nxs", "h5", "hdf5" ], + "mount_path": "/config", + "icon": null, "maintainer": [ { "name": "Florian Dobener", "email": "florian.dobener@physik.hu-berlin.de" } ], - "privileged": true, "external_mounts": [] }, "xps": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/north/xps/jupyter", - "description": "Includes tools for analyzing X-ray Photoelectron Spectroscopy (XPS) spectra and converting SPECS SLE files into NeXus.", "short_description": "An example for analyzing XPS data.", + "description": "Includes tools for analyzing X-ray Photoelectron Spectroscopy (XPS) spectra and converting SPECS SLE files into NeXus.", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/north/xps/jupyter:master", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": false, "path_prefix": "lab/tree", - "mount_path": "/home/jovyan", - "icon": "jupyter_logo.svg", + "with_path": false, "file_extensions": [ "ipynb", "nxs", "h5", "hdf5" ], + "mount_path": "/home/jovyan", + "icon": "jupyter_logo.svg", "maintainer": [ { "name": "Florian Dobener", @@ -103423,126 +103426,131 @@ window.nomadArtifacts = { "email": "rubel.mozumder@physik.hu-berlin.de" } ], - "privileged": false, "external_mounts": [] }, "sts": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/sts-jupyter", - "description": "This example is for two types of experiments: Scanning Tunneling Microscopy (STM) and Scanning Tunneling Spectroscopy (STS) from Scanning Probe Microscopy. It can transform the data from files generated by a the nanonis software into the NeXus application definition NXsts. The example contains data files from the two specific nanonis software versions generic 5e and generic 4.5.", "short_description": "An example for analyzing SPM (STM / STS) experiment.", + "description": "This example is for two types of experiments: Scanning Tunneling Microscopy (STM) and Scanning Tunneling Spectroscopy (STS) from Scanning Probe Microscopy. It can transform the data from files generated by a the nanonis software into the NeXus application definition NXsts. The example contains data files from the two specific nanonis software versions generic 5e and generic 4.5.", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/sts-jupyter", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": false, "path_prefix": "lab/tree", - "mount_path": "/home/jovyan", - "icon": "jupyter_logo.svg", + "with_path": false, "file_extensions": [ "ipynb", "nxs", "h5", "hdf5" ], + "mount_path": "/home/jovyan", + "icon": "jupyter_logo.svg", "maintainer": [ { "name": "Rubel Mozumder", "email": "rubel.mozumder@physik.hu-berlin.de" } ], - "privileged": false, "external_mounts": [] }, "webtop": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/webtop", - "description": "Baseline webtop image for test", "short_description": null, + "description": "Baseline webtop image for test", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, + "with_path": false, + "file_extensions": [], "mount_path": "/config", "icon": null, - "file_extensions": [], "maintainer": [ { "name": "Sherjeel Shabih", "email": "sherjeel.shabih@hu-berlin.de" } ], - "privileged": true, "external_mounts": [] }, "apmtools": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/apmtools-webtop", - "description": "Miscellaneous tools from the atom probe community:\nCurrently APTyzer, paraprobe-toolbox, and APAV", "short_description": "An example for analyzing atom probe data.", + "description": "Miscellaneous tools from the atom probe community:\nCurrently APTyzer, paraprobe-toolbox, and APAV", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/apmtools-webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, + "with_path": false, + "file_extensions": [], "mount_path": "/config", "icon": "jupyter_logo.svg", - "file_extensions": [], "maintainer": [ { "name": "Markus K\u00fchbach", "email": "markus.kuehbach@physik.hu-berlin.de" } ], - "privileged": true, "external_mounts": [] }, "fiji": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/fiji-webtop", - "description": "ImageJ and Fiji with amongst others several electron-microscopy specific plug-ins", "short_description": "ImageJ and Fiji for image processing", + "description": "ImageJ and Fiji with amongst others several electron-microscopy specific plug-ins", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/fiji-webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, + "with_path": false, + "file_extensions": [], "mount_path": "/config", "icon": "jupyter_logo.svg", - "file_extensions": [], "maintainer": [ { "name": "Markus K\u00fchbach", "email": "markus.kuehbach@physik.hu-berlin.de" } ], - "privileged": true, "external_mounts": [] }, "frwr": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/frwr-webtop", - "description": "FRWR3 in-line holography/focus series reconstruction code", "short_description": "Inline electron holography by C. Koch", + "description": "FRWR3 in-line holography/focus series reconstruction code", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/frwr-webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, + "with_path": false, + "file_extensions": [], "mount_path": "/config", "icon": "jupyter_logo.svg", - "file_extensions": [], "maintainer": [ { "name": "Markus K\u00fchbach", "email": "markus.kuehbach@physik.hu-berlin.de" } ], - "privileged": true, "external_mounts": [] }, "abtem": { - "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/abtem-webtop", - "description": "VESTA, GPAW, and abTEM configured in one container for simulating images and diffraction patterns in transmission electron microscopy", "short_description": "Electronic structure supported image simulation for transmission electron microscopy.", + "description": "VESTA, GPAW, and abTEM configured in one container for simulating images and diffraction patterns in transmission electron microscopy", + "image": "gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/abtem-webtop", "cmd": null, - "with_path": false, + "image_pull_policy": "Always", + "privileged": true, "path_prefix": null, + "with_path": false, + "file_extensions": [], "mount_path": "/config", "icon": "jupyter_logo.svg", - "file_extensions": [], "maintainer": [ { "name": "Markus K\u00fchbach", "email": "markus.kuehbach@physik.hu-berlin.de" } ], - "privileged": true, "external_mounts": [] } }, diff --git a/nomad/app/v1/routers/north.py b/nomad/app/v1/routers/north.py index be57d7eab2..7df361a995 100644 --- a/nomad/app/v1/routers/north.py +++ b/nomad/app/v1/routers/north.py @@ -29,6 +29,7 @@ from nomad import config from nomad.config.north import NORTHTool from nomad.utils import strip, get_logger, slugify from nomad.processing import Upload +from nomad.app.v1.routers.auth import generate_simple_token from .auth import create_user_dependency, oauth2_scheme from ..models import User, HTTPExceptionModel from ..utils import create_responses @@ -159,7 +160,6 @@ async def get_tool( ) async def start_tool( tool: ToolModel = Depends(tool), - access_token: str = Depends(oauth2_scheme), user: User = Depends(create_user_dependency(required=True)), upload_id: Optional[str] = None, ): @@ -238,6 +238,9 @@ async def start_tool( ) url = f'{config.hub_url()}/api/users/{user.username}/servers/{tool.name}' + access_token = generate_simple_token( + user_id=user.user_id, expires_in=config.north.nomad_access_token_expiry_time + ) body = { 'tool': {'image': tool.image, 'cmd': tool.cmd, 'privileged': tool.privileged}, 'environment': { diff --git a/nomad/config/north.py b/nomad/config/north.py index 43ab014442..3aa5aa7201 100644 --- a/nomad/config/north.py +++ b/nomad/config/north.py @@ -46,18 +46,60 @@ class NORTHExternalMount(BaseModel): class NORTHTool(BaseModel): - image: str - description: str = None - short_description: str = None - cmd: str = None - with_path: bool = False - path_prefix: str = None - mount_path: str = None - icon: str = None - file_extensions: List[str] = [] - maintainer: List[NORTHToolMaintainer] = [] - privileged: bool = False - external_mounts: List[NORTHExternalMount] = [] + short_description: str = Field( + None, + description='A short description of the tool, e.g. shown in the NOMAD GUI.', + ) + description: str = Field( + None, description='A description of the tool, e.g. shown in the NOMAD GUI.' + ) + image: str = Field( + None, description='The docker image (incl. tags) to use for the tool.' + ) + cmd: str = Field( + None, description='The container cmd that is passed to the spawner.' + ) + image_pull_policy: str = Field( + 'Always', description='The image pull policy used in k8s deployments.' + ) + privileged: bool = Field( + False, description='Whether the tool needs to run in privileged mode.' + ) + path_prefix: str = Field( + None, + description=( + 'An optional path prefix that is added to the container URL to ' + 'reach the tool, e.g. "lab/tree" for jupyterlab.' + ), + ) + with_path: bool = Field( + False, + description=( + 'Whether the tool supports a path to a file or directory. ' + 'This also enables tools to be launched from files in the NOMAD UI.' + ), + ) + file_extensions: List[str] = Field( + [], + description='The file extensions of files that this tool should be launchable for.', + ) + mount_path: str = Field( + None, + description=( + 'The path in the container where uploads and work directories will be mounted, ' + 'e.g. /home/jovyan for Jupyter containers.' + ), + ) + icon: str = Field( + None, + description='A URL to an icon that is used to represent the tool in the NOMAD UI.', + ) + maintainer: List[NORTHToolMaintainer] = Field( + [], description='The maintainers of the tool.' + ) + external_mounts: List[NORTHExternalMount] = Field( + [], description='Additional mounts to be added to tool containers.' + ) class NORTHTools(Options): @@ -107,14 +149,25 @@ class NORTH(NomadSettings): None, description='The NOMAD app host name that spawned containers use.' ) windows = Field(True, description='Enable windows OS hacks.') + nomad_access_token_expiry_time: int = Field( + 24 * 3600, + description=( + 'All tools are run with an access token for the NOMAD api in the NOMAD_CLIENT_ACCESS_TOKEN ' + 'environment variable. This token will be automatically used by the nomad-lab Python package, ' + 'e.g. if you use the ArchiveQuery to access data. ' + 'This option sets the amount of seconds that this token is valid for.' + ), + ) tools: NORTHTools = Field( NORTHTools( + include=None, + exclude=['pyiron'], options={ 'jupyter': NORTHTool( short_description='Basic jupyter run with an empty notebook or on given notebook file.', description='### **Jupyter Notebook**: The Classic Notebook Interface\n\nThe Jupyter Notebook is the original web application for creating and sharing computational documents. It offers a simple, streamlined, document-centric experience.', - image='gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/jupyterlab:prod', + image='gitlab-registry.mpcdf.mpg.de/nomad-lab/north/jupyter:latest', path_prefix='lab/tree', with_path=True, mount_path='/home/jovyan', @@ -124,11 +177,23 @@ class NORTH(NomadSettings): NORTHToolMaintainer( name='Markus Scheidgen', email='markus.scheidgen@physik.hu-berlin.de', - ), + ) + ], + ), + 'pyiron': NORTHTool( + short_description='Jupyterlab with pyiron installed.', + description='## Pyiron: Complex workflows made easy\n\nFrom rapid prototyping to high performance computing in material science. [Homepage](https://pyiron.org/).', + image='pyiron/pyiron:latest', + path_prefix='lab/tree', + with_path=True, + mount_path='/home/jovyan', + icon='pyiron_logo.png', + file_extensions=['ipynb'], + maintainer=[ NORTHToolMaintainer( - name='Some-one Else', + name='Markus Scheidgen', email='markus.scheidgen@physik.hu-berlin.de', - ), + ) ], ), 'nionswift': NORTHTool( @@ -201,7 +266,7 @@ class NORTH(NomadSettings): 'xps': NORTHTool( short_description='An example for analyzing XPS data.', description='Includes tools for analyzing X-ray Photoelectron Spectroscopy (XPS) spectra and converting SPECS SLE files into NeXus.', - image='gitlab-registry.mpcdf.mpg.de/nomad-lab/north/xps/jupyter', + image='gitlab-registry.mpcdf.mpg.de/nomad-lab/north/xps/jupyter:master', path_prefix='lab/tree', icon='jupyter_logo.svg', mount_path='/home/jovyan', @@ -303,7 +368,7 @@ class NORTH(NomadSettings): ) ], ), - } + }, ), description='The available north tools. Either the tools definitions as dict or a path to a .json file.', ) diff --git a/nomad/jupyterhub_config.py b/nomad/jupyterhub_config.py index c023eb62e2..418b75afc3 100644 --- a/nomad/jupyterhub_config.py +++ b/nomad/jupyterhub_config.py @@ -77,13 +77,13 @@ def pre_spawn(spawner): c.Spawner.pre_spawn_hook = pre_spawn # configure nomad service -c.JupyterHub.services = [ +c.JupyterHub.services.append( { 'name': 'nomad-service', 'admin': True, 'api_token': config.north.hub_service_api_token, } -] +) # Allow named single-user servers per user (Default: False) c.JupyterHub.allow_named_servers = True @@ -117,6 +117,7 @@ c.GenericOAuthenticator.username_key = 'preferred_username' c.GenericOAuthenticator.scope = ['openid', 'profile'] c.Authenticator.auto_login = True c.Authenticator.enable_auth_state = True +c.Ahtenticator.allow_all = True # configure docker spawner diff --git a/ops/kubernetes/nomad-prod-develop.yaml b/ops/kubernetes/nomad-prod-develop.yaml index 52e600b2d0..565cf041f9 100644 --- a/ops/kubernetes/nomad-prod-develop.yaml +++ b/ops/kubernetes/nomad-prod-develop.yaml @@ -41,7 +41,7 @@ nomad: memory: "8Gi" jupyterhub: - fullnameOverride: "nomad-prod-staging-north" + fullnameOverride: "nomad-prod-develop-north" hub: baseUrl: "/prod/v1/develop/north" config: diff --git a/ops/kubernetes/nomad/Chart.lock b/ops/kubernetes/nomad/Chart.lock index c79e2d604f..ca21ee2e9c 100644 --- a/ops/kubernetes/nomad/Chart.lock +++ b/ops/kubernetes/nomad/Chart.lock @@ -10,6 +10,6 @@ dependencies: version: 14.0.4 - name: jupyterhub repository: https://jupyterhub.github.io/helm-chart/ - version: 1.2.0 -digest: sha256:75cf4c73a86fb9a6ca46cbfd7676d20600c64932659c30b36d4b494170a7b6d0 -generated: "2024-02-08T20:14:29.044024+01:00" + version: 3.2.1 +digest: sha256:f77e87c16f5417c9ba3d30143451035d6b570c5eb9d736589069e31e26ab5adf +generated: "2024-02-26T13:51:48.48639+01:00" diff --git a/ops/kubernetes/nomad/Chart.yaml b/ops/kubernetes/nomad/Chart.yaml index 22860c0cae..e7adb99ecf 100644 --- a/ops/kubernetes/nomad/Chart.yaml +++ b/ops/kubernetes/nomad/Chart.yaml @@ -37,7 +37,7 @@ dependencies: version: 14.0.4 repository: oci://registry-1.docker.io/bitnamicharts - name: jupyterhub - version: "1.2.0" + version: "3.2.1" repository: "https://jupyterhub.github.io/helm-chart/" condition: nomad.config.north.enabled diff --git a/ops/kubernetes/nomad/updatevalues.py b/ops/kubernetes/nomad/updatevalues.py new file mode 100644 index 0000000000..3a4ba1e04c --- /dev/null +++ b/ops/kubernetes/nomad/updatevalues.py @@ -0,0 +1,74 @@ +# Updates the values.yaml file based on the nomad configuration. Currently this +# includes the following: +# - populating jupyterhub.singleUser.profileList with NORTH tools + +from typing import Any, Dict +import os +from sys import stdout, argv +from ruamel.yaml import YAML +from nomad import config + +dir_path = os.path.dirname(os.path.realpath(__file__)) +file_path = os.path.join(dir_path, 'values.yaml') + +yaml = YAML() +yaml.allow_duplicate_keys = True +with open(file_path, 'r') as file: + data = yaml.load(file) + +# Profiles currently break how NOMAD interacts with JupyterHub, so we're only using +# the extraImages to feed the prePuller +generate_profiles = False + +if generate_profiles: + profile_list = ( + data.setdefault('jupyterhub', {}) + .setdefault('singleuser', {}) + .setdefault('profileList', []) + ) + for name, tool in config.north.tools.filtered_items(): + profile = next( + (profile for profile in profile_list if profile['display_name'] == name), + None, + ) + if profile is None: + profile = dict() + profile_list.append(profile) + + profile.update( + dict( + display_name=name, + description=tool.description, + kubespawner_override=dict( + image=tool.image, + image_pull_policy=tool.image_pull_policy, + ), + ) + ) + + if tool.path_prefix: + profile['kubespawner_override']['default_url'] = tool.path_prefix + if tool.cmd: + profile['kubespawner_override']['cmd'] = tool.cmd + if tool.privileged: + profile['kubespawner_override']['privileged'] = tool.privileged + +else: + pre_puller = data.setdefault('jupyterhub', {}).setdefault('prePuller', {}) + extra_images: Dict[str, Any] = {} + pre_puller['extraImages'] = extra_images + + for name, tool in config.north.tools.filtered_items(): + try: + image_name, image_tag = tool.image.rsplit(':', 1) + except ValueError: + image_name, image_tag = tool.image, 'latest' + + extra_images[name] = dict(name=image_name, tag=image_tag) + + +if len(argv) == 2: + with open(argv[1], 'w') as file: + yaml.dump(data, file) +else: + yaml.dump(data, stdout) diff --git a/ops/kubernetes/nomad/values.yaml b/ops/kubernetes/nomad/values.yaml index ac2cba4fee..6835cc20f3 100644 --- a/ops/kubernetes/nomad/values.yaml +++ b/ops/kubernetes/nomad/values.yaml @@ -2,8 +2,8 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. roll: false -nameOverride: "" -fullnameOverride: "" +nameOverride: '' +fullnameOverride: '' serviceAccount: # Specifies whether a service account should be created @@ -14,42 +14,33 @@ serviceAccount: annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template - name: "" + name: '' nomad: enabled: true image: repository: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair - tag: "latest" + tag: latest pullPolicy: Always imagePullSecrets: [] - - # Default values for nomad. - # This is a YAML-formatted file. - # Declare variables to be passed into your templates. - - # GLOBAL parameters - enabled: false - - ## Default values for nomad@FAIRDI config: version: - label: "latest" + label: latest isTest: false isBeta: false usesBetaData: false - officialUrl: "https://nomad-lab.eu/prod/v1/gui" + officialUrl: https://nomad-lab.eu/prod/v1/gui meta: - service: "app" - homepage: "https://nomad-lab.eu" - source_url: "https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR" - maintainer_email: "markus.scheidgen@physik.hu-berlin.de" + service: app + homepage: https://nomad-lab.eu + source_url: https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR + maintainer_email: markus.scheidgen@physik.hu-berlin.de api: ## Secret used as cryptographic seed - secret: "defaultApiSecret" + secret: defaultApiSecret ## Limit of unpublished uploads per user, except admin user uploadLimit: 10 @@ -63,15 +54,15 @@ nomad: ## There are two routing modes "queue" and "worker". The "queue" routing will use a general # task queue and spread calc processing task over worker instances. The "worker" routing # will send all tasks related to an upload to the same worker - routing: "queue" + routing: queue timeout: 7200 acks_late: false mail: enabled: false - host: "localhost" + host: localhost port: 25 - from: "support@nomad-lab.eu" + from: support@nomad-lab.eu client: username: admin @@ -93,17 +84,17 @@ nomad: datacite: enabled: false - prefix: "10.17172" + prefix: '10.17172' ## A common name/prefix for all dbs and indices. dbname: fairdi_nomad_latest mongo: - host: "" + host: '' port: 27017 elastic: - host: "" + host: '' port: 9200 timeout: 60 bulkTimeout: 600 @@ -113,16 +104,16 @@ nomad: logstash: enabled: true port: 5000 - host: "" + host: '' keycloak: - serverExternalUrl: "https://nomad-lab.eu/fairdi/keycloak/auth/" - serverUrl: "https://nomad-lab.eu/keycloak/auth/" - realmName: "fairdi_nomad_test" - username: "admin" - clientId: "nomad_public" - guiClientId: "nomad_public" - admin_user_id: "00000000-0000-0000-0000-000000000000" + serverExternalUrl: https://nomad-lab.eu/fairdi/keycloak/auth/ + serverUrl: https://nomad-lab.eu/keycloak/auth/ + realmName: fairdi_nomad_test + username: admin + clientId: nomad_public + guiClientId: nomad_public + admin_user_id: 00000000-0000-0000-0000-000000000000 ## Everything concerning the data that is used by the service volumes: @@ -140,7 +131,7 @@ nomad: north: enabled: false - hubServiceApiToken: "secret-token" + hubServiceApiToken: secret-token gui: ## This variable is used in the GUI to show or hide additional information @@ -148,16 +139,27 @@ nomad: ## automatically gz based on header gzip: true + proxy: + # Set a nodePort to create a NodePort service instead of ClusterIP. Also set a nodeIP for the externalIP. + timeout: 120 + editTimeout: 1800 + external: + host: nomad-lab.eu + port: 80 + path: /fairdi/nomad/latest + https: true + + ingress: enabled: false limitConnections: 32 limitConnectionsApi: 8 hosts: - - nomad-lab.eu - className: "" + - nomad-lab.eu + className: '' annotations: - nginx.ingress.kubernetes.io/ssl-redirect: "false" - nginx.ingress.kubernetes.io/proxy-body-size: "32g" + nginx.ingress.kubernetes.io/ssl-redirect: 'false' + nginx.ingress.kubernetes.io/proxy-body-size: 32g tls: [] # Additional volumes on the output Deployment definition. @@ -182,7 +184,7 @@ nomad: ## Everything concerning the nginx that serves the gui, proxies the api # It is run via NodePort service proxy: - path: "/fairdi/nomad/latest" + path: /fairdi/nomad/latest timeout: 60 editTimeout: 60 connectionTimeout: 10 @@ -196,8 +198,8 @@ nomad: tag: 1.13.9-alpine pullPolicy: IfNotPresent - command: ["nginx"] - args: ["-g", "daemon off;"] + command: [nginx] + args: [-g, daemon off;] imagePullSecrets: [] @@ -379,7 +381,7 @@ jupyterhub: type: ClusterIP singleuser: image: - pullPolicy: "Always" + pullPolicy: Always storage: type: none hub: @@ -416,13 +418,13 @@ jupyterhub: hub_service_api_token = os.getenv('NOMAD_NORTH_HUB_SERVICE_API_TOKEN') # configure nomad service - c.JupyterHub.services = [ + c.JupyterHub.services.append( { "name": "nomad-service", "admin": True, "api_token": hub_service_api_token, } - ] + ) async def pre_spawn_hook(spawner): await spawner.load_user_options() @@ -433,10 +435,6 @@ jupyterhub: if spawner.handler.current_user.name != 'nomad-service': # Do nothing, will only launch the default image with no volumes. - # Only the nomad-service can launch specialized tools with mounted volumes - if spawner.name: - spawner.log.error(f'The {spawner.name} server is not allowed to start this way, raise an error') - raise NotImplementedError('Only the nomad-service can launch specialized tools.') return user_home = spawner.user_options.get('user_home') @@ -479,10 +477,11 @@ jupyterhub: spawner.uid = 0 c.Spawner.pre_spawn_hook = pre_spawn_hook + c.OAuthenticator.allow_all = True cull: enabled: true - timeout: 3600 + timeout: 86400 # 24 hours every: 600 removeNamedServers: true @@ -490,10 +489,46 @@ jupyterhub: hook: enabled: true image: - pullPolicy: "Always" + pullPolicy: Always continuous: enabled: false - + extraImages: + jupyter: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/north/jupyter + tag: latest + nionswift: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/nionswift-webtop + tag: latest + nexustools: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/nexus-webtop + tag: latest + ellips: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/ellips-jupyter + tag: latest + mpes: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/north/mpes/webtop + tag: latest + xps: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/north/xps/jupyter + tag: master + sts: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/sts-jupyter + tag: latest + webtop: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/webtop + tag: latest + apmtools: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/apmtools-webtop + tag: latest + fiji: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/fiji-webtop + tag: latest + frwr: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/frwr-webtop + tag: latest + abtem: + name: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-remote-tools-hub/abtem-webtop + tag: latest scheduling: userScheduler: enabled: false diff --git a/ops/kubernetes/values.yaml b/ops/kubernetes/values.yaml index 8a5de79855..4bd569c4d8 100644 --- a/ops/kubernetes/values.yaml +++ b/ops/kubernetes/values.yaml @@ -85,7 +85,7 @@ nomad: ingress: enabled: true limitConnections: 32 - limitConnectionsApi: 8 + limitConnectionsApi: 16 className: "nginx" annotations: cert-manager.io/cluster-issuer: "letsencrypt-production" diff --git a/pyproject.toml b/pyproject.toml index d3dcfb2c81..5ec11c8d4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -102,7 +102,7 @@ infrastructure = [ 'fastapi==0.92.0', 'uvicorn[standard]', 'python-multipart==0.0.5', - 'jupyterhub==1.4.2', + 'jupyterhub==4.0.2', 'dockerspawner==12.1.0', 'oauthenticator==15.1.0', 'validators==0.18.2', @@ -140,7 +140,8 @@ dev = [ 'mkdocs-click==0.8.0', 'mkdocs-redirects==1.2.0', 'mkdocs-git-revision-date-localized-plugin==1.2.1', - 'ruff==0.1.8' + 'ruff==0.1.8', + 'ruamel.yaml==0.17.21' ] diff --git a/requirements-dev.txt b/requirements-dev.txt index 5be4fda0fc..292843e01e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,18 +2,19 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --annotation-style=line --extra=dev --extra=infrastructure --extra=parsing --output-file=requirements-dev.txt --resolver=backtracking pyproject.toml requirements.txt +# pip-compile --annotation-style=line --extra=dev --extra=infrastructure --extra=parsing --output-file=requirements-dev.txt --pip-args='--prefer-binary' pyproject.toml requirements.txt # aiosmtpd==1.4.4.post2 # via nomad-lab (pyproject.toml) alabaster==0.7.12 # via -r requirements.txt, sphinx alembic==1.9.1 # via -r requirements.txt, jupyterhub amqp==5.1.1 # via -r requirements.txt, kombu -aniso8601==7.0.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +aniso8601==7.0.0 # via -r requirements.txt, nomad-lab (pyproject.toml) anyio==3.6.2 # via -r requirements.txt, httpcore, starlette, watchfiles +appnope==0.1.4 # via -r requirements.txt, ipykernel, ipython arrow==1.2.3 # via -r requirements.txt, isoduration asciitree==0.3.3 # via -r requirements.txt, zarr -ase==3.19.0 # via -r requirements.txt, asr, ifes-apt-tc-data-modeling, matid, nomad-lab, nomad-lab (pyproject.toml), quippy-ase -asgiref==3.6.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +ase==3.19.0 # via -r requirements.txt, asr, ifes-apt-tc-data-modeling, matid, nomad-lab (pyproject.toml), quippy-ase +asgiref==3.6.0 # via -r requirements.txt, nomad-lab (pyproject.toml) asr==0.4.1 # via -r requirements.txt, nomad-lab (pyproject.toml) asteval==0.9.31 # via -r requirements.txt, lmfit astroid==2.11.7 # via nomad-lab (pyproject.toml), pylint @@ -24,25 +25,25 @@ atpublic==3.1.1 # via aiosmtpd attrs==22.2.0 # via -r requirements.txt, aiosmtpd, cattrs, jsonschema, pytest, requests-cache babel==2.11.0 # via -r requirements.txt, mkdocs-git-revision-date-localized-plugin, sphinx backcall==0.2.0 # via -r requirements.txt, ipython -bagit==1.8.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -basicauth==0.4.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -bcrypt==3.2.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +bagit==1.8.1 # via -r requirements.txt, nomad-lab (pyproject.toml) +basicauth==0.4.1 # via -r requirements.txt, nomad-lab (pyproject.toml) +bcrypt==3.2.0 # via -r requirements.txt, nomad-lab (pyproject.toml) beautifulsoup4==4.11.1 # via -r requirements.txt, bs4 billiard==3.6.4.0 # via -r requirements.txt, celery biopython==1.80 # via -r requirements.txt, mdanalysis -bitarray==2.3.5 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +bitarray==2.3.5 # via -r requirements.txt, nomad-lab (pyproject.toml) bleach==5.0.1 # via readme-renderer -bs4==0.0.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +bs4==0.0.1 # via -r requirements.txt, nomad-lab (pyproject.toml) build==0.9.0 # via nomad-lab (pyproject.toml), pip-tools -cachetools==4.2.4 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +cachetools==4.2.4 # via -r requirements.txt, nomad-lab (pyproject.toml) cattrs==22.2.0 # via -r requirements.txt, requests-cache -celery[redis]==5.2.7 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +celery[redis]==5.2.7 # via -r requirements.txt, nomad-lab (pyproject.toml) certifi==2022.12.7 # via -r requirements.txt, elasticsearch, httpcore, httpx, requests certipy==0.1.3 # via -r requirements.txt, jupyterhub cffi==1.15.1 # via -r requirements.txt, bcrypt, cryptography cftime==1.6.2 # via -r requirements.txt, netcdf4 charset-normalizer==2.0.12 # via -r requirements.txt, requests -click==8.1.3 # via -r requirements.txt, asr, celery, click-didyoumean, click-plugins, click-repl, flask, mkdocs, mkdocs-click, nomad-lab, nomad-lab (pyproject.toml), pip-tools, uvicorn +click==8.1.3 # via -r requirements.txt, asr, celery, click-didyoumean, click-plugins, click-repl, flask, mkdocs, mkdocs-click, nomad-lab (pyproject.toml), pip-tools, uvicorn click-didyoumean==0.3.0 # via -r requirements.txt, celery click-plugins==1.1.1 # via -r requirements.txt, celery click-repl==0.2.0 # via -r requirements.txt, celery @@ -51,7 +52,7 @@ colorama==0.4.6 # via twine comm==0.1.4 # via -r requirements.txt, ipywidgets commonmark==0.9.1 # via -r requirements.txt, recommonmark coverage==6.5.0 # via pytest-cov -cryptography==39.0.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml), pyjwt, pyopenssl, rfc3161ng, secretstorage +cryptography==39.0.0 # via -r requirements.txt, nomad-lab (pyproject.toml), pyjwt, pyopenssl, rfc3161ng cycler==0.11.0 # via -r requirements.txt, matplotlib dask[array]==2022.2.0 # via -r requirements.txt, hyperspy, kikuchipy, orix, pyxem debugpy==1.6.5 # via -r requirements.txt, ipykernel @@ -62,14 +63,14 @@ diffsims==0.5.2 # via -r requirements.txt, kikuchipy, pyxem dill==0.3.6 # via -r requirements.txt, hyperspy, pylint dnspython==2.2.1 # via -r requirements.txt, email-validator, pymongo docker==6.0.1 # via -r requirements.txt, dockerspawner -dockerspawner==12.1.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -docstring-parser==0.12 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +dockerspawner==12.1.0 # via -r requirements.txt, nomad-lab (pyproject.toml) +docstring-parser==0.12 # via -r requirements.txt, nomad-lab (pyproject.toml) docutils==0.19 # via -r requirements.txt, m2r, readme-renderer, recommonmark, sphinx ecdsa==0.18.0 # via -r requirements.txt, python-jose -elasticsearch==7.17.1 # via -r requirements.txt, elasticsearch-dsl, nomad-lab, nomad-lab (pyproject.toml) -elasticsearch-dsl==7.4.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +elasticsearch==7.17.1 # via -r requirements.txt, elasticsearch-dsl, nomad-lab (pyproject.toml) +elasticsearch-dsl==7.4.0 # via -r requirements.txt, nomad-lab (pyproject.toml) email-validator==1.3.0 # via -r requirements.txt, optimade -entrypoints==0.4 # via -r requirements.txt, ipyparallel, jupyter-client, jupyterhub, numcodecs +entrypoints==0.4 # via -r requirements.txt, ipyparallel, jupyter-client, numcodecs escapism==1.0.1 # via -r requirements.txt, dockerspawner essential-generators==1.0 # via nomad-lab (pyproject.toml) et-xmlfile==1.1.0 # via -r requirements.txt, openpyxl @@ -78,9 +79,9 @@ execnet==1.9.0 # via pytest-xdist executing==0.10.0 # via devtools f90wrap==0.2.13 # via -r requirements.txt, quippy-ase fabio==2023.6.0 # via -r requirements.txt, pyfai, silx -fastapi==0.92.0 # via -r requirements.txt, h5grove, nomad-lab, nomad-lab (pyproject.toml) +fastapi==0.92.0 # via -r requirements.txt, h5grove, nomad-lab (pyproject.toml) fasteners==0.18 # via -r requirements.txt, mdanalysis, zarr -filelock==3.3.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +filelock==3.3.1 # via -r requirements.txt, nomad-lab (pyproject.toml) flask==2.2.2 # via -r requirements.txt, asr flatdict==4.0.1 # via -r requirements.txt fonttools==4.38.0 # via -r requirements.txt, matplotlib @@ -89,26 +90,26 @@ fsspec==2022.11.0 # via -r requirements.txt, dask, hyperspy future==0.18.2 # via -r requirements.txt, uncertainties ghp-import==2.1.0 # via mkdocs gitdb==4.0.10 # via -r requirements.txt, gitpython -gitpython==3.1.24 # via -r requirements.txt, mkdocs-git-revision-date-localized-plugin, nomad-lab, nomad-lab (pyproject.toml) +gitpython==3.1.24 # via -r requirements.txt, mkdocs-git-revision-date-localized-plugin, nomad-lab (pyproject.toml) greenlet==2.0.1 # via -r requirements.txt, sqlalchemy griddataformats==0.7.0 # via -r requirements.txt, mdanalysis gsd==2.7.0 # via -r requirements.txt, mdanalysis -gunicorn==21.2.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +gunicorn==21.2.0 # via -r requirements.txt, nomad-lab (pyproject.toml) h11==0.14.0 # via -r requirements.txt, httpcore, uvicorn -h5grove[fastapi]==1.3.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -h5py==3.6.0 # via -r requirements.txt, h5grove, hyperspy, ifes-apt-tc-data-modeling, kikuchipy, nionswift, nomad-lab, nomad-lab (pyproject.toml), orix, phonopy, pyfai, silx -hjson==3.0.2 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -html5lib==1.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +h5grove[fastapi]==1.3.0 # via -r requirements.txt, nomad-lab (pyproject.toml) +h5py==3.6.0 # via -r requirements.txt, h5grove, hyperspy, ifes-apt-tc-data-modeling, kikuchipy, nionswift, nomad-lab (pyproject.toml), orix, phonopy, pyfai, silx +hjson==3.0.2 # via -r requirements.txt, nomad-lab (pyproject.toml) +html5lib==1.1 # via -r requirements.txt, nomad-lab (pyproject.toml) httpcore==0.16.3 # via -r requirements.txt, httpx httptools==0.5.0 # via -r requirements.txt, uvicorn -httpx==0.23.3 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +httpx==0.23.3 # via -r requirements.txt, nomad-lab (pyproject.toml) hyperspy==1.7.5 # via -r requirements.txt, kikuchipy, pyxem idna==3.4 # via -r requirements.txt, anyio, email-validator, jsonschema, requests, rfc3986 ifes-apt-tc-data-modeling==0.0.9 # via -r requirements.txt imageio==2.24.0 # via -r requirements.txt, hyperspy, kikuchipy, nionswift, nionswift-io, nionui, scikit-image imagesize==1.4.1 # via -r requirements.txt, sphinx -importlib-metadata==4.13.0 # via -r requirements.txt, flask, hyperspy, keyring, markdown, mkdocs, nomad-lab, nomad-lab (pyproject.toml), sphinx, twine -inflection==0.5.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +importlib-metadata==4.13.0 # via -r requirements.txt, flask, hyperspy, jupyterhub, keyring, markdown, mkdocs, nomad-lab (pyproject.toml), sphinx, twine +inflection==0.5.1 # via -r requirements.txt, nomad-lab (pyproject.toml) ipykernel==6.16.2 # via -r requirements.txt, ipyparallel ipyparallel==8.4.1 # via -r requirements.txt, hyperspy ipython==7.34.0 # via -r requirements.txt, hyperspy, ipykernel, ipyparallel, ipywidgets @@ -116,19 +117,18 @@ ipywidgets==8.1.1 # via -r requirements.txt, pyxem isodate==0.6.1 # via -r requirements.txt, rdflib isoduration==20.11.0 # via -r requirements.txt, jsonschema isort==4.3.21 # via pylint -itsdangerous==2.1.2 # via -r requirements.txt, flask, nomad-lab, nomad-lab (pyproject.toml) +itsdangerous==2.1.2 # via -r requirements.txt, flask, nomad-lab (pyproject.toml) jaraco-classes==3.2.3 # via keyring jedi==0.18.2 # via -r requirements.txt, ipython -jeepney==0.8.0 # via keyring, secretstorage jinja2==3.0.3 # via -r requirements.txt, flask, hyperspy, jupyterhub, mkdocs, mkdocs-macros-plugin, mkdocs-material, sphinx -jmespath==0.10.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -joblib==1.1.0 # via -r requirements.txt, mdanalysis, nomad-lab, pymatgen, scikit-learn +jmespath==0.10.0 # via -r requirements.txt, nomad-lab (pyproject.toml) +joblib==1.1.0 # via -r requirements.txt, mdanalysis, pymatgen, scikit-learn jsonpointer==2.3 # via -r requirements.txt, jsonschema -jsonschema[format]==4.17.3 # via -r requirements.txt, jupyter-telemetry, nomad-lab, nomad-lab (pyproject.toml), oauthenticator +jsonschema[format]==4.17.3 # via -r requirements.txt, jupyter-telemetry, nomad-lab (pyproject.toml), oauthenticator jupyter-client==7.4.8 # via -r requirements.txt, ipykernel, ipyparallel jupyter-core==4.12.0 # via -r requirements.txt, jupyter-client jupyter-telemetry==0.1.0 # via -r requirements.txt, jupyterhub -jupyterhub==1.4.2 # via -r requirements.txt, dockerspawner, nomad-lab, nomad-lab (pyproject.toml), oauthenticator +jupyterhub==4.0.2 # via -r requirements.txt, dockerspawner, nomad-lab (pyproject.toml), oauthenticator jupyterlab-widgets==3.0.9 # via -r requirements.txt, ipywidgets keyring==23.11.0 # via twine kikuchipy==0.8.7 # via -r requirements.txt @@ -140,18 +140,18 @@ lazy-object-proxy==1.9.0 # via astroid llvmlite==0.39.1 # via -r requirements.txt, numba lmfit==1.2.2 # via -r requirements.txt, pyxem locket==1.0.0 # via -r requirements.txt, partd -lxml==4.7.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -m2r==0.2.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +lxml==4.7.1 # via -r requirements.txt, nomad-lab (pyproject.toml) +m2r==0.2.1 # via -r requirements.txt, nomad-lab (pyproject.toml) mako==1.2.4 # via -r requirements.txt, alembic markdown==3.4.1 # via mkdocs, mkdocs-click, mkdocs-material, pymdown-extensions markupsafe==2.1.1 # via -r requirements.txt, jinja2, mako, nomad-lab (pyproject.toml), werkzeug -matid==2.0.0.dev2 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +matid==2.0.0.dev2 # via -r requirements.txt, nomad-lab (pyproject.toml) matplotlib==3.5.3 # via -r requirements.txt, ase, asr, diffsims, hyperspy, kikuchipy, matplotlib-scalebar, mdanalysis, orix, phonopy, pyfai, pymatgen, pyxem, radioactivedecay matplotlib-inline==0.1.6 # via -r requirements.txt, ipykernel, ipython matplotlib-scalebar==0.8.1 # via -r requirements.txt, orix mccabe==0.6.1 # via pylint -mdanalysis==2.5.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -memoization==0.4.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +mdanalysis==2.5.0 # via -r requirements.txt, nomad-lab (pyproject.toml) +memoization==0.4.0 # via -r requirements.txt, nomad-lab (pyproject.toml) mergedeep==1.3.4 # via -r requirements.txt, mkdocs mistune==2.0.4 # via -r requirements.txt, m2r mkdocs==1.3.0 # via mkdocs-git-revision-date-localized-plugin, mkdocs-macros-plugin, mkdocs-material, mkdocs-redirects, nomad-lab (pyproject.toml) @@ -163,55 +163,52 @@ mkdocs-material==8.2.8 # via nomad-lab (pyproject.toml) mkdocs-material-extensions==1.3.1 # via mkdocs-material, nomad-lab (pyproject.toml) mkdocs-redirects==1.2.0 # via nomad-lab (pyproject.toml) mmtf-python==1.1.3 # via -r requirements.txt, mdanalysis -mongoengine==0.25.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +mongoengine==0.25.0 # via -r requirements.txt, nomad-lab (pyproject.toml) mongomock==4.1.2 # via -r requirements.txt, optimade monty==2022.9.9 # via -r requirements.txt, pymatgen more-itertools==9.0.0 # via jaraco-classes, pytest mpmath==1.2.1 # via -r requirements.txt, sympy mrcfile==1.4.3 # via -r requirements.txt, griddataformats -msgpack==1.0.4 # via -r requirements.txt, mmtf-python, nomad-lab, nomad-lab (pyproject.toml) +msgpack==1.0.4 # via -r requirements.txt, mmtf-python, nomad-lab (pyproject.toml) mypy==1.0.1 # via nomad-lab (pyproject.toml) mypy-extensions==0.4.3 # via mypy names==0.3.0 # via nomad-lab (pyproject.toml) natsort==8.2.0 # via -r requirements.txt, hyperspy nest-asyncio==1.5.6 # via -r requirements.txt, ipykernel, jupyter-client netcdf4==1.5.4 # via -r requirements.txt, nomad-lab (pyproject.toml) -networkx==2.6.3 # via -r requirements.txt, matid, mdanalysis, nomad-lab, nomad-lab (pyproject.toml), pymatgen, radioactivedecay, scikit-image +networkx==2.6.3 # via -r requirements.txt, matid, mdanalysis, nomad-lab (pyproject.toml), pymatgen, radioactivedecay, scikit-image niondata==0.15.5 # via -r requirements.txt, nionswift, nionswift-io nionswift==0.16.8 # via -r requirements.txt nionswift-io==0.15.1 # via -r requirements.txt, nionswift nionui==0.6.11 # via -r requirements.txt, nionswift nionutils==0.4.8 # via -r requirements.txt, niondata, nionswift, nionswift-io, nionui -nomad-lab @ git+https://github.com/nomad-coe/nomad.git@develop # via -r requirements.txt, nomad-schema-plugin-run, nomad-schema-plugin-simulation-workflow, simulationparsers -nomad-schema-plugin-run @ git+https://github.com/nomad-coe/nomad-schema-plugin-run.git@develop # via -r requirements.txt, nomad-schema-plugin-simulation-workflow, simulationparsers -nomad-schema-plugin-simulation-workflow @ git+https://github.com/nomad-coe/nomad-schema-plugin-simulation-workflow.git@develop # via -r requirements.txt -nptyping==1.4.4 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +nptyping==1.4.4 # via -r requirements.txt, nomad-lab (pyproject.toml) numba==0.56.4 # via -r requirements.txt, diffsims, hyperspy, kikuchipy, orix, pyxem, sparse numcodecs==0.10.2 # via -r requirements.txt, zarr numexpr==2.8.4 # via -r requirements.txt, hyperspy, pyfai -numpy==1.22.4 # via -r requirements.txt, ase, biopython, cftime, dask, diffsims, f90wrap, fabio, griddataformats, gsd, h5grove, h5py, hyperspy, ifes-apt-tc-data-modeling, imageio, kikuchipy, lmfit, matid, matplotlib, mdanalysis, mrcfile, netcdf4, niondata, nionswift, nionswift-io, nionui, nomad-lab, nomad-lab (pyproject.toml), nptyping, numba, numcodecs, numexpr, numpy-quaternion, orix, pandas, phonopy, pyfai, pymatgen, pywavelets, pyxem, quippy-ase, radioactivedecay, scikit-image, scikit-learn, scipy, silx, sparse, spglib, tifffile, xarray, zarr +numpy==1.22.4 # via -r requirements.txt, ase, biopython, cftime, dask, diffsims, f90wrap, fabio, griddataformats, gsd, h5grove, h5py, hyperspy, ifes-apt-tc-data-modeling, imageio, kikuchipy, lmfit, matid, matplotlib, mdanalysis, mrcfile, netcdf4, niondata, nionswift, nionswift-io, nionui, nomad-lab (pyproject.toml), nptyping, numba, numcodecs, numexpr, numpy-quaternion, orix, pandas, phonopy, pyfai, pymatgen, pywavelets, pyxem, quippy-ase, radioactivedecay, scikit-image, scikit-learn, scipy, silx, sparse, spglib, tifffile, xarray, zarr numpy-quaternion==2022.4.3 # via -r requirements.txt, orix -oauthenticator==15.1.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +oauthenticator==15.1.0 # via -r requirements.txt, nomad-lab (pyproject.toml) oauthlib==3.2.2 # via -r requirements.txt, jupyterhub -openpyxl==3.1.2 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -optimade[mongo]==0.22.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +openpyxl==3.1.2 # via -r requirements.txt, nomad-lab (pyproject.toml) +optimade[mongo]==0.22.1 # via -r requirements.txt, nomad-lab (pyproject.toml) orix==0.11.1 # via -r requirements.txt, diffsims, kikuchipy, pyxem -orjson==3.9.4 # via -r requirements.txt, h5grove, nomad-lab, nomad-lab (pyproject.toml) -packaging==24.0 # via -r requirements.txt, build, dask, docker, gunicorn, hyperspy, ipykernel, matplotlib, mdanalysis, mkdocs, mongomock, pint, pooch, pytest, scikit-image, sphinx +orjson==3.9.4 # via -r requirements.txt, h5grove, nomad-lab (pyproject.toml) +packaging==23.0 # via -r requirements.txt, build, dask, docker, gunicorn, hyperspy, ipykernel, jupyterhub, matplotlib, mdanalysis, mkdocs, mongomock, pint, pooch, pytest, scikit-image, sphinx palettable==3.3.0 # via -r requirements.txt, pymatgen pamela==1.0.0 # via -r requirements.txt, jupyterhub -pandas==1.3.5 # via -r requirements.txt, ifes-apt-tc-data-modeling, nomad-lab, nomad-lab (pyproject.toml), panedr, pybis, pymatgen, xarray -panedr==0.2 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -parmed==3.0.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +pandas==1.3.5 # via -r requirements.txt, ifes-apt-tc-data-modeling, nomad-lab (pyproject.toml), panedr, pybis, pymatgen, xarray +panedr==0.2 # via -r requirements.txt, nomad-lab (pyproject.toml) +parmed==3.0.0 # via -r requirements.txt, nomad-lab (pyproject.toml) parso==0.8.3 # via -r requirements.txt, jedi partd==1.3.0 # via -r requirements.txt, dask -passlib==1.7.4 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +passlib==1.7.4 # via -r requirements.txt, nomad-lab (pyproject.toml) pep517==0.13.0 # via build pexpect==4.8.0 # via -r requirements.txt, ipython phonopy==2.11.0 # via -r requirements.txt, asr pickleshare==0.7.5 # via -r requirements.txt, ipython pillow==9.4.0 # via -r requirements.txt, imageio, matplotlib, nionswift, scikit-image -pint==0.17 # via -r requirements.txt, hyperspy, nomad-lab, nomad-lab (pyproject.toml) +pint==0.17 # via -r requirements.txt, hyperspy, nomad-lab (pyproject.toml) pip-tools==6.13.0 # via nomad-lab (pyproject.toml) pkginfo==1.8.3 # via twine platformdirs==3.1.1 # via -r requirements.txt, pooch, pylint, requests-cache @@ -231,16 +228,16 @@ pybtex==0.24.0 # via -r requirements.txt, pymatgen pycifrw==4.4.5 # via -r requirements.txt, diffpy-structure pycodestyle==2.8.0 # via nomad-lab (pyproject.toml) pycparser==2.21 # via -r requirements.txt, cffi -pydantic==1.10.9 # via -r requirements.txt, fastapi, nomad-lab, nomad-lab (pyproject.toml), optimade +pydantic==1.10.9 # via -r requirements.txt, fastapi, nomad-lab (pyproject.toml), optimade pyfai==2023.9.0 # via -r requirements.txt, pyxem pygments==2.14.0 # via -r requirements.txt, ipython, mkdocs-material, readme-renderer, sphinx -pyjwt[crypto]==2.6.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +pyjwt[crypto]==2.6.0 # via -r requirements.txt, nomad-lab (pyproject.toml) pylint==2.13.9 # via nomad-lab (pyproject.toml), pylint-mongoengine, pylint-plugin-utils pylint-mongoengine==0.4.0 # via nomad-lab (pyproject.toml) pylint-plugin-utils==0.7 # via nomad-lab (pyproject.toml), pylint-mongoengine -pymatgen==2023.9.25 # via -r requirements.txt, asr, nomad-lab, nomad-lab (pyproject.toml) +pymatgen==2023.9.25 # via -r requirements.txt, asr, nomad-lab (pyproject.toml) pymdown-extensions==9.7 # via mkdocs-material -pymongo==4.3.3 # via -r requirements.txt, mongoengine, nomad-lab, nomad-lab (pyproject.toml), optimade +pymongo==4.3.3 # via -r requirements.txt, mongoengine, nomad-lab (pyproject.toml), optimade pyopenssl==23.0.0 # via -r requirements.txt, certipy pyparsing==3.0.9 # via -r requirements.txt, matplotlib, rdflib pyrsistent==0.19.3 # via -r requirements.txt, jsonschema @@ -253,45 +250,43 @@ python-dateutil==2.8.2 # via -r requirements.txt, arrow, elasticsearch-dsl, g python-dotenv==0.21.0 # via -r requirements.txt, uvicorn python-gitlab==2.10.1 # via nomad-lab (pyproject.toml) python-jose==3.3.0 # via -r requirements.txt, python-keycloak -python-json-logger==2.0.2 # via -r requirements.txt, jupyter-telemetry, nomad-lab, nomad-lab (pyproject.toml) -python-keycloak==0.26.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -python-logstash==0.4.6 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -python-magic==0.4.24 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -python-multipart==0.0.5 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) -pytz==2022.7.1 # via -r requirements.txt, babel, celery, mkdocs-git-revision-date-localized-plugin, nionswift, nomad-lab, nomad-lab (pyproject.toml), pandas +python-json-logger==2.0.2 # via -r requirements.txt, jupyter-telemetry, nomad-lab (pyproject.toml) +python-keycloak==0.26.1 # via -r requirements.txt, nomad-lab (pyproject.toml) +python-logstash==0.4.6 # via -r requirements.txt, nomad-lab (pyproject.toml) +python-magic==0.4.24 # via -r requirements.txt, nomad-lab (pyproject.toml) +python-multipart==0.0.5 # via -r requirements.txt, nomad-lab (pyproject.toml) +pytz==2022.7.1 # via -r requirements.txt, babel, celery, mkdocs-git-revision-date-localized-plugin, nionswift, nomad-lab (pyproject.toml), pandas pytz-deprecation-shim==0.1.0.post0 # via -r requirements.txt, tzlocal pywavelets==1.3.0 # via -r requirements.txt, scikit-image pyxem==0.15.1 # via -r requirements.txt -pyyaml==6.0 # via -r requirements.txt, dask, hyperspy, kikuchipy, mkdocs, mkdocs-macros-plugin, nomad-lab, nomad-lab (pyproject.toml), phonopy, pybtex, pyyaml-env-tag, uvicorn +pyyaml==6.0 # via -r requirements.txt, dask, hyperspy, kikuchipy, mkdocs, mkdocs-macros-plugin, nomad-lab (pyproject.toml), phonopy, pybtex, pyyaml-env-tag, uvicorn pyyaml-env-tag==0.1 # via mkdocs pyzeo==0.1.4 # via -r requirements.txt, nomad-lab (pyproject.toml) pyzmq==25.0.0 # via -r requirements.txt, ipykernel, ipyparallel, jupyter-client quippy-ase==0.9.14 # via -r requirements.txt, nomad-lab (pyproject.toml) radioactivedecay==0.4.17 # via -r requirements.txt, ifes-apt-tc-data-modeling -rdflib==5.0.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +rdflib==5.0.0 # via -r requirements.txt, nomad-lab (pyproject.toml) readme-renderer==37.3 # via twine -recommonmark==0.7.1 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +recommonmark==0.7.1 # via -r requirements.txt, nomad-lab (pyproject.toml) redis==4.4.2 # via -r requirements.txt, celery -requests==2.28.2 # via -r requirements.txt, docker, hyperspy, jupyterhub, nomad-lab, nomad-lab (pyproject.toml), oauthenticator, optimade, pooch, pybis, pymatgen, python-gitlab, python-keycloak, requests-cache, requests-toolbelt, rfc3161ng, sphinx, twine +requests==2.28.2 # via -r requirements.txt, docker, hyperspy, jupyterhub, nomad-lab (pyproject.toml), oauthenticator, optimade, pooch, pybis, pymatgen, python-gitlab, python-keycloak, requests-cache, requests-toolbelt, rfc3161ng, sphinx, twine requests-cache==1.0.1 # via -r requirements.txt requests-toolbelt==0.10.1 # via python-gitlab, twine -rfc3161ng==2.1.3 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +rfc3161ng==2.1.3 # via -r requirements.txt, nomad-lab (pyproject.toml) rfc3339-validator==0.1.4 # via -r requirements.txt, jsonschema rfc3986[idna2008]==1.5.0 # via -r requirements.txt, httpx, twine rfc3987==1.3.8 # via -r requirements.txt, jsonschema rope==0.21.0 # via nomad-lab (pyproject.toml) rsa==4.9 # via -r requirements.txt, python-jose -ruamel-yaml==0.17.21 # via -r requirements.txt, jupyter-telemetry, oauthenticator, pymatgen +ruamel-yaml==0.17.21 # via -r requirements.txt, jupyter-telemetry, nomad-lab (pyproject.toml), oauthenticator, pymatgen ruamel-yaml-clib==0.2.7 # via -r requirements.txt, ruamel-yaml ruff==0.1.8 # via nomad-lab (pyproject.toml) -runstats==2.0.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +runstats==2.0.0 # via -r requirements.txt, nomad-lab (pyproject.toml) scikit-image==0.19.3 # via -r requirements.txt, hyperspy, kikuchipy, pyxem -scikit-learn==1.0.2 # via -r requirements.txt, kikuchipy, matid, nomad-lab, nomad-lab (pyproject.toml), pyxem -scipy==1.7.1 # via -r requirements.txt, ase, diffsims, griddataformats, hyperspy, kikuchipy, lmfit, matid, mdanalysis, niondata, nionswift, nomad-lab, nomad-lab (pyproject.toml), orix, pyfai, pymatgen, pyxem, radioactivedecay, scikit-image, scikit-learn, sparse -secretstorage==3.3.3 # via keyring +scikit-learn==1.0.2 # via -r requirements.txt, kikuchipy, matid, nomad-lab (pyproject.toml), pyxem +scipy==1.7.1 # via -r requirements.txt, ase, diffsims, griddataformats, hyperspy, kikuchipy, lmfit, matid, mdanalysis, niondata, nionswift, nomad-lab (pyproject.toml), orix, pyfai, pymatgen, pyxem, radioactivedecay, scikit-image, scikit-learn, sparse sentinels==1.0.0 # via -r requirements.txt, mongomock silx==1.1.2 # via -r requirements.txt, pyfai -simulationparsers @ git+https://github.com/nomad-coe/simulation-parsers.git@develop # via -r requirements.txt six==1.16.0 # via -r requirements.txt, asttokens, basicauth, bcrypt, bleach, click-repl, diffpy-structure, ecdsa, elasticsearch-dsl, griddataformats, html5lib, isodate, latexcodec, pybtex, pytest-xdist, python-dateutil, python-multipart, rdflib, rfc3339-validator, url-normalize, validators smmap==5.0.0 # via -r requirements.txt, gitdb sniffio==1.3.0 # via -r requirements.txt, anyio, httpcore, httpx @@ -308,9 +303,9 @@ sphinxcontrib-qthelp==1.0.3 # via -r requirements.txt, sphinx sphinxcontrib-serializinghtml==1.1.5 # via -r requirements.txt, sphinx sqlalchemy==1.4.46 # via -r requirements.txt, alembic, jupyterhub starlette==0.25.0 # via -r requirements.txt, fastapi -structlog==22.3.0 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +structlog==22.3.0 # via -r requirements.txt, nomad-lab (pyproject.toml) sympy==1.10.1 # via -r requirements.txt, hyperspy, pymatgen, radioactivedecay -tabulate==0.8.9 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml), pybis, pymatgen +tabulate==0.8.9 # via -r requirements.txt, nomad-lab (pyproject.toml), pybis, pymatgen tenacity==8.1.0 # via -r requirements.txt, plotly termcolor==2.1.0 # via mkdocs-macros-plugin texttable==1.7.0 # via -r requirements.txt, pybis @@ -318,7 +313,7 @@ threadpoolctl==3.1.0 # via -r requirements.txt, mdanalysis, scikit-learn tifffile==2021.11.2 # via -r requirements.txt, h5grove, hyperspy, scikit-image tomli==2.0.1 # via build, mypy, pep517, pylint toolz==0.12.0 # via -r requirements.txt, dask, hyperspy, partd -toposort==1.9 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +toposort==1.9 # via -r requirements.txt, nomad-lab (pyproject.toml) tornado==6.2 # via -r requirements.txt, ipykernel, ipyparallel, jupyter-client, jupyterhub tqdm==4.64.1 # via -r requirements.txt, diffsims, hyperspy, ipyparallel, kikuchipy, mdanalysis, orix, pymatgen, twine traitlets==5.8.1 # via -r requirements.txt, comm, ipykernel, ipyparallel, ipython, ipywidgets, jupyter-client, jupyter-core, jupyter-telemetry, jupyterhub, matplotlib-inline @@ -331,13 +326,13 @@ typish==1.9.3 # via -r requirements.txt, nptyping tzdata==2023.3 # via -r requirements.txt, pytz-deprecation-shim tzlocal==4.3 # via -r requirements.txt, nionswift uncertainties==3.1.7 # via -r requirements.txt, lmfit, pymatgen -unidecode==1.3.2 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +unidecode==1.3.2 # via -r requirements.txt, nomad-lab (pyproject.toml) uri-template==1.2.0 # via -r requirements.txt, jsonschema url-normalize==1.4.3 # via -r requirements.txt, requests-cache urllib3==1.26.14 # via -r requirements.txt, docker, elasticsearch, pybis, requests, requests-cache -uvicorn[standard]==0.20.0 # via -r requirements.txt, h5grove, nomad-lab, nomad-lab (pyproject.toml) +uvicorn[standard]==0.20.0 # via -r requirements.txt, h5grove, nomad-lab (pyproject.toml) uvloop==0.17.0 # via -r requirements.txt, uvicorn -validators==0.18.2 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +validators==0.18.2 # via -r requirements.txt, nomad-lab (pyproject.toml) vine==5.0.0 # via -r requirements.txt, amqp, celery, kombu watchdog==2.1.9 # via mkdocs watchfiles==0.18.1 # via -r requirements.txt, uvicorn @@ -349,12 +344,12 @@ websockets==10.4 # via -r requirements.txt, uvicorn werkzeug==2.2.2 # via -r requirements.txt, flask wheel==0.38.4 # via pip-tools widgetsnbextension==4.0.9 # via -r requirements.txt, ipywidgets -wrapt==1.12.1 # via -r requirements.txt, astroid, nomad-lab, nomad-lab (pyproject.toml) -xarray==0.20.2 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +wrapt==1.12.1 # via -r requirements.txt, astroid, nomad-lab (pyproject.toml) +xarray==0.20.2 # via -r requirements.txt, nomad-lab (pyproject.toml) zarr==2.12.0 # via -r requirements.txt, hyperspy zipfile37==0.1.3 # via -r requirements.txt zipp==3.11.0 # via -r requirements.txt, importlib-metadata -zipstream-new==1.1.5 # via -r requirements.txt, nomad-lab, nomad-lab (pyproject.toml) +zipstream-new==1.1.5 # via -r requirements.txt, nomad-lab (pyproject.toml) # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/requirements.txt b/requirements.txt index 6761ecddc3..8c69d3eff2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,48 +2,49 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --annotation-style=line --extra=infrastructure --extra=parsing --output-file=requirements.txt --resolver=backtracking dependencies/nomad-dos-fingerprints/pyproject.toml dependencies/parsers/atomistic/pyproject.toml dependencies/parsers/database/pyproject.toml dependencies/parsers/eelsdb/pyproject.toml dependencies/parsers/electronic/pyproject.toml dependencies/parsers/nexus/pyproject.toml dependencies/parsers/workflow/pyproject.toml pyproject.toml +# pip-compile --annotation-style=line --extra=infrastructure --extra=parsing --output-file=requirements.txt --pip-args='--prefer-binary' dependencies/nomad-dos-fingerprints/pyproject.toml dependencies/parsers/eelsdb/pyproject.toml dependencies/parsers/nexus/pyproject.toml pyproject.toml # alabaster==0.7.12 # via sphinx alembic==1.9.1 # via jupyterhub amqp==5.1.1 # via kombu -aniso8601==7.0.0 # via nomad-lab, nomad-lab (pyproject.toml) +aniso8601==7.0.0 # via nomad-lab (pyproject.toml) anyio==3.6.2 # via httpcore, starlette, watchfiles +appnope==0.1.4 # via ipykernel, ipython arrow==1.2.3 # via isoduration asciitree==0.3.3 # via zarr -ase==3.19.0 # via asr, ifes-apt-tc-data-modeling, matid, nomad-lab, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml), quippy-ase -asgiref==3.6.0 # via nomad-lab, nomad-lab (pyproject.toml) -asr==0.4.1 # via nomad-lab (pyproject.toml), workflowparsers (dependencies/parsers/workflow/pyproject.toml) +ase==3.19.0 # via asr, ifes-apt-tc-data-modeling, matid, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml), quippy-ase +asgiref==3.6.0 # via nomad-lab (pyproject.toml) +asr==0.4.1 # via nomad-lab (pyproject.toml) asteval==0.9.31 # via lmfit async-generator==1.10 # via jupyterhub async-timeout==4.0.2 # via redis attrs==22.2.0 # via cattrs, jsonschema, requests-cache babel==2.11.0 # via sphinx backcall==0.2.0 # via ipython -bagit==1.8.1 # via nomad-lab, nomad-lab (pyproject.toml) -basicauth==0.4.1 # via nomad-lab, nomad-lab (pyproject.toml) -bcrypt==3.2.0 # via nomad-lab, nomad-lab (pyproject.toml) +bagit==1.8.1 # via nomad-lab (pyproject.toml) +basicauth==0.4.1 # via nomad-lab (pyproject.toml) +bcrypt==3.2.0 # via nomad-lab (pyproject.toml) beautifulsoup4==4.11.1 # via bs4 billiard==3.6.4.0 # via celery biopython==1.80 # via mdanalysis -bitarray==2.3.5 # via nomad-lab, nomad-lab (pyproject.toml), nomad_dos_fingerprints (dependencies/nomad-dos-fingerprints/pyproject.toml) -bs4==0.0.1 # via nomad-lab, nomad-lab (pyproject.toml) -cachetools==4.2.4 # via nomad-lab, nomad-lab (pyproject.toml) +bitarray==2.3.5 # via nomad-lab (pyproject.toml), nomad_dos_fingerprints (dependencies/nomad-dos-fingerprints/pyproject.toml) +bs4==0.0.1 # via nomad-lab (pyproject.toml) +cachetools==4.2.4 # via nomad-lab (pyproject.toml) cattrs==22.2.0 # via requests-cache -celery[redis]==5.2.7 # via nomad-lab, nomad-lab (pyproject.toml) +celery[redis]==5.2.7 # via nomad-lab (pyproject.toml) certifi==2022.12.7 # via elasticsearch, httpcore, httpx, requests certipy==0.1.3 # via jupyterhub cffi==1.15.1 # via bcrypt, cryptography cftime==1.6.2 # via netcdf4 charset-normalizer==2.0.12 # via requests -click==8.1.3 # via asr, celery, click-didyoumean, click-plugins, click-repl, flask, nomad-lab, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml), uvicorn +click==8.1.3 # via asr, celery, click-didyoumean, click-plugins, click-repl, flask, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml), uvicorn click-didyoumean==0.3.0 # via celery click-plugins==1.1.1 # via celery click-repl==0.2.0 # via celery cloudpickle==2.2.0 # via dask comm==0.1.4 # via ipywidgets commonmark==0.9.1 # via recommonmark -cryptography==39.0.0 # via nomad-lab, nomad-lab (pyproject.toml), pyjwt, pyopenssl, rfc3161ng +cryptography==39.0.0 # via nomad-lab (pyproject.toml), pyjwt, pyopenssl, rfc3161ng cycler==0.11.0 # via matplotlib dask[array]==2022.2.0 # via hyperspy, kikuchipy, orix, pyxem debugpy==1.6.5 # via ipykernel @@ -53,22 +54,22 @@ diffsims==0.5.2 # via kikuchipy, pyxem dill==0.3.6 # via hyperspy dnspython==2.2.1 # via email-validator, pymongo docker==6.0.1 # via dockerspawner -dockerspawner==12.1.0 # via nomad-lab, nomad-lab (pyproject.toml) -docstring-parser==0.12 # via nomad-lab, nomad-lab (pyproject.toml) +dockerspawner==12.1.0 # via nomad-lab (pyproject.toml) +docstring-parser==0.12 # via nomad-lab (pyproject.toml) docutils==0.19 # via m2r, recommonmark, sphinx ecdsa==0.18.0 # via python-jose -elasticsearch==7.17.1 # via elasticsearch-dsl, nomad-lab, nomad-lab (pyproject.toml) -elasticsearch-dsl==7.4.0 # via nomad-lab, nomad-lab (pyproject.toml) +elasticsearch==7.17.1 # via elasticsearch-dsl, nomad-lab (pyproject.toml) +elasticsearch-dsl==7.4.0 # via nomad-lab (pyproject.toml) email-validator==1.3.0 # via optimade -entrypoints==0.4 # via ipyparallel, jupyter-client, jupyterhub, numcodecs +entrypoints==0.4 # via ipyparallel, jupyter-client, numcodecs escapism==1.0.1 # via dockerspawner et-xmlfile==1.1.0 # via openpyxl exceptiongroup==1.2.0 # via cattrs f90wrap==0.2.13 # via quippy-ase fabio==2023.6.0 # via pyfai, silx -fastapi==0.92.0 # via h5grove, nomad-lab, nomad-lab (pyproject.toml) +fastapi==0.92.0 # via h5grove, nomad-lab (pyproject.toml) fasteners==0.18 # via mdanalysis, zarr -filelock==3.3.1 # via nomad-lab, nomad-lab (pyproject.toml) +filelock==3.3.1 # via nomad-lab (pyproject.toml) flask==2.2.2 # via asr flatdict==4.0.1 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) fonttools==4.38.0 # via matplotlib @@ -76,43 +77,43 @@ fqdn==1.5.1 # via jsonschema fsspec==2022.11.0 # via dask, hyperspy future==0.18.2 # via uncertainties gitdb==4.0.10 # via gitpython -gitpython==3.1.24 # via nomad-lab, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml) +gitpython==3.1.24 # via nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml) greenlet==2.0.1 # via sqlalchemy griddataformats==0.7.0 # via mdanalysis gsd==2.7.0 # via mdanalysis -gunicorn==21.2.0 # via nomad-lab, nomad-lab (pyproject.toml) +gunicorn==21.2.0 # via nomad-lab (pyproject.toml) h11==0.14.0 # via httpcore, uvicorn -h5grove[fastapi]==1.3.0 # via nomad-lab, nomad-lab (pyproject.toml) -h5py==3.6.0 # via electronicparsers (dependencies/parsers/electronic/pyproject.toml), h5grove, hyperspy, ifes-apt-tc-data-modeling, kikuchipy, nionswift, nomad-lab, nomad-lab (pyproject.toml), orix, phonopy, pyfai, silx -hjson==3.0.2 # via nomad-lab, nomad-lab (pyproject.toml) -html5lib==1.1 # via nomad-lab, nomad-lab (pyproject.toml) +h5grove[fastapi]==1.3.0 # via nomad-lab (pyproject.toml) +h5py==3.6.0 # via h5grove, hyperspy, ifes-apt-tc-data-modeling, kikuchipy, nionswift, nomad-lab (pyproject.toml), orix, phonopy, pyfai, pynxtools (dependencies/parsers/nexus/pyproject.toml), silx +hjson==3.0.2 # via nomad-lab (pyproject.toml) +html5lib==1.1 # via nomad-lab (pyproject.toml) httpcore==0.16.3 # via httpx httptools==0.5.0 # via uvicorn -httpx==0.23.3 # via nomad-lab, nomad-lab (pyproject.toml) +httpx==0.23.3 # via nomad-lab (pyproject.toml) hyperspy==1.7.5 # via kikuchipy, pynxtools (dependencies/parsers/nexus/pyproject.toml), pyxem idna==3.4 # via anyio, email-validator, jsonschema, requests, rfc3986 ifes-apt-tc-data-modeling==0.0.9 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) imageio==2.24.0 # via hyperspy, kikuchipy, nionswift, nionswift-io, nionui, scikit-image imagesize==1.4.1 # via sphinx -importlib-metadata==4.13.0 # via flask, hyperspy, nomad-lab, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml), sphinx -inflection==0.5.1 # via nomad-lab, nomad-lab (pyproject.toml) +importlib-metadata==4.13.0 # via flask, hyperspy, jupyterhub, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml), sphinx +inflection==0.5.1 # via nomad-lab (pyproject.toml) ipykernel==6.16.2 # via ipyparallel ipyparallel==8.4.1 # via hyperspy ipython==7.34.0 # via hyperspy, ipykernel, ipyparallel, ipywidgets ipywidgets==8.1.1 # via pyxem isodate==0.6.1 # via rdflib isoduration==20.11.0 # via jsonschema -itsdangerous==2.1.2 # via flask, nomad-lab, nomad-lab (pyproject.toml) +itsdangerous==2.1.2 # via flask, nomad-lab (pyproject.toml) jedi==0.18.2 # via ipython jinja2==3.0.3 # via flask, hyperspy, jupyterhub, sphinx -jmespath==0.10.0 # via nomad-lab, nomad-lab (pyproject.toml) -joblib==1.1.0 # via mdanalysis, nomad-lab, pymatgen, scikit-learn +jmespath==0.10.0 # via nomad-lab (pyproject.toml) +joblib==1.1.0 # via mdanalysis, pymatgen, scikit-learn jsonpointer==2.3 # via jsonschema -jsonschema[format]==4.17.3 # via jupyter-telemetry, nomad-lab, nomad-lab (pyproject.toml), oauthenticator +jsonschema[format]==4.17.3 # via jupyter-telemetry, nomad-lab (pyproject.toml), oauthenticator jupyter-client==7.4.8 # via ipykernel, ipyparallel jupyter-core==4.12.0 # via jupyter-client jupyter-telemetry==0.1.0 # via jupyterhub -jupyterhub==1.4.2 # via dockerspawner, nomad-lab, nomad-lab (pyproject.toml), oauthenticator +jupyterhub==4.0.2 # via dockerspawner, nomad-lab (pyproject.toml), oauthenticator jupyterlab-widgets==3.0.9 # via ipywidgets kikuchipy==0.8.7 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) kiwisolver==1.4.4 # via matplotlib @@ -122,63 +123,60 @@ latexcodec==2.0.1 # via pybtex llvmlite==0.39.1 # via numba lmfit==1.2.2 # via pyxem locket==1.0.0 # via partd -lxml==4.7.1 # via atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), nomad-lab, nomad-lab (pyproject.toml) -m2r==0.2.1 # via nomad-lab, nomad-lab (pyproject.toml) +lxml==4.7.1 # via nomad-lab (pyproject.toml) +m2r==0.2.1 # via nomad-lab (pyproject.toml) mako==1.2.4 # via alembic markupsafe==2.1.1 # via jinja2, mako, werkzeug -matid==2.0.0.dev2 # via nomad-lab, nomad-lab (pyproject.toml) +matid==2.0.0.dev2 # via nomad-lab (pyproject.toml) matplotlib==3.5.3 # via ase, asr, diffsims, hyperspy, kikuchipy, matplotlib-scalebar, mdanalysis, orix, phonopy, pyfai, pymatgen, pyxem, radioactivedecay matplotlib-inline==0.1.6 # via ipykernel, ipython matplotlib-scalebar==0.8.1 # via orix -mdanalysis==2.5.0 # via atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), nomad-lab, nomad-lab (pyproject.toml) -memoization==0.4.0 # via nomad-lab, nomad-lab (pyproject.toml) +mdanalysis==2.5.0 # via nomad-lab (pyproject.toml) +memoization==0.4.0 # via nomad-lab (pyproject.toml) mergedeep==1.3.4 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) mistune==2.0.4 # via m2r mmtf-python==1.1.3 # via mdanalysis -mongoengine==0.25.0 # via nomad-lab, nomad-lab (pyproject.toml) +mongoengine==0.25.0 # via nomad-lab (pyproject.toml) mongomock==4.1.2 # via optimade monty==2022.9.9 # via pymatgen mpmath==1.2.1 # via sympy mrcfile==1.4.3 # via griddataformats -msgpack==1.0.4 # via mmtf-python, nomad-lab, nomad-lab (pyproject.toml) +msgpack==1.0.4 # via mmtf-python, nomad-lab (pyproject.toml) natsort==8.2.0 # via hyperspy nest-asyncio==1.5.6 # via ipykernel, jupyter-client -netcdf4==1.5.4 # via electronicparsers (dependencies/parsers/electronic/pyproject.toml), nomad-lab (pyproject.toml) -networkx==2.6.3 # via matid, mdanalysis, nomad-lab, nomad-lab (pyproject.toml), pymatgen, radioactivedecay, scikit-image +netcdf4==1.5.4 # via nomad-lab (pyproject.toml) +networkx==2.6.3 # via matid, mdanalysis, nomad-lab (pyproject.toml), pymatgen, radioactivedecay, scikit-image niondata==0.15.5 # via nionswift, nionswift-io nionswift==0.16.8 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) nionswift-io==0.15.1 # via nionswift nionui==0.6.11 # via nionswift nionutils==0.4.8 # via niondata, nionswift, nionswift-io, nionui -nomad-lab @ git+https://github.com/nomad-coe/nomad.git@develop # via atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), nomad-schema-plugin-run, nomad-schema-plugin-simulation-workflow, simulationparsers, workflowparsers (dependencies/parsers/workflow/pyproject.toml) -nomad-schema-plugin-run @ git+https://github.com/nomad-coe/nomad-schema-plugin-run.git@develop # via atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), nomad-schema-plugin-simulation-workflow, simulationparsers, workflowparsers (dependencies/parsers/workflow/pyproject.toml) -nomad-schema-plugin-simulation-workflow @ git+https://github.com/nomad-coe/nomad-schema-plugin-simulation-workflow.git@develop # via atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), workflowparsers (dependencies/parsers/workflow/pyproject.toml) -nptyping==1.4.4 # via nomad-lab, nomad-lab (pyproject.toml) +nptyping==1.4.4 # via nomad-lab (pyproject.toml) numba==0.56.4 # via diffsims, hyperspy, kikuchipy, orix, pyxem, sparse numcodecs==0.10.2 # via zarr numexpr==2.8.4 # via hyperspy, pyfai -numpy==1.22.4 # via ase, biopython, cftime, dask, diffsims, f90wrap, fabio, griddataformats, gsd, h5grove, h5py, hyperspy, ifes-apt-tc-data-modeling, imageio, kikuchipy, lmfit, matid, matplotlib, mdanalysis, mrcfile, netcdf4, niondata, nionswift, nionswift-io, nionui, nomad-lab, nomad-lab (pyproject.toml), nomad_dos_fingerprints (dependencies/nomad-dos-fingerprints/pyproject.toml), nptyping, numba, numcodecs, numexpr, numpy-quaternion, orix, pandas, phonopy, pyfai, pymatgen, pywavelets, pyxem, quippy-ase, radioactivedecay, scikit-image, scikit-learn, scipy, silx, sparse, spglib, tifffile, xarray, zarr +numpy==1.22.4 # via ase, biopython, cftime, dask, diffsims, f90wrap, fabio, griddataformats, gsd, h5grove, h5py, hyperspy, ifes-apt-tc-data-modeling, imageio, kikuchipy, lmfit, matid, matplotlib, mdanalysis, mrcfile, netcdf4, niondata, nionswift, nionswift-io, nionui, nomad-lab (pyproject.toml), nomad_dos_fingerprints (dependencies/nomad-dos-fingerprints/pyproject.toml), nptyping, numba, numcodecs, numexpr, numpy-quaternion, orix, pandas, phonopy, pyfai, pymatgen, pynxtools (dependencies/parsers/nexus/pyproject.toml), pywavelets, pyxem, quippy-ase, radioactivedecay, scikit-image, scikit-learn, scipy, silx, sparse, spglib, tifffile, xarray, zarr numpy-quaternion==2022.4.3 # via orix -oauthenticator==15.1.0 # via nomad-lab, nomad-lab (pyproject.toml) +oauthenticator==15.1.0 # via nomad-lab (pyproject.toml) oauthlib==3.2.2 # via jupyterhub -openpyxl==3.1.2 # via nomad-lab, nomad-lab (pyproject.toml) -optimade[mongo]==0.22.1 # via nomad-lab, nomad-lab (pyproject.toml) +openpyxl==3.1.2 # via nomad-lab (pyproject.toml) +optimade[mongo]==0.22.1 # via nomad-lab (pyproject.toml) orix==0.11.1 # via diffsims, kikuchipy, pyxem -orjson==3.9.4 # via h5grove, nomad-lab, nomad-lab (pyproject.toml) -packaging==24.0 # via dask, docker, gunicorn, hyperspy, ipykernel, matplotlib, mdanalysis, mongomock, pint, pooch, scikit-image, sphinx +orjson==3.9.4 # via h5grove, nomad-lab (pyproject.toml) +packaging==23.0 # via dask, docker, gunicorn, hyperspy, ipykernel, jupyterhub, matplotlib, mdanalysis, mongomock, pint, pooch, scikit-image, sphinx palettable==3.3.0 # via pymatgen pamela==1.0.0 # via jupyterhub -pandas==1.3.5 # via eelsdbconverter (dependencies/parsers/eelsdb/pyproject.toml), ifes-apt-tc-data-modeling, nomad-lab, nomad-lab (pyproject.toml), panedr, pybis, pymatgen, xarray -panedr==0.2 # via atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), nomad-lab, nomad-lab (pyproject.toml) -parmed==3.0.0 # via nomad-lab, nomad-lab (pyproject.toml) +pandas==1.3.5 # via eelsdbconverter (dependencies/parsers/eelsdb/pyproject.toml), ifes-apt-tc-data-modeling, nomad-lab (pyproject.toml), panedr, pybis, pymatgen, pynxtools (dependencies/parsers/nexus/pyproject.toml), xarray +panedr==0.2 # via nomad-lab (pyproject.toml) +parmed==3.0.0 # via nomad-lab (pyproject.toml) parso==0.8.3 # via jedi partd==1.3.0 # via dask -passlib==1.7.4 # via nomad-lab, nomad-lab (pyproject.toml) +passlib==1.7.4 # via nomad-lab (pyproject.toml) pexpect==4.8.0 # via ipython -phonopy==2.11.0 # via asr, workflowparsers (dependencies/parsers/workflow/pyproject.toml) +phonopy==2.11.0 # via asr pickleshare==0.7.5 # via ipython pillow==9.4.0 # via imageio, matplotlib, nionswift, scikit-image -pint==0.17 # via hyperspy, nomad-lab, nomad-lab (pyproject.toml) +pint==0.17 # via hyperspy, nomad-lab (pyproject.toml) platformdirs==3.1.1 # via pooch, requests-cache plotly==5.11.0 # via asr, pymatgen pooch==1.7.0 # via kikuchipy, orix @@ -193,51 +191,50 @@ pybis @ git+https://github.com/FAIRmat-NFDI/fairmat-pybis.git # via nomad-lab ( pybtex==0.24.0 # via pymatgen pycifrw==4.4.5 # via diffpy-structure pycparser==2.21 # via cffi -pydantic==1.10.9 # via fastapi, nomad-lab, nomad-lab (pyproject.toml), optimade +pydantic==1.10.9 # via fastapi, nomad-lab (pyproject.toml), optimade pyfai==2023.9.0 # via pyxem pygments==2.14.0 # via ipython, sphinx -pyjwt[crypto]==2.6.0 # via nomad-lab, nomad-lab (pyproject.toml) -pymatgen==2023.9.25 # via asr, nomad-lab, nomad-lab (pyproject.toml) -pymongo==4.3.3 # via mongoengine, nomad-lab, nomad-lab (pyproject.toml), optimade +pyjwt[crypto]==2.6.0 # via nomad-lab (pyproject.toml) +pymatgen==2023.9.25 # via asr, nomad-lab (pyproject.toml) +pymongo==4.3.3 # via mongoengine, nomad-lab (pyproject.toml), optimade pyopenssl==23.0.0 # via certipy pyparsing==3.0.9 # via matplotlib, rdflib pyrsistent==0.19.3 # via jsonschema python-dateutil==2.8.2 # via arrow, elasticsearch-dsl, hyperspy, ipyparallel, jupyter-client, jupyterhub, matplotlib, pandas, pybis, rfc3161ng python-dotenv==0.21.0 # via uvicorn python-jose==3.3.0 # via python-keycloak -python-json-logger==2.0.2 # via jupyter-telemetry, nomad-lab, nomad-lab (pyproject.toml) -python-keycloak==0.26.1 # via nomad-lab, nomad-lab (pyproject.toml) -python-logstash==0.4.6 # via nomad-lab, nomad-lab (pyproject.toml) -python-magic==0.4.24 # via nomad-lab, nomad-lab (pyproject.toml) -python-multipart==0.0.5 # via nomad-lab, nomad-lab (pyproject.toml) -pytz==2022.7.1 # via babel, celery, nionswift, nomad-lab, nomad-lab (pyproject.toml), pandas, pynxtools (dependencies/parsers/nexus/pyproject.toml) +python-json-logger==2.0.2 # via jupyter-telemetry, nomad-lab (pyproject.toml) +python-keycloak==0.26.1 # via nomad-lab (pyproject.toml) +python-logstash==0.4.6 # via nomad-lab (pyproject.toml) +python-magic==0.4.24 # via nomad-lab (pyproject.toml) +python-multipart==0.0.5 # via nomad-lab (pyproject.toml) +pytz==2022.7.1 # via babel, celery, nionswift, nomad-lab (pyproject.toml), pandas, pynxtools (dependencies/parsers/nexus/pyproject.toml) pytz-deprecation-shim==0.1.0.post0 # via tzlocal pywavelets==1.3.0 # via scikit-image pyxem==0.15.1 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) -pyyaml==6.0 # via dask, electronicparsers (dependencies/parsers/electronic/pyproject.toml), hyperspy, kikuchipy, nomad-lab, nomad-lab (pyproject.toml), phonopy, pybtex, uvicorn +pyyaml==6.0 # via dask, hyperspy, kikuchipy, nomad-lab (pyproject.toml), phonopy, pybtex, pynxtools (dependencies/parsers/nexus/pyproject.toml), uvicorn pyzeo==0.1.4 # via nomad-lab (pyproject.toml) pyzmq==25.0.0 # via ipykernel, ipyparallel, jupyter-client quippy-ase==0.9.14 # via nomad-lab (pyproject.toml) radioactivedecay==0.4.17 # via ifes-apt-tc-data-modeling -rdflib==5.0.0 # via nomad-lab, nomad-lab (pyproject.toml) -recommonmark==0.7.1 # via nomad-lab, nomad-lab (pyproject.toml) +rdflib==5.0.0 # via nomad-lab (pyproject.toml) +recommonmark==0.7.1 # via nomad-lab (pyproject.toml) redis==4.4.2 # via celery -requests==2.28.2 # via docker, eelsdbconverter (dependencies/parsers/eelsdb/pyproject.toml), hyperspy, jupyterhub, nomad-lab, nomad-lab (pyproject.toml), oauthenticator, optimade, pooch, pybis, pymatgen, python-keycloak, requests-cache, rfc3161ng, sphinx +requests==2.28.2 # via docker, eelsdbconverter (dependencies/parsers/eelsdb/pyproject.toml), hyperspy, jupyterhub, nomad-lab (pyproject.toml), oauthenticator, optimade, pooch, pybis, pymatgen, pynxtools (dependencies/parsers/nexus/pyproject.toml), python-keycloak, requests-cache, rfc3161ng, sphinx requests-cache==1.0.1 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) -rfc3161ng==2.1.3 # via nomad-lab, nomad-lab (pyproject.toml) +rfc3161ng==2.1.3 # via nomad-lab (pyproject.toml) rfc3339-validator==0.1.4 # via jsonschema rfc3986[idna2008]==1.5.0 # via httpx rfc3987==1.3.8 # via jsonschema rsa==4.9 # via python-jose ruamel-yaml==0.17.21 # via jupyter-telemetry, oauthenticator, pymatgen ruamel-yaml-clib==0.2.7 # via ruamel-yaml -runstats==2.0.0 # via nomad-lab, nomad-lab (pyproject.toml) +runstats==2.0.0 # via nomad-lab (pyproject.toml) scikit-image==0.19.3 # via hyperspy, kikuchipy, pyxem -scikit-learn==1.0.2 # via kikuchipy, matid, nomad-lab, nomad-lab (pyproject.toml), pyxem -scipy==1.7.1 # via ase, atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), diffsims, griddataformats, hyperspy, kikuchipy, lmfit, matid, mdanalysis, niondata, nionswift, nomad-lab, nomad-lab (pyproject.toml), orix, pyfai, pymatgen, pyxem, radioactivedecay, scikit-image, scikit-learn, sparse +scikit-learn==1.0.2 # via kikuchipy, matid, nomad-lab (pyproject.toml), pyxem +scipy==1.7.1 # via ase, diffsims, griddataformats, hyperspy, kikuchipy, lmfit, matid, mdanalysis, niondata, nionswift, nomad-lab (pyproject.toml), orix, pyfai, pymatgen, pynxtools (dependencies/parsers/nexus/pyproject.toml), pyxem, radioactivedecay, scikit-image, scikit-learn, sparse sentinels==1.0.0 # via mongomock silx==1.1.2 # via pyfai -simulationparsers @ git+https://github.com/nomad-coe/simulation-parsers.git@develop # via atomisticparsers (dependencies/parsers/atomistic/pyproject.toml), electronicparsers (dependencies/parsers/electronic/pyproject.toml) six==1.16.0 # via basicauth, bcrypt, click-repl, diffpy-structure, ecdsa, elasticsearch-dsl, griddataformats, html5lib, isodate, latexcodec, pybtex, python-dateutil, python-multipart, rdflib, rfc3339-validator, url-normalize, validators smmap==5.0.0 # via gitdb sniffio==1.3.0 # via anyio, httpcore, httpx @@ -254,15 +251,15 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx sqlalchemy==1.4.46 # via alembic, jupyterhub starlette==0.25.0 # via fastapi -structlog==22.3.0 # via nomad-lab, nomad-lab (pyproject.toml) +structlog==22.3.0 # via nomad-lab (pyproject.toml) sympy==1.10.1 # via hyperspy, pymatgen, radioactivedecay -tabulate==0.8.9 # via nomad-lab, nomad-lab (pyproject.toml), pybis, pymatgen +tabulate==0.8.9 # via nomad-lab (pyproject.toml), pybis, pymatgen tenacity==8.1.0 # via plotly texttable==1.7.0 # via pybis threadpoolctl==3.1.0 # via mdanalysis, scikit-learn tifffile==2021.11.2 # via h5grove, hyperspy, scikit-image toolz==0.12.0 # via dask, hyperspy, partd -toposort==1.9 # via nomad-lab, nomad-lab (pyproject.toml) +toposort==1.9 # via nomad-lab (pyproject.toml) tornado==6.2 # via ipykernel, ipyparallel, jupyter-client, jupyterhub tqdm==4.64.1 # via diffsims, hyperspy, ipyparallel, kikuchipy, mdanalysis, orix, pymatgen traitlets==5.8.1 # via comm, ipykernel, ipyparallel, ipython, ipywidgets, jupyter-client, jupyter-core, jupyter-telemetry, jupyterhub, matplotlib-inline @@ -273,13 +270,13 @@ typish==1.9.3 # via nptyping tzdata==2023.3 # via pytz-deprecation-shim tzlocal==4.3 # via nionswift, pynxtools (dependencies/parsers/nexus/pyproject.toml) uncertainties==3.1.7 # via lmfit, pymatgen -unidecode==1.3.2 # via nomad-lab, nomad-lab (pyproject.toml) +unidecode==1.3.2 # via nomad-lab (pyproject.toml) uri-template==1.2.0 # via jsonschema url-normalize==1.4.3 # via requests-cache urllib3==1.26.14 # via docker, elasticsearch, pybis, requests, requests-cache -uvicorn[standard]==0.20.0 # via h5grove, nomad-lab, nomad-lab (pyproject.toml) +uvicorn[standard]==0.20.0 # via h5grove, nomad-lab (pyproject.toml) uvloop==0.17.0 # via uvicorn -validators==0.18.2 # via nomad-lab, nomad-lab (pyproject.toml) +validators==0.18.2 # via nomad-lab (pyproject.toml) vine==5.0.0 # via amqp, celery, kombu watchfiles==0.18.1 # via uvicorn wcwidth==0.2.5 # via prettytable, prompt-toolkit @@ -289,12 +286,12 @@ websocket-client==1.4.2 # via docker websockets==10.4 # via uvicorn werkzeug==2.2.2 # via flask widgetsnbextension==4.0.9 # via ipywidgets -wrapt==1.12.1 # via nomad-lab, nomad-lab (pyproject.toml) -xarray==0.20.2 # via nomad-lab, nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml) +wrapt==1.12.1 # via nomad-lab (pyproject.toml) +xarray==0.20.2 # via nomad-lab (pyproject.toml), pynxtools (dependencies/parsers/nexus/pyproject.toml) zarr==2.12.0 # via hyperspy zipfile37==0.1.3 # via pynxtools (dependencies/parsers/nexus/pyproject.toml) zipp==3.11.0 # via importlib-metadata -zipstream-new==1.1.5 # via nomad-lab, nomad-lab (pyproject.toml) +zipstream-new==1.1.5 # via nomad-lab (pyproject.toml) # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/scripts/check_helm_chart.sh b/scripts/check_helm_chart.sh new file mode 100755 index 0000000000..f840fd2121 --- /dev/null +++ b/scripts/check_helm_chart.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e +set -x # echo on + +working_dir=$(pwd) +project_dir=$(dirname $(dirname $(realpath $0))) + +cd $project_dir + +mkdir tmp + +python ops/kubernetes/nomad/updatevalues.py > tmp/helm-values.yaml +diff ops/kubernetes/nomad/values.yaml tmp/helm-values.yaml + +# cleanup +rm -rf tmp diff --git a/scripts/check_python_dependencies.sh b/scripts/check_python_dependencies.sh index b6680a822c..fb033199c1 100755 --- a/scripts/check_python_dependencies.sh +++ b/scripts/check_python_dependencies.sh @@ -1,5 +1,12 @@ #!/bin/sh +# For now we exclude the following dependencies, because they import an older version +# of nomad-lab causing inevitable conflicts. +# dependencies/parsers/atomistic/pyproject.toml \ +# dependencies/parsers/database/pyproject.toml \ +# dependencies/parsers/electronic/pyproject.toml \ +# dependencies/parsers/workflow/pyproject.toml \ + set -e working_dir=$(pwd) @@ -7,28 +14,30 @@ project_dir=$(dirname $(dirname $(realpath $0))) cd $project_dir -set -x # echo on +# backup +cp requirements.txt requirements.txt.tmp +cp requirements-dev.txt requirements-dev.txt.tmp -pip-compile --resolver=backtracking --quiet --annotation-style=line \ +pip-compile --resolver=backtracking --annotation-style=line \ --extra=infrastructure --extra=parsing \ - --output-file=requirements.txt.tmp \ + --output-file=requirements.txt \ + --pip-args="--prefer-binary" \ dependencies/nomad-dos-fingerprints/pyproject.toml \ - dependencies/parsers/atomistic/pyproject.toml \ - dependencies/parsers/database/pyproject.toml \ dependencies/parsers/eelsdb/pyproject.toml \ - dependencies/parsers/electronic/pyproject.toml \ dependencies/parsers/nexus/pyproject.toml \ - dependencies/parsers/workflow/pyproject.toml pyproject.toml + pyproject.toml -diff requirements.txt requirements.txt.tmp +diff requirements.txt.tmp requirements.txt -pip-compile --resolver=backtracking --quiet --annotation-style=line \ +pip-compile --resolver=backtracking --annotation-style=line \ --extra=dev --extra=infrastructure --extra=parsing \ - --output-file=requirements-dev.txt.tmp \ + --output-file=requirements-dev.txt \ + --pip-args="--prefer-binary" \ requirements.txt \ pyproject.toml -diff requirements-dev.txt requirements-dev.txt.tmp +diff requirements-dev.txt.tmp requirements-dev.txt # cleanup -rm requirements.txt.tmp requirements-dev.txt.tmp +mv requirements.txt.tmp requirements.txt +mv requirements-dev.txt.tmp requirements-dev.txt diff --git a/scripts/generate_python_dependencies.sh b/scripts/generate_python_dependencies.sh index df678273e9..91de80c94d 100755 --- a/scripts/generate_python_dependencies.sh +++ b/scripts/generate_python_dependencies.sh @@ -1,5 +1,12 @@ #!/bin/sh +# For now we exclude the following dependencies, because they import an older version +# of nomad-lab causing inevitable conflicts. +# dependencies/parsers/atomistic/pyproject.toml \ +# dependencies/parsers/database/pyproject.toml \ +# dependencies/parsers/electronic/pyproject.toml \ +# dependencies/parsers/workflow/pyproject.toml \ + set -e working_dir=$(pwd) @@ -10,18 +17,16 @@ cd $project_dir pip-compile --resolver=backtracking --annotation-style=line \ --extra=infrastructure --extra=parsing \ --output-file=requirements.txt \ + --pip-args="--prefer-binary" \ dependencies/nomad-dos-fingerprints/pyproject.toml \ - dependencies/parsers/atomistic/pyproject.toml \ - dependencies/parsers/database/pyproject.toml \ dependencies/parsers/eelsdb/pyproject.toml \ - dependencies/parsers/electronic/pyproject.toml \ dependencies/parsers/nexus/pyproject.toml \ - dependencies/parsers/workflow/pyproject.toml pyproject.toml - + pyproject.toml pip-compile --resolver=backtracking --annotation-style=line \ --extra=dev --extra=infrastructure --extra=parsing \ --output-file=requirements-dev.txt \ + --pip-args="--prefer-binary" \ requirements.txt \ pyproject.toml diff --git a/scripts/update_helm_chart.sh b/scripts/update_helm_chart.sh new file mode 100755 index 0000000000..a58bff4d03 --- /dev/null +++ b/scripts/update_helm_chart.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +set -e + +working_dir=$(pwd) +project_dir=$(dirname $(dirname $(realpath $0))) + +cd $project_dir + +python ops/kubernetes/nomad/updatevalues.py ops/kubernetes/nomad/values.yaml -- GitLab