tableauserverclient 0.33__py3-none-any.whl → 0.34__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. tableauserverclient/__init__.py +28 -22
  2. tableauserverclient/_version.py +3 -3
  3. tableauserverclient/config.py +5 -3
  4. tableauserverclient/models/column_item.py +1 -1
  5. tableauserverclient/models/connection_credentials.py +1 -1
  6. tableauserverclient/models/connection_item.py +6 -6
  7. tableauserverclient/models/custom_view_item.py +29 -6
  8. tableauserverclient/models/data_acceleration_report_item.py +2 -2
  9. tableauserverclient/models/data_alert_item.py +5 -5
  10. tableauserverclient/models/data_freshness_policy_item.py +6 -6
  11. tableauserverclient/models/database_item.py +3 -3
  12. tableauserverclient/models/datasource_item.py +10 -10
  13. tableauserverclient/models/dqw_item.py +1 -1
  14. tableauserverclient/models/favorites_item.py +5 -6
  15. tableauserverclient/models/fileupload_item.py +1 -1
  16. tableauserverclient/models/flow_item.py +6 -6
  17. tableauserverclient/models/flow_run_item.py +3 -3
  18. tableauserverclient/models/group_item.py +4 -4
  19. tableauserverclient/models/groupset_item.py +4 -4
  20. tableauserverclient/models/interval_item.py +9 -9
  21. tableauserverclient/models/job_item.py +8 -8
  22. tableauserverclient/models/linked_tasks_item.py +5 -5
  23. tableauserverclient/models/metric_item.py +5 -5
  24. tableauserverclient/models/pagination_item.py +1 -1
  25. tableauserverclient/models/permissions_item.py +12 -10
  26. tableauserverclient/models/project_item.py +35 -19
  27. tableauserverclient/models/property_decorators.py +12 -11
  28. tableauserverclient/models/reference_item.py +2 -2
  29. tableauserverclient/models/revision_item.py +3 -3
  30. tableauserverclient/models/schedule_item.py +2 -2
  31. tableauserverclient/models/server_info_item.py +26 -6
  32. tableauserverclient/models/site_item.py +69 -3
  33. tableauserverclient/models/subscription_item.py +3 -3
  34. tableauserverclient/models/table_item.py +1 -1
  35. tableauserverclient/models/tableau_auth.py +115 -5
  36. tableauserverclient/models/tableau_types.py +2 -2
  37. tableauserverclient/models/tag_item.py +3 -4
  38. tableauserverclient/models/task_item.py +4 -4
  39. tableauserverclient/models/user_item.py +47 -17
  40. tableauserverclient/models/view_item.py +11 -10
  41. tableauserverclient/models/virtual_connection_item.py +6 -5
  42. tableauserverclient/models/webhook_item.py +6 -6
  43. tableauserverclient/models/workbook_item.py +90 -12
  44. tableauserverclient/namespace.py +1 -1
  45. tableauserverclient/server/__init__.py +2 -1
  46. tableauserverclient/server/endpoint/auth_endpoint.py +65 -8
  47. tableauserverclient/server/endpoint/custom_views_endpoint.py +62 -18
  48. tableauserverclient/server/endpoint/data_acceleration_report_endpoint.py +2 -2
  49. tableauserverclient/server/endpoint/data_alert_endpoint.py +14 -14
  50. tableauserverclient/server/endpoint/databases_endpoint.py +13 -12
  51. tableauserverclient/server/endpoint/datasources_endpoint.py +49 -54
  52. tableauserverclient/server/endpoint/default_permissions_endpoint.py +19 -18
  53. tableauserverclient/server/endpoint/dqw_endpoint.py +9 -9
  54. tableauserverclient/server/endpoint/endpoint.py +19 -21
  55. tableauserverclient/server/endpoint/exceptions.py +23 -7
  56. tableauserverclient/server/endpoint/favorites_endpoint.py +31 -31
  57. tableauserverclient/server/endpoint/fileuploads_endpoint.py +9 -11
  58. tableauserverclient/server/endpoint/flow_runs_endpoint.py +15 -13
  59. tableauserverclient/server/endpoint/flow_task_endpoint.py +2 -2
  60. tableauserverclient/server/endpoint/flows_endpoint.py +30 -29
  61. tableauserverclient/server/endpoint/groups_endpoint.py +18 -17
  62. tableauserverclient/server/endpoint/groupsets_endpoint.py +2 -2
  63. tableauserverclient/server/endpoint/jobs_endpoint.py +7 -7
  64. tableauserverclient/server/endpoint/linked_tasks_endpoint.py +2 -2
  65. tableauserverclient/server/endpoint/metadata_endpoint.py +2 -2
  66. tableauserverclient/server/endpoint/metrics_endpoint.py +10 -10
  67. tableauserverclient/server/endpoint/permissions_endpoint.py +13 -15
  68. tableauserverclient/server/endpoint/projects_endpoint.py +81 -30
  69. tableauserverclient/server/endpoint/resource_tagger.py +14 -13
  70. tableauserverclient/server/endpoint/schedules_endpoint.py +17 -18
  71. tableauserverclient/server/endpoint/server_info_endpoint.py +40 -5
  72. tableauserverclient/server/endpoint/sites_endpoint.py +282 -17
  73. tableauserverclient/server/endpoint/subscriptions_endpoint.py +10 -10
  74. tableauserverclient/server/endpoint/tables_endpoint.py +15 -14
  75. tableauserverclient/server/endpoint/tasks_endpoint.py +8 -8
  76. tableauserverclient/server/endpoint/users_endpoint.py +366 -19
  77. tableauserverclient/server/endpoint/views_endpoint.py +19 -18
  78. tableauserverclient/server/endpoint/virtual_connections_endpoint.py +6 -5
  79. tableauserverclient/server/endpoint/webhooks_endpoint.py +11 -11
  80. tableauserverclient/server/endpoint/workbooks_endpoint.py +647 -61
  81. tableauserverclient/server/filter.py +2 -2
  82. tableauserverclient/server/pager.py +5 -6
  83. tableauserverclient/server/query.py +68 -19
  84. tableauserverclient/server/request_factory.py +37 -36
  85. tableauserverclient/server/request_options.py +123 -145
  86. tableauserverclient/server/server.py +65 -9
  87. tableauserverclient/server/sort.py +2 -2
  88. {tableauserverclient-0.33.dist-info → tableauserverclient-0.34.dist-info}/METADATA +6 -6
  89. tableauserverclient-0.34.dist-info/RECORD +106 -0
  90. {tableauserverclient-0.33.dist-info → tableauserverclient-0.34.dist-info}/WHEEL +1 -1
  91. tableauserverclient-0.33.dist-info/RECORD +0 -106
  92. {tableauserverclient-0.33.dist-info → tableauserverclient-0.34.dist-info}/LICENSE +0 -0
  93. {tableauserverclient-0.33.dist-info → tableauserverclient-0.34.dist-info}/LICENSE.versioneer +0 -0
  94. {tableauserverclient-0.33.dist-info → tableauserverclient-0.34.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  from .request_options import RequestOptions
2
2
 
3
3
 
4
- class Filter(object):
4
+ class Filter:
5
5
  def __init__(self, field, operator, value):
6
6
  self.field = field
7
7
  self.operator = operator
@@ -16,7 +16,7 @@ class Filter(object):
16
16
  # to [<string1>,<string2>]
17
17
  # so effectively, remove any spaces between "," and "'" and then remove all "'"
18
18
  value_string = value_string.replace(", '", ",'").replace("'", "")
19
- return "{0}:{1}:{2}".format(self.field, self.operator, value_string)
19
+ return f"{self.field}:{self.operator}:{value_string}"
20
20
 
21
21
  @property
22
22
  def value(self):
@@ -1,6 +1,7 @@
1
1
  import copy
2
2
  from functools import partial
3
- from typing import Iterable, Iterator, List, Optional, Protocol, Tuple, TypeVar, Union, runtime_checkable
3
+ from typing import Optional, Protocol, TypeVar, Union, runtime_checkable
4
+ from collections.abc import Iterable, Iterator
4
5
 
5
6
  from tableauserverclient.models.pagination_item import PaginationItem
6
7
  from tableauserverclient.server.request_options import RequestOptions
@@ -11,14 +12,12 @@ T = TypeVar("T")
11
12
 
12
13
  @runtime_checkable
13
14
  class Endpoint(Protocol[T]):
14
- def get(self, req_options: Optional[RequestOptions]) -> Tuple[List[T], PaginationItem]:
15
- ...
15
+ def get(self, req_options: Optional[RequestOptions]) -> tuple[list[T], PaginationItem]: ...
16
16
 
17
17
 
18
18
  @runtime_checkable
19
19
  class CallableEndpoint(Protocol[T]):
20
- def __call__(self, __req_options: Optional[RequestOptions], **kwargs) -> Tuple[List[T], PaginationItem]:
21
- ...
20
+ def __call__(self, __req_options: Optional[RequestOptions], **kwargs) -> tuple[list[T], PaginationItem]: ...
22
21
 
23
22
 
24
23
  class Pager(Iterable[T]):
@@ -27,7 +26,7 @@ class Pager(Iterable[T]):
27
26
  Supports all `RequestOptions` including starting on any page. Also used by models to load sub-models
28
27
  (users in a group, views in a workbook, etc) by passing a different endpoint.
29
28
 
30
- Will loop over anything that returns (List[ModelItem], PaginationItem).
29
+ Will loop over anything that returns (list[ModelItem], PaginationItem).
31
30
  """
32
31
 
33
32
  def __init__(
@@ -1,8 +1,10 @@
1
- from collections.abc import Sized
1
+ from collections.abc import Iterable, Iterator, Sized
2
2
  from itertools import count
3
- from typing import Iterable, Iterator, List, Optional, Protocol, Tuple, TYPE_CHECKING, TypeVar, overload
3
+ from typing import Optional, Protocol, TYPE_CHECKING, TypeVar, overload
4
+ import sys
4
5
  from tableauserverclient.config import config
5
6
  from tableauserverclient.models.pagination_item import PaginationItem
7
+ from tableauserverclient.server.endpoint.exceptions import ServerResponseError
6
8
  from tableauserverclient.server.filter import Filter
7
9
  from tableauserverclient.server.request_options import RequestOptions
8
10
  from tableauserverclient.server.sort import Sort
@@ -34,10 +36,36 @@ see pagination_sample
34
36
 
35
37
 
36
38
  class QuerySet(Iterable[T], Sized):
39
+ """
40
+ QuerySet is a class that allows easy filtering, sorting, and iterating over
41
+ many endpoints in TableauServerClient. It is designed to be used in a similar
42
+ way to Django QuerySets, but with a more limited feature set.
43
+
44
+ QuerySet is an iterable, and can be used in for loops, list comprehensions,
45
+ and other places where iterables are expected.
46
+
47
+ QuerySet is also Sized, and can be used in places where the length of the
48
+ QuerySet is needed. The length of the QuerySet is the total number of items
49
+ available in the QuerySet, not just the number of items that have been
50
+ fetched. If the endpoint does not return a total count of items, the length
51
+ of the QuerySet will be sys.maxsize. If there is no total count, the
52
+ QuerySet will continue to fetch items until there are no more items to
53
+ fetch.
54
+
55
+ QuerySet is not re-entrant. It is not designed to be used in multiple places
56
+ at the same time. If you need to use a QuerySet in multiple places, you
57
+ should create a new QuerySet for each place you need to use it, convert it
58
+ to a list, or create a deep copy of the QuerySet.
59
+
60
+ QuerySets are also indexable, and can be sliced. If you try to access an
61
+ index that has not been fetched, the QuerySet will fetch the page that
62
+ contains the item you are looking for.
63
+ """
64
+
37
65
  def __init__(self, model: "QuerysetEndpoint[T]", page_size: Optional[int] = None) -> None:
38
66
  self.model = model
39
67
  self.request_options = RequestOptions(pagesize=page_size or config.PAGE_SIZE)
40
- self._result_cache: List[T] = []
68
+ self._result_cache: list[T] = []
41
69
  self._pagination_item = PaginationItem()
42
70
 
43
71
  def __iter__(self: Self) -> Iterator[T]:
@@ -49,19 +77,30 @@ class QuerySet(Iterable[T], Sized):
49
77
  for page in count(1):
50
78
  self.request_options.pagenumber = page
51
79
  self._result_cache = []
52
- self._fetch_all()
80
+ self._pagination_item._page_number = None
81
+ try:
82
+ self._fetch_all()
83
+ except ServerResponseError as e:
84
+ if e.code == "400006":
85
+ # If the endpoint does not support pagination, it will end
86
+ # up overrunning the total number of pages. Catch the
87
+ # error and break out of the loop.
88
+ raise StopIteration
89
+ if len(self._result_cache) == 0:
90
+ return
53
91
  yield from self._result_cache
54
- # Set result_cache to empty so the fetch will populate
55
- if (page * self.page_size) >= len(self):
92
+ # If the length of the QuerySet is unknown, continue fetching until
93
+ # the result cache is empty.
94
+ if (size := len(self)) == 0:
95
+ continue
96
+ if (page * self.page_size) >= size:
56
97
  return
57
98
 
58
99
  @overload
59
- def __getitem__(self: Self, k: Slice) -> List[T]:
60
- ...
100
+ def __getitem__(self: Self, k: Slice) -> list[T]: ...
61
101
 
62
102
  @overload
63
- def __getitem__(self: Self, k: int) -> T:
64
- ...
103
+ def __getitem__(self: Self, k: int) -> T: ...
65
104
 
66
105
  def __getitem__(self, k):
67
106
  page = self.page_number
@@ -103,6 +142,7 @@ class QuerySet(Iterable[T], Sized):
103
142
  elif k in range(self.total_available):
104
143
  # Otherwise, check if k is even sensible to return
105
144
  self._result_cache = []
145
+ self._pagination_item._page_number = None
106
146
  # Add one to k, otherwise it gets stuck at page boundaries, e.g. 100
107
147
  self.request_options.pagenumber = max(1, math.ceil((k + 1) / size))
108
148
  return self[k]
@@ -114,11 +154,16 @@ class QuerySet(Iterable[T], Sized):
114
154
  """
115
155
  Retrieve the data and store result and pagination item in cache
116
156
  """
117
- if not self._result_cache:
118
- self._result_cache, self._pagination_item = self.model.get(self.request_options)
157
+ if not self._result_cache and self._pagination_item._page_number is None:
158
+ response = self.model.get(self.request_options)
159
+ if isinstance(response, tuple):
160
+ self._result_cache, self._pagination_item = response
161
+ else:
162
+ self._result_cache = response
163
+ self._pagination_item = PaginationItem()
119
164
 
120
165
  def __len__(self: Self) -> int:
121
- return self.total_available
166
+ return sys.maxsize if self.total_available is None else self.total_available
122
167
 
123
168
  @property
124
169
  def total_available(self: Self) -> int:
@@ -128,12 +173,16 @@ class QuerySet(Iterable[T], Sized):
128
173
  @property
129
174
  def page_number(self: Self) -> int:
130
175
  self._fetch_all()
131
- return self._pagination_item.page_number
176
+ # If the PaginationItem is not returned from the endpoint, use the
177
+ # pagenumber from the RequestOptions.
178
+ return self._pagination_item.page_number or self.request_options.pagenumber
132
179
 
133
180
  @property
134
181
  def page_size(self: Self) -> int:
135
182
  self._fetch_all()
136
- return self._pagination_item.page_size
183
+ # If the PaginationItem is not returned from the endpoint, use the
184
+ # pagesize from the RequestOptions.
185
+ return self._pagination_item.page_size or self.request_options.pagesize
137
186
 
138
187
  def filter(self: Self, *invalid, page_size: Optional[int] = None, **kwargs) -> Self:
139
188
  if invalid:
@@ -160,22 +209,22 @@ class QuerySet(Iterable[T], Sized):
160
209
  return self
161
210
 
162
211
  @staticmethod
163
- def _parse_shorthand_filter(key: str) -> Tuple[str, str]:
212
+ def _parse_shorthand_filter(key: str) -> tuple[str, str]:
164
213
  tokens = key.split("__", 1)
165
214
  if len(tokens) == 1:
166
215
  operator = RequestOptions.Operator.Equals
167
216
  else:
168
217
  operator = tokens[1]
169
218
  if operator not in RequestOptions.Operator.__dict__.values():
170
- raise ValueError("Operator `{}` is not valid.".format(operator))
219
+ raise ValueError(f"Operator `{operator}` is not valid.")
171
220
 
172
221
  field = to_camel_case(tokens[0])
173
222
  if field not in RequestOptions.Field.__dict__.values():
174
- raise ValueError("Field name `{}` is not valid.".format(field))
223
+ raise ValueError(f"Field name `{field}` is not valid.")
175
224
  return (field, operator)
176
225
 
177
226
  @staticmethod
178
- def _parse_shorthand_sort(key: str) -> Tuple[str, str]:
227
+ def _parse_shorthand_sort(key: str) -> tuple[str, str]:
179
228
  direction = RequestOptions.Direction.Asc
180
229
  if key.startswith("-"):
181
230
  direction = RequestOptions.Direction.Desc
@@ -1,5 +1,6 @@
1
1
  import xml.etree.ElementTree as ET
2
- from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, TypeVar, TYPE_CHECKING, Union
2
+ from typing import Any, Callable, Optional, TypeVar, TYPE_CHECKING, Union
3
+ from collections.abc import Iterable
3
4
 
4
5
  from typing_extensions import ParamSpec
5
6
 
@@ -15,7 +16,7 @@ if TYPE_CHECKING:
15
16
  # this file could be largely replaced if we were willing to import the huge file from generateDS
16
17
 
17
18
 
18
- def _add_multipart(parts: Dict) -> Tuple[Any, str]:
19
+ def _add_multipart(parts: dict) -> tuple[Any, str]:
19
20
  mime_multipart_parts = list()
20
21
  for name, (filename, data, content_type) in parts.items():
21
22
  multipart_part = RequestField(name=name, data=data, filename=filename)
@@ -80,7 +81,7 @@ def _add_credentials_element(parent_element, connection_credentials):
80
81
  credentials_element.attrib["oAuth"] = "true"
81
82
 
82
83
 
83
- class AuthRequest(object):
84
+ class AuthRequest:
84
85
  def signin_req(self, auth_item):
85
86
  xml_request = ET.Element("tsRequest")
86
87
 
@@ -104,7 +105,7 @@ class AuthRequest(object):
104
105
  return ET.tostring(xml_request)
105
106
 
106
107
 
107
- class ColumnRequest(object):
108
+ class ColumnRequest:
108
109
  def update_req(self, column_item):
109
110
  xml_request = ET.Element("tsRequest")
110
111
  column_element = ET.SubElement(xml_request, "column")
@@ -115,7 +116,7 @@ class ColumnRequest(object):
115
116
  return ET.tostring(xml_request)
116
117
 
117
118
 
118
- class DataAlertRequest(object):
119
+ class DataAlertRequest:
119
120
  def add_user_to_alert(self, alert_item: "DataAlertItem", user_id: str) -> bytes:
120
121
  xml_request = ET.Element("tsRequest")
121
122
  user_element = ET.SubElement(xml_request, "user")
@@ -140,7 +141,7 @@ class DataAlertRequest(object):
140
141
  return ET.tostring(xml_request)
141
142
 
142
143
 
143
- class DatabaseRequest(object):
144
+ class DatabaseRequest:
144
145
  def update_req(self, database_item):
145
146
  xml_request = ET.Element("tsRequest")
146
147
  database_element = ET.SubElement(xml_request, "database")
@@ -159,7 +160,7 @@ class DatabaseRequest(object):
159
160
  return ET.tostring(xml_request)
160
161
 
161
162
 
162
- class DatasourceRequest(object):
163
+ class DatasourceRequest:
163
164
  def _generate_xml(self, datasource_item: DatasourceItem, connection_credentials=None, connections=None):
164
165
  xml_request = ET.Element("tsRequest")
165
166
  datasource_element = ET.SubElement(xml_request, "datasource")
@@ -244,7 +245,7 @@ class DatasourceRequest(object):
244
245
  return _add_multipart(parts)
245
246
 
246
247
 
247
- class DQWRequest(object):
248
+ class DQWRequest:
248
249
  def add_req(self, dqw_item):
249
250
  xml_request = ET.Element("tsRequest")
250
251
  dqw_element = ET.SubElement(xml_request, "dataQualityWarning")
@@ -274,7 +275,7 @@ class DQWRequest(object):
274
275
  return ET.tostring(xml_request)
275
276
 
276
277
 
277
- class FavoriteRequest(object):
278
+ class FavoriteRequest:
278
279
  def add_request(self, id_: Optional[str], target_type: str, label: Optional[str]) -> bytes:
279
280
  """
280
281
  <favorite label="...">
@@ -329,7 +330,7 @@ class FavoriteRequest(object):
329
330
  return self.add_request(id_, Resource.Workbook, name)
330
331
 
331
332
 
332
- class FileuploadRequest(object):
333
+ class FileuploadRequest:
333
334
  def chunk_req(self, chunk):
334
335
  parts = {
335
336
  "request_payload": ("", "", "text/xml"),
@@ -338,8 +339,8 @@ class FileuploadRequest(object):
338
339
  return _add_multipart(parts)
339
340
 
340
341
 
341
- class FlowRequest(object):
342
- def _generate_xml(self, flow_item: "FlowItem", connections: Optional[List["ConnectionItem"]] = None) -> bytes:
342
+ class FlowRequest:
343
+ def _generate_xml(self, flow_item: "FlowItem", connections: Optional[list["ConnectionItem"]] = None) -> bytes:
343
344
  xml_request = ET.Element("tsRequest")
344
345
  flow_element = ET.SubElement(xml_request, "flow")
345
346
  if flow_item.name is not None:
@@ -370,8 +371,8 @@ class FlowRequest(object):
370
371
  flow_item: "FlowItem",
371
372
  filename: str,
372
373
  file_contents: bytes,
373
- connections: Optional[List["ConnectionItem"]] = None,
374
- ) -> Tuple[Any, str]:
374
+ connections: Optional[list["ConnectionItem"]] = None,
375
+ ) -> tuple[Any, str]:
375
376
  xml_request = self._generate_xml(flow_item, connections)
