tableauserverclient 0.33__py3-none-any.whl → 0.35__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 +33 -23
  2. tableauserverclient/{_version.py → bin/_version.py} +3 -3
  3. tableauserverclient/config.py +5 -3
  4. tableauserverclient/models/column_item.py +1 -1
  5. tableauserverclient/models/connection_credentials.py +18 -2
  6. tableauserverclient/models/connection_item.py +44 -6
  7. tableauserverclient/models/custom_view_item.py +78 -11
  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 +54 -9
  17. tableauserverclient/models/flow_run_item.py +3 -3
  18. tableauserverclient/models/group_item.py +44 -4
  19. tableauserverclient/models/groupset_item.py +4 -4
  20. tableauserverclient/models/interval_item.py +9 -9
  21. tableauserverclient/models/job_item.py +73 -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 +73 -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 +34 -4
  39. tableauserverclient/models/user_item.py +47 -17
  40. tableauserverclient/models/view_item.py +66 -13
  41. tableauserverclient/models/virtual_connection_item.py +6 -5
  42. tableauserverclient/models/webhook_item.py +39 -6
  43. tableauserverclient/models/workbook_item.py +116 -13
  44. tableauserverclient/namespace.py +1 -1
  45. tableauserverclient/server/__init__.py +2 -1
  46. tableauserverclient/server/endpoint/auth_endpoint.py +69 -10
  47. tableauserverclient/server/endpoint/custom_views_endpoint.py +258 -29
  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 +61 -62
  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 +344 -29
  61. tableauserverclient/server/endpoint/groups_endpoint.py +342 -27
  62. tableauserverclient/server/endpoint/groupsets_endpoint.py +2 -2
  63. tableauserverclient/server/endpoint/jobs_endpoint.py +116 -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 +681 -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 +86 -8
  76. tableauserverclient/server/endpoint/users_endpoint.py +366 -19
  77. tableauserverclient/server/endpoint/views_endpoint.py +262 -20
  78. tableauserverclient/server/endpoint/virtual_connections_endpoint.py +6 -5
  79. tableauserverclient/server/endpoint/webhooks_endpoint.py +88 -11
  80. tableauserverclient/server/endpoint/workbooks_endpoint.py +653 -65
  81. tableauserverclient/server/filter.py +2 -2
  82. tableauserverclient/server/pager.py +29 -6
  83. tableauserverclient/server/query.py +68 -19
  84. tableauserverclient/server/request_factory.py +57 -37
  85. tableauserverclient/server/request_options.py +243 -141
  86. tableauserverclient/server/server.py +76 -10
  87. tableauserverclient/server/sort.py +16 -2
  88. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/METADATA +7 -7
  89. tableauserverclient-0.35.dist-info/RECORD +106 -0
  90. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/WHEEL +1 -1
  91. tableauserverclient-0.33.dist-info/RECORD +0 -106
  92. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/LICENSE +0 -0
  93. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/LICENSE.versioneer +0 -0
  94. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/top_level.txt +0 -0
@@ -1,24 +1,31 @@
1
1
  from defusedxml.ElementTree import fromstring
2
- from typing import Optional
2
+ from typing import Mapping, Optional, TypeVar
3
+
4
+
5
+ def split_pascal_case(s: str) -> str:
6
+ return "".join([f" {c}" if c.isupper() else c for c in s]).strip()
3
7
 
4
8
 
5
9
  class TableauError(Exception):
6
10
  pass
7
11
 
8
12
 
9
- class ServerResponseError(TableauError):
10
- def __init__(self, code, summary, detail, url=None):
13
+ T = TypeVar("T")
14
+
15
+
16
+ class XMLError(TableauError):
17
+ def __init__(self, code: str, summary: str, detail: str, url: Optional[str] = None) -> None:
11
18
  self.code = code
12
19
  self.summary = summary
13
20
  self.detail = detail
14
21
  self.url = url
15
- super(ServerResponseError, self).__init__(str(self))
22
+ super().__init__(str(self))
16
23
 
17
24
  def __str__(self):
