diff --git a/tableauserverclient/server/endpoint/favorites_endpoint.py b/tableauserverclient/server/endpoint/favorites_endpoint.py index 228792e14..02c6f5ad0 100644 --- a/tableauserverclient/server/endpoint/favorites_endpoint.py +++ b/tableauserverclient/server/endpoint/favorites_endpoint.py @@ -17,6 +17,17 @@ class Favorites(Endpoint): + """Get, add, and remove favorites for a user. + + Favorites can be workbooks, views, datasources, flows, projects, or metrics. + Retrieved favorites are stored on the target ``UserItem`` object as a + dictionary keyed by content type (e.g. ``"workbooks"``, ``"views"``, + ``"datasources"``, ``"flows"``, ``"projects"``, ``"metrics"``), where + each value is a list of the corresponding item objects. + + REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_favorites.htm + """ + @property def baseurl(self) -> str: return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}/favorites" @@ -24,6 +35,33 @@ def baseurl(self) -> str: # Gets all favorites @api(version="2.5") def get(self, user_item: UserItem, req_options: RequestOptions | None = None) -> None: + """Populate the favorites on the specified user. + + After calling this method, the favorites are available through + ``user_item.favorites``, keyed by content type. + + REST API: `Get Favorites for User `_ + + Parameters + ---------- + user_item : UserItem + The user for whom to retrieve favorites. The user's ``id`` attribute + must be set. + + req_options : RequestOptions, optional + Request options such as page size and page number. + + Returns + ------- + None + Favorites are populated on ``user_item.favorites``. + + Examples + -------- + >>> server.favorites.get(user_item) + >>> for workbook in user_item.favorites["workbooks"]: + ... print(workbook.name) + """ logger.info(f"Querying all favorites for user {user_item.name}") url = f"{self.baseurl}/{user_item.id}" server_response = self.get_request(url, req_options) @@ -33,6 +71,32 @@ def get(self, user_item: UserItem, req_options: RequestOptions | None = None) -> @api(version="3.15") def add_favorite(self, user_item: UserItem, content_type: str, item: TableauItem) -> "Response": + """Add a content item of any supported type to the user's favorites. + + Type-specific helpers (``add_favorite_workbook``, ``add_favorite_view``, + etc.) exist for each individual content type; this method is the + polymorphic entry point. + + REST API: `Add to Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to add the favorite for. + + content_type : str + The type of content as a string (e.g. ``"workbook"``, ``"view"``, + ``"datasource"``, ``"flow"``, ``"project"``, ``"metric"``). + + item : TableauItem + The content item to favorite. Must have ``id`` and ``name`` + attributes. + + Returns + ------- + requests.Response + The server response. + """ url = f"{self.baseurl}/{user_item.id}" add_req = RequestFactory.Favorite.add_request(item.id, content_type, item.name) server_response = self.put_request(url, add_req) @@ -41,6 +105,22 @@ def add_favorite(self, user_item: UserItem, content_type: str, item: TableauItem @api(version="2.0") def add_favorite_workbook(self, user_item: UserItem, workbook_item: WorkbookItem) -> None: + """Add a workbook to the user's favorites. + + REST API: `Add Workbook to Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to add the favorite for. + + workbook_item : WorkbookItem + The workbook to add to favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}" add_req = RequestFactory.Favorite.add_workbook_req(workbook_item.id, workbook_item.name) server_response = self.put_request(url, add_req) @@ -48,6 +128,22 @@ def add_favorite_workbook(self, user_item: UserItem, workbook_item: WorkbookItem @api(version="2.0") def add_favorite_view(self, user_item: UserItem, view_item: ViewItem) -> None: + """Add a view to the user's favorites. + + REST API: `Add View to Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to add the favorite for. + + view_item : ViewItem + The view to add to favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}" add_req = RequestFactory.Favorite.add_view_req(view_item.id, view_item.name) server_response = self.put_request(url, add_req) @@ -55,6 +151,22 @@ def add_favorite_view(self, user_item: UserItem, view_item: ViewItem) -> None: @api(version="2.3") def add_favorite_datasource(self, user_item: UserItem, datasource_item: DatasourceItem) -> None: + """Add a datasource to the user's favorites. + + REST API: `Add Data Source to Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to add the favorite for. + + datasource_item : DatasourceItem + The datasource to add to favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}" add_req = RequestFactory.Favorite.add_datasource_req(datasource_item.id, datasource_item.name) server_response = self.put_request(url, add_req) @@ -62,6 +174,22 @@ def add_favorite_datasource(self, user_item: UserItem, datasource_item: Datasour @api(version="3.1") def add_favorite_project(self, user_item: UserItem, project_item: ProjectItem) -> None: + """Add a project to the user's favorites. + + REST API: `Add Project to Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to add the favorite for. + + project_item : ProjectItem + The project to add to favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}" add_req = RequestFactory.Favorite.add_project_req(project_item.id, project_item.name) server_response = self.put_request(url, add_req) @@ -69,6 +197,22 @@ def add_favorite_project(self, user_item: UserItem, project_item: ProjectItem) - @api(version="3.3") def add_favorite_flow(self, user_item: UserItem, flow_item: FlowItem) -> None: + """Add a flow to the user's favorites. + + REST API: `Add Flow to Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to add the favorite for. + + flow_item : FlowItem + The flow to add to favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}" add_req = RequestFactory.Favorite.add_flow_req(flow_item.id, flow_item.name) server_response = self.put_request(url, add_req) @@ -76,6 +220,20 @@ def add_favorite_flow(self, user_item: UserItem, flow_item: FlowItem) -> None: @api(version="3.3") def add_favorite_metric(self, user_item: UserItem, metric_item: MetricItem) -> None: + """Add a metric to the user's favorites. + + Parameters + ---------- + user_item : UserItem + The user to add the favorite for. + + metric_item : MetricItem + The metric to add to favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}" add_req = RequestFactory.Favorite.add_request(metric_item.id, Resource.Metric, metric_item.name) server_response = self.put_request(url, add_req) @@ -93,42 +251,163 @@ def add_favorite_metric(self, user_item: UserItem, metric_item: MetricItem) -> N @api(version="3.15") def delete_favorite(self, user_item: UserItem, content_type: Resource, item: TableauItem) -> None: + """Remove a content item of any supported type from the user's favorites. + + Type-specific helpers (``delete_favorite_workbook``, + ``delete_favorite_view``, etc.) exist for each individual content + type; this method is the polymorphic entry point. + + Parameters + ---------- + user_item : UserItem + The user to remove the favorite from. + + content_type : Resource + The ``Resource`` type of the content (e.g. ``Resource.Workbook``, + ``Resource.View``). + + item : TableauItem + The content item to remove from favorites. Must have an ``id`` + attribute. + + Returns + ------- + None + + Examples + -------- + >>> server.favorites.delete_favorite(user_item, TSC.Resource.Workbook, workbook_item) + """ url = f"{self.baseurl}/{user_item.id}/{content_type}/{item.id}" logger.info(f"Removing favorite {content_type}({item.id}) for user (ID: {user_item.id})") self.delete_request(url) @api(version="2.0") def delete_favorite_workbook(self, user_item: UserItem, workbook_item: WorkbookItem) -> None: + """Remove a workbook from the user's favorites. + + REST API: `Delete Workbook from Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to remove the favorite from. + + workbook_item : WorkbookItem + The workbook to remove from favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}/workbooks/{workbook_item.id}" logger.info(f"Removing favorite workbook {workbook_item.id} for user (ID: {user_item.id})") self.delete_request(url) @api(version="2.0") def delete_favorite_view(self, user_item: UserItem, view_item: ViewItem) -> None: + """Remove a view from the user's favorites. + + REST API: `Delete View from Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to remove the favorite from. + + view_item : ViewItem + The view to remove from favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}/views/{view_item.id}" logger.info(f"Removing favorite view {view_item.id} for user (ID: {user_item.id})") self.delete_request(url) @api(version="2.3") def delete_favorite_datasource(self, user_item: UserItem, datasource_item: DatasourceItem) -> None: + """Remove a datasource from the user's favorites. + + REST API: `Delete Data Source from Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to remove the favorite from. + + datasource_item : DatasourceItem + The datasource to remove from favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}/datasources/{datasource_item.id}" logger.info(f"Removing favorite {datasource_item.id} for user (ID: {user_item.id})") self.delete_request(url) @api(version="3.1") def delete_favorite_project(self, user_item: UserItem, project_item: ProjectItem) -> None: + """Remove a project from the user's favorites. + + REST API: `Delete Project from Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to remove the favorite from. + + project_item : ProjectItem + The project to remove from favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}/projects/{project_item.id}" logger.info(f"Removing favorite project {project_item.id} for user (ID: {user_item.id})") self.delete_request(url) @api(version="3.3") def delete_favorite_flow(self, user_item: UserItem, flow_item: FlowItem) -> None: + """Remove a flow from the user's favorites. + + REST API: `Delete Flow from Favorites `_ + + Parameters + ---------- + user_item : UserItem + The user to remove the favorite from. + + flow_item : FlowItem + The flow to remove from favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}/flows/{flow_item.id}" logger.info(f"Removing favorite flow {flow_item.id} for user (ID: {user_item.id})") self.delete_request(url) @api(version="3.15") def delete_favorite_metric(self, user_item: UserItem, metric_item: MetricItem) -> None: + """Remove a metric from the user's favorites. + + Parameters + ---------- + user_item : UserItem + The user to remove the favorite from. + + metric_item : MetricItem + The metric to remove from favorites. + + Returns + ------- + None + """ url = f"{self.baseurl}/{user_item.id}/metrics/{metric_item.id}" logger.info(f"Removing favorite metric {metric_item.id} for user (ID: {user_item.id})") self.delete_request(url)