376
377
 
377
378
  parts = {
@@ -380,14 +381,14 @@ class FlowRequest(object):
380
381
  }
381
382
  return _add_multipart(parts)
382
383
 
383
- def publish_req_chunked(self, flow_item, connections=None) -> Tuple[Any, str]:
384
+ def publish_req_chunked(self, flow_item, connections=None) -> tuple[Any, str]:
384
385
  xml_request = self._generate_xml(flow_item, connections)
385
386
 
386
387
  parts = {"request_payload": ("", xml_request, "text/xml")}
387
388
  return _add_multipart(parts)
388
389
 
389
390
 
390
- class GroupRequest(object):
391
+ class GroupRequest:
391
392
  def add_user_req(self, user_id: str) -> bytes:
392
393
  xml_request = ET.Element("tsRequest")
393
394
  user_element = ET.SubElement(xml_request, "user")
@@ -477,7 +478,7 @@ class GroupRequest(object):
477
478
  return ET.tostring(xml_request)
478
479
 
479
480
 
480
- class PermissionRequest(object):
481
+ class PermissionRequest:
481
482
  def add_req(self, rules: Iterable[PermissionsRule]) -> bytes:
482
483
  xml_request = ET.Element("tsRequest")
483
484
  permissions_element = ET.SubElement(xml_request, "permissions")