18
- return "\n\n\t{0}: {1}\n\t\t{2}".format(self.code, self.summary, self.detail)
25
+ return f"\n\n\t{self.code}: {self.summary}\n\t\t{self.detail}"
19
26
 
20
27
  @classmethod
21
- def from_response(cls, resp, ns, url=None):
28
+ def from_response(cls, resp, ns, url):
22
29
  # Check elements exist before .text
23
30
  parsed_response = fromstring(resp)
24
31
  try:
@@ -33,6 +40,10 @@ class ServerResponseError(TableauError):
33
40
  return error_response
34
41
 
35
42
 
43
+ class ServerResponseError(XMLError):
44
+ pass
45
+
46
+
36
47
  class InternalServerError(TableauError):
37
48
  def __init__(self, server_response, request_url: Optional[str] = None):
38
49
  self.code = server_response.status_code
@@ -40,7 +51,7 @@ class InternalServerError(TableauError):
40
51
  self.url = request_url or "server"
41
52
 
42
53
  def __str__(self):
43
- return "\n\nInternal error {0} at {1}\n{2}".format(self.code, self.url, self.content)
54
+ return f"\n\nInternal error {self.code} at {self.url}\n{self.content}"
44
55
 
45
56
 
46
57
  class MissingRequiredFieldError(TableauError):
@@ -51,6 +62,11 @@ class NotSignedInError(TableauError):
51
62
  pass
52
63
 
53
64
 
65
+ class FailedSignInError(XMLError, NotSignedInError):
66
+ def __str__(self):
67
+ return f"{split_pascal_case(self.__class__.__name__)}: {super().__str__()}"
68
+
69
+
54
70
  class ItemTypeNotAllowed(TableauError):
55
71
  pass
56
72
 
@@ -20,13 +20,13 @@ from typing import Optional
20
20
  class Favorites(Endpoint):
21
21
  @property
22
22
  def baseurl(self) -> str:
23
- return "{0}/sites/{1}/favorites".format(self.parent_srv.baseurl, self.parent_srv.site_id)
23
+ return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}/favorites"
24
24
 
25
25
  # Gets all favorites
26
26
  @api(version="2.5")
27
27
  def get(self, user_item: UserItem, req_options: Optional[RequestOptions] = None) -> None:
28
- logger.info("Querying all favorites for user {0}".format(user_item.name))
29
- url = "{0}/{1}".format(self.baseurl, user_item.id)
28
+ logger.info(f"Querying all favorites for user {user_item.name}")
29
+ url = f"{self.baseurl}/{user_item.id}"
30
30
  server_response = self.get_request(url, req_options)
31
31
  user_item._favorites = FavoriteItem.from_response(server_response.content, self.parent_srv.namespace)
32
32
 
@@ -34,53 +34,53 @@ class Favorites(Endpoint):
34
34
 
35
35
  @api(version="3.15")
36
36
  def add_favorite(self, user_item: UserItem, content_type: str, item: TableauItem) -> "Response":
37
- url = "{0}/{1}".format(self.baseurl, user_item.id)
37
+ url = f"{self.baseurl}/{user_item.id}"
38
38
  add_req = RequestFactory.Favorite.add_request(item.id, content_type, item.name)
39
39
  server_response = self.put_request(url, add_req)
40
- logger.info("Favorited {0} for user (ID: {1})".format(item.name, user_item.id))
40
+ logger.info(f"Favorited {item.name} for user (ID: {user_item.id})")
41
41
  return server_response
42
42
 
43
43
  @api(version="2.0")
44
44
  def add_favorite_workbook(self, user_item: UserItem, workbook_item: WorkbookItem) -> None:
45
- url = "{0}/{1}".format(self.baseurl, user_item.id)
45
+ url = f"{self.baseurl}/{user_item.id}"
46
46
  add_req = RequestFactory.Favorite.add_workbook_req(workbook_item.id, workbook_item.name)
47
47
  server_response = self.put_request(url, add_req)
48
- logger.info("Favorited {0} for user (ID: {1})".format(workbook_item.name, user_item.id))
48
+ logger.info(f"Favorited {workbook_item.name} for user (ID: {user_item.id})")
49
49
 
