Skip to content

Commit 15963c4

Browse files
committed
Merge branch 'development' into bcantoni/1365-monthly-schedule
2 parents 71bcb4f + 4d67996 commit 15963c4

34 files changed

+4329
-3468
lines changed

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
- name: Test with pytest
4949
if: always()
5050
run: |
51-
pytest test
51+
pytest test -n auto
5252
5353
- name: Test build
5454
if: always()

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ dependencies = [
1515
'defusedxml>=0.7.1', # latest as at 7/31/23
1616
'packaging>=23.1', # latest as at 7/31/23
1717
'requests>=2.32', # latest as at 7/31/23
18-
'urllib3>=2.2.2,<3',
18+
'urllib3>=2.6.0,<3',
1919
'typing_extensions>=4.0',
2020
]
2121
requires-python = ">=3.9"
@@ -32,8 +32,8 @@ classifiers = [
3232
repository = "https://github.com/tableau/server-client-python"
3333

3434
[project.optional-dependencies]
35-
test = ["black==24.8", "build", "mypy==1.4", "pytest>=7.0", "pytest-cov", "pytest-subtests",
36-
"requests-mock>=1.0,<2.0", "types-requests>=2.32.4.20250913"]
35+
test = ["black==24.10", "build", "mypy==1.4", "pytest>=7.0", "pytest-cov", "pytest-subtests",
36+
"pytest-xdist", "requests-mock>=1.0,<2.0", "types-requests>=2.32.4.20250913"]
3737
[tool.black]
3838
line-length = 120
3939
target-version = ['py39', 'py310', 'py311', 'py312', 'py313']

tableauserverclient/models/schedule_item.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import xml.etree.ElementTree as ET
22
from datetime import datetime
3-
from typing import Optional, Union
3+
from typing import Optional, Union, TYPE_CHECKING
44

55
from defusedxml.ElementTree import fromstring
66

@@ -16,6 +16,10 @@
1616
property_is_enum,
1717
)
1818

19+
if TYPE_CHECKING:
20+
from requests import Response
21+
22+
1923
Interval = Union[HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval]
2024

2125

@@ -407,3 +411,8 @@ def _read_warnings(parsed_response, ns):
407411
for warning_xml in all_warning_xml:
408412
warnings.append(warning_xml.get("message", None))
409413
return warnings
414+
415+
416+
def parse_batch_schedule_state(response: "Response", ns) -> list[str]:
417+
xml = fromstring(response.content)
418+
return [text for tag in xml.findall(".//t:scheduleLuid", namespaces=ns) if (text := tag.text)]

tableauserverclient/server/endpoint/schedules_endpoint.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
from collections.abc import Iterable
12
import copy
23
import logging
34
import warnings
45
from collections import namedtuple
5-
from typing import TYPE_CHECKING, Callable, Optional, Union
6+
from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Union, overload
67

78
from .endpoint import Endpoint, api, parameter_added_in
89
from .exceptions import MissingRequiredFieldError
910
from tableauserverclient.server import RequestFactory
1011
from tableauserverclient.models import PaginationItem, ScheduleItem, TaskItem, ExtractItem
12+
from tableauserverclient.models.schedule_item import parse_batch_schedule_state
1113

1214
from tableauserverclient.helpers.logging import logger
1315

@@ -279,3 +281,48 @@ def get_extract_refresh_tasks(
279281
extract_items = ExtractItem.from_response(server_response.content, self.parent_srv.namespace)
280282

281283
return extract_items, pagination_item
284+
285+
@overload
286+
def batch_update_state(
287+
self,
288+
schedules: Iterable[ScheduleItem | str],
289+
state: Literal["active", "suspended"],
290+
update_all: Literal[False] = False,
291+
) -> list[str]: ...
292+
293+
@overload
294+
def batch_update_state(
295+
self, schedules: Any, state: Literal["active", "suspended"], update_all: Literal[True]
296+
) -> list[str]: ...
297+
298+
@api(version="3.27")
299+
def batch_update_state(self, schedules, state, update_all=False) -> list[str]:
300+
"""
301+
Batch update the status of one or more scheudles. If update_all is set,
302+
all schedules on the Tableau Server are affected.
303+
304+
Parameters
305+
----------
306+
schedules: Iterable[ScheudleItem | str] | Any
307+
The schedules to be updated. If update_all=True, this is ignored.
308+
309+
state: Literal["active", "suspended"]
310+
The state of the schedules, whether active or suspended.
311+
312+
update_all: bool
313+
Whether or not to apply the status to all schedules.
314+
315+
Returns
316+
-------
317+
List[str]
318+
The IDs of the affected schedules.
319+
"""
320+
params = {"state": state}
321+
if update_all:
322+
params["updateAll"] = "true"
323+
payload = RequestFactory.Empty.empty_req()
324+
else:
325+
payload = RequestFactory.Schedule.batch_update_state(schedules)
326+
327+
response = self.put_request(self.baseurl, payload, parameters={"params": params})
328+
return parse_batch_schedule_state(response, self.parent_srv.namespace)

0 commit comments

Comments
 (0)