@@ -499,7 +500,7 @@ class PermissionRequest(object):
499
500
  capability_element.attrib["mode"] = mode
500
501
 
501
502
 
502
- class ProjectRequest(object):
503
+ class ProjectRequest:
503
504
  def update_req(self, project_item: "ProjectItem") -> bytes:
504
505
  xml_request = ET.Element("tsRequest")
505
506
  project_element = ET.SubElement(xml_request, "project")
@@ -530,7 +531,7 @@ class ProjectRequest(object):
530
531
  return ET.tostring(xml_request)
531
532
 
532
533
 
533
- class ScheduleRequest(object):
534
+ class ScheduleRequest:
534
535
  def create_req(self, schedule_item):
535
536
  xml_request = ET.Element("tsRequest")
536
537
  schedule_element = ET.SubElement(xml_request, "schedule")
@@ -609,7 +610,7 @@ class ScheduleRequest(object):
609
610
  return self._add_to_req(id_, "flow", task_type)
610
611
 
611
612
 
612
- class SiteRequest(object):
613
+ class SiteRequest:
613
614
  def update_req(self, site_item: "SiteItem", parent_srv: Optional["Server"] = None):
614
615
  xml_request = ET.Element("tsRequest")
615
616
  site_element = ET.SubElement(xml_request, "site")