50
50
  @api(version="2.0")
51
51
  def add_favorite_view(self, user_item: UserItem, view_item: ViewItem) -> None:
52
- url = "{0}/{1}".format(self.baseurl, user_item.id)
52
+ url = f"{self.baseurl}/{user_item.id}"
53
53
  add_req = RequestFactory.Favorite.add_view_req(view_item.id, view_item.name)
54
54
  server_response = self.put_request(url, add_req)
55
- logger.info("Favorited {0} for user (ID: {1})".format(view_item.name, user_item.id))
55
+ logger.info(f"Favorited {view_item.name} for user (ID: {user_item.id})")
56
56
 
57
57
  @api(version="2.3")
58
58
  def add_favorite_datasource(self, user_item: UserItem, datasource_item: DatasourceItem) -> None:
59
- url = "{0}/{1}".format(self.baseurl, user_item.id)
59
+ url = f"{self.baseurl}/{user_item.id}"
60
60
  add_req = RequestFactory.Favorite.add_datasource_req(datasource_item.id, datasource_item.name)
61
61
  server_response = self.put_request(url, add_req)
62
- logger.info("Favorited {0} for user (ID: {1})".format(datasource_item.name, user_item.id))
62
+ logger.info(f"Favorited {datasource_item.name} for user (ID: {user_item.id})")
63
63
 
64
64
  @api(version="3.1")
65
65
  def add_favorite_project(self, user_item: UserItem, project_item: ProjectItem) -> None:
66
- url = "{0}/{1}".format(self.baseurl, user_item.id)
66
+ url = f"{self.baseurl}/{user_item.id}"
67
67
  add_req = RequestFactory.Favorite.add_project_req(project_item.id, project_item.name)
68
68
  server_response = self.put_request(url, add_req)
69
- logger.info("Favorited {0} for user (ID: {1})".format(project_item.name, user_item.id))
69
+ logger.info(f"Favorited {project_item.name} for user (ID: {user_item.id})")
70
70
 
71
71
  @api(version="3.3")
72
72
  def add_favorite_flow(self, user_item: UserItem, flow_item: FlowItem) -> None:
73
- url = "{0}/{1}".format(self.baseurl, user_item.id)
73
+ url = f"{self.baseurl}/{user_item.id}"
74
74
  add_req = RequestFactory.Favorite.add_flow_req(flow_item.id, flow_item.name)
75
75
  server_response = self.put_request(url, add_req)
76
- logger.info("Favorited {0} for user (ID: {1})".format(flow_item.name, user_item.id))
76
+ logger.info(f"Favorited {flow_item.name} for user (ID: {user_item.id})")
77
77
 
78
78
  @api(version="3.3")
79
79
  def add_favorite_metric(self, user_item: UserItem, metric_item: MetricItem) -> None:
80
- url = "{0}/{1}".format(self.baseurl, user_item.id)
80
+ url = f"{self.baseurl}/{user_item.id}"
81
81
  add_req = RequestFactory.Favorite.add_request(metric_item.id, Resource.Metric, metric_item.name)
82
82
  server_response = self.put_request(url, add_req)
83
- logger.info("Favorited metric {0} for user (ID: {1})".format(metric_item.name, user_item.id))
83
+ logger.info(f"Favorited metric {metric_item.name} for user (ID: {user_item.id})")
84
84
 
85
85
  # ------- delete from favorites
86
86
  # Response:
@@ -94,42 +94,42 @@ class Favorites(Endpoint):
94
94
 
95
95
  @api(version="3.15")
96
96
  def delete_favorite(self, user_item: UserItem, content_type: Resource, item: TableauItem) -> None:
97
- url = "{0}/{1}/{2}/{3}".format(self.baseurl, user_item.id, content_type, item.id)
98
- logger.info("Removing favorite {0}({1}) for user (ID: {2})".format(content_type, item.id, user_item.id))
97
+ url = f"{self.baseurl}/{user_item.id}/{content_type}/{item.id}"
98
+ logger.info(f"Removing favorite {content_type}({item.id}) for user (ID: {user_item.id})")
99
99
  self.delete_request(url)
