Repository: box/box-python-sdk
Pull request #325 (2018-08-20 22:56:38)

Watermaking v2

boxcla: Hi @carycheng, thanks for the pull request. Before we can merge it, we need you to sign our Contributor License Agreement. You can do so electronically here: http://opensource.box.com/cla

Once you have signed, just add a comment to this pull request saying, "CLA signed". Thanks!

Patch:
diff --git a/boxsdk/object/__init__.py b/boxsdk/object/__init__.py
index 1e213c6..f680836 100644
--- a/boxsdk/object/__init__.py
+++ b/boxsdk/object/__init__.py
@@ -22,5 +22,6 @@
     'recent_item',
     'search',
     'user',
+    'watermark',
     'web_link',
 ]))
diff --git a/boxsdk/object/item.py b/boxsdk/object/item.py
index 7c8268e..fec3bcc 100644
--- a/boxsdk/object/item.py
+++ b/boxsdk/object/item.py
@@ -358,6 +358,52 @@ def metadata(self, scope='global', template='properties'):
         """
         return Metadata(self._session, self, scope, template)
 
+    def get_watermark(self):
+        """
+        Return the watermark info for a Box file
+
+        :return:
+            Watermark object.
+        :rtype:
+            :class:`Watermark`
+        """
+        url = self.get_url('watermark')
+        box_response = self._session.get(url)
+        response = box_response.json()
+        return self.translator.translate('watermark')(response['watermark'])
+
+    def apply_watermark(self):
+        """
+        Apply watermark on a Box file
+
+        :return:
+            Watermark object.
+        :rtype:
+            :class:`Watermark`
+        """
+        url = self.get_url('watermark')
+        body_attributes = {
+            'watermark': {
+                'imprint': 'default'
+            }
+        }
+        box_response = self._session.put(url, data=json.dumps(body_attributes))
+        response = box_response.json()
+        return self.translator.translate('watermark')(response['watermark'])
+
+    def delete_watermark(self):
+        """
+        Deletes the watermark info for a Box file
+
+        :return:
+            Whether or not the delete succeeded.
+        :rtype:
+            `bool`
+        """
+        url = self.get_url('watermark')
+        box_response = self._session.delete(url, expect_json_response=False)
+        return box_response.ok
+
     @api_call
     def add_to_collection(self, collection):
         """
