Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ This document describes changes between each past release.
10.5.0 (unreleased)
===================

- Nothing changed yet.
**New features**

- Add history support (fixes #112), Thanks @FlorianKuckelkorn!


10.4.1 (2019-05-22)
Expand Down
22 changes: 22 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,28 @@ of them, you can specify the number of pages:
records = client.get_records(_limit=10, pages=float('inf')) # Infinity


History
-------

If the built-in `history plugin <https://kinto.readthedocs.io/en/latest/api/1.x/history.html>`_ is enabled, it is possible to retrieve the history of changes:

.. code-block:: python

# Get the complete history of a bucket
changes = client.get_history(bucket='default')

# and optionally use filters
hist = client.get_history(bucket='default', _limit=2, _sort='-last_modified', _since='1533762576015')
hist = client.get_history(bucket='default', resource_name='collection')


The history of a bucket can also be purged with:

.. code-block:: python

client.purge_history(bucket='default')


Endpoint URLs
-------------

Expand Down
13 changes: 13 additions & 0 deletions kinto_http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Endpoints(object):
"batch": "{root}/batch",
"buckets": "{root}/buckets",
"bucket": "{root}/buckets/{bucket}",
"history": "{root}/buckets/{bucket}/history",
"groups": "{root}/buckets/{bucket}/groups",
"group": "{root}/buckets/{bucket}/groups/{group}",
"collections": "{root}/buckets/{bucket}/collections",
Expand Down Expand Up @@ -862,6 +863,18 @@ def delete_records(self, *, collection=None, bucket=None, safe=True, if_match=No
resp, _ = self.session.request("delete", endpoint, headers=headers)
return resp["data"]

def get_history(self, *, bucket=None, **kwargs):
endpoint = self.get_endpoint("history", bucket=bucket)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the previous round of this PR, you suggested it would be good to check for the history plugin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I thought we had the capabilities check already, but I realized we don't. So I went for the shortest approach...

logger.info("Get history from bucket %r" % bucket or self._bucket_name)
return self._paginated(endpoint, **kwargs)

def purge_history(self, *, bucket=None, safe=True, if_match=None):
endpoint = self.get_endpoint('history', bucket=bucket)
headers = self._get_cache_headers(safe, if_match=if_match)
logger.info("Purge History of bucket %r" % bucket or self._bucket_name)
resp, _ = self.session.request('delete', endpoint, headers=headers)
return resp['data']

def __repr__(self):
if self._collection_name:
endpoint = self.get_endpoint(
Expand Down
2 changes: 1 addition & 1 deletion kinto_http/tests/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def test_group_creation_if_not_exists(self):
def test_group_creation_if_bucket_does_not_exist(self):
with pytest.raises(KintoException) as e:
self.client.create_group(id="payments", bucket="mozilla", data={"members": ["blah"]})
assert str(e).endswith(
assert str(e.value).endswith(
"PUT /v1/buckets/mozilla/groups/payments - "
"403 Unauthorized. Please check that the "
"bucket exists and that you have the permission "
Expand Down
40 changes: 40 additions & 0 deletions kinto_http/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1182,3 +1182,43 @@ def test_update_record_can_deduce_id_from_data(self):
permissions=None,
headers=None,
)


class HistoryTest(unittest.TestCase):
def setUp(self):
self.session = mock.MagicMock()
self.client = Client(session=self.session)

def test_basic_retrivial_of_bucket_history(self):
mock_response(self.session)
self.client.get_history(bucket='mybucket')
url = '/buckets/mybucket/history'
self.session.request.assert_called_with('get', url, headers={}, params={})

def test_filter_sorting_operations_on_bucket_history(self):
mock_response(self.session)
self.client.get_history(bucket='mybucket',
_limit=2,
_sort='-last_modified',
_since='1533762576015')

url = '/buckets/mybucket/history'
self.session.request.assert_called_with('get', url, headers={},
params={'_limit': 2,
'_sort': '-last_modified',
'_since': '1533762576015'}
)

def test_filtering_by_resource_name(self):
mock_response(self.session)
self.client.get_history(bucket='mybucket', resource_name='collection')
url = '/buckets/mybucket/history'
self.session.request.assert_called_with('get', url, headers={},
params={'resource_name': 'collection'}
)

def test_purging_of_history(self):
mock_response(self.session)
self.client.purge_history(bucket='mybucket')
url = '/buckets/mybucket/history'
self.session.request.assert_called_with('delete', url, headers=None)
3 changes: 3 additions & 0 deletions kinto_http/tests/test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def test_record(self):
== "/buckets/buck/collections/coll/records/1"
)

def test_history(self):
assert self.endpoints.get("history", **self.kwargs) == "/buckets/buck/history"

def test_missing_arguments_raise_an_error(self):
# Don't include the record id; it should raise an error.
with self.assertRaises(KintoException) as context:
Expand Down