100
100
 
101
101
  @api(version="2.0")
102
102
  def delete_favorite_workbook(self, user_item: UserItem, workbook_item: WorkbookItem) -> None:
103
- url = "{0}/{1}/workbooks/{2}".format(self.baseurl, user_item.id, workbook_item.id)
104
- logger.info("Removing favorite workbook {0} for user (ID: {1})".format(workbook_item.id, user_item.id))
103
+ url = f"{self.baseurl}/{user_item.id}/workbooks/{workbook_item.id}"
104
+ logger.info(f"Removing favorite workbook {workbook_item.id} for user (ID: {user_item.id})")
105
105
  self.delete_request(url)
106
106
 
107
107
  @api(version="2.0")
108
108
  def delete_favorite_view(self, user_item: UserItem, view_item: ViewItem) -> None:
109
- url = "{0}/{1}/views/{2}".format(self.baseurl, user_item.id, view_item.id)
110
- logger.info("Removing favorite view {0} for user (ID: {1})".format(view_item.id, user_item.id))
109
+ url = f"{self.baseurl}/{user_item.id}/views/{view_item.id}"
110
+ logger.info(f"Removing favorite view {view_item.id} for user (ID: {user_item.id})")
111
111
  self.delete_request(url)
112
112
 
113
113
  @api(version="2.3")
114
114
  def delete_favorite_datasource(self, user_item: UserItem, datasource_item: DatasourceItem) -> None:
115
- url = "{0}/{1}/datasources/{2}".format(self.baseurl, user_item.id, datasource_item.id)
116
- logger.info("Removing favorite {0} for user (ID: {1})".format(datasource_item.id, user_item.id))
115
+ url = f"{self.baseurl}/{user_item.id}/datasources/{datasource_item.id}"
116
+ logger.info(f"Removing favorite {datasource_item.id} for user (ID: {user_item.id})")
117
117
  self.delete_request(url)
118
118
 
119
119
  @api(version="3.1")
120
120
  def delete_favorite_project(self, user_item: UserItem, project_item: ProjectItem) -> None:
121
- url = "{0}/{1}/projects/{2}".format(self.baseurl, user_item.id, project_item.id)
122
- logger.info("Removing favorite project {0} for user (ID: {1})".format(project_item.id, user_item.id))
121
+ url = f"{self.baseurl}/{user_item.id}/projects/{project_item.id}"
122
+ logger.info(f"Removing favorite project {project_item.id} for user (ID: {user_item.id})")
123
123
  self.delete_request(url)
124
124
 
125
125
  @api(version="3.3")
126
126
  def delete_favorite_flow(self, user_item: UserItem, flow_item: FlowItem) -> None:
127
- url = "{0}/{1}/flows/{2}".format(self.baseurl, user_item.id, flow_item.id)
128
- logger.info("Removing favorite flow {0} for user (ID: {1})".format(flow_item.id, user_item.id))
127
+ url = f"{self.baseurl}/{user_item.id}/flows/{flow_item.id}"
128
+ logger.info(f"Removing favorite flow {flow_item.id} for user (ID: {user_item.id})")
129
129
  self.delete_request(url)
130
130
 
131
131
  @api(version="3.15")
132
132
  def delete_favorite_metric(self, user_item: UserItem, metric_item: MetricItem) -> None:
133
- url = "{0}/{1}/metrics/{2}".format(self.baseurl, user_item.id, metric_item.id)
134
- logger.info("Removing favorite metric {0} for user (ID: {1})".format(metric_item.id, user_item.id))
133
+ url = f"{self.baseurl}/{user_item.id}/metrics/{metric_item.id}"
134
+ logger.info(f"Removing favorite metric {metric_item.id} for user (ID: {user_item.id})")
135
135
  self.delete_request(url)
@@ -9,11 +9,11 @@ from tableauserverclient.server import RequestFactory
9
9
 
10
10
  class Fileuploads(Endpoint):
11
11
  def __init__(self, parent_srv):
12
- super(Fileuploads, self).__init__(parent_srv)
12
+ super().__init__(parent_srv)
13
13
 
14
14
  @property
15
15
  def baseurl(self):
16
- return "{0}/sites/{1}/fileUploads".format(self.parent_srv.baseurl, self.parent_srv.site_id)
16
+ return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}/fileUploads"
17
17
 
18
18
  @api(version="2.0")
19
19
  def initiate(self):
@@ -21,14 +21,14 @@ class Fileuploads(Endpoint):
21
21
  server_response = self.post_request(url, "")
22
22
  fileupload_item = FileuploadItem.from_response(server_response.content, self.parent_srv.namespace)
23
23
  upload_id = fileupload_item.upload_session_id
24
- logger.info("Initiated file upload session (ID: {0})".format(upload_id))
24
+ logger.info(f"Initiated file upload session (ID: {upload_id})")
25
25
  return upload_id
26
26
 
27
27
  @api(version="2.0")
28
28
  def append(self, upload_id, data, content_type):
29
- url = "{0}/{1}".format(self.baseurl, upload_id)
29
+ url = f"{self.baseurl}/{upload_id}"
30
30
  server_response = self.put_request(url, data, content_type)
31
- logger.info("Uploading a chunk to session (ID: {0})".format(upload_id))
31
+ logger.info(f"Uploading a chunk to session (ID: {upload_id})")
32
32
  return FileuploadItem.from_response(server_response.content, self.parent_srv.namespace)
33
33
 
34
34
  def _read_chunks(self, file):
@@ -52,12 +52,10 @@ class Fileuploads(Endpoint):
52
52
  def upload(self, file):
53
53
  upload_id = self.initiate()
54
54
  for chunk in self._read_chunks(file):
55
- logger.debug("{} processing chunk...".format(datetime.timestamp()))
55
+ logger.debug(f"{datetime.timestamp()} processing chunk...")
56
56
  request, content_type = RequestFactory.Fileupload.chunk_req(chunk)
57
- logger.debug("{} created chunk request".format(datetime.timestamp()))
57
+ logger.debug(f"{datetime.timestamp()} created chunk request")
58
58
  fileupload_item = self.append(upload_id, request, content_type)
59
- logger.info(
60
- "\t{0} Published {1}MB".format(datetime.timestamp(), (fileupload_item.file_size / BYTES_PER_MB))
61
- )
62
- logger.info("File upload finished (ID: {0})".format(upload_id))
59
+ logger.info(f"\t{datetime.timestamp()} Published {(fileupload_item.file_size / BYTES_PER_MB)}MB")
60
+ logger.info(f"File upload finished (ID: {upload_id})")
63
61
  return upload_id
@@ -1,9 +1,9 @@
1
1
  import logging
2
- from typing import List, Optional, Tuple, TYPE_CHECKING
2
+ from typing import Optional, TYPE_CHECKING, Union
3
3
 
4
4
  from tableauserverclient.server.endpoint.endpoint import QuerysetEndpoint, api
5
5
  from tableauserverclient.server.endpoint.exceptions import FlowRunFailedException, FlowRunCancelledException
6
- from tableauserverclient.models import FlowRunItem, PaginationItem
6
+ from tableauserverclient.models import FlowRunItem
7
7
  from tableauserverclient.exponential_backoff import ExponentialBackoffTimer
8
8
 
9
9
  from tableauserverclient.helpers.logging import logger
@@ -16,22 +16,24 @@ if TYPE_CHECKING:
16
16
 
17
17
  class FlowRuns(QuerysetEndpoint[FlowRunItem]):
18
18
  def __init__(self, parent_srv: "Server") -> None:
19
- super(FlowRuns, self).__init__(parent_srv)
19
+ super().__init__(parent_srv)
20
20
  return None
21
21
 
22
22
  @property
23
23
  def baseurl(self) -> str:
24
- return "{0}/sites/{1}/flows/runs".format(self.parent_srv.baseurl, self.parent_srv.site_id)
24
+ return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}/flows/runs"
25
25
 
