aiidalab package#

Subpackages#

Submodules#

aiidalab.__main__ module#

Module that implements a basic command line interface (CLI) for AiiDAlab.

aiidalab.__main__._find_app_and_releases(app_requirement)[source]#

Find app and a suitable release for a given requirement.

aiidalab.__main__._find_registered_app_from_id(name)[source]#

Find app for a given requirement.

aiidalab.__main__._find_version_to_install(app_requirement, force, dependencies, python_bin, prereleases)[source]#
aiidalab.__main__._list_apps(apps_path)[source]#
aiidalab.__main__._mock_schemas_endpoints()[source]#
aiidalab.__main__._parse_requirement(app_requirement)[source]#
aiidalab.__main__._spinner_with_message(message, message_final='Done.\n', **kwargs)[source]#
aiidalab.__main__._tabulate_apps(apps, headers=('App name', 'Version', 'Path'), **kwargs)[source]#

aiidalab.app module#

Module to manage AiiDAlab apps.

class aiidalab.app.AiidaLabApp(**kwargs: Any)[source]#

Bases: traitlets.traitlets.HasTraits

Manage installation status of an AiiDAlab app.

Arguments:

name (str):

Name of the Aiida lab app.

app_data (dict):

Dictionary containing the app metadata.

aiidalab_apps_path (str):

Path to directory at which the app is expected to be installed.

watch (bool):

If true (default), automatically watch the repository for changes.

__annotations__ = {}#
__init__(name: str, app_data: dict[str, Any], aiidalab_apps_path: str, watch: bool = True)[source]#
__module__ = 'aiidalab.app'#
__str__()[source]#

Return str(self).

_all_trait_default_generators: dict[str, t.Any] = {'available_versions': <bound method TraitType.default of <traitlets.traitlets.List object>>, 'busy': <traitlets.traitlets.DefaultHandler object>, 'compatibility_info': <bound method TraitType.default of <traitlets.traitlets.Dict object>>, 'compatible': <traitlets.traitlets.DefaultHandler object>, 'dependencies_to_install': <bound method TraitType.default of <traitlets.traitlets.List object>>, 'detached': <traitlets.traitlets.DefaultHandler object>, 'has_prereleases': <bound method TraitType.default of <traitlets.traitlets.Bool object>>, 'include_prereleases': <traitlets.traitlets.DefaultHandler object>, 'install_info': <bound method TraitType.default of <traitlets.traitlets.Unicode object>>, 'installed_version': <bound method Union.default of <traitlets.traitlets.Union object>>, 'path': <bound method TraitType.default of <traitlets.traitlets.Unicode object>>, 'remote_update_status': <bound method TraitType.default of <traitlets.traitlets.UseEnum object>>, 'version_to_install': <bound method TraitType.default of <traitlets.traitlets.Unicode object>>}#
_default_busy#
_default_compatible#
_default_detached#
_default_include_prereleases#
_descriptors = [<traitlets.traitlets.DefaultHandler object>, <traitlets.traitlets.DefaultHandler object>, <traitlets.traitlets.DefaultHandler object>, <traitlets.traitlets.DefaultHandler object>, <traitlets.traitlets.ObserveHandler object>, <traitlets.traitlets.ObserveHandler object>, <traitlets.traitlets.ValidateHandler object>, <traitlets.traitlets.List object>, <traitlets.traitlets.Bool object>, <traitlets.traitlets.Dict object>, <traitlets.traitlets.Bool object>, <traitlets.traitlets.List object>, <traitlets.traitlets.Bool object>, <traitlets.traitlets.Bool object>, <traitlets.traitlets.Bool object>, <traitlets.traitlets.Unicode object>, <traitlets.traitlets.Union object>, <traitlets.traitlets.Unicode object>, <traitlets.traitlets.UseEnum object>, <traitlets.traitlets.Unicode object>]#
_get_from_metadata(what: str) str[source]#

Get information from metadata.

_get_installed_version() aiidalab.app.AppVersion | str[source]#

Determine the currently installed version.

_has_git_repo()[source]#

Check if the app has a .git folder in it.

_instance_inits = [<bound method BaseDescriptor.instance_init of <traitlets.traitlets.DefaultHandler object>>, <bound method BaseDescriptor.instance_init of <traitlets.traitlets.DefaultHandler object>>, <bound method BaseDescriptor.instance_init of <traitlets.traitlets.DefaultHandler object>>, <bound method BaseDescriptor.instance_init of <traitlets.traitlets.DefaultHandler object>>, <bound method ObserveHandler.instance_init of <traitlets.traitlets.ObserveHandler object>>, <bound method ObserveHandler.instance_init of <traitlets.traitlets.ObserveHandler object>>, <bound method ValidateHandler.instance_init of <traitlets.traitlets.ValidateHandler object>>, <bound method BaseDescriptor.instance_init of <traitlets.traitlets.UseEnum object>>, <bound method BaseDescriptor.instance_init of <traitlets.traitlets.UseEnum object>>]#
_is_compatible(app_version: str) bool[source]#

Determine whether the specified version is compatible.

_observe_include_prereleases#
_observe_version_to_install#
_refresh_dependencies_to_install() None[source]#
_refresh_versions() None[source]#
property _repo: aiidalab.git_util.GitManagedAppRepo#

Returns Git repository.

_show_busy()[source]#

Apply this decorator to indicate that the app is busy during execution.

_static_immutable_initial_values: dict[str, t.Any] = {'has_prereleases': False, 'install_info': '', 'path': '', 'version_to_install': ''}#
_trait_default_generators = {'busy': <traitlets.traitlets.DefaultHandler object>, 'compatible': <traitlets.traitlets.DefaultHandler object>, 'detached': <traitlets.traitlets.DefaultHandler object>, 'include_prereleases': <traitlets.traitlets.DefaultHandler object>}#
_traits: dict[str, t.Any] = {'available_versions': <traitlets.traitlets.List object>, 'busy': <traitlets.traitlets.Bool object>, 'compatibility_info': <traitlets.traitlets.Dict object>, 'compatible': <traitlets.traitlets.Bool object>, 'dependencies_to_install': <traitlets.traitlets.List object>, 'detached': <traitlets.traitlets.Bool object>, 'has_prereleases': <traitlets.traitlets.Bool object>, 'include_prereleases': <traitlets.traitlets.Bool object>, 'install_info': <traitlets.traitlets.Unicode object>, 'installed_version': <traitlets.traitlets.Union object>, 'path': <traitlets.traitlets.Unicode object>, 'remote_update_status': <traitlets.traitlets.UseEnum object>, 'version_to_install': <traitlets.traitlets.Unicode object>}#
_validate_version_to_install#
property authors: str#
available_versions#

An instance of a Python list.

busy#

A boolean (True, False) trait.

compatibility_info#

An instance of a Python dict.

One or more traits can be passed to the constructor to validate the keys and/or values of the dict. If you need more detailed validation, you may use a custom validator method.

Changed in version 5.0: Added key_trait for validating dict keys.

Changed in version 5.0: Deprecated ambiguous trait, traits args in favor of value_trait, per_key_traits.

compatible#

A boolean (True, False) trait.

dependencies_to_install#

An instance of a Python list.

property description: str#
detached#

A boolean (True, False) trait.

has_prereleases#

A boolean (True, False) trait.

in_category(category)[source]#
include_prereleases#

A boolean (True, False) trait.

install_app(version: Optional[str] = None, stdout: Optional[str] = None) aiidalab.app.AppVersion | str[source]#

Installing the app.

install_info#

A trait for unicode strings.

installed_version#

A trait type representing a Union type.

property metadata#

Return metadata dictionary. Give the priority to the local copy (better for the developers).

property more: str#
path#

A trait for unicode strings.

refresh() None[source]#

Refresh app state.

refresh_async() None[source]#

Asynchronized (non-blocking) refresh of the app state.

remote_update_status#

Use a Enum class as model for the data type description. Note that if no default-value is provided, the first enum-value is used as default-value.

# -- SINCE: Python 3.4 (or install backport: pip install enum34)
import enum
from traitlets import HasTraits, UseEnum


class Color(enum.Enum):
    red = 1  # -- IMPLICIT: default_value
    blue = 2
    green = 3


class MyEntity(HasTraits):
    color = UseEnum(Color, default_value=Color.blue)


entity = MyEntity(color=Color.red)
entity.color = Color.green  # USE: Enum-value (preferred)
entity.color = "green"  # USE: name (as string)
entity.color = "Color.green"  # USE: scoped-name (as string)
entity.color = 3  # USE: number (as int)
assert entity.color is Color.green
property title: str#
uninstall_app(_=None)[source]#

Perfrom app uninstall.

update_app(_: Optional[str] = None, stdout: Optional[str] = None) aiidalab.app.AppVersion | str[source]#

Perform app update.

property url: str#

Provide explicit link to Git repository.

version_to_install#

A trait for unicode strings.

class aiidalab.app.AiidaLabAppWatch(app)[source]#

Bases: object

Watch to monitor the app installation status.

Create a watch instance to monitor the installation status of an AiiDAlab app. This is achieved by monitoring the app repository for existance and changes.

If there is a change in the app repository, the app is refreshed.

