From f5398a1b21fe2e5d7742a1f8ce040c656af1ff84 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 10:12:50 +0000 Subject: [PATCH 01/11] feat: add support for add and remove report scope --- CHANGELOG.md | 7 ++ smartsheet/models/enums/report_asset_type.py | 22 +++++ smartsheet/models/report_scope_inclusion.py | 65 +++++++++++++ smartsheet/reports.py | 45 +++++++++ smartsheet/util.py | 1 - .../mock_api/reports/common_test_constants.py | 5 + .../mock_api/reports/test_add_report_scope.py | 97 +++++++++++++++++++ .../reports/test_remove_report_scope.py | 97 +++++++++++++++++++ 8 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 smartsheet/models/enums/report_asset_type.py create mode 100644 smartsheet/models/report_scope_inclusion.py create mode 100644 tests/mock_api/reports/common_test_constants.py create mode 100644 tests/mock_api/reports/test_add_report_scope.py create mode 100644 tests/mock_api/reports/test_remove_report_scope.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 74b8c9c..d1fc4c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [x.x.x] - Unreleased +### Added + +- Support for POST /2.0/reports/{reportId}/scope endpoint +- Support for DELETE /2.0/reports/{ReportId}/scope endpoint +- Added wiremock integration tests for POST /2.0/reports/{reportId}/scope endpoint +- Added wiremock integration tests for DELETE /2.0/reports/{reportId}/scope endpoint + ## [3.7.2] - 2026-01-29 ### Added diff --git a/smartsheet/models/enums/report_asset_type.py b/smartsheet/models/enums/report_asset_type.py new file mode 100644 index 0000000..ffc7d79 --- /dev/null +++ b/smartsheet/models/enums/report_asset_type.py @@ -0,0 +1,22 @@ +# pylint: disable=C0111,R0902,R0904,R0912,R0913,R0915,E1101 +# Smartsheet Python SDK. +# +# Copyright 2018 Smartsheet.com, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"): you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from enum import Enum + + +class ReportAssetType(str, Enum): + SHEET = 'SHEET' + WORKSPACE = 'WORKSPACE' \ No newline at end of file diff --git a/smartsheet/models/report_scope_inclusion.py b/smartsheet/models/report_scope_inclusion.py new file mode 100644 index 0000000..add6d59 --- /dev/null +++ b/smartsheet/models/report_scope_inclusion.py @@ -0,0 +1,65 @@ +# pylint: disable=C0111,R0902,R0904,R0912,R0913,R0915,E1101 +# Smartsheet Python SDK. +# +# Copyright 2018 Smartsheet.com, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"): you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from __future__ import absolute_import + +from ..types import EnumeratedValue, Number, json +from ..util import deserialize, serialize + +from smartsheet.models.enums.report_asset_type import ReportAssetType + +class ReportScopeInclusion: + + """Smartsheet ReportScopeInclusion data model.""" + + def __init__(self, props=None, base_obj=None): + """Initialize the ReportScopeInclusion model.""" + self._base = None + if base_obj is not None: + self._base = base_obj + + self._asset_type = EnumeratedValue(ReportAssetType) + self._asset_id = Number() + + if props: + deserialize(self, props) + + @property + def asset_id(self): + return self._asset_id.value + + @asset_id.setter + def asset_id(self, value): + self._asset_id.value = value + + @property + def asset_type(self): + return self._asset_type + + @asset_type.setter + def asset_type(self, value): + self._asset_type.set(value) + + def to_dict(self): + return serialize(self) + + def to_json(self): + return json.dumps(self.to_dict()) + + def __str__(self): + return self.to_json() + diff --git a/smartsheet/reports.py b/smartsheet/reports.py index 09513d6..518999c 100644 --- a/smartsheet/reports.py +++ b/smartsheet/reports.py @@ -17,6 +17,7 @@ from __future__ import absolute_import +import json from typing import Union import logging @@ -383,3 +384,47 @@ def set_publish_status(self, report_id, report_publish_obj) -> Union[Result[Repo response = self._base.request(prepped_request, expected, _op) return response + + def add_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: + """Add one or more scopes to the report. + + Args: + report_id (int): Report ID + scopes (list[ReportScopeInclusion]): List of scopes to add. + + Returns: + Union[Result[None], Error]: The result of the operation, or an Error object if the request fails. + """ + _op = fresh_operation("add_report_scope") + _op["method"] = "POST" + _op["path"] = "/reports/" + str(report_id) + "/scope" + _op["json"] = json.dumps([ob.to_dict() for ob in scopes]) + + expected = ["Result", None] + + prepped_request = self._base.prepare_request(_op) + response = self._base.request(prepped_request, expected, _op) + + return response + + def remove_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: + """Remove one or more scopes to the report. + + Args: + report_id (int): Report ID + scopes (list[ReportScopeInclusion]): List of scopes to remove. + + Returns: + Union[Result[None], Error]: The result of the operation, or an Error object if the request fails. + """ + _op = fresh_operation("remove_report_scope") + _op["method"] = "DELETE" + _op["path"] = "/reports/" + str(report_id) + "/scope" + _op["json"] = json.dumps([ob.to_dict() for ob in scopes]) + + expected = ["Result", None] + + prepped_request = self._base.prepare_request(_op) + response = self._base.request(prepped_request, expected, _op) + + return response diff --git a/smartsheet/util.py b/smartsheet/util.py index dfb7723..bc8c985 100644 --- a/smartsheet/util.py +++ b/smartsheet/util.py @@ -168,7 +168,6 @@ def deserialize(obj, props): key_ = _camel_to_underscore(key) if hasattr(obj, key_): setattr(obj, key_, value) - else: _log.debug( "object '%s' is missing property '%s'", obj.__class__.__name__, key_ diff --git a/tests/mock_api/reports/common_test_constants.py b/tests/mock_api/reports/common_test_constants.py new file mode 100644 index 0000000..7f0129c --- /dev/null +++ b/tests/mock_api/reports/common_test_constants.py @@ -0,0 +1,5 @@ +TEST_SUCCESS_MESSAGE = "SUCCESS" +TEST_RESULT_CODE = 0 +TEST_SHEET_ID = 9876543210 +TEST_WORKSPACE_ID = 1122334455 +TEST_REPORT_ID = 2233445566 diff --git a/tests/mock_api/reports/test_add_report_scope.py b/tests/mock_api/reports/test_add_report_scope.py new file mode 100644 index 0000000..d2d5d68 --- /dev/null +++ b/tests/mock_api/reports/test_add_report_scope.py @@ -0,0 +1,97 @@ +import json +import uuid +from urllib.parse import urlparse + +from smartsheet.models import Error +from smartsheet.models.enums.report_asset_type import ReportAssetType +from smartsheet.models.report_scope_inclusion import ReportScopeInclusion +from tests.mock_api.reports.common_test_constants import TEST_REPORT_ID, TEST_SHEET_ID, TEST_SUCCESS_MESSAGE, TEST_RESULT_CODE +from tests.mock_api.mock_api_test_helper import ( + get_mock_api_client, + get_wiremock_request, +) + + +def test_add_report_scope_generated_url_is_correct(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/reports/add-report-scope/all-response-body-properties", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + client.Reports.add_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + wiremock_request = get_wiremock_request(request_id) + url = urlparse(wiremock_request["absoluteUrl"]) + assert url.path == f'/2.0/reports/{TEST_REPORT_ID}/scope' + assert wiremock_request["method"] == "POST" + +def test_add_report_scope_all_response_properties(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/reports/add-report-scope/all-response-body-properties", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + response = client.Reports.add_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + assert response.message == TEST_SUCCESS_MESSAGE + assert response.result_code == TEST_RESULT_CODE + + wiremock_request = get_wiremock_request(request_id) + body = json.loads(wiremock_request["body"]) + assert body == '[{"assetId": ' + str(TEST_SHEET_ID) + ', "assetType": "SHEET"}]' + + + +def test_add_report_scope_error_4xx(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/errors/400-response", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + response = client.Reports.add_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + assert isinstance(response, Error) + + +def test_add_report_scope_error_5xx(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/errors/500-response", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + response = client.Reports.add_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + assert isinstance(response, Error) + diff --git a/tests/mock_api/reports/test_remove_report_scope.py b/tests/mock_api/reports/test_remove_report_scope.py new file mode 100644 index 0000000..068089f --- /dev/null +++ b/tests/mock_api/reports/test_remove_report_scope.py @@ -0,0 +1,97 @@ +import json +import uuid +from urllib.parse import urlparse + +from smartsheet.models import Error +from smartsheet.models.enums.report_asset_type import ReportAssetType +from smartsheet.models.report_scope_inclusion import ReportScopeInclusion +from tests.mock_api.reports.common_test_constants import TEST_REPORT_ID, TEST_SHEET_ID, TEST_SUCCESS_MESSAGE, TEST_RESULT_CODE +from tests.mock_api.mock_api_test_helper import ( + get_mock_api_client, + get_wiremock_request, +) + + +def test_remove_report_scope_generated_url_is_correct(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/reports/remove-report-scope/all-response-body-properties", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + client.Reports.remove_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + wiremock_request = get_wiremock_request(request_id) + url = urlparse(wiremock_request["absoluteUrl"]) + assert url.path == f'/2.0/reports/{TEST_REPORT_ID}/scope' + assert wiremock_request["method"] == "DELETE" + +def test_remove_report_scope_all_response_properties(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/reports/remove-report-scope/all-response-body-properties", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + response = client.Reports.remove_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + assert response.message == TEST_SUCCESS_MESSAGE + assert response.result_code == TEST_RESULT_CODE + + wiremock_request = get_wiremock_request(request_id) + body = json.loads(wiremock_request["body"]) + assert body == '[{"assetId": ' + str(TEST_SHEET_ID) + ', "assetType": "SHEET"}]' + + + +def test_remove_report_scope_error_4xx(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/errors/400-response", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + response = client.Reports.remove_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + assert isinstance(response, Error) + + +def test_remove_report_scope_error_5xx(): + request_id = uuid.uuid4().hex + client = get_mock_api_client( + "/errors/500-response", request_id + ) + + scopes = [ReportScopeInclusion({ + "assetId": TEST_SHEET_ID, "assetType": ReportAssetType.SHEET + } + )] + + response = client.Reports.remove_report_scope( + report_id=TEST_REPORT_ID, + scopes=scopes + ) + + assert isinstance(response, Error) + From 5be666bd23a3f7d0efa2cb92f0550b99ef4dddb7 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 10:28:30 +0000 Subject: [PATCH 02/11] feat: add support for add and remove report scope fix linting issues --- smartsheet/models/enums/report_asset_type.py | 2 +- smartsheet/models/report_scope_inclusion.py | 5 ++--- smartsheet/reports.py | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/smartsheet/models/enums/report_asset_type.py b/smartsheet/models/enums/report_asset_type.py index ffc7d79..b682b99 100644 --- a/smartsheet/models/enums/report_asset_type.py +++ b/smartsheet/models/enums/report_asset_type.py @@ -19,4 +19,4 @@ class ReportAssetType(str, Enum): SHEET = 'SHEET' - WORKSPACE = 'WORKSPACE' \ No newline at end of file + WORKSPACE = 'WORKSPACE' diff --git a/smartsheet/models/report_scope_inclusion.py b/smartsheet/models/report_scope_inclusion.py index add6d59..272444f 100644 --- a/smartsheet/models/report_scope_inclusion.py +++ b/smartsheet/models/report_scope_inclusion.py @@ -17,11 +17,11 @@ from __future__ import absolute_import +from smartsheet.models.enums.report_asset_type import ReportAssetType + from ..types import EnumeratedValue, Number, json from ..util import deserialize, serialize -from smartsheet.models.enums.report_asset_type import ReportAssetType - class ReportScopeInclusion: """Smartsheet ReportScopeInclusion data model.""" @@ -62,4 +62,3 @@ def to_json(self): def __str__(self): return self.to_json() - diff --git a/smartsheet/reports.py b/smartsheet/reports.py index 518999c..e30487e 100644 --- a/smartsheet/reports.py +++ b/smartsheet/reports.py @@ -384,7 +384,7 @@ def set_publish_status(self, report_id, report_publish_obj) -> Union[Result[Repo response = self._base.request(prepped_request, expected, _op) return response - + def add_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: """Add one or more scopes to the report. @@ -406,7 +406,7 @@ def add_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: response = self._base.request(prepped_request, expected, _op) return response - + def remove_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: """Remove one or more scopes to the report. From 7a3b6b7e43d7814082e1d1b8ac1d22815b578afd Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 10:51:00 +0000 Subject: [PATCH 03/11] feat: add support for add and remove report scope fix double marshalling issue --- smartsheet/reports.py | 6 +++--- tests/mock_api/reports/test_add_report_scope.py | 2 +- tests/mock_api/reports/test_remove_report_scope.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/smartsheet/reports.py b/smartsheet/reports.py index e30487e..207c959 100644 --- a/smartsheet/reports.py +++ b/smartsheet/reports.py @@ -398,7 +398,7 @@ def add_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: _op = fresh_operation("add_report_scope") _op["method"] = "POST" _op["path"] = "/reports/" + str(report_id) + "/scope" - _op["json"] = json.dumps([ob.to_dict() for ob in scopes]) + _op["json"] = scopes expected = ["Result", None] @@ -408,7 +408,7 @@ def add_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: return response def remove_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: - """Remove one or more scopes to the report. + """Remove one or more scopes from the report. Args: report_id (int): Report ID @@ -420,7 +420,7 @@ def remove_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: _op = fresh_operation("remove_report_scope") _op["method"] = "DELETE" _op["path"] = "/reports/" + str(report_id) + "/scope" - _op["json"] = json.dumps([ob.to_dict() for ob in scopes]) + _op["json"] = scopes expected = ["Result", None] diff --git a/tests/mock_api/reports/test_add_report_scope.py b/tests/mock_api/reports/test_add_report_scope.py index d2d5d68..9ce1e1d 100644 --- a/tests/mock_api/reports/test_add_report_scope.py +++ b/tests/mock_api/reports/test_add_report_scope.py @@ -54,7 +54,7 @@ def test_add_report_scope_all_response_properties(): wiremock_request = get_wiremock_request(request_id) body = json.loads(wiremock_request["body"]) - assert body == '[{"assetId": ' + str(TEST_SHEET_ID) + ', "assetType": "SHEET"}]' + assert body == [{"assetId": TEST_SHEET_ID, "assetType": "SHEET"}] diff --git a/tests/mock_api/reports/test_remove_report_scope.py b/tests/mock_api/reports/test_remove_report_scope.py index 068089f..2c10e81 100644 --- a/tests/mock_api/reports/test_remove_report_scope.py +++ b/tests/mock_api/reports/test_remove_report_scope.py @@ -54,7 +54,7 @@ def test_remove_report_scope_all_response_properties(): wiremock_request = get_wiremock_request(request_id) body = json.loads(wiremock_request["body"]) - assert body == '[{"assetId": ' + str(TEST_SHEET_ID) + ', "assetType": "SHEET"}]' + assert body == [{"assetId": TEST_SHEET_ID, "assetType": "SHEET"}] From 4145bbb3cef724410d40af84605122be38fde0ad Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 11:24:41 +0000 Subject: [PATCH 04/11] feat: add support for add and remove report scope update documentation --- docs-source/smartsheet_enums.rst | 8 ++++++++ docs-source/smartsheet_models.rst | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/docs-source/smartsheet_enums.rst b/docs-source/smartsheet_enums.rst index 20cb4d1..98e7ab1 100644 --- a/docs-source/smartsheet_enums.rst +++ b/docs-source/smartsheet_enums.rst @@ -185,6 +185,14 @@ PublishAccessibleBy :undoc-members: :show-inheritance: +ReportAssetType +------------------------------------------------------ + +.. automodule:: smartsheet.models.enums.report_asset_type + :members: + :undoc-members: + :show-inheritance: + ScheduleType --------------------------------------------- diff --git a/docs-source/smartsheet_models.rst b/docs-source/smartsheet_models.rst index 30de3cc..b91934b 100644 --- a/docs-source/smartsheet_models.rst +++ b/docs-source/smartsheet_models.rst @@ -569,6 +569,14 @@ ReportColumn :undoc-members: :show-inheritance: +ReportScopeInclusion +------------ + +.. automodule:: smartsheet.models.report + :members: + :undoc-members: + :show-inheritance: + ReportPublish ------------- From c42e77cdaa8e46c3273b97b32f7e86b9040a99c7 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 11:41:34 +0000 Subject: [PATCH 05/11] feat: add support for add and remove report scope update documentation --- docs-source/smartsheet_models.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-source/smartsheet_models.rst b/docs-source/smartsheet_models.rst index b91934b..e874d17 100644 --- a/docs-source/smartsheet_models.rst +++ b/docs-source/smartsheet_models.rst @@ -572,7 +572,7 @@ ReportColumn ReportScopeInclusion ------------ -.. automodule:: smartsheet.models.report +.. automodule:: smartsheet.models.report_scope_inclusion :members: :undoc-members: :show-inheritance: From cf38ef69dac79f4827fec34670d4e7e641b09c59 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 12:28:43 +0000 Subject: [PATCH 06/11] feat: add support for add and remove report scope remove unused import --- smartsheet/reports.py | 1 - 1 file changed, 1 deletion(-) diff --git a/smartsheet/reports.py b/smartsheet/reports.py index 207c959..3c0723e 100644 --- a/smartsheet/reports.py +++ b/smartsheet/reports.py @@ -17,7 +17,6 @@ from __future__ import absolute_import -import json from typing import Union import logging From e5a572b90842c72be5ef759d9f6cee7384098fb6 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 12:36:20 +0000 Subject: [PATCH 07/11] feat: add support for add and remove report scope keep imports consistent --- smartsheet/models/__init__.py | 1 + smartsheet/models/enums/__init__.py | 1 + 2 files changed, 2 insertions(+) diff --git a/smartsheet/models/__init__.py b/smartsheet/models/__init__.py index 2df18ec..8879e94 100644 --- a/smartsheet/models/__init__.py +++ b/smartsheet/models/__init__.py @@ -82,6 +82,7 @@ from .report import Report from .report_cell import ReportCell from .report_column import ReportColumn +from .report_scope_inclusion import ReportScopeInclusion from .report_publish import ReportPublish from .report_row import ReportRow from .result import Result diff --git a/smartsheet/models/enums/__init__.py b/smartsheet/models/enums/__init__.py index ec5e4b9..4b2b006 100644 --- a/smartsheet/models/enums/__init__.py +++ b/smartsheet/models/enums/__init__.py @@ -41,6 +41,7 @@ from .paper_type import PaperType from .predecessor_type import PredecessorType from .publish_accessible_by import PublishAccessibleBy +from .report_asset_type import ReportAssetType from .schedule_type import ScheduleType from .share_scope import ShareScope from .share_type import ShareType From 11c23129b84e01d452b524403eae91387803de01 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Tue, 10 Feb 2026 12:50:16 +0000 Subject: [PATCH 08/11] feat: add support for add and remove report scope fix imports order --- smartsheet/models/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartsheet/models/__init__.py b/smartsheet/models/__init__.py index 8879e94..2b44975 100644 --- a/smartsheet/models/__init__.py +++ b/smartsheet/models/__init__.py @@ -82,9 +82,9 @@ from .report import Report from .report_cell import ReportCell from .report_column import ReportColumn -from .report_scope_inclusion import ReportScopeInclusion from .report_publish import ReportPublish from .report_row import ReportRow +from .report_scope_inclusion import ReportScopeInclusion from .result import Result from .row import Row from .row_email import RowEmail From 0811911f0513bdfea7aba4c4815eac0ed01b0f74 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Wed, 11 Feb 2026 13:26:44 +0000 Subject: [PATCH 09/11] feat: add support for add and remove report scope Added type definitions --- smartsheet/models/report_scope_inclusion.py | 16 ++++++++-------- smartsheet/reports.py | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/smartsheet/models/report_scope_inclusion.py b/smartsheet/models/report_scope_inclusion.py index 272444f..9412598 100644 --- a/smartsheet/models/report_scope_inclusion.py +++ b/smartsheet/models/report_scope_inclusion.py @@ -39,26 +39,26 @@ def __init__(self, props=None, base_obj=None): deserialize(self, props) @property - def asset_id(self): + def asset_id(self) -> Number: return self._asset_id.value @asset_id.setter - def asset_id(self, value): + def asset_id(self, value: Number): self._asset_id.value = value @property - def asset_type(self): - return self._asset_type + def asset_type(self) -> ReportAssetType: + return self._asset_type.value @asset_type.setter - def asset_type(self, value): + def asset_type(self, value: ReportAssetType): self._asset_type.set(value) - def to_dict(self): + def to_dict(self) -> dict: return serialize(self) - def to_json(self): + def to_json(self ) -> str: return json.dumps(self.to_dict()) - def __str__(self): + def __str__(self) -> str: return self.to_json() diff --git a/smartsheet/reports.py b/smartsheet/reports.py index 3c0723e..ed021a4 100644 --- a/smartsheet/reports.py +++ b/smartsheet/reports.py @@ -23,6 +23,8 @@ import os.path from datetime import datetime +from smartsheet.models.report_scope_inclusion import ReportScopeInclusion + from .util import fresh_operation from .models import Error, DownloadedFile, IndexResult, Report, ReportPublish, Result, Share @@ -384,7 +386,7 @@ def set_publish_status(self, report_id, report_publish_obj) -> Union[Result[Repo return response - def add_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: + def add_report_scope(self, report_id: int, scopes: list[ReportScopeInclusion]) -> Union[Result[None], Error]: """Add one or more scopes to the report. Args: @@ -406,7 +408,7 @@ def add_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: return response - def remove_report_scope(self, report_id, scopes) -> Union[Result[None], Error]: + def remove_report_scope(self, report_id: int, scopes: list[ReportScopeInclusion]) -> Union[Result[None], Error]: """Remove one or more scopes from the report. Args: From dc215520786e4f1dc29ab3f8db005cd9e67aef48 Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Wed, 11 Feb 2026 13:40:55 +0000 Subject: [PATCH 10/11] feat: add support for add and remove report scope Added type definitions --- smartsheet/models/report_scope_inclusion.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/smartsheet/models/report_scope_inclusion.py b/smartsheet/models/report_scope_inclusion.py index 9412598..b305dd5 100644 --- a/smartsheet/models/report_scope_inclusion.py +++ b/smartsheet/models/report_scope_inclusion.py @@ -39,16 +39,16 @@ def __init__(self, props=None, base_obj=None): deserialize(self, props) @property - def asset_id(self) -> Number: + def asset_id(self) -> int: return self._asset_id.value @asset_id.setter - def asset_id(self, value: Number): + def asset_id(self, value: int): self._asset_id.value = value - + @property def asset_type(self) -> ReportAssetType: - return self._asset_type.value + return self._asset_type @asset_type.setter def asset_type(self, value: ReportAssetType): From f1f5f6934796c1086174844ee01558fa7775904b Mon Sep 17 00:00:00 2001 From: Scott McGowan Date: Wed, 11 Feb 2026 13:43:30 +0000 Subject: [PATCH 11/11] feat: add support for add and remove report scope remove tailing whitespace --- smartsheet/models/report_scope_inclusion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smartsheet/models/report_scope_inclusion.py b/smartsheet/models/report_scope_inclusion.py index b305dd5..3a6cb7a 100644 --- a/smartsheet/models/report_scope_inclusion.py +++ b/smartsheet/models/report_scope_inclusion.py @@ -45,7 +45,7 @@ def asset_id(self) -> int: @asset_id.setter def asset_id(self, value: int): self._asset_id.value = value - + @property def asset_type(self) -> ReportAssetType: return self._asset_type @@ -57,7 +57,7 @@ def asset_type(self, value: ReportAssetType): def to_dict(self) -> dict: return serialize(self) - def to_json(self ) -> str: + def to_json(self) -> str: return json.dumps(self.to_dict()) def __str__(self) -> str: