diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c78b30..8648986 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - Add case for a template resource_type in append_data method in PaginatedChildrenResult model +- Add `Proof` model and `ProofType` enum +- Add a proof field to the `Row` model +- Add serialization tests for the new model ## [4.2.0] - 2026-07-09 diff --git a/docs-source/smartsheet_enums.rst b/docs-source/smartsheet_enums.rst index 6dc5c82..7010a8c 100644 --- a/docs-source/smartsheet_enums.rst +++ b/docs-source/smartsheet_enums.rst @@ -177,6 +177,14 @@ PredecessorType :undoc-members: :show-inheritance: +ProofType +------------------------------------------ + +.. automodule:: smartsheet.models.enums.proof_type + :members: + :undoc-members: + :show-inheritance: + PublishAccessibleBy ------------------------------------------------------ diff --git a/docs-source/smartsheet_models.rst b/docs-source/smartsheet_models.rst index ba2cc8f..d887377 100644 --- a/docs-source/smartsheet_models.rst +++ b/docs-source/smartsheet_models.rst @@ -561,6 +561,14 @@ ProjectSettings :undoc-members: :show-inheritance: +Proof +----- + +.. automodule:: smartsheet.models.proof + :members: + :undoc-members: + :show-inheritance: + Recipient --------- diff --git a/smartsheet/models/__init__.py b/smartsheet/models/__init__.py index 564e175..259ea51 100644 --- a/smartsheet/models/__init__.py +++ b/smartsheet/models/__init__.py @@ -78,6 +78,7 @@ from .predecessor import Predecessor from .predecessor_list import PredecessorList from .project_settings import ProjectSettings +from .proof import Proof from .recipient import Recipient from .create_report_request import CreateReportRequest from .create_report_result import CreateReportResult diff --git a/smartsheet/models/enums/__init__.py b/smartsheet/models/enums/__init__.py index 35a8eb8..bba2815 100644 --- a/smartsheet/models/enums/__init__.py +++ b/smartsheet/models/enums/__init__.py @@ -41,6 +41,7 @@ from .operator import Operator from .paper_type import PaperType from .predecessor_type import PredecessorType +from .proof_type import ProofType from .publish_accessible_by import PublishAccessibleBy from .report_aggregation_type import ReportAggregationType from .report_asset_type import ReportAssetType diff --git a/smartsheet/models/enums/proof_type.py b/smartsheet/models/enums/proof_type.py new file mode 100644 index 0000000..b25ac1e --- /dev/null +++ b/smartsheet/models/enums/proof_type.py @@ -0,0 +1,28 @@ +# pylint: disable=C0111,C0302 +# Smartsheet Python SDK. +# +# Copyright 2016 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 enum import Enum + + +class ProofType(Enum): + DOCUMENT = "DOCUMENT" + IMAGE = "IMAGE" + MIXED = "MIXED" + NONE = "NONE" + VIDEO = "VIDEO" diff --git a/smartsheet/models/proof.py b/smartsheet/models/proof.py new file mode 100644 index 0000000..f89fbff --- /dev/null +++ b/smartsheet/models/proof.py @@ -0,0 +1,174 @@ +# pylint: disable=C0111,R0902,R0904,R0912,R0913,R0915,E1101 +# Smartsheet Python SDK. +# +# Copyright 2016 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 Boolean, EnumeratedValue, Number, String, Timestamp, TypedList, TypedObject, json +from ..util import deserialize, serialize +from .attachment import Attachment +from .discussion import Discussion +from .enums import ProofType +from .user import User + + +class Proof: + + """Smartsheet Proof data model.""" + + def __init__(self, props=None, base_obj=None): + """Initialize the Proof model.""" + self._base = None + if base_obj is not None: + self._base = base_obj + + self._id_ = Number() + self._original_id = Number() + self._name = String() + self._type_ = EnumeratedValue(ProofType) + self._document_type = String() + self._proof_request_url = String() + self._version = Number() + self._last_updated_at = Timestamp() + self._last_updated_by = TypedObject(User) + self._is_completed = Boolean() + self._attachments = TypedList(Attachment) + self._discussions = TypedList(Discussion) + + if props: + deserialize(self, props) + + self.__initialized = True + + def __getattr__(self, key): + if key == "id": + return self.id_ + elif key == "type": + return self.type_ + else: + raise AttributeError(key) + + def __setattr__(self, key, value): + if key == "id": + self.id_ = value + elif key == "type": + self.type_ = value + else: + super().__setattr__(key, value) + + @property + def id_(self): + return self._id_.value + + @id_.setter + def id_(self, value): + self._id_.value = value + + @property + def original_id(self): + return self._original_id.value + + @original_id.setter + def original_id(self, value): + self._original_id.value = value + + @property + def name(self): + return self._name.value + + @name.setter + def name(self, value): + self._name.value = value + + @property + def type_(self): + return self._type_ + + @type_.setter + def type_(self, value): + self._type_.set(value) + + @property + def document_type(self): + return self._document_type.value + + @document_type.setter + def document_type(self, value): + self._document_type.value = value + + @property + def proof_request_url(self): + return self._proof_request_url.value + + @proof_request_url.setter + def proof_request_url(self, value): + self._proof_request_url.value = value + + @property + def version(self): + return self._version.value + + @version.setter + def version(self, value): + self._version.value = value + + @property + def last_updated_at(self): + return self._last_updated_at.value + + @last_updated_at.setter + def last_updated_at(self, value): + self._last_updated_at.value = value + + @property + def last_updated_by(self): + return self._last_updated_by.value + + @last_updated_by.setter + def last_updated_by(self, value): + self._last_updated_by.value = value + @property + def is_completed(self): + return self._is_completed.value + + @is_completed.setter + def is_completed(self, value): + self._is_completed.value = value + + @property + def attachments(self): + return self._attachments + + @attachments.setter + def attachments(self, value): + self._attachments.load(value) + + @property + def discussions(self): + return self._discussions + + @discussions.setter + def discussions(self, value): + self._discussions.load(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/models/row.py b/smartsheet/models/row.py index 2b00215..964dd53 100644 --- a/smartsheet/models/row.py +++ b/smartsheet/models/row.py @@ -27,6 +27,7 @@ from .column import Column from .discussion import Discussion from .enums import AccessLevel +from .proof import Proof from .user import User @@ -62,6 +63,7 @@ def __init__(self, props=None, base_obj=None): self._outdent = Number() self._parent_id = Number() self._permalink = String() + self._proof = TypedObject(Proof) self._row_number = Number() self._sheet_id = Number() self._sibling_id = Number() @@ -268,6 +270,14 @@ def permalink(self): def permalink(self, value): self._permalink.value = value + @property + def proof(self): + return self._proof.value + + @proof.setter + def proof(self, value): + self._proof.value = value + @property def row_number(self): return self._row_number.value diff --git a/smartsheet/reports.py b/smartsheet/reports.py index f1add31..3be704a 100644 --- a/smartsheet/reports.py +++ b/smartsheet/reports.py @@ -143,7 +143,7 @@ def get_report( page (int): Which page to return. include (list[str]): A comma-separated list of optional elements to include in the response. Valid list values: - attachments, discussions, format, objectValue, scope, source, sourceSheets. + attachments, discussions, proofs, format, objectValue, scope, source, sourceSheets. level (int): compatibility level Returns: diff --git a/tests/mock_api/test_mock_serialization.py b/tests/mock_api/test_mock_serialization.py index d86bdc7..6bbdffe 100644 --- a/tests/mock_api/test_mock_serialization.py +++ b/tests/mock_api/test_mock_serialization.py @@ -3,9 +3,10 @@ import pytest from smartsheet.models import ( AlternateEmail, Attachment, Column, Comment, ContainerDestination, CrossSheetReference, - Discussion, ExplicitNull, Favorite, FormatDetails, Group, ImageUrl, MultiRowEmail, Recipient, - Row, Schedule, Sheet, SheetEmail, UpdateRequest, User, Workspace + Discussion, ExplicitNull, Favorite, FormatDetails, Group, ImageUrl, MultiRowEmail, Proof, + Recipient, Row, Schedule, Sheet, SheetEmail, UpdateRequest, User, Workspace ) +from smartsheet.models.enums import ProofType from smartsheet.models.object_value import DURATION from tests.mock_api.mock_api_test_helper import MockApiTestHelper, clean_api_error @@ -532,3 +533,19 @@ def test_cross_sheet_reference_serialization(self): })) assert response.result.name == 'Some Cross Sheet Reference' + + @clean_api_error + def test_proof_serialization(self): + self.client.as_test_scenario('Serialization - Proof') + + row = self.client.Sheets.get_row(1, 2, include=['proofs']) + + assert row.proof.id == 100 + assert row.proof.original_id == 100 + assert row.proof.name == 'Sample Proof Document' + assert row.proof.type.value == ProofType.IMAGE + assert row.proof.document_type == 'NONE' + assert row.proof.proof_request_url == 'https://app.smartsheet.com/b/proofs/sheets/test123/proofs/proof456' + assert row.proof.version == 1 + assert row.proof.last_updated_by.email == 'john.doe@smartsheet.com' + assert row.proof.is_completed is False