@@ -848,7 +849,7 @@ class SiteRequest(object):
848
849
  warnings.warn("In version 3.10 and earlier there is only one option: FlowsEnabled")
849
850
 
850
851
 
851
- class TableRequest(object):
852
+ class TableRequest:
852
853
  def update_req(self, table_item):
853
854
  xml_request = ET.Element("tsRequest")
854
855
  table_element = ET.SubElement(xml_request, "table")
@@ -871,7 +872,7 @@ class TableRequest(object):
871
872
  content_types = Iterable[Union["ColumnItem", "DatabaseItem", "DatasourceItem", "FlowItem", "TableItem", "WorkbookItem"]]
872
873
 
873
874
 
874
- class TagRequest(object):
875
+ class TagRequest:
875
876
  def add_req(self, tag_set):
876
877
  xml_request = ET.Element("tsRequest")
877
878
  tags_element = ET.SubElement(xml_request, "tags")
@@ -881,7 +882,7 @@ class TagRequest(object):
881
882
  return ET.tostring(xml_request)
882
883
 
883
884
  @_tsrequest_wrapped
884
- def batch_create(self, element: ET.Element, tags: Set[str], content: content_types) -> bytes:
885
+ def batch_create(self, element: ET.Element, tags: set[str], content: content_types) -> bytes:
885
886
  tag_batch = ET.SubElement(element, "tagBatch")
