8000 Jorwoods/type hint user by jorwoods · Pull Request #944 · tableau/server-client-python · GitHub
[go: up one dir, main page]

Skip to content

Jorwoods/type hint user #944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 41 additions & 31 deletions tableauserverclient/models/user_item.py
10000 10000
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
import xml.etree.ElementTree as ET
from .exceptions import UnpopulatedPropertyError
from .property_decorators import (
Expand All @@ -8,10 +9,15 @@
from ..datetime_helpers import parse_datetime
from .reference_item import ResourceReference

from typing import Dict, List, Optional, TYPE_CHECKING

if TYPE_CHECKING:
from ..server.pager import Pager


class UserItem(object):

tag_name = "user"
tag_name: str = "user"

class Roles:
Interactor = "Interactor"
Expand Down Expand Up @@ -39,23 +45,27 @@ class Auth:
SAML = "SAML"
ServerDefault = "ServerDefault"

def __init__(self, name=None, site_role=None, auth_setting=None):
self._auth_setting = None
self._domain_name = None
self._external_auth_user_id = None
self._id = None
self._last_login = None
def __init__(
self, name: Optional[str] = None, site_role: Optional[str] = None, auth_setting: Optional[str] = None
) -> None:
self._auth_setting: Optional[str] = None
self._domain_name: Optional[str] = None
self._external_auth_user_id: Optional[str] = None
self._id: Optional[str] = None
self._last_login: Optional[datetime] = None
self._workbooks = None
self._favorites = None
self._favorites: Optional[Dict[str, List]] = None
self._groups = None
self.email = None
self.fullname = None
self.name = name
self.site_role = site_role
self.auth_setting = auth_setting
self.email: Optional[str] = None
self.fullname: Optional[str] = None
self.name: Optional[str] = name
self.site_role: Optional[str] = site_role
self.auth_setting: Optional[str] = auth_setting

return None

@property
def auth_setting(self):
def auth_setting(self) -> Optional[str]:
return self._auth_setting

@auth_setting.setter
Expand All @@ -64,32 +74,32 @@ def auth_setting(self, value):
self._auth_setting = value

@property
def domain_name(self):
def domain_name(self) -> Optional[str]:
return self._domain_name

@property
def external_auth_user_id(self):
def external_auth_user_id(self) -> Optional[str]:
return self._external_auth_user_id

@property
def id(self):
def id(self) -> Optional[str]:
return self._id

@property
def last_login(self):
def last_login(self) -> Optional[datetime]:
return self._last_login

@property
def name(self):
def name(self) -> Optional[str]:
return self._name

@name.setter
@property_not_empty
def name(self, value):
def name(self, value: str):
self._name = value

@property
def site_role(self):
def site_role(self) -> Optional[str]:
return self._site_role

@site_role.setter
Expand All @@ -99,36 +109,36 @@ def site_role(self, value):
self._site_role = value

@property
def workbooks(self):
def workbooks(self) -> "Pager":
if self._workbooks is None:
error = "User item must be populated with workbooks first."
raise UnpopulatedPropertyError(error)
return self._workbooks()

@property
def favorites(self):
def favorites(self) -> Dict[str, List]:
if self._favorites is None:
error = "User item must be populated with favorites first."
raise UnpopulatedPropertyError(error)
return self._favorites

@property
def groups(self):
def groups(self) -> "Pager":
if self._groups is None:
error = "User item must be populated with groups first."
raise UnpopulatedPropertyError(error)
return self._groups()

def to_reference(self):
def to_reference(self) -> ResourceReference:
return ResourceReference(id_=self.id, tag_name=self.tag_name)

def _set_workbooks(self, workbooks):
def _set_workbooks(self, workbooks) -> None:
self._workbooks = workbooks

def _set_groups(self, groups):
def _set_groups(self, groups) -> None:
self._groups = groups

def _parse_common_tags(self, user_xml, ns):
def _parse_common_tags(self, user_xml, ns) -> "UserItem":
if not isinstance(user_xml, ET.Element):
user_xml = ET.fromstring(user_xml).find(".//t:user", namespaces=ns)
if user_xml is not None:
Expand Down Expand Up @@ -178,7 +188,7 @@ def _set_values(
self._domain_name = domain_name

@classmethod
def from_response(cls, resp, ns):
def from_response(cls, resp, ns) -> List["UserItem"]:
all_user_items = []
parsed_response = ET.fromstring(resp)
all_user_xml = parsed_response.findall(".//t:user", namespaces=ns)
Expand Down Expand Up @@ -210,7 +220,7 @@ def from_response(cls, resp, ns):
return all_user_items

@staticmethod
def as_reference(id_):
def as_reference(id_) -> ResourceReference:
return ResourceReference(id_, UserItem.tag_name)

@staticmethod
Expand Down Expand Up @@ -241,5 +251,5 @@ def _parse_element(user_xml, ns):
domain_name,
)

def __repr__(self):
def __repr__(self) -> str:
return "<User {} name={} role={}>".format(self.id, self.name, self.site_role)
27 changes: 16 additions & 11 deletions tableauserverclient/server/endpoint/users_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import List, Tuple
from .endpoint import QuerysetEndpoint, api
from .exceptions import MissingRequiredFieldError
from .. import (
Expand All @@ -18,12 +19,12 @@

class Users(QuerysetEndpoint):
@property
def baseurl(self):
def baseurl(self) -> str:
return "{0}/sites/{1}/users".format(self.parent_srv.baseurl, self.parent_srv.site_id)

# Gets all users
@api(version="2.0")
def get(self, req_options=None):
def get(self, req_options: RequestOptions = None) -> Tuple[List[UserItem], PaginationItem]:
logger.info("Querying all users on site")

if req_options is None:
Expand All @@ -38,7 +39,7 @@ def get(self, req_options=None):

# Gets 1 user by id
@api(version="2.0")
def get_by_id(self, user_id):
def get_by_id(self, user_id: str) -> UserItem:
if not user_id:
error = "User ID undefined."
raise ValueError(error)
Expand All @@ -49,7 +50,7 @@ def get_by_id(self, user_id):

# Update user
@api(version="2.0")
def update(self, user_item, password=None):
def update(self, user_item: UserItem, password: str = None) -> UserItem:
if not user_item.id:
error = "User item missing ID."
raise MissingRequiredFieldError(error)
Expand All @@ -63,7 +64,7 @@ def update(self, user_item, password=None):

# Delete 1 user by id
@api(version="2.0")
def remove(self, user_id):
def remove(self, user_id: str) -> None:
if not user_id:
error = "User ID undefined."
raise ValueError(error)
Expand All @@ -73,7 +74,7 @@ def remove(self, user_id):

# Add new user to site
@api(version="2.0")
def add(self, user_item):
def add(self, user_item: UserItem) -> UserItem:
url = self.baseurl
add_req = RequestFactory.User.add_req(user_item)
server_response = self.post_request(url, add_req)
Expand All @@ -83,7 +84,7 @@ def add(self, user_item):

# Get workbooks for user
@api(version="2.0")
def populate_workbooks(self, user_item, req_options=None):
def populate_workbooks(self, user_item: UserItem, req_options: RequestOptions = None) -> None:
if not user_item.id:
error = "User item missing ID."
raise MissingRequiredFieldError(error)
Expand All @@ -93,20 +94,22 @@ def wb_pager():

user_item._set_workbooks(wb_pager)

def _get_wbs_for_user(self, user_item, req_options=None):
def _get_wbs_for_user(
self, user_item: UserItem, req_options: RequestOptions = None
) -> Tuple[List[WorkbookItem], PaginationItem]:
url = "{0}/{1}/workbooks".format(self.baseurl, user_item.id)
server_response = self.get_request(url, req_options)
logger.info("Populated workbooks for user (ID: {0})".format(user_item.id))
workbook_item = WorkbookItem.from_response(server_response.content, self.parent_srv.namespace)
pagination_item = PaginationItem.from_response(server_response.content, self.parent_srv.namespace)
return workbook_item, pagination_item

def populate_favorites(self, user_item):
def populate_favorites(self, user_item: UserItem) -> None:
self.parent_srv.favorites.get(user_item)

# Get groups for user
@api(version="3.7")
def populate_groups(self, user_item, req_options=None):
def populate_groups(self, user_item: UserItem, req_options: RequestOptions = None) -> None:
if not user_item.id:
error = "User item missing ID."
raise MissingRequiredFieldError(error)
Expand All @@ -119,7 +122,9 @@ def groups_for_user_pager():

user_item._set_groups(groups_for_user_pager)

def _get_groups_for_user(self, user_item, req_options=None):
def _get_groups_for_user(
self, user_item: UserItem, req_options: RequestOptions = None
) -> Tuple[List[GroupItem], PaginationItem]:
url = "{0}/{1}/groups".format(self.baseurl, user_item.id)
server_response = self.get_request(url, req_options)
logger.info("Populated groups for user (ID: {0})".format(user_item.id))
Expand Down
15 changes: 11 additions & 4 deletions tableauserverclient/server/request_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ def add_req(self, tag_set):


class UserRequest(object):
def update_req(self, user_item, password):
def update_req(self, user_item: UserItem, password: Optional[str]) -> bytes:
xml_request = ET.Element("tsRequest")
user_element = ET.SubElement(xml_request, "user")
if user_item.fullname:
Expand All @@ -814,11 +814,18 @@ def update_req(self, user_item, password):
user_element.attrib["password"] = password
return ET.tostring(xml_request)

def add_req(self, user_item):
def add_req(self, user_item: UserItem) -> bytes:
xml_request = ET.Element("tsRequest")
user_element = ET.SubElement(xml_request, "user")
user_element.attrib["name"] = user_item.name
user_element.attrib["siteRole"] = user_item.site_role
if isinstance(user_item.name, str):
user_element.attrib["name"] = user_item.name
else:
raise ValueError(f"{user_item} missing name.")
if isinstance(user_item.site_role, str):
user_element.attrib["siteRole"] = user_item.site_role
else:
raise ValueError(f"{user_item} must have site role populated.")

if user_item.auth_setting:
user_element.attrib["authSetting"] = user_item.auth_setting
return ET.tostring(xml_request)
Expand Down
Loading
0