diff --git a/tableauserverclient/server/endpoint/datasources_endpoint.py b/tableauserverclient/server/endpoint/datasources_endpoint.py index 0fb5c7dc9..431ede65a 100644 --- a/tableauserverclient/server/endpoint/datasources_endpoint.py +++ b/tableauserverclient/server/endpoint/datasources_endpoint.py @@ -93,6 +93,9 @@ HyperAction = HyperActionTable | HyperActionRow +_UNSET = object() + + class Datasources(QuerysetEndpoint[DatasourceItem], TaggingMixin[DatasourceItem]): def __init__(self, parent_srv: "Server") -> None: super().__init__(parent_srv) @@ -235,6 +238,7 @@ def download( datasource_id: str, filepath: T, include_extract: bool = True, + no_extract: object = ..., ) -> T: ... @overload @@ -243,17 +247,18 @@ def download( datasource_id: str, filepath: FilePath | None = None, include_extract: bool = True, + no_extract: object = ..., ) -> str: ... # Download 1 datasource by id @api(version="2.0") - @parameter_added_in(no_extract="2.5") @parameter_added_in(include_extract="2.5") def download( self, datasource_id, filepath=None, include_extract=True, + no_extract=_UNSET, ): """ Downloads the specified data source from a site. The data source is @@ -274,10 +279,20 @@ def download( If True, the extract is included in the download. If False, the extract is not included. - Returns - ------- - filepath : PathOrFileW + Notes + ----- + The ``no_extract`` parameter is deprecated. Use ``include_extract=False`` + instead. """ + if no_extract is not _UNSET: + import warnings + + warnings.warn( + "no_extract is deprecated and will be removed. Use include_extract=False instead.", + DeprecationWarning, + stacklevel=2, + ) + include_extract = not no_extract return self.download_revision( datasource_id, None, diff --git a/tableauserverclient/server/endpoint/workbooks_endpoint.py b/tableauserverclient/server/endpoint/workbooks_endpoint.py index ce605806f..ec82550c3 100644 --- a/tableauserverclient/server/endpoint/workbooks_endpoint.py +++ b/tableauserverclient/server/endpoint/workbooks_endpoint.py @@ -63,6 +63,9 @@ PathOrFileW = FilePath | FileObjectW +_UNSET = object() + + class Workbooks(QuerysetEndpoint[WorkbookItem], TaggingMixin[WorkbookItem]): def __init__(self, parent_srv: "Server") -> None: super().__init__(parent_srv) @@ -404,6 +407,7 @@ def download( workbook_id: str, filepath: T, include_extract: bool = True, + no_extract: object = ..., ) -> T: ... @overload @@ -412,17 +416,18 @@ def download( workbook_id: str, filepath: FilePath | None = None, include_extract: bool = True, + no_extract: object = ..., ) -> str: ... # Download workbook contents with option of passing in filepath @api(version="2.0") - @parameter_added_in(no_extract="2.5") @parameter_added_in(include_extract="2.5") def download( self, workbook_id, filepath=None, include_extract=True, + no_extract=_UNSET, ): """ Downloads a workbook to the specified directory (optional). @@ -450,8 +455,21 @@ def download( ------ ValueError If the workbook ID is not defined. + + Notes + ----- + The ``no_extract`` parameter is deprecated. Use ``include_extract=False`` + instead. """ + if no_extract is not _UNSET: + import warnings + warnings.warn( + "no_extract is deprecated and will be removed. Use include_extract=False instead.", + DeprecationWarning, + stacklevel=2, + ) + include_extract = not no_extract return self.download_revision( workbook_id, None, diff --git a/test/test_datasource.py b/test/test_datasource.py index cb1157bc5..48b27ec80 100644 --- a/test/test_datasource.py +++ b/test/test_datasource.py @@ -645,6 +645,22 @@ def test_download_extract_only(server) -> None: os.remove(file_path) +def test_download_no_extract_emits_deprecation_warning(server) -> None: + """no_extract=True should emit a DeprecationWarning and map to includeExtract=False.""" + server.version = "2.5" + + with requests_mock.mock() as m: + m.get( + server.datasources.baseurl + "/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/content?includeExtract=False", + headers={"Content-Disposition": 'name="tableau_datasource"; filename="Sample datasource.tds"'}, + complete_qs=True, + ) + with pytest.warns(DeprecationWarning, match="deprecated and will be removed"): + file_path = server.datasources.download("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", no_extract=True) + assert os.path.exists(file_path) + os.remove(file_path) + + def test_update_missing_id(server) -> None: single_datasource = TSC.DatasourceItem("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", "test") with pytest.raises(TSC.MissingRequiredFieldError): diff --git a/test/test_workbook.py b/test/test_workbook.py index c5c4f6662..c68718e28 100644 --- a/test/test_workbook.py +++ b/test/test_workbook.py @@ -340,6 +340,22 @@ def test_download_extract_only(server: TSC.Server) -> None: os.remove(file_path) +def test_download_no_extract_emits_deprecation_warning(server: TSC.Server) -> None: + """no_extract=True should emit a DeprecationWarning and map to includeExtract=False.""" + server.version = "2.5" + + with requests_mock.mock() as m: + m.get( + server.workbooks.baseurl + "/1f951daf-4061-451a-9df1-69a8062664f2/content?includeExtract=False", + headers={"Content-Disposition": 'name="tableau_workbook"; filename="RESTAPISample.twbx"'}, + complete_qs=True, + ) + with pytest.warns(DeprecationWarning, match="deprecated and will be removed"): + file_path = server.workbooks.download("1f951daf-4061-451a-9df1-69a8062664f2", no_extract=True) + assert os.path.exists(file_path) + os.remove(file_path) + + def test_download_missing_id(server: TSC.Server) -> None: with pytest.raises(ValueError): server.workbooks.download("")