26
26
  # Get all flows
27
27
  @api(version="3.10")
28
- def get(self, req_options: Optional["RequestOptions"] = None) -> Tuple[List[FlowRunItem], PaginationItem]:
28
+ # QuerysetEndpoint expects a PaginationItem to be returned, but FlowRuns
29
+ # does not return a PaginationItem. Suppressing the mypy error because the
30
+ # changes to the QuerySet class should permit this to function regardless.
31
+ def get(self, req_options: Optional["RequestOptions"] = None) -> list[FlowRunItem]: # type: ignore[override]
29
32
  logger.info("Querying all flow runs on site")
30
33
  url = self.baseurl
31
34
  server_response = self.get_request(url, req_options)
32
- pagination_item = PaginationItem.from_response(server_response.content, self.parent_srv.namespace)
33
35
  all_flow_run_items = FlowRunItem.from_response(server_response.content, self.parent_srv.namespace)
34
- return all_flow_run_items, pagination_item
36
+ return all_flow_run_items
35
37
 
36
38
  # Get 1 flow by id
37
39
  @api(version="3.10")
@@ -39,21 +41,21 @@ class FlowRuns(QuerysetEndpoint[FlowRunItem]):
39
41
  if not flow_run_id:
40
42
  error = "Flow ID undefined."
41
43
  raise ValueError(error)
42
- logger.info("Querying single flow (ID: {0})".format(flow_run_id))
43
- url = "{0}/{1}".format(self.baseurl, flow_run_id)
44
+ logger.info(f"Querying single flow (ID: {flow_run_id})")
45
+ url = f"{self.baseurl}/{flow_run_id}"
44
46
  server_response = self.get_request(url)
45
47
  return FlowRunItem.from_response(server_response.content, self.parent_srv.namespace)[0]
46
48
 
47
49
  # Cancel 1 flow run by id
48
50
  @api(version="3.10")
49
- def cancel(self, flow_run_id: str) -> None:
51
+ def cancel(self, flow_run_id: Union[str, FlowRunItem]) -> None:
50
52
  if not flow_run_id:
51
53
  error = "Flow ID undefined."
52
54
  raise ValueError(error)
53
55
  id_ = getattr(flow_run_id, "id", flow_run_id)
54
- url = "{0}/{1}".format(self.baseurl, id_)
56
+ url = f"{self.baseurl}/{id_}"
55
57
  self.put_request(url)
56
- logger.info("Deleted single flow (ID: {0})".format(id_))
58
+ logger.info(f"Deleted single flow (ID: {id_})")
57
59
 
58
60
  @api(version="3.10")
59
61
  def wait_for_job(self, flow_run_id: str, *, timeout: Optional[int] = None) -> FlowRunItem:
@@ -69,7 +71,7 @@ class FlowRuns(QuerysetEndpoint[FlowRunItem]):
69
71
  flow_run = self.get_by_id(flow_run_id)
70
72
  logger.debug(f"\tFlowRun {flow_run_id} progress={flow_run.progress}")
71
73
 
72
- logger.info("FlowRun {} Completed: Status: {}".format(flow_run_id, flow_run.status))
74
+ logger.info(f"FlowRun {flow_run_id} Completed: Status: {flow_run.status}")
73
75
 
74
76
  if flow_run.status == "Success":
75
77
  return flow_run
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import List, Optional, Tuple, TYPE_CHECKING
2
+ from typing import TYPE_CHECKING
3
3
 
4
4
  from tableauserverclient.server.endpoint.endpoint import Endpoint, api
5
5
  from tableauserverclient.server.endpoint.exceptions import MissingRequiredFieldError
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
15
15
  class FlowTasks(Endpoint):
16
16
  @property
17
17
  def baseurl(self) -> str:
18
- return "{0}/sites/{1}/tasks/flows".format(self.parent_srv.baseurl, self.parent_srv.site_id)
18
+ return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}/tasks/flows"
19
19
 
20
20
  @api(version="3.22")
21
21
  def create(self, flow_item: TaskItem) -> TaskItem: