Source code for aiida.orm.users

###########################################################################
# Copyright (c), The AiiDA team. All rights reserved.                     #
# This file is part of the AiiDA code.                                    #
#                                                                         #
# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core #
# For further information on the license, see the LICENSE.txt file        #
# For further information please visit http://www.aiida.net               #
###########################################################################
"""Module for the ORM user class."""

from typing import TYPE_CHECKING, Optional, Tuple, Type

from aiida.common import exceptions
from aiida.manage import get_manager

from . import entities
from .fields import add_field

if TYPE_CHECKING:
    from aiida.orm.implementation import StorageBackend
    from aiida.orm.implementation.users import BackendUser  # noqa: F401

__all__ = ('User',)


[docs] class UserCollection(entities.Collection['User']): """The collection of users stored in a backend."""
[docs] @staticmethod def _entity_base_cls() -> Type['User']: return User
[docs] def get_or_create(self, email: str, **kwargs) -> Tuple[bool, 'User']: """Get the existing user with a given email address or create an unstored one :param kwargs: The properties of the user to get or create :return: The corresponding user object :raises: :class:`aiida.common.exceptions.MultipleObjectsError`, :class:`aiida.common.exceptions.NotExistent` """ try: return False, self.get(email=email) except exceptions.NotExistent: return True, User(backend=self.backend, email=email, **kwargs)
[docs] def get_default(self) -> Optional['User']: """Get the current default user""" return self.backend.default_user
[docs] class User(entities.Entity['BackendUser', UserCollection]): """AiiDA User""" _CLS_COLLECTION = UserCollection __qb_fields__ = [ add_field( 'email', dtype=str, is_attribute=False, doc='The user email', ), add_field( 'first_name', dtype=str, is_attribute=False, doc='The user first name', ), add_field( 'last_name', dtype=str, is_attribute=False, doc='The user last name', ), add_field( 'institution', dtype=str, is_attribute=False, doc='The user institution', ), ]
[docs] def __init__( self, email: str, first_name: str = '', last_name: str = '', institution: str = '', backend: Optional['StorageBackend'] = None, ): """Create a new `User`.""" backend = backend or get_manager().get_profile_storage() email = self.normalize_email(email) backend_entity = backend.users.create( email=email, first_name=first_name, last_name=last_name, institution=institution ) super().__init__(backend_entity)
[docs] def __str__(self) -> str: return self.email
[docs] @staticmethod def normalize_email(email: str) -> str: """Normalize the address by lowercasing the domain part of the email address (taken from Django).""" email = email or '' try: email_name, domain_part = email.strip().rsplit('@', 1) except ValueError: pass else: email = '@'.join([email_name, domain_part.lower()]) return email
@property def is_default(self) -> bool: """Return whether the user is the default user. :returns: Boolean, ``True`` if the user is the default, ``False`` otherwise. """ default_user = self.collection.get_default() return default_user is not None and self.pk == default_user.pk @property def email(self) -> str: return self._backend_entity.email @email.setter def email(self, email: str) -> None: self._backend_entity.email = email @property def first_name(self) -> str: return self._backend_entity.first_name @first_name.setter def first_name(self, first_name: str) -> None: self._backend_entity.first_name = first_name @property def last_name(self) -> str: return self._backend_entity.last_name @last_name.setter def last_name(self, last_name: str) -> None: self._backend_entity.last_name = last_name @property def institution(self) -> str: return self._backend_entity.institution @institution.setter def institution(self, institution: str) -> None: self._backend_entity.institution = institution
[docs] def get_full_name(self) -> str: """Return the user full name :return: the user full name """ if self.first_name and self.last_name: full_name = f'{self.first_name} {self.last_name} ({self.email})' elif self.first_name: full_name = f'{self.first_name} ({self.email})' elif self.last_name: full_name = f'{self.last_name} ({self.email})' else: full_name = f'{self.email}' return full_name
[docs] def get_short_name(self) -> str: """Return the user short name (typically, this returns the email) :return: The short name """ return self.email
@property def uuid(self) -> None: """For now users do not have UUIDs so always return None""" return None