Skip to content

Commit bf770be

Browse files
committed
Add client wrapper for import of documents.
1 parent 9bc6604 commit bf770be

File tree

4 files changed

+68
-32
lines changed

4 files changed

+68
-32
lines changed

examples/collection_operations.py

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import os
23
import sys
34

@@ -7,31 +8,30 @@
78
import typesense
89

910
client = typesense.Client({
10-
'api_key': 'abcd',
11-
'nodes': [{
12-
'host': 'localhost',
13-
'port': '8108',
14-
'protocol': 'http'
15-
}],
16-
'timeout_seconds': 2
11+
'api_key': 'abcd',
12+
'nodes': [{
13+
'host': 'localhost',
14+
'port': '8108',
15+
'protocol': 'http'
16+
}],
17+
'timeout_seconds': 2
1718
})
1819

19-
2020
# Create a collection
2121

2222
create_response = client.collections.create({
23-
"name": "books",
24-
"fields": [
25-
{"name": "title", "type": "string" },
26-
{"name": "authors", "type": "string[]" },
27-
{"name": "authors_facet", "type": "string[]", "facet": True },
28-
{"name": "publication_year", "type": "int32" },
29-
{"name": "publication_year_facet", "type": "string", "facet": True },
30-
{"name": "ratings_count", "type": "int32" },
31-
{"name": "average_rating", "type": "float" },
32-
{"name": "image_url", "type": "string" }
33-
],
34-
"default_sorting_field": "ratings_count"
23+
"name": "books",
24+
"fields": [
25+
{"name": "title", "type": "string"},
26+
{"name": "authors", "type": "string[]"},
27+
{"name": "authors_facet", "type": "string[]", "facet": True},
28+
{"name": "publication_year", "type": "int32"},
29+
{"name": "publication_year_facet", "type": "string", "facet": True},
30+
{"name": "ratings_count", "type": "int32"},
31+
{"name": "average_rating", "type": "float"},
32+
{"name": "image_url", "type": "string"}
33+
],
34+
"default_sorting_field": "ratings_count"
3535
})
3636

3737
print(create_response)
@@ -48,18 +48,19 @@
4848
# Add a book
4949

5050
hunger_games_book = {
51-
'id': '1', 'original_publication_year': 2008, 'authors': ['Suzanne Collins'], 'average_rating': 4.34,
52-
'publication_year': 2008, 'publication_year_facet': '2008', 'authors_facet': ['Suzanne Collins'],
53-
'title': 'The Hunger Games',
54-
'image_url': 'https://images.gr-assets.com/books/1447303603m/2767052.jpg',
55-
'ratings_count': 4780653
51+
'id': '1', 'original_publication_year': 2008, 'authors': ['Suzanne Collins'], 'average_rating': 4.34,
52+
'publication_year': 2008, 'publication_year_facet': '2008', 'authors_facet': ['Suzanne Collins'],
53+
'title': 'The Hunger Games',
54+
'image_url': 'https://images.gr-assets.com/books/1447303603m/2767052.jpg',
55+
'ratings_count': 4780653
5656
}
5757

5858
client.collections['books'].documents.create(hunger_games_book)
5959

6060
# Export the documents from a collection
6161

62-
print(client.collections['books'].documents.export())
62+
exported_doc_strs = client.collections['books'].documents.export()
63+
print(exported_doc_strs)
6364

6465
# Fetch a document in a collection
6566

@@ -77,6 +78,14 @@
7778

7879
print(client.collections['books'].documents['1'].delete())
7980

81+
# Import documents into a collection
82+
docs_to_import = []
83+
for exported_doc_str in exported_doc_strs:
84+
docs_to_import.append(json.loads(exported_doc_str))
85+
86+
import_res = client.collections['books'].documents.create_many(docs_to_import)
87+
print(import_res["success"])
88+
8089
# Drop the collection
8190

8291
drop_response = client.collections['books'].delete()

examples/indexing_in_loop.py renamed to examples/index_and_search.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,19 @@
4848

4949
print(create_response)
5050

51+
# Let's use bulk import
52+
book_documents = []
5153
with open('/tmp/books.jsonl') as infile:
5254
for json_line in infile:
53-
book_document = json.loads(json_line)
54-
client.collections['books'].documents.create(book_document)
55+
book_documents.append(json.loads(json_line))
56+
57+
print(client.collections['books'].documents.create_many(book_documents))
58+
59+
i = 0
60+
while i < 10000:
61+
res = client.collections['books'].documents.search({
62+
'q': 'the',
63+
'query_by': 'title',
64+
'sort_by': 'ratings_count:desc'
65+
})
66+
print(res['found'])

typesense/api_call.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import time
23

34
import requests
@@ -69,15 +70,19 @@ def make_request(self, fn, method, endpoint, as_json, **kwargs):
6970

7071
try:
7172
url = node.url() + endpoint
73+
if kwargs.get('data') and not isinstance(kwargs['data'], str):
74+
kwargs['data'] = json.dumps(kwargs['data'])
75+
7276
r = fn(url, headers={ApiCall.API_KEY_HEADER_NAME: self.config.api_key}, **kwargs)
7377

7478
if 0 < r.status_code < 500:
7579
node.healthy = True
7680

77-
if (method != 'post' and r.status_code != 200) or (method == 'post' and r.status_code != 201):
81+
if (method != 'post' and r.status_code != 200) or \
82+
(method == 'post' and not (r.status_code == 200 or r.status_code == 201)):
7883
error_message = r.json().get('message', 'API error.')
7984
# print('error_message: ' + error_message)
80-
raise ApiCall.get_exception(r.status_code)(error_message)
85+
raise ApiCall.get_exception(r.status_code)(r.status_code, error_message)
8186

8287
return r.json() if as_json else r.text
8388
except requests.exceptions.Timeout:
@@ -102,11 +107,11 @@ def get(self, endpoint, params=None, as_json=True):
102107

103108
def post(self, endpoint, body):
104109
return self.make_request(requests.post, 'post', endpoint, True,
105-
json=body, timeout=self.config.timeout_seconds)
110+
data=body, timeout=self.config.timeout_seconds)
106111

107112
def put(self, endpoint, body):
108113
return self.make_request(requests.put, 'put', endpoint, True,
109-
json=body, timeout=self.config.timeout_seconds)
114+
data=body, timeout=self.config.timeout_seconds)
110115

111116
def delete(self, endpoint):
112117
return self.make_request(requests.delete, 'delete', endpoint, True,

typesense/documents.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import json
2+
13
from .document import Document
24
from .api_call import ApiCall
35

@@ -27,6 +29,14 @@ def _endpoint_path(self, action=None):
2729
def create(self, document):
2830
return self.api_call.post(self._endpoint_path(), document)
2931

32+
def create_many(self, documents):
33+
document_strs = []
34+
for document in documents:
35+
document_strs.append(json.dumps(document))
36+
37+
docs_import = '\n'.join(document_strs)
38+
return self.api_call.post(self._endpoint_path('import'), docs_import)
39+
3040
def export(self):
3141
api_response = self.api_call.get(self._endpoint_path('export'), {}, as_json=False)
3242
return api_response.split('\n')

0 commit comments

Comments
 (0)