Source code for supervisely.api.user_api

# coding: utf-8
"""create and manipulate already existing users in your team"""

# docs
from __future__ import annotations

from collections import namedtuple
from typing import TYPE_CHECKING, Callable, Dict, List, NamedTuple, Optional, Union

from supervisely.api.module_api import ApiField, ModuleApiBase, _get_single_item

if TYPE_CHECKING:
    from pandas.core.frame import DataFrame

from tqdm import tqdm


class UserInfo(NamedTuple):
    """ """

    id: int
    login: str
    role: str
    role_id: int
    name: str
    email: str
    logins: int
    disabled: bool
    last_login: str
    created_at: str
    updated_at: str


[docs]class UserApi(ModuleApiBase): """ API for working with :class:`Users<supervisely.user.user.UserRoleName>`. :class:`UserApi<UserApi>` object is immutable. :param api: API connection to the server. :type api: Api :Usage example: .. code-block:: python import os from dotenv import load_dotenv import supervisely as sly # Load secrets and create API object from .env file (recommended) # Learn more here: https://developer.supervisely.com/getting-started/basics-of-authentication if sly.is_development(): load_dotenv(os.path.expanduser("~/supervisely.env")) api = sly.Api.from_env() # Pass values into the API constructor (optional, not recommended) # api = sly.Api(server_address="https://app.supervise.ly", token="4r47N...xaTatb") users = api.user.get_list() # api usage example """ Membership = namedtuple("Membership", ["id", "name", "role_id", "role"])
[docs] @staticmethod def info_sequence(): """ NamedTuple UserInfo information about User. :Example: .. code-block:: python UserInfo(id=8, login='alex', role=None, role_id=None, name=None, email=None, logins=20, disabled=False, last_login='2021-03-24T15:06:26.804Z', created_at='2020-04-17T10:24:09.077Z', updated_at='2021-03-24T15:13:01.148Z') """ return [ ApiField.ID, ApiField.LOGIN, ApiField.ROLE, ApiField.ROLE_ID, ApiField.NAME, ApiField.EMAIL, ApiField.LOGINS, ApiField.DISABLED, ApiField.LAST_LOGIN, ApiField.CREATED_AT, ApiField.UPDATED_AT, ]
[docs] @staticmethod def info_tuple_name(): """ NamedTuple name - **UserInfo**. """ return "UserInfo"
def _convert_json_info(self, info: dict, skip_missing=True): res = super(UserApi, self)._convert_json_info(info, skip_missing=skip_missing) return UserInfo(**res._asdict())
[docs] def get_info_by_id(self, id: int) -> UserInfo: """ Get User information by ID. :param id: User ID in Supervisely. :type id: int :return: Information about User. See :class:`info_sequence<info_sequence>` :rtype: :class:`UserInfo` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_info = api.user.get_info_by_id(8) print(user_info) # Output: [ # 8, # "alex", # null, # null, # null, # null, # 20, # false, # "2021-03-24T15:06:26.804Z", # "2020-04-17T10:24:09.077Z", # "2021-03-24T15:13:01.148Z" # ] """ return self._get_info_by_id(id, "users.info")
[docs] def get_info_by_login(self, login: str) -> UserInfo: """ Get User information by login. :param login: User login in Supervisely. :type login: str :return: Information about User. See :class:`info_sequence<info_sequence>` :rtype: :class:`UserInfo` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_info = api.user.get_info_by_login('alex') print(user_info) # Output: [ # 8, # "alex", # null, # null, # null, # null, # 20, # false, # "2021-03-24T15:06:26.804Z", # "2020-04-17T10:24:09.077Z", # "2021-03-24T15:13:01.148Z" # ] """ filters = [{"field": ApiField.LOGIN, "operator": "=", "value": login}] items = self.get_list(filters) return _get_single_item(items)
[docs] def get_member_info_by_login(self, team_id: int, login: str) -> UserInfo: """ Get information about team member by Team ID and User login. :param team_id: Team ID in Supervisely. :type team_id: int :param login: User login in Supervisely. :type login: str :return: Information about User. See :class:`info_sequence<info_sequence>` :rtype: :class:`UserInfo` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() member_info = api.user.get_member_info_by_login(64, 'alex') print(member_info) # Output: [ # 8, # "alex", # "manager", # 3, # null, # null, # 20, # false, # "2021-03-24T15:06:26.804Z", # "2020-04-17T10:24:09.077Z", # "2021-03-24T15:13:01.148Z" # ] """ filters = [{"field": ApiField.LOGIN, "operator": "=", "value": login}] team_members = self.get_list_all_pages( "members.list", {ApiField.TEAM_ID: team_id, ApiField.FILTER: filters}, convert_json_info_cb=self._api.user._convert_json_info, ) return _get_single_item(team_members)
[docs] def get_member_info_by_id(self, team_id: int, user_id: int) -> UserInfo: """ Get information about team member by Team ID and User ID. :param team_id: Team ID in Supervisely. :type team_id: int :param user_id: User ID in Supervisely. :type user_id: int :return: Information about User. See :class:`info_sequence<info_sequence>` :rtype: :class:`UserInfo` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() member_info = api.user.get_member_info_by_id(64, 8) print(member_info) # Output: [ # 8, # "alex", # "manager", # 3, # null, # null, # 20, # false, # "2021-03-24T15:06:26.804Z", # "2020-04-17T10:24:09.077Z", # "2021-03-24T15:13:01.148Z" # ] """ filters = [{"field": ApiField.ID, "operator": "=", "value": user_id}] team_members = self.get_list_all_pages( "members.list", {ApiField.TEAM_ID: team_id, ApiField.FILTER: filters}, convert_json_info_cb=self._api.user._convert_json_info, ) return _get_single_item(team_members)
[docs] def get_list(self, filters: List[Dict[str, str]] = None) -> List[UserInfo]: """ Get list of information about Users. :param filters: List of params to sort output Users. :type filters: List[dict], optional :return: List of information about Users. See :class:`info_sequence<info_sequence>` :rtype: :class:`List[UserInfo]` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() # Get list of Users with id = 8 user_info = api.user.get_list(filters=[{'field': 'id', 'operator': '=', 'value': '8'}]) print(user_info) # Output: [ # 8, # "alex", # "manager", # 3, # null, # null, # 20, # false, # "2021-03-24T15:06:26.804Z", # "2020-04-17T10:24:09.077Z", # "2021-03-24T15:13:01.148Z" # ] """ return self.get_list_all_pages("users.list", {ApiField.FILTER: filters or []})
[docs] def create( self, login: str, password: str, is_restricted: Optional[bool] = False, name: Optional[str] = "", email: Optional[str] = "", ) -> UserInfo: """ Creates new User with given login and password. :param login: New User login. :type login: str :param password: New User password. :type password: str :param is_restricted: If True, new User will have no access to Explore section, won't be able to create or switch Teams, and no personal Team will be created for this User during signup. :type is_restricted: bool, optional :param name: New User name. :type name: str, optional :param email: New User email. :type email: str, optional :return: Information about new User. See :class:`info_sequence<info_sequence>` :rtype: :class:`UserInfo` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() new_user_info = api.user.create('John', 'qwerty', is_restricted=True, name='John Wick', email='excomunicado@gmail.com') print(new_user_info) # Output: [ # 274, # "John", # null, # null, # "John Wick", # "excomunicado@gmail.com", # 0, # false, # null, # "2021-03-24T16:20:03.110Z", # "2021-03-24T16:20:03.110Z" # ] """ response = self._api.post( "users.add", { ApiField.LOGIN: login, ApiField.PASSWORD: password, ApiField.IS_RESTRICTED: is_restricted, ApiField.NAME: name, ApiField.EMAIL: email, }, ) return self.get_info_by_id(response.json()[ApiField.USER_ID])
def _set_disabled(self, id, disable): """ Check status of the user with given id :param id: int :param disable: bool """ self._api.post("users.disable", {ApiField.ID: id, ApiField.DISABLE: disable})
[docs] def disable(self, id: int) -> None: """ Disables User with the given ID. :param id: User ID in Supervisely. :type id: int :return: None :rtype: :class:`NoneType` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_id = 8 api.user.disable(user_id) """ self._set_disabled(id, True)
[docs] def enable(self, id: int) -> None: """ Enables User with the given ID. :param id: User ID in Supervisely. :type id: int :return: None :rtype: :class:`NoneType` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_id = 8 api.user.enable(user_id) """ self._set_disabled(id, False)
def get_token(self, login): raise NotImplementedError()
[docs] def get_teams(self, id: int) -> List[UserInfo]: """ Get list with information about User Teams. :param id: User ID in Supervisely. :type id: int :return: List of teams in which the User with the given ID is located :rtype: :class:`List[UserInfo]` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() teams = api.user.get_teams(8) print(teams) # Output: [ # [ # 9, # "alex", # 1, # "admin" # ], # [ # 64, # "test", # 3, # "manager" # ] # ] """ response = self._api.post("users.info", {ApiField.ID: id}) teams_json = response.json()[ApiField.TEAMS] teams = [] for team in teams_json: member = self.Membership( id=team[ApiField.ID], name=team[ApiField.NAME], role_id=team[ApiField.ROLE_ID], role=team[ApiField.ROLE], ) teams.append(member) return teams
[docs] def add_to_team(self, user_id: int, team_id: int, role_id: int) -> None: """ Invites User to Team with the given role. :param user_id: User ID in Supervisely. :type user_id: int :param team_id: Team ID in Supervisely. :type team_id: int :param role_id: Role ID in Supervisely. :type role_id: int :return: None :rtype: :class:`NoneType` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_id = 8 team_id = 76 role_id = 5 api.user.add_to_team(user_id, team_id, role_id) """ user = self.get_info_by_id(user_id) self._api.post( "members.add", { ApiField.LOGIN: user.login, ApiField.TEAM_ID: team_id, ApiField.ROLE_ID: role_id, }, )
[docs] def remove_from_team(self, user_id: int, team_id: int) -> None: """ Removes User from Team. :param user_id: User ID in Supervisely. :type user_id: int :param team_id: Team ID in Supervisely. :type team_id: int :return: None :rtype: :class:`NoneType` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_id = 8 team_id = 76 api.user.remove_from_team(user_id, team_id) """ self._api.post("members.remove", {ApiField.ID: user_id, ApiField.TEAM_ID: team_id})
[docs] def update( self, id: int, password: Optional[str] = None, name: Optional[str] = None ) -> UserInfo: """ Updates User info. :param id: User ID in Supervisely. :type id: int :param password: User password. :type password: str :param name: User name. :type name: str :return: New information about User. See :class:`info_sequence<info_sequence>` :rtype: :class:`UserInfo` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_info = api.user.update(8, name='Aleksey') print(user_info) # Output: [ # 8, # "alex", # null, # null, # "Aleksey", # null, # 21, # false, # "2021-03-25T08:06:03.498Z", # "2020-04-17T10:24:09.077Z", # "2021-03-25T08:37:17.257Z" # ] """ data = {} if password is not None: data[ApiField.PASSWORD] = password if name is not None: data[ApiField.NAME] = name if len(data) == 0: return data[ApiField.ID] = id self._api.post("users.editInfo", data) return self.get_info_by_id(id)
[docs] def change_team_role(self, user_id: int, team_id: int, role_id: int) -> None: """ Changes User role in the given Team. :param user_id: User ID in Supervisely. :type user_id: int :param team_id: Team ID in Supervisely. :type team_id: int :param role_id: Role ID in Supervisely. :type role_id: int :return: None :rtype: :class:`NoneType` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_id = 8 team_id = 64 new_role_id = 2 api.user.change_team_role(user_id, team_id, new_role_id) """ self._api.post( "members.editInfo", { ApiField.ID: user_id, ApiField.TEAM_ID: team_id, ApiField.ROLE_ID: role_id, }, )
[docs] def get_team_members(self, team_id: int) -> List[UserInfo]: """ Get list of information about Team Users. :param team_id: Team ID in Supervisely. :type team_id: int :return: List of information about Team Users :rtype: :class:`List[UserInfo]` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() team_id = 9 team_members = api.user.get_team_members(team_id) """ team_members = self.get_list_all_pages( "members.list", {ApiField.TEAM_ID: team_id, ApiField.FILTER: []}, convert_json_info_cb=self._api.user._convert_json_info, ) return team_members
[docs] def get_team_role(self, user_id: int, team_id: int) -> UserInfo: """ Get Team role for given User and Team IDs. :param user_id: User ID in Supervisely. :type user_id: int :param team_id: Team ID in Supervisely. :type team_id: int :return: Information about Team :class:`Role<supervisely.api.role_api.RoleApi` :rtype: :class:`UserInfo` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() user_id = 8 team_id = 9 team_role = api.user.get_team_role(user_id, team_id) print(team_role) # Output: [ # 9, # "alex", # 1, # "admin" # ] """ user_teams = self.get_teams(user_id) for member in user_teams: if member.id == team_id: return member return None
[docs] def get_member_activity( self, team_id: int, user_id: int, progress_cb: Optional[Union[tqdm, Callable]] = None ) -> DataFrame: """ Get User activity data. :param team_id: Team ID in Supervisely. :type team_id: int :param user_id: User ID in Supervisely. :type user_id: int :param progress_cb: Function to check progress. :type progress_cb: tqdm or callable, optional :return: Activity data as `pd.DataFrame <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html>`_ :rtype: :class:`pd.DataFrame` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() activity = api.user.get_member_activity(64, 8) print(activity) # Output: # userId action date ... jobId tag tagId # 0 8 login_to_team 2021-03-13T08:57:26.832Z ... None None None # 1 8 annotation_duration 2021-03-02T13:16:23.833Z ... None None None # 2 8 login_to_team 2021-03-02T13:15:58.775Z ... None None None # 3 8 login_to_team 2021-02-06T09:47:22.999Z ... None None None # ................................................................................ # 38 8 create_workspace 2021-01-04T12:25:37.916Z ... None None None # 39 8 login_to_team 2021-01-04T12:24:58.257Z ... None None None # 40 8 login_to_team 2021-01-04T12:23:43.056Z ... None None None # 41 8 login_to_team 2021-01-04T11:53:56.447Z ... None None None # [42 rows x 18 columns] """ import pandas as pd activity = self._api.team.get_activity( team_id, filter_user_id=user_id, progress_cb=progress_cb ) df = pd.DataFrame(activity) return df
[docs] def add_to_team_by_login(self, user_login: str, team_id: int, role_id: int) -> Dict[str, int]: """ Invite User to Team with given role by login. :param user_login: User login in Supervisely. :type user_login: str :param team_id: Team ID in Supervisely. :type team_id: int :param role_id: Role ID in Supervisely. :type role_id: int :return: Information about new User in Team :rtype: :class:`dict` :Usage example: .. code-block:: python import supervisely as sly os.environ['SERVER_ADDRESS'] = 'https://app.supervise.ly' os.environ['API_TOKEN'] = 'Your Supervisely API Token' api = sly.Api.from_env() team_id = 13 role_id = 2 new_user_data = api.user.add_to_team_by_login('alex', team_id, role_id) print(new_user_data) # Output: { # "userId": 8 # } """ response = self._api.post( "members.add", { ApiField.LOGIN: user_login, ApiField.TEAM_ID: team_id, ApiField.ROLE_ID: role_id, }, ) return response.json()
def get_ssh_keys(self): """ """ response = self._api.post("users.ssh-keys", {}) return response.json() def get_my_info(self): response = self._api.post("users.me", {}) return self._convert_json_info(response.json())