Skip to content
This repository was archived by the owner on Sep 1, 2021. It is now read-only.

Commit c5d5b21

Browse files
author
Christopher Wang
authored
Merge pull request #2 from swiftype/christopherjwang/add_document_index
Add index_document method to client
2 parents 98323fd + 78fc2b9 commit c5d5b21

File tree

3 files changed

+60
-6
lines changed

3 files changed

+60
-6
lines changed

README.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ Instantiating a client
4040
>>> api_key = 'api-mu75psc5egt9ppzuycnc2mc3'
4141
>>> client = Client(account_host_key, api_key)
4242
43+
Index document
44+
--------------
45+
46+
.. code-block:: python
47+
48+
>>> engine_name = 'favorite-videos'
49+
>>> documents = {
50+
'id': 'INscMGmhmX4',
51+
'url': 'https://www.youtube.com/watch?v=INscMGmhmX4',
52+
'title': 'The Original Grumpy Cat',
53+
'body': 'A wonderful video of a magnificent cat.'
54+
}
55+
>>> client.index_document(engine_name, document)
56+
{'id': 'INscMGmhmX4'}
4357
4458
Index documents
4559
---------------

swiftype_app_search/client.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,38 @@ def get_documents(self, engine_name, document_ids):
3232
data = json.dumps(document_ids)
3333
return self.swiftype_session.request('get', endpoint, data=data)
3434

35+
def index_document(self, engine_name, document):
36+
"""
37+
Create or update a document for an engine. Raises
38+
:class:`~swiftype_app_search.exceptions.InvalidDocument` when the document
39+
is missing required fields, contains unsupported fields, or has
40+
processing errors
41+
42+
:param engine_name: Name of engine to index documents into.
43+
:param document: Hash representing a single document.
44+
:return: dict processed document status
45+
"""
46+
document_status = self.index_documents(engine_name, [document])[0]
47+
errors = document_status['errors']
48+
if errors:
49+
raise InvalidDocument('; '.join(errors), document)
50+
51+
return {
52+
key: document_status[key]
53+
for key in document_status
54+
if key != 'errors'
55+
}
56+
3557
def index_documents(self, engine_name, documents):
3658
"""
3759
Create or update documents for an engine. Raises
38-
:class:`~swiftype_app_search.exceptions.InvalidDocument` if any
39-
documents do not have an `id`.
60+
:class:`~swiftype_app_search.exceptions.InvalidDocument` when the document
61+
is missing required fields or contains unsupported fields
4062
4163
:param engine_name: Name of engine to index documents into.
4264
:param documents: Hashes representing documents.
43-
:return: Array of hashes with keys of id and errors. Errors will be an
44-
array of errors if the document could not be indexed successfully.
65+
:return: Array of document status dictionaries. Errors will be present
66+
in a document status with a key of `errors`.
4567
"""
4668
self._raise_if_documents_invalid(documents)
4769

tests/test_client.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,40 @@
77
class TestClient(TestCase):
88

99
def setUp(self):
10-
self.engine_name = 'engine_name'
10+
self.engine_name = 'some-engine-name'
1111
self.client = Client('account_host_key', 'api_key')
1212

1313
self.document_index_url = "{}/{}".format(
1414
self.client.swiftype_session.base_url,
1515
"engines/{}/documents".format(self.engine_name)
1616
)
1717

18+
def test_index_document_validation(self):
19+
invalid_document = {'does': 'not have the id field'}
20+
with self.assertRaises(InvalidDocument) as context:
21+
self.client.index_documents(self.engine_name, [invalid_document])
22+
self.assertEqual(str(context.exception), 'Missing required fields: id')
23+
self.assertEqual(context.exception.document, invalid_document)
24+
25+
def test_index_document_processing_error(self):
26+
invalid_document = {'id': 'something', 'bad': {'no': 'nested'}}
27+
error = 'some processing error'
28+
stubbed_return = [{'id': 'something', 'errors': [error]}]
29+
with requests_mock.Mocker() as m:
30+
m.register_uri('POST', self.document_index_url, json=stubbed_return, status_code=200)
31+
32+
with self.assertRaises(InvalidDocument) as context:
33+
self.client.index_document(self.engine_name, invalid_document)
34+
self.assertEqual(str(context.exception), error)
35+
1836
def test_index_documents_validation(self):
1937
invalid_documents = [
2038
{
2139
'does': 'not have the id field'
2240
}
2341
]
2442
with self.assertRaises(InvalidDocument) as context:
25-
self.client.index_documents('some engine name', invalid_documents)
43+
self.client.index_documents(self.engine_name, invalid_documents)
2644
self.assertEqual(str(context.exception), 'Missing required fields: id')
2745
self.assertEqual(context.exception.document, invalid_documents[0])
2846

0 commit comments

Comments
 (0)