Arguments:
app (AiidaLabApp):

The AiidaLab app to monitor.

class AppPathFileSystemEventHandler(app)[source]#

Bases: watchdog.events.FileSystemEventHandler

Internal event handeler for app path file system events.

__init__(app)[source]#
__module__ = 'aiidalab.app'#
on_any_event(event)[source]#

Refresh app for any event except opened.

__dict__ = mappingproxy({'__module__': 'aiidalab.app', '__doc__': 'Watch to monitor the app installation status.\n\n    Create a watch instance to monitor the installation status of an\n    AiiDAlab app. This is achieved by monitoring the app repository\n    for existance and changes.\n\n    If there is a change in the app repository, the app is refreshed.\n\n    Arguments:\n        app (AiidaLabApp):\n            The AiidaLab app to monitor.\n    ', 'AppPathFileSystemEventHandler': <class 'aiidalab.app.AiidaLabAppWatch.AppPathFileSystemEventHandler'>, '__init__': <function AiidaLabAppWatch.__init__>, '__repr__': <function AiidaLabAppWatch.__repr__>, '_start_observer': <function AiidaLabAppWatch._start_observer>, '_stop_observer': <function AiidaLabAppWatch._stop_observer>, 'start': <function AiidaLabAppWatch.start>, 'stop': <function AiidaLabAppWatch.stop>, 'is_alive': <function AiidaLabAppWatch.is_alive>, 'join': <function AiidaLabAppWatch.join>, '__dict__': <attribute '__dict__' of 'AiidaLabAppWatch' objects>, '__weakref__': <attribute '__weakref__' of 'AiidaLabAppWatch' objects>, '__annotations__': {}})#
__init__(app)[source]#
__module__ = 'aiidalab.app'#
__repr__() str[source]#

Return repr(self).

__weakref__#

list of weak references to the object (if defined)

_start_observer() None[source]#

Start the directory observer thread.

The ._observer thread is controlled by the ._monitor_thread.

_stop_observer() None[source]#

Stop the directory observer thread.

The ._observer thread is controlled by the ._monitor_thread.

is_alive() bool | None[source]#

Return True if this watch is still alive.

join(timeout: Optional[float] = None) None[source]#

Join the watch and observer after stopping.

This function will timeout if a timeout argument is provided. Use the is_alive() function to determien whether the watch was stopped within the given timout.

start() None[source]#

Watch the app repository for file system events.

The app state is refreshed automatically for all events.

stop() None[source]#

Stop watching the app repository for file system events.

exception aiidalab.app.AppNotInstalledException[source]#

Bases: Exception

__module__ = 'aiidalab.app'#
__weakref__#

list of weak references to the object (if defined)

class aiidalab.app.AppRemoteUpdateStatus(value)[source]#

Bases: enum.Flag

An enumeration.

CANNOT_REACH_REGISTRY = 8#
DETACHED = 16#
NOT_REGISTERED = 1#
UPDATE_AVAILABLE = 4#
UP_TO_DATE = 2#
__module__ = 'aiidalab.app'#
class aiidalab.app.AppVersion(value)[source]#

Bases: enum.Enum

An enumeration.

NOT_INSTALLED = 2#
UNKNOWN = 1#
__module__ = 'aiidalab.app'#
class aiidalab.app._AiidaLabApp(metadata: 'dict[str, Any]', name: 'str', path: 'Path', releases: 'dict[str, Any]' = <factory>)[source]#

Bases: object

