Skip to content

Commit

Permalink
Merge 8ae8fed into b709d6b
Browse files Browse the repository at this point in the history
  • Loading branch information
dtrodger committed Aug 11, 2023
2 parents b709d6b + 8ae8fed commit 6791fb8
Show file tree
Hide file tree
Showing 9 changed files with 409 additions and 1 deletion.
55 changes: 55 additions & 0 deletions boxsdk/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from boxsdk.object.group_membership import GroupMembership
from boxsdk.object.enterprise import Enterprise
from boxsdk.object.collection import Collection
from boxsdk.object.sign_template import SignTemplate
from boxsdk.pagination.box_object_collection import BoxObjectCollection


Expand Down Expand Up @@ -1629,3 +1630,57 @@ def get_sign_requests(
fields=fields,
return_full_pages=False,
)

def sign_template(self, sign_template_id: str) -> 'SignTemplate':
"""
Initialize a :class:`SignTemplate` object, whose box id is sign_template_id.
:param sign_template_id:
The box id of the :class:`SignTemplate` object.
:return:
A :class:`SignTemplate` object with the given sign_template_id.
"""
return self.translator.get('sign_template')(session=self._session, object_id=sign_template_id)

@api_call
def get_sign_templates(
self,
limit: Optional[int] = None,
marker: Optional[str] = None,
) -> 'BoxObjectCollection':
"""
Returns all sign templates
:param limit:
The maximum number of entries to return per page. If not specified, then will use the server-side default.
:param marker:
The paging marker to start paging from.
:returns:
Sign templates
"""
return MarkerBasedObjectCollection(
session=self._session,
url=self.get_url("sign_templates"),
limit=limit,
marker=marker,
return_full_pages=False,
)

@api_call
def get_sign_template(
self,
sign_template_id: str,
) -> Any:
"""
Returns a sign template
:param sign_template_id:
ID of Sign template to fetch
:returns:
Sign template
"""
response = self._session.get(f"{self._session.get_url('sign_templates')}/{sign_template_id}")
return self.translator.translate(
session=self._session,
response_object=response.json(),
)
16 changes: 16 additions & 0 deletions boxsdk/object/sign_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import Any

from .base_object import BaseObject


class SignTemplate(BaseObject):
"""
Represents a Sign Template used by Box Sign
"""
_item_type = 'sign-template'

def get_url(self, *args: Any) -> str:
"""
Returns the url for this sign template.
"""
return self._session.get_url('sign_templates', self._object_id, *args)
16 changes: 16 additions & 0 deletions docs/source/boxsdk.object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,14 @@ boxsdk.object.file module
:undoc-members:
:show-inheritance:

boxsdk.object.file\_request module
----------------------------------

.. automodule:: boxsdk.object.file_request
:members:
:undoc-members:
:show-inheritance:

boxsdk.object.file\_version module
----------------------------------

Expand Down Expand Up @@ -300,6 +308,14 @@ boxsdk.object.sign\_request module
:undoc-members:
:show-inheritance:

boxsdk.object.sign\_template module
-----------------------------------

.. automodule:: boxsdk.object.sign_template
:members:
:undoc-members:
:show-inheritance:

boxsdk.object.storage\_policy module
------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/usage/sign_requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Get All Sign Requests
------------------------

Calling the [`client.get_sign_requests()`][get-all-sign-requests]
will return an iterable that will page through all the Sign Requests. This method offers `limit` and `fields` parameters. The `limit` parameter specifies the maximum number of items to be returned in a single response. The `fields` parameter is used to specify what additional properties should be returned on the return object. For more information on what `fields` are available, please refer to the [developer documentation](https://developer.box.com/guides/sign-request/).
will return an iterable that will page through all the Sign Requests. This method offers `limit` and `fields` parameters. The `limit` parameter specifies the maximum number of items to be returned in a single response. The `fields` parameter is used to specify what additional properties should be returned on the return object. For more information on what `fields` are available, please refer to the [developer documentation](https://developer.box.com/guides/box-sign/).

<!-- sample get_sign_requests -->
```python
Expand Down
39 changes: 39 additions & 0 deletions docs/usage/sign_templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Sign Templates
==============

Sign Templates are reusable templates that can be used to create Sign Requests. For now, Sign Templates can only be created through the Box web application.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Get All Sign Templates](#get-all-sign-templates)
- [Get Sign Template by ID](#get-sign-template-by-id)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Get All Sign Templates
----------------------

Calling the [`client.get_sign_templates()`][get-all-sign-templates] method will return an iterable that will page through all the Sign Templates. This method offers `limit` parameter. The `limit` parameter specifies the maximum number of items to be returned in a single response.

<!-- sample get_sign_templates -->
```python
sign_templates = client.get_sign_templates()
for sign_template in sign_templates:
print(f'(Sign Template ID: {sign_template.id})')
```

[get-all-sign-templates]: https://box-python-sdk.readthedocs.io/en/latest/boxsdk.client.html#boxsdk.client.client.Client.get_sign_templates

Get Sign Template by ID
-----------------------

Calling the [`client.get_sign_template(template_id)`][get-sign-template] method will return a Sign Template object.

<!-- sample get_sign_template -->
```python
sign_template = client.get_sign_template('12345')
print(f'(Sign Template ID: {sign_template.id})')
```

[get-sign-template]: https://box-python-sdk.readthedocs.io/en/latest/boxsdk.client.html#boxsdk.client.client.Client.get_sign_template
8 changes: 8 additions & 0 deletions test/integration_new/object/sign_template_itest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from boxsdk.pagination.box_object_collection import BoxObjectCollection

from test.integration_new import CLIENT


def test_get_sign_templates():
sign_templates = CLIENT.get_sign_templates()
assert isinstance(sign_templates, BoxObjectCollection)
150 changes: 150 additions & 0 deletions test/unit/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from boxsdk.object.legal_hold_policy_assignment import LegalHoldPolicyAssignment
from boxsdk.object.metadata_cascade_policy import MetadataCascadePolicy
from boxsdk.object.sign_request import SignRequest
from boxsdk.object.sign_template import SignTemplate
from boxsdk.object.task import Task
from boxsdk.object.task_assignment import TaskAssignment
from boxsdk.object.webhook import Webhook
Expand Down Expand Up @@ -1663,6 +1664,105 @@ def mock_sign_request_response():
return mock_sign_request


@pytest.fixture(scope='module')
def mock_sign_template_response():
mock_sign_template = {
"id": "93153068-5420-467b-b8ef-8e54bfb7be42",
"type": "sign-template",
"name": "important-file.pdf",
"email_message": "Please sign this document.\n\nKind regards",
"email_subject": "Box User (boxuser@box.com) has requested your signature on a document",
"parent_folder": {
"id": "123456789",
"etag": "0",
"type": "folder",
"sequence_id": "0",
"name": "My Sign Requests"
},
"auto_expire_days": "null",
"source_files": [
{
"id": "123456",
"etag": "0",
"type": "file",
"sequence_id": "0",
"sha1": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"file_version": {
"id": "123456",
"type": "file_version",
"sha1": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
],
"are_email_settings_locked": "false",
"are_fields_locked": "false",
"are_files_locked": "false",
"are_options_locked": "false",
"are_recipients_locked": "false",
"signers": [
{
"email": "",
"label": "",
"public_id": "AAQXQXJZ4",
"role": "final_copy_reader",
"is_in_person": "false",
"order": 1,
"inputs": []
},
{
"email": "",
"label": "",
"public_id": "13XQXJZ4",
"role": "signer",
"is_in_person": "false",
"order": 1,
"inputs": [
{
"document_tag_id": None,
"id": "0260f921-3b52-477f-ae74-0b0b0b0b0b0b",
"type": "signature",
"text_value": None,
"is_required": True,
"coordinates": {
"x": 0.27038464059712,
"y": 0.10051756244533624
},
"dimensions": {
"width": 0.23570031566618235,
"height": 0.04781003891921971
},
"date_value": None,
"page_index": 0,
"checkbox_value": None,
"document_id": "2fdf9003-d798-40ee-be7f-0b0b0b0b0b0b",
"content_type": "signature",
"dropdown_choices": None,
"group_id": None,
"label": None
}
]
}
],
"ready_sign_link": None,
"custom_branding": None,
"days_valid": 0,
"additional_info": {
"non_editable": [],
"required": {
"signers": [
[
"email"
],
[
"email"
]
]
}
}
}
return mock_sign_template


def test_get_sign_requests(mock_client, mock_box_session, mock_sign_request_response):
expected_url = f'{API.BASE_API_URL}/sign_requests'

Expand Down Expand Up @@ -1750,3 +1850,53 @@ def test_file_request(mock_client):

assert isinstance(file_request, FileRequest)
assert file_request.object_id == file_request_id


def test_get_sign_templates_from_id(mock_client, mock_box_session, mock_sign_template_response):
test_sign_template_id = '93153068-5420-467b-b8ef-8e54bfb7be42'
expected_url = f'{API.BASE_API_URL}/sign_templates/{test_sign_template_id}'
mock_box_session.get.return_value.json.return_value = mock_sign_template_response

sign_template = mock_client.sign_template(test_sign_template_id).get()

mock_box_session.get.assert_called_once_with(expected_url, headers=None, params=None)

assert isinstance(sign_template, SignTemplate)
assert sign_template.id == '93153068-5420-467b-b8ef-8e54bfb7be42'


def test_get_sign_template(mock_client, mock_box_session, mock_sign_template_response):
test_sign_template_id = '93153068-5420-467b-b8ef-8e54bfb7be42'
expected_url = f'{API.BASE_API_URL}/sign_templates/{test_sign_template_id}'
mock_box_session.get.return_value.json.return_value = mock_sign_template_response

sign_template = mock_client.get_sign_template(test_sign_template_id)

mock_box_session.get.assert_called_once_with(expected_url)

assert isinstance(sign_template, SignTemplate)
assert sign_template.id == '93153068-5420-467b-b8ef-8e54bfb7be42'
assert sign_template.name == 'important-file.pdf'
assert sign_template.email_message == 'Please sign this document.\n\nKind regards'


def test_get_sign_templates(mock_client, mock_box_session, mock_sign_template_response):
expected_url = f'{API.BASE_API_URL}/sign_templates'

mock_sign_template = mock_sign_template_response
mock_box_session.get.return_value.json.return_value = {
'total_count': 1,
'limit': 100,
'entries': [mock_sign_template],
'next_marker': None,
'previous_marker': None,
}

sign_templates = mock_client.get_sign_templates()

sign_template = sign_templates.next()

mock_box_session.get.assert_called_once_with(expected_url, params={})
assert isinstance(sign_template, SignTemplate)
assert sign_template.id == '93153068-5420-467b-b8ef-8e54bfb7be42'
assert sign_template.name == 'important-file.pdf'
6 changes: 6 additions & 0 deletions test/unit/object/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from boxsdk.object.retention_policy_assignment import RetentionPolicyAssignment
from boxsdk.object.search import Search
from boxsdk.object.sign_request import SignRequest
from boxsdk.object.sign_template import SignTemplate
from boxsdk.object.storage_policy import StoragePolicy
from boxsdk.object.storage_policy_assignment import StoragePolicyAssignment
from boxsdk.object.terms_of_service import TermsOfService
Expand Down Expand Up @@ -420,3 +421,8 @@ def test_sign_request(mock_box_session, mock_object_id):
@pytest.fixture()
def test_file_request(mock_box_session, mock_object_id):
return FileRequest(mock_box_session, mock_object_id)


@pytest.fixture()
def test_sign_template(mock_box_session, mock_object_id):
return SignTemplate(mock_box_session, mock_object_id)

0 comments on commit 6791fb8

Please sign in to comment.