diff --git a/boxsdk/object/watermark.py b/boxsdk/object/watermark.py
new file mode 100644
index 0000000..17daba0
--- /dev/null
+++ b/boxsdk/object/watermark.py
@@ -0,0 +1,11 @@
+# coding: utf-8
+from __future__ import unicode_literals
+
+
+from .api_json_object import APIJSONObject
+
+
+class Watermark(APIJSONObject):
+    """Box API endpoint for applying watermark in a Box account."""
+
+    _item_type = 'watermark'
diff --git a/docs/watermarking.md b/docs/watermarking.md
new file mode 100644
index 0000000..dd141ef
--- /dev/null
+++ b/docs/watermarking.md
@@ -0,0 +1,54 @@
+Watermarking
+============
+
+The ability to watermark files and folders is represented as a sub-resource on the Files and Folders resources, respectively. You can think of the sub-resource as a "label" marking whether the file or folder is watermarked or not. If you apply a watermark label to a folder, then all files inside of it will be protected by the watermark (e.g. previews will be watermarked). However, those files' watermark sub-resource is independent from the folder that got watermarked. This allows you to watermark files and folders independently.
+
+<!-- START doctoc generated TOC please keep comment here to allow auto update -->
+<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
+
+
+- [Watermarking](#watermarking)
+  - [Get Watermark on File or Folder](#get-watermark-on-file-or-folder)
+  - [Apply Watermark on File or Folder](#apply-watermark-on-file-or-folder)
+  - [Remove Watermark on File or Folder](#remove-watermark-on-file-or-folder)
+
+<!-- END doctoc generated TOC please keep comment here to allow auto update -->
+
+Get Watermark on File or Folder
+-------------------------------
+
+Calling `file.get_watermark()` will return the watermark object containing information about the watermark on the file. Or `folder.get_watermark()` will return the watermark object containing information about the watermark on the folder.
+
+```python
+watermark_info = client.file('1234').get_watermark()
+```
+
+```python
+watermark_info = client.folder('5678').get_watermark()
+```
+
+Apply Watermark on File or Folder
+---------------------------------
+
+To assign a watermark on a file, use `file.apply_watermark()`. To assign a watermark on a folder, use `folder.apply_watermark()`.
+
+```python
+watermark_info = client.file('1234').apply_watermark()
+```
+
+```python
+watermark_info = client.folder('5678').apply_watermark()
+```
+
+Remove Watermark on File or Folder
+----------------------------------
+
+To remove watermark on a file, use `file.delete_watermark()`. To remove a watermark on a folder, use `folder.delete_watermark()`
+
+```python
+client.file('1234').delete_watermark()
+```
+
+```python
+client.folder('5678').delete_watermark()
+```


Test patch:
diff --git a/test/unit/object/test_item.py b/test/unit/object/test_item.py
index 1bf2c3a..e577980 100644
--- a/test/unit/object/test_item.py
+++ b/test/unit/object/test_item.py
@@ -5,6 +5,7 @@
 import pytest
 
 from boxsdk.config import API
+from boxsdk.object.watermark import Watermark
 from boxsdk.object.collaboration import Collaboration
 
 
@@ -220,6 +221,51 @@ def test_remove_from_collection(test_item_and_response, mock_box_session, mock_c
     mock_box_session.put.assert_called_once_with(expected_url, data=json.dumps(expected_data), headers=None, params=None)
 
 
+def test_get_watermark(test_item_and_response, mock_box_session):
+    test_item, _ = test_item_and_response
+    created_at = '2016-10-31T15:33:33-07:00'
+    modified_at = '2016-10-31T15:33:33-07:00'
+    expected_url = '{0}/{1}s/{2}/watermark'.format(API.BASE_API_URL, test_item.object_type, test_item.object_id)
+    mock_box_session.get.return_value.json.return_value = {
+        'watermark': {
+            'created_at': created_at,
+            'modified_at': modified_at,
+        },
+    }
+    watermark = test_item.get_watermark()
+    mock_box_session.get.assert_called_once_with(expected_url)
+    assert isinstance(watermark, Watermark)
+    assert watermark['created_at'] == created_at
+    assert watermark['modified_at'] == modified_at
+
+
+def test_apply_watermark(test_item_and_response, mock_box_session):
+    test_item, _ = test_item_and_response
+    created_at = '2016-10-31T15:33:33-07:00'
+    modified_at = '2016-10-31T15:33:33-07:00'
+    expected_url = '{0}/{1}s/{2}/watermark'.format(API.BASE_API_URL, test_item.object_type, test_item.object_id)
+    mock_box_session.put.return_value.json.return_value = {
+        'watermark': {
+            'created_at': created_at,
+            'modified_at': modified_at,
+        },
+    }
+    watermark = test_item.apply_watermark()
+    mock_box_session.put.assert_called_once_with(expected_url, data='{"watermark": {"imprint": "default"}}')
+    assert isinstance(watermark, Watermark)
+    assert watermark['created_at'] == created_at
+    assert watermark['modified_at'] == modified_at
+
+
+def test_delete_watermark(test_item_and_response, mock_box_session):
+    test_item, _ = test_item_and_response
+    expected_url = '{0}/{1}s/{2}/watermark'.format(API.BASE_API_URL, test_item.object_type, test_item.object_id)
+    mock_box_session.delete.return_value.ok = True
+    is_watermark_deleted = test_item.delete_watermark()
+    mock_box_session.delete.assert_called_once_with(expected_url, expect_json_response=False)
+    assert is_watermark_deleted is True
+
+
 def test_collaborate_with_group(test_item_and_response, test_group, mock_box_session):
     # pylint:disable=redefined-outer-name, protected-access
     test_item, _ = test_item_and_response