886
887
  tags_element = ET.SubElement(tag_batch, "tags")
887
888
  for tag in tags:
@@ -897,7 +898,7 @@ class TagRequest(object):
897
898
  return ET.tostring(element)
898
899
 
899
900
 
900
- class UserRequest(object):
901
+ class UserRequest:
901
902
  def update_req(self, user_item: UserItem, password: Optional[str]) -> bytes:
902
903
  xml_request = ET.Element("tsRequest")
903
904
  user_element = ET.SubElement(xml_request, "user")
@@ -931,7 +932,7 @@ class UserRequest(object):
931
932
  return ET.tostring(xml_request)
932
933
 
933
934
 
934
- class WorkbookRequest(object):
935
+ class WorkbookRequest:
935
936
  def _generate_xml(
936
937
  self,
937
938
  workbook_item,
@@ -995,9 +996,9 @@ class WorkbookRequest(object):
995
996
  if data_freshness_policy_config.option == "FreshEvery":
996
997
  if data_freshness_policy_config.fresh_every_schedule is not None:
997
998
  fresh_every_element = ET.SubElement(data_freshness_policy_element, "freshEverySchedule")
998
- fresh_every_element.attrib[
999
- "frequency"
1000
- ] = data_freshness_policy_config.fresh_every_schedule.frequency
999
+ fresh_every_element.attrib["frequency"] = (
1000
+ data_freshness_policy_config.fresh_every_schedule.frequency
1001
+ )
1001
1002
  fresh_every_element.attrib["value"] = str(data_freshness_policy_config.fresh_every_schedule.value)
1002
1003
  else:
1003
1004
  raise ValueError(f"data_freshness_policy_config.fresh_every_schedule must be populated.")
@@ -1075,7 +1076,7 @@ class WorkbookRequest(object):
1075
1076
  datasource_element.attrib["id"] = id_
1076
1077
 
1077
1078
 
1078
- class Connection(object):
1079
+ class Connection:
1079
1080
  @_tsrequest_wrapped
1080
1081
  def update_req(self, xml_request: ET.Element, connection_item: "ConnectionItem") -> None:
1081
1082
  connection_element = ET.SubElement(xml_request, "connection")
@@ -1098,7 +1099,7 @@ class Connection(object):
1098
1099
  connection_element.attrib["queryTaggingEnabled"] = str(connection_item.query_tagging).lower()
1099
1100
 
1100
1101
 
1101
- class TaskRequest(object):
1102
+ class TaskRequest:
1102
1103
  @_tsrequest_wrapped
1103
1104
  def run_req(self, xml_request: ET.Element, task_item: Any) -> None:
1104
1105
  # Send an empty tsRequest
@@ -1137,7 +1138,7 @@ class TaskRequest(object):
1137
1138
  return ET.tostring(xml_request)
1138
1139
 
1139
1140
 
1140
- class FlowTaskRequest(object):
1141
+ class FlowTaskRequest:
1141
1142
  @_tsrequest_wrapped
1142
1143
  def create_flow_task_req(self, xml_request: ET.Element, flow_item: "TaskItem") -> bytes:
1143
1144
  flow_element = ET.SubElement(xml_request, "runFlow")
@@ -1171,7 +1172,7 @@ class FlowTaskRequest(object):
1171
1172
  return ET.tostring(xml_request)
1172
1173
 
1173
1174
 
1174
- class SubscriptionRequest(object):
1175
+ class SubscriptionRequest:
1175
1176
  @_tsrequest_wrapped
1176
1177
  def create_req(self, xml_request: ET.Element, subscription_item: "SubscriptionItem") -> bytes:
1177
1178
  subscription_element = ET.SubElement(xml_request, "subscription")
@@ -1235,13 +1236,13 @@ class SubscriptionRequest(object):
1235
1236
  return ET.tostring(xml_request)
1236
1237
 
1237
1238
 
1238
- class EmptyRequest(object):
1239
+ class EmptyRequest:
1239
1240
  @_tsrequest_wrapped
1240
1241
  def empty_req(self, xml_request: ET.Element) -> None:
1241
1242
  pass
1242
1243
 
1243
1244
 
1244
- class WebhookRequest(object):
1245
+ class WebhookRequest:
1245
1246
  @_tsrequest_wrapped
1246
1247
  def create_req(self, xml_request: ET.Element, webhook_item: "WebhookItem") -> bytes:
1247
1248
  webhook = ET.SubElement(xml_request, "webhook")
@@ -1287,7 +1288,7 @@ class MetricRequest:
1287
1288
  return ET.tostring(xml_request)
1288
1289
 
1289
1290
 
1290
- class CustomViewRequest(object):
1291
+ class CustomViewRequest:
1291
1292
  @_tsrequest_wrapped
1292
1293
  def update_req(self, xml_request: ET.Element, custom_view_item: CustomViewItem):
1293
1294
  updating_element = ET.SubElement(xml_request, "customView")
@@ -1415,7 +1416,7 @@ class VirtualConnectionRequest:
1415
1416
  return ET.tostring(xml_request)
1416
1417
 
1417
1418
 
1418
- class RequestFactory(object):
1419
+ class RequestFactory:
1419
1420
  Auth = AuthRequest()
1420
1421
  Connection = Connection()
1421
1422
  Column = ColumnRequest()