__annotations__ = {'metadata': 'dict[str, Any]', 'name': 'str', 'path': 'Path', 'releases': 'dict[str, Any]'}#
__dataclass_fields__ = {'metadata': Field(name='metadata',type='dict[str, Any]',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'name': Field(name='name',type='str',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'path': Field(name='path',type='Path',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'releases': Field(name='releases',type='dict[str, Any]',default=<dataclasses._MISSING_TYPE object>,default_factory=<class 'dict'>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)}#
__dataclass_params__ = _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False)#
__dict__ = mappingproxy({'__module__': 'aiidalab.app', '__annotations__': {'metadata': 'dict[str, Any]', 'name': 'str', 'path': 'Path', 'releases': 'dict[str, Any]'}, 'from_registry_entry': <classmethod(<function _AiidaLabApp.from_registry_entry>)>, '_registry_entry_from_path': <classmethod(<function _AiidaLabApp._registry_entry_from_path>)>, 'from_id': <classmethod(<function _AiidaLabApp.from_id>)>, 'is_registered': <function _AiidaLabApp.is_registered>, '_repo': <property object>, 'installed_version': <function _AiidaLabApp.installed_version>, 'available_versions': <function _AiidaLabApp.available_versions>, 'dirty': <function _AiidaLabApp.dirty>, 'is_installed': <function _AiidaLabApp.is_installed>, 'remote_update_status': <function _AiidaLabApp.remote_update_status>, '_move_to_trash': <function _AiidaLabApp._move_to_trash>, '_restore_from': <function _AiidaLabApp._restore_from>, 'uninstall': <function _AiidaLabApp.uninstall>, 'find_matching_releases': <function _AiidaLabApp.find_matching_releases>, '_strict_dependencies_met': <staticmethod(<function _AiidaLabApp._strict_dependencies_met>)>, '_find_incompatibilities_python': <staticmethod(<function _AiidaLabApp._find_incompatibilities_python>)>, 'is_detached': <function _AiidaLabApp.is_detached>, 'find_incompatibilities': <function _AiidaLabApp.find_incompatibilities>, 'is_compatible': <function _AiidaLabApp.is_compatible>, 'find_dependencies_to_install': <function _AiidaLabApp.find_dependencies_to_install>, '_install_dependencies': <function _AiidaLabApp._install_dependencies>, '_post_install_triggers': <function _AiidaLabApp._post_install_triggers>, '_install_from_path': <function _AiidaLabApp._install_from_path>, '_install_from_https': <function _AiidaLabApp._install_from_https>, '_install_from_git_repository': <function _AiidaLabApp._install_from_git_repository>, 'install': <function _AiidaLabApp.install>, '__dict__': <attribute '__dict__' of '_AiidaLabApp' objects>, '__weakref__': <attribute '__weakref__' of '_AiidaLabApp' objects>, '__doc__': "_AiidaLabApp(metadata: 'dict[str, Any]', name: 'str', path: 'Path', releases: 'dict[str, Any]' = <factory>)", '__dataclass_params__': _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False), '__dataclass_fields__': {'metadata': Field(name='metadata',type='dict[str, Any]',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'name': Field(name='name',type='str',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'path': Field(name='path',type='Path',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'releases': Field(name='releases',type='dict[str, Any]',default=<dataclasses._MISSING_TYPE object>,default_factory=<class 'dict'>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)}, '__init__': <function _AiidaLabApp.__init__>, '__repr__': <function _AiidaLabApp.__repr__>, '__eq__': <function _AiidaLabApp.__eq__>, '__hash__': None, '__match_args__': ('metadata', 'name', 'path', 'releases')})#
__eq__(other)#

Return self==value.

__hash__ = None#
__init__(metadata: dict[str, typing.Any], name: str, path: pathlib.Path, releases: dict[str, typing.Any] = <factory>) None#
__match_args__ = ('metadata', 'name', 'path', 'releases')#
__module__ = 'aiidalab.app'#
__repr__()#

Return repr(self).

__weakref__#

list of weak references to the object (if defined)

static _find_incompatibilities_python(requirements: list[str], python_bin: str) Generator[packaging.requirements.Requirement, None, None][source]#
_install_dependencies(python_bin, stdout)[source]#

Try to install the app dependencies with pip (if specified).

_install_from_git_repository(git_url)[source]#
_install_from_https(url)[source]#
_install_from_path(path)[source]#
_move_to_trash() pathlib.Path | None[source]#
_post_install_triggers() None[source]#

Run a post_install script.

Typically used to execute additional commands after the app installation.

classmethod _registry_entry_from_path(path: pathlib.Path) dict[str, Any][source]#
property _repo: aiidalab.git_util.GitManagedAppRepo | None#
_restore_from(trash_path: pathlib.Path) None[source]#
static _strict_dependencies_met(requirements: list[packaging.requirements.Requirement], python_bin: str | None) bool[source]#

Check whether the given requirements are compatible with the core dependencies of a package.

available_versions(python_bin: Optional[str] = None, prereleases: bool = False) Generator[str, None, None][source]#

Return a list of available versions excluding the ones with core dependency conflicts.

dirty()[source]#
find_dependencies_to_install(version_to_install: str, python_bin: Optional[str] = None) list[dict[str, aiidalab.utils.Package | packaging.requirements.Requirement]][source]#

Returns a list of dependencies that need to be installed.

If an unsupported version of a dependency is installed, it will look something like: {installed=<Package…>, required=<Requirement(…)>}.

If the dependency is not present at all, it will look something like: {installed=None, required=<Requirement(…)>}.

find_incompatibilities(version, python_bin=None)[source]#

Compatibility is checked by comparing the app requirements with the packages installed in the python environment.

If the app is registered the list of requirements is fetched from the registry for the specific version. If the app is not registered or if it is detached (i.e. locally modified), the requirements list is read from the local repository (e.g. by parsing setup.cfg).

find_matching_releases(specifier, prereleases=None)[source]#
classmethod from_id(app_id: str, registry_entry: Optional[dict[str, Any]] = None, apps_path: Optional[str] = None) aiidalab.app._AiidaLabApp[source]#
classmethod from_registry_entry(path: pathlib.Path, registry_entry: dict[str, Any]) aiidalab.app._AiidaLabApp[source]#
install(version=None, python_bin=None, install_dependencies=True, stdout=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, prereleases=False, post_install_triggers=True)[source]#
installed_version() aiidalab.app.AppVersion | str[source]#
is_compatible(version, python_bin=None)[source]#
is_detached() bool[source]#

Check whether the app is detached from the registry.

is_installed() bool[source]#

The app is installed if the corresponding folder is present.

is_registered() bool | None[source]#
metadata: dict[str, Any]#
name: str#
path: pathlib.Path#
releases: dict[str, Any]#
remote_update_status(prereleases: bool = False) aiidalab.app.AppRemoteUpdateStatus[source]#

Determine the remote update satus.

Arguments:
prereleases (Bool):

Set to True to include available preleases. Defaults to False.

Returns:

AppRemoteUpdateStatus

uninstall() None[source]#

aiidalab.config module#

Module to manage AiiDAlab configuration.

aiidalab.config._as_env_var_name(key: str) str[source]#
aiidalab.config._get_config_value(key: str, default: Optional[str] = None) Any[source]#

Return config value from configuration source.

The standard configuration source order is:

  1. environment variables

  2. local configuration

In ‘develop’ mode the order is reversed to simplify local override of configuration values.

The convention for environment variables it to prefix keys with AIIDALAB_ and to convert all letters to uppercase. For example, the configuration key registry is interpreted as AIIDALAB_REGISTRY when sourced as an environment variable.

aiidalab.environment module#

App environment specification

The specification is used to describe a reproducible environment for a specific app, similar to the Reproducible Environment Specification (REES) [1]

[1] https://repo2docker.readthedocs.io/en/latest/specification.html

The following configuration files are recognized with the order of precedence matching the order shown here:

setup.cfg#

Requirements listed as part of the [options]/install_requires field are parsed as pip-installable Python requirements for this app.

requirements.txt#

Requirements listed within this file are parsed as pip-installable Python requirements for this app unless already parsed from the setup.cfg file.

class aiidalab.environment.Environment(python_requirements: list[str] = <factory>)[source]#

Bases: object

App environment specification.

This dataclass contains the specification of an app environment and can be used to scan an existing environment configuration from a given path and to detect whether a given environment is meeting the specification.

_FILES = ('requirements.txt',)#
__annotations__ = {'python_requirements': 'list[str]'}#
__dataclass_fields__ = {'python_requirements': Field(name='python_requirements',type='list[str]',default=<dataclasses._MISSING_TYPE object>,default_factory=<class 'list'>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)}#
__dataclass_params__ = _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False)#
__dict__ = mappingproxy({'__module__': 'aiidalab.environment', '__annotations__': {'python_requirements': 'list[str]'}, '__doc__': 'App environment specification.\n\n    This dataclass contains the specification of an app environment and can be\n    used to scan an existing environment configuration from a given path and to\n    detect whether a given environment is meeting the specification.\n    ', '_FILES': ('requirements.txt',), '_scan': <staticmethod(<function Environment._scan>)>, 'scan': <classmethod(<function Environment.scan>)>, '__dict__': <attribute '__dict__' of 'Environment' objects>, '__weakref__': <attribute '__weakref__' of 'Environment' objects>, '__dataclass_params__': _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False), '__dataclass_fields__': {'python_requirements': Field(name='python_requirements',type='list[str]',default=<dataclasses._MISSING_TYPE object>,default_factory=<class 'list'>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)}, '__init__': <function Environment.__init__>, '__repr__': <function Environment.__repr__>, '__eq__': <function Environment.__eq__>, '__hash__': None, '__match_args__': ('python_requirements',)})#
__eq__(other)#

Return self==value.

__hash__ = None#
__init__(python_requirements: list[str] = <factory>) None#
__match_args__ = ('python_requirements',)#
__module__ = 'aiidalab.environment'#
__repr__()#

Return repr(self).

__weakref__#

list of weak references to the object (if defined)

static _scan(path: pathlib.Path | aiidalab.git_util.GitPath) Generator[Any, None, None][source]#
python_requirements: list[str]#
classmethod scan(root: pathlib.Path | aiidalab.git_util.GitPath) aiidalab.environment.Environment[source]#

Scan the root path and determine the environment specification.

aiidalab.fetch module#

aiidalab.fetch._fetch_from_git_https(git_url: str) Generator[pathlib.Path | aiidalab.git_util.GitPath, None, None][source]#
aiidalab.fetch._fetch_from_git_local(git_url: str) Generator[pathlib.Path | aiidalab.git_util.GitPath, None, None][source]#
aiidalab.fetch._fetch_from_https(url: str) Generator[pathlib.Path | aiidalab.git_util.GitPath, None, None][source]#
aiidalab.fetch._fetch_from_path(path: pathlib.Path | aiidalab.git_util.GitPath) Generator[pathlib.Path | aiidalab.git_util.GitPath, None, None][source]#
aiidalab.fetch._parse_git_url(git_url: str) tuple[str, str, str][source]#
aiidalab.fetch._this_or_only_subdir(path: pathlib.Path) pathlib.Path[source]#
aiidalab.fetch.fetch_from_url(url: str) Generator[pathlib.Path | aiidalab.git_util.GitPath, None, None][source]#

aiidalab.git_util module#

Utility module for git-managed AiiDAlab apps.

class aiidalab.git_util.BranchTrackingStatus(value)[source]#

Bases: enum.Enum

Descripe the tracking status of a branch.

AHEAD = 1#
BEHIND = -1#
DIVERGED = 2#
EQUAL = 0#
__module__ = 'aiidalab.git_util'#
class aiidalab.git_util.GitManagedAppRepo(root: str, object_store: Optional[dulwich.object_store.PackBasedObjectStore] = None, bare: Optional[bool] = None)[source]#

Bases: dulwich.repo.Repo

Utility class to simplify management of git-based apps.

__annotations__ = {}#
__module__ = 'aiidalab.git_util'#
_get_branch_for_ref(ref: bytes) list[bytes][source]#

Get the branch name for a given reference.

branch() bytes[source]#

Return the current branch.

Raises RuntimeError if the repository is in a detached HEAD state.

dirty() bool[source]#

Check if there are likely local user modifications to the app repository.

get_branch_tracking_status(branch: bytes) aiidalab.git_util.BranchTrackingStatus | None[source]#

Return the tracking status of branch.

get_tracked_branch(branch: Optional[bytes] = None) Any[source]#

Return the tracked branch for a given branch or None if the branch is not tracking.

list_branches() Any[source]#

List all repository branches.

update_available() bool[source]#

Check whether there non-pulled commits on the tracked branch.

class aiidalab.git_util.GitPath(repo: pathlib.Path, commit: str, path: pathlib.Path = PosixPath('.'))[source]#

Bases: os.PathLike

Utility class to operate on git objects like path objects.

__abstractmethods__ = frozenset({})#
__annotations__ = {'commit': 'str', 'path': 'Path', 'repo': 'Path'}#
__dataclass_fields__ = {'commit': Field(name='commit',type='str',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'path': Field(name='path',type='Path',default=PosixPath('.'),default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'repo': Field(name='repo',type='Path',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)}#
__dataclass_params__ = _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False)#
__eq__(other)#

Return self==value.

__fspath__() str[source]#

Return the file system path representation of the object.

__hash__ = None#
__init__(repo: pathlib.Path, commit: str, path: pathlib.Path = PosixPath('.')) None#
__match_args__ = ('repo', 'commit', 'path')#
__module__ = 'aiidalab.git_util'#
__repr__()#

Return repr(self).

_abc_impl = <_abc._abc_data object>#
_get_type() str | None[source]#
commit: str#
is_dir() bool[source]#
is_file() bool[source]#
joinpath(*other: str) aiidalab.git_util.GitPath[source]#
path: pathlib.Path = PosixPath('.')#
read_bytes() bytes[source]#
read_text(encoding: Optional[str] = None, errors: Optional[str] = None) str[source]#
repo: pathlib.Path#
resolve(strict: bool = False) aiidalab.git_util.GitPath[source]#
class aiidalab.git_util.GitRepo(root: str, object_store: Optional[dulwich.object_store.PackBasedObjectStore] = None, bare: Optional[bool] = None)[source]#

Bases: dulwich.repo.Repo

__annotations__ = {}#
__module__ = 'aiidalab.git_util'#
classmethod clone_from_url(url: str, path: str) aiidalab.git_util.GitRepo[source]#
get_commit_for_tag(tag: str) Any[source]#
get_current_branch() str | None[source]#
get_merged_tags(branch: str) Generator[str, None, None][source]#
ref_from_rev(rev: str) str[source]#

Determine ref from rev.

Returns branch reference if a branch with that name exists, otherwise a tag reference, otherwise the rev itself (assuming it is a commit id).

rev_list(rev_selection: str) list[str][source]#
aiidalab.git_util.git_clone(url, commit, path: pathlib.Path)[source]#

aiidalab.metadata module#

App metadata specification

class aiidalab.metadata.Metadata(title: str, description: str, authors: typing.Optional[str] = None, state: typing.Optional[str] = None, documentation_url: typing.Optional[str] = None, external_url: typing.Optional[str] = None, logo: typing.Optional[str] = None, categories: list[str] = <factory>, version: typing.Optional[str] = None)[source]#

Bases: object

App metadata specification.

__annotations__ = {'authors': 'None | str', 'categories': 'list[str]', 'description': 'str', 'documentation_url': 'None | str', 'external_url': 'None | str', 'logo': 'None | str', 'state': 'None | str', 'title': 'str', 'version': 'None | str'}#
__dataclass_fields__ = {'authors': Field(name='authors',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'categories': Field(name='categories',type='list[str]',default=<dataclasses._MISSING_TYPE object>,default_factory=<class 'list'>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'description': Field(name='description',type='str',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'documentation_url': Field(name='documentation_url',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'external_url': Field(name='external_url',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'logo': Field(name='logo',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'state': Field(name='state',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'title': Field(name='title',type='str',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'version': Field(name='version',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)}#
__dataclass_params__ = _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False)#
__dict__ = mappingproxy({'__module__': 'aiidalab.metadata', '__annotations__': {'title': 'str', 'description': 'str', 'authors': 'None | str', 'state': 'None | str', 'documentation_url': 'None | str', 'external_url': 'None | str', 'logo': 'None | str', 'categories': 'list[str]', 'version': 'None | str'}, '__doc__': 'App metadata specification.', 'authors': None, 'state': None, 'documentation_url': None, 'external_url': None, 'logo': None, 'version': None, '_search_dirs': ('.aiidalab', './'), '_parse': <staticmethod(<function Metadata._parse>)>, 'parse': <classmethod(<function Metadata.parse>)>, '__dict__': <attribute '__dict__' of 'Metadata' objects>, '__weakref__': <attribute '__weakref__' of 'Metadata' objects>, '__dataclass_params__': _DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False), '__dataclass_fields__': {'title': Field(name='title',type='str',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'description': Field(name='description',type='str',default=<dataclasses._MISSING_TYPE object>,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'authors': Field(name='authors',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'state': Field(name='state',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'documentation_url': Field(name='documentation_url',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'external_url': Field(name='external_url',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'logo': Field(name='logo',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'categories': Field(name='categories',type='list[str]',default=<dataclasses._MISSING_TYPE object>,default_factory=<class 'list'>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), 'version': Field(name='version',type='None | str',default=None,default_factory=<dataclasses._MISSING_TYPE object>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)}, '__init__': <function Metadata.__init__>, '__repr__': <function Metadata.__repr__>, '__eq__': <function Metadata.__eq__>, '__hash__': None, '__match_args__': ('title', 'description', 'authors', 'state', 'documentation_url', 'external_url', 'logo', 'categories', 'version')})#
__eq__(other)#

Return self==value.

__hash__ = None#
__init__(title: str, description: str, authors: typing.Optional[str] = None, state: typing.Optional[str] = None, documentation_url: typing.Optional[str] = None, external_url: typing.Optional[str] = None, logo: typing.Optional[str] = None, categories: list[str] = <factory>, version: typing.Optional[str] = None) None#
__match_args__ = ('title', 'description', 'authors', 'state', 'documentation_url', 'external_url', 'logo', 'categories', 'version')#
__module__ = 'aiidalab.metadata'#
__repr__()#

Return repr(self).

__weakref__#

list of weak references to the object (if defined)

static _parse(path: Path | GitPath) dict[str, Any][source]#
_search_dirs = ('.aiidalab', './')#
authors: None | str = None#
categories: list[str]#
description: str#
documentation_url: None | str = None#
external_url: None | str = None#
classmethod parse(root: Path | GitPath) Metadata[source]#

Parse the app metadata from a setup.cfg within the app repository.

This function will parse metadata fields from a possible “aiidalab” section, but falls back to the standard fields defined as part of the PEP 426-compliant metadata section for any missing values.

state: None | str = None#
title: str#
version: None | str = None#

aiidalab.utils module#

Helpful utilities for the AiiDAlab tools.

class aiidalab.utils.PEP508CompliantUrl[source]#

Bases: str

Represents a PEP 508 compliant URL.

__dict__ = mappingproxy({'__module__': 'aiidalab.utils', '__doc__': 'Represents a PEP 508 compliant URL.', '__dict__': <attribute '__dict__' of 'PEP508CompliantUrl' objects>, '__weakref__': <attribute '__weakref__' of 'PEP508CompliantUrl' objects>, '__annotations__': {}})#
__module__ = 'aiidalab.utils'#
__weakref__#

list of weak references to the object (if defined)

class aiidalab.utils.Package(name: str, version: Optional[str] = None)[source]#

Bases: object

Helper class to check whether a given package fulfills a requirement.

__dict__ = mappingproxy({'__module__': 'aiidalab.utils', '__doc__': 'Helper class to check whether a given package fulfills a requirement.', '__init__': <function Package.__init__>, '__repr__': <function Package.__repr__>, '__str__': <function Package.__str__>, 'canonical_name': <property object>, 'fulfills': <function Package.fulfills>, '__dict__': <attribute '__dict__' of 'Package' objects>, '__weakref__': <attribute '__weakref__' of 'Package' objects>, '__annotations__': {}})#
__init__(name: str, version: Optional[str] = None)[source]#

If version is None, means not confinement for the version therefore the package always fulfill.

__module__ = 'aiidalab.utils'#
__repr__() str[source]#

Return repr(self).

__str__() str[source]#

Return str(self).

__weakref__#

list of weak references to the object (if defined)

property canonical_name: packaging.utils.NormalizedName#

Return the cananicalized name of the package.

fulfills(requirement: packaging.requirements.Requirement) bool[source]#

Returns True if this entry fulfills the requirement.

aiidalab.utils._pip_list(python_bin: Optional[str] = None) Any[source]#

Return all currently installed packages.

aiidalab.utils.find_installed_packages(python_bin: str | None = None) dict[str, aiidalab.utils.Package][source]#

Return all currently installed packages.

aiidalab.utils.get_package_by_name(packages: dict[str, aiidalab.utils.Package], name: str) aiidalab.utils.Package | None[source]#

Return the package with the given name from the list of packages. The name can be the canonicalized name or the requirement name which may not canonicalized. We try to convert the name to the canonicalized in both side and compare them.

For example, the requirement name is ‘jupyter-client’ and the package name is ‘jupyter_client’. The implementation of this method is inspired by pypa/pip#8054

aiidalab.utils.load_app_registry_entry(app_id: str) Any[source]#

Load registry enty for app with app_id.

aiidalab.utils.load_app_registry_index() Any[source]#

Load apps’ information from the AiiDAlab registry.

aiidalab.utils.parse_app_repo(url: str, metadata_fallback: Optional[dict[str, Any]] = None) dict[str, Any] | None[source]#

Parse an app repo for metadata and other information.

Use this function to parse a local or remote app repository for the app metadata and environment specification.

Examples:

For a local app repository, provide the absolute or relative path:

url=”/path/to/aiidalab-hello-world”

For a remote app repository, provide a PEP 508 compliant URL, for example:

url=”git+https://github.com/aiidalab/aiidalab-hello-world.git@v1.0.0”

aiidalab.utils.run_pip_install(*args: Any, python_bin: str) Any[source]#
aiidalab.utils.run_post_install_script(post_install_script_path: pathlib.Path) Any[source]#
aiidalab.utils.run_reentry_scan() Any[source]#
aiidalab.utils.run_verdi_daemon_restart() Any[source]#
aiidalab.utils.split_git_url(git_url)[source]#

Split the base url and the ref pointer of a git url.

For example: git+https://example.com/app.git@v1 is split into and returned as tuple: (git+https://example.com/app.git, v1)

aiidalab.utils.this_or_only_subdir(path: pathlib.Path) pathlib.Path[source]#
class aiidalab.utils.throttled(calls_per_second: int = 1)[source]#

Bases: object

Decorator to throttle calls to a function to a specified rate.

The throttle is specific to the first argument of the wrapped function. That means for class methods it is specific to each instance.

Adapted from: https://gist.github.com/gregburek/1441055

__call__(func)[source]#

Return decorator function.

__dict__ = mappingproxy({'__module__': 'aiidalab.utils', '__doc__': 'Decorator to throttle calls to a function to a specified rate.\n\n    The throttle is specific to the first argument of the wrapped\n    function. That means for class methods it is specific to each\n    instance.\n\n    Adapted from: https://gist.github.com/gregburek/1441055\n\n    ', '__init__': <function throttled.__init__>, '__call__': <function throttled.__call__>, '__dict__': <attribute '__dict__' of 'throttled' objects>, '__weakref__': <attribute '__weakref__' of 'throttled' objects>, '__annotations__': {}})#
__init__(calls_per_second: int = 1)[source]#
__module__ = 'aiidalab.utils'#
__weakref__#

list of weak references to the object (if defined)

Module contents#

AiiDAlab core tools.