Skip to content

Commit 1deb8f0

Browse files
authored
Merge branch 'development' into jorwoods/metadata_paginated_sample
2 parents 7450742 + 4417beb commit 1deb8f0

28 files changed

+1885
-1624
lines changed

tableauserverclient/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from tableauserverclient.namespace import NEW_NAMESPACE as DEFAULT_NAMESPACE
33
from tableauserverclient.models import (
44
BackgroundJobItem,
5+
CollectionItem,
56
ColumnItem,
67
ConnectionCredentials,
78
ConnectionItem,
@@ -73,7 +74,7 @@
7374

7475
__all__ = [
7576
"BackgroundJobItem",
76-
"BackgroundJobItem",
77+
"CollectionItem",
7778
"ColumnItem",
7879
"ConnectionCredentials",
7980
"ConnectionItem",

tableauserverclient/models/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from tableauserverclient.models.collection_item import CollectionItem
12
from tableauserverclient.models.column_item import ColumnItem
23
from tableauserverclient.models.connection_credentials import ConnectionCredentials
34
from tableauserverclient.models.connection_item import ConnectionItem
@@ -53,6 +54,7 @@
5354
from tableauserverclient.models.extract_item import ExtractItem
5455

5556
__all__ = [
57+
"CollectionItem",
5658
"ColumnItem",
5759
"ConnectionCredentials",
5860
"ConnectionItem",
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from datetime import datetime
2+
from typing import Optional
3+
from xml.etree.ElementTree import Element
4+
5+
from defusedxml.ElementTree import fromstring
6+
from typing_extensions import Self
7+
8+
from tableauserverclient.datetime_helpers import parse_datetime
9+
from tableauserverclient.models.user_item import UserItem
10+
11+
12+
class CollectionItem:
13+
def __init__(self) -> None:
14+
self.id: Optional[str] = None
15+
self.name: Optional[str] = None
16+
self.description: Optional[str] = None
17+
self.created_at: Optional[datetime] = None
18+
self.updated_at: Optional[datetime] = None
19+
self.owner: Optional[UserItem] = None
20+
self.total_item_count: Optional[int] = None
21+
self.permissioned_item_count: Optional[int] = None
22+
self.visibility: Optional[str] = None # Assuming visibility is a string, adjust as necessary
23+
24+
@classmethod
25+
def from_response(cls, response: bytes, ns) -> list[Self]:
26+
parsed_response = fromstring(response)
27+
28+
collection_elements = parsed_response.findall(".//t:collection", namespaces=ns)
29+
if not collection_elements:
30+
raise ValueError("No collection element found in the response")
31+
32+
collections = [cls.from_xml(c, ns) for c in collection_elements]
33+
return collections
34+
35+
@classmethod
36+
def from_xml(cls, xml: Element, ns) -> Self:
37+
collection_item = cls()
38+
collection_item.id = xml.get("id")
39+
collection_item.name = xml.get("name")
40+
collection_item.description = xml.get("description")
41+
collection_item.created_at = parse_datetime(xml.get("createdAt"))
42+
collection_item.updated_at = parse_datetime(xml.get("updatedAt"))
43+
owner_element = xml.find(".//t:owner", namespaces=ns)
44+
if owner_element is not None:
45+
collection_item.owner = UserItem.from_xml(owner_element, ns)
46+
else:
47+
collection_item.owner = None
48+
collection_item.total_item_count = int(xml.get("totalItemCount", 0))
49+
collection_item.permissioned_item_count = int(xml.get("permissionedItemCount", 0))
50+
collection_item.visibility = xml.get("visibility")
51+
52+
return collection_item

tableauserverclient/models/data_freshness_policy_item.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def interval_item(self) -> Optional[list[str]]:
6666
return self._interval_item
6767

6868
@interval_item.setter
69-
def interval_item(self, value: list[str]):
69+
def interval_item(self, value: Optional[list[str]]):
7070
self._interval_item = value
7171

7272
@property
@@ -127,15 +127,15 @@ def fresh_every_schedule(self) -> Optional[FreshEvery]:
127127
return self._fresh_every_schedule
128128

129129
@fresh_every_schedule.setter
130-
def fresh_every_schedule(self, value: FreshEvery):
130+
def fresh_every_schedule(self, value: Optional[FreshEvery]):
131131
self._fresh_every_schedule = value
132132

133133
@property
134134
def fresh_at_schedule(self) -> Optional[FreshAt]:
135135
return self._fresh_at_schedule
136136

137137
@fresh_at_schedule.setter
138-
def fresh_at_schedule(self, value: FreshAt):
138+
def fresh_at_schedule(self, value: Optional[FreshAt]):
139139
self._fresh_at_schedule = value
140140

141141
@classmethod

tableauserverclient/models/datasource_item.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ def _set_values(
490490
self._owner = owner
491491

492492
@classmethod
493-
def from_response(cls, resp: str, ns: dict) -> list["DatasourceItem"]:
493+
def from_response(cls, resp: bytes, ns: dict) -> list["DatasourceItem"]:
494494
all_datasource_items = list()
495495
parsed_response = fromstring(resp)
496496
all_datasource_xml = parsed_response.findall(".//t:datasource", namespaces=ns)

tableauserverclient/models/favorites_item.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import logging
22

3-
from typing import Union
3+
from typing import TypedDict, Union
44
from defusedxml.ElementTree import fromstring
5-
6-
from tableauserverclient.models.tableau_types import TableauItem
5+
from tableauserverclient.models.collection_item import CollectionItem
76
from tableauserverclient.models.datasource_item import DatasourceItem
87
from tableauserverclient.models.flow_item import FlowItem
98
from tableauserverclient.models.project_item import ProjectItem
@@ -13,16 +12,22 @@
1312

1413
from tableauserverclient.helpers.logging import logger
1514

16-
FavoriteType = dict[
17-
str,
18-
list[TableauItem],
19-
]
15+
16+
class FavoriteType(TypedDict):
17+
collections: list[CollectionItem]
18+
datasources: list[DatasourceItem]
19+
flows: list[FlowItem]
20+
projects: list[ProjectItem]
21+
metrics: list[MetricItem]
22+
views: list[ViewItem]
23+
workbooks: list[WorkbookItem]
2024

2125

2226
class FavoriteItem:
2327
@classmethod
2428
def from_response(cls, xml: Union[str, bytes], namespace: dict) -> FavoriteType:
2529
favorites: FavoriteType = {
30+
"collections": [],
2631
"datasources": [],
2732
"flows": [],
2833
"projects": [],
@@ -32,6 +37,7 @@ def from_response(cls, xml: Union[str, bytes], namespace: dict) -> FavoriteType:
3237
}
3338
parsed_response = fromstring(xml)
3439

40+
collections_xml = parsed_response.findall(".//t:favorite/t:collection", namespace)
3541
datasources_xml = parsed_response.findall(".//t:favorite/t:datasource", namespace)
3642
flows_xml = parsed_response.findall(".//t:favorite/t:flow", namespace)
3743
metrics_xml = parsed_response.findall(".//t:favorite/t:metric", namespace)
@@ -40,13 +46,14 @@ def from_response(cls, xml: Union[str, bytes], namespace: dict) -> FavoriteType:
4046
workbooks_xml = parsed_response.findall(".//t:favorite/t:workbook", namespace)
4147

4248
logger.debug(
43-
"ds: {}, flows: {}, metrics: {}, projects: {}, views: {}, wbs: {}".format(
49+
"ds: {}, flows: {}, metrics: {}, projects: {}, views: {}, wbs: {}, collections: {}".format(
4450
len(datasources_xml),
4551
len(flows_xml),
4652
len(metrics_xml),
4753
len(projects_xml),
4854
len(views_xml),
4955
len(workbooks_xml),
56+
len(collections_xml),
5057
)
5158
)
5259
for datasource in datasources_xml:
@@ -85,5 +92,11 @@ def from_response(cls, xml: Union[str, bytes], namespace: dict) -> FavoriteType:
8592
logger.debug(fav_workbook)
8693
favorites["workbooks"].append(fav_workbook)
8794

95+
for collection in collections_xml:
96+
fav_collection = CollectionItem.from_xml(collection, namespace)
97+
if fav_collection:
98+
logger.debug(fav_collection)
99+
favorites["collections"].append(fav_collection)
100+
88101
logger.debug(favorites)
89102
return favorites

tableauserverclient/models/flow_item.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def description(self) -> Optional[str]:
129129
return self._description
130130

131131
@description.setter
132-
def description(self, value: str) -> None:
132+
def description(self, value: Optional[str]) -> None:
133133
self._description = value
134134

135135
@property

tableauserverclient/models/group_item.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def name(self) -> Optional[str]:
9292
return self._name
9393

9494
@name.setter
95-
def name(self, value: str) -> None:
95+
def name(self, value: Optional[str]) -> None:
9696
self._name = value
9797

9898
@property

tableauserverclient/models/groupset_item.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ def __str__(self) -> str:
2424
def __repr__(self) -> str:
2525
return self.__str__()
2626

27+
@property
28+
def name(self) -> Optional[str]:
29+
return self._name
30+
31+
@name.setter
32+
def name(self, value: Optional[str]) -> None:
33+
self._name = value
34+
2735
@classmethod
2836
def from_response(cls, response: bytes, ns: dict[str, str]) -> list["GroupSetItem"]:
2937
parsed_response = fromstring(response)

tableauserverclient/models/permissions_item.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class Capability:
4343
CreateRefreshMetrics = "CreateRefreshMetrics"
4444
SaveAs = "SaveAs"
4545
PulseMetricDefine = "PulseMetricDefine"
46+
ExtractRefresh = "ExtractRefresh"
47+
WebAuthoringForFlows = "WebAuthoringForFlows"
4648

4749
def __repr__(self):
4850
return "<Enum Capability: AddComment | ChangeHierarchy | ChangePermission ... (17 more) >"

0 commit comments

Comments
 (0)