meilisearch 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c31820aca925f28c1e53011587a9f6f2d9dfd210425ee3e1bce4c6e2728cb655
4
+ data.tar.gz: a74b7e2540093dc1f7fc65f5da4259cd2c07e17460ce2497be66899559cd0137
5
+ SHA512:
6
+ metadata.gz: 9b07704bb782d34b98b68b39e6a243f2882e22bc088e1ea3d66ca89f5371efa6843aa7a9b58251d3a9d0acb68825b65e61037a70f9b1ca0cd0e7e6a614aad5a3
7
+ data.tar.gz: c3a1018f981315a8e55135074ac88c688e94c8fab6ce0d2544c0db587d3ba3e9a91e24771455ddf32716c283931092c751ce4d7a413b45e9a26deaf4894f153e
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Documents
6
+ def add_documents(index_name, documents)
7
+ documents.each_slice(1000).map do |slice|
8
+ post "/indexes/#{index_name}/documents", slice
9
+ end
10
+ end
11
+
12
+ def document(index_name, document_uid)
13
+ get "/indexes/#{index_name}/documents/#{document_uid}"
14
+ end
15
+
16
+ def get_all_documents(index_name)
17
+ get "/indexes/#{index_name}/documents"
18
+ end
19
+
20
+ def batch_documents
21
+ raise NotImplementedError
22
+ end
23
+
24
+ def update_documents
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def delete_one_document(index_name, document_uid)
29
+ delete "/indexes/#{index_name}/documents/#{document_uid}"
30
+ end
31
+
32
+ def delete_multiple_documents(index_name, document_uids)
33
+ post "/indexes/#{index_name}/documents/delete", document_uids
34
+ end
35
+
36
+ def clear_all_documents(index_name)
37
+ delete "/indexes/#{index_name}/documents"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Health
6
+ def is_healthy?
7
+ get '/health'
8
+ true
9
+ rescue StandardError
10
+ false
11
+ end
12
+
13
+ def health
14
+ get '/health'
15
+ end
16
+
17
+ def update_health(bool)
18
+ put '/health', health: bool
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Indexes
6
+ def indexes
7
+ get '/indexes'
8
+ end
9
+
10
+ def index(index_uid)
11
+ get "/indexes/#{index_uid}"
12
+ end
13
+
14
+ def create_index(index_uid, schema = nil)
15
+ if schema.nil?
16
+ post "/indexes/#{index_uid}"
17
+ else
18
+ post "/indexes/#{index_uid}", schema
19
+ end
20
+ end
21
+
22
+ def update_index(index_uid, schema = nil)
23
+ put "/indexes/#{index_uid}", schema
24
+ end
25
+
26
+ def delete_index(index_uid)
27
+ delete "/indexes/#{index_uid}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Keys
6
+ def keys
7
+ get '/keys'
8
+ end
9
+
10
+ def key(key_hash)
11
+ get "/keys/#{key_hash}"
12
+ end
13
+
14
+ def create_key(options = {})
15
+ post '/keys', options
16
+ end
17
+
18
+ def update_key(key_hash, options = {})
19
+ put "/keys/#{key_hash}", options
20
+ end
21
+
22
+ def delete_key(key_hash)
23
+ delete "/keys/#{key_hash}"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Objects
6
+ def add_objects(index_name, objects)
7
+ if objects.size <= 1000
8
+ post "/indexes/#{index_name}/objects", objects
9
+ else
10
+ objects.each_slice(1000) do |slice|
11
+ post "/indexes/#{index_name}/objects", slice
12
+ end
13
+ end
14
+ end
15
+
16
+ def object(index_name, object_identifier)
17
+ get "/indexes/#{index_name}/objects/#{object_identifier}"
18
+ end
19
+
20
+ def browse(index_name)
21
+ get "/indexes/#{index_name}/objects"
22
+ end
23
+
24
+ def batch_objects
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def update_objects
29
+ raise NotImplementedError
30
+ end
31
+
32
+ def delete_objects(index_name, object_ids)
33
+ delete "/indexes/#{index_name}/objects", object_ids
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Prepare
6
+ def rollout
7
+ put '/prepare/rollout'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Search
6
+ def search(index_uid, query, options = {})
7
+ get "/indexes/#{index_uid}/search", { q: query }.merge(options)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class Client
5
+ module Stats
6
+ def version
7
+ get '/version'
8
+ end
9
+
10
+ def sysinfo
11
+ get '/sys-info'
12
+ end
13
+
14
+ def stats
15
+ get '/stats'
16
+ end
17
+
18
+ def stats_index(index_uid)
19
+ get "/stats/#{index_uid}"
20
+ end
21
+
22
+ def number_of_documents_in_index(index_uid)
23
+ stats_index(index_uid)['numberOfDocuments']
24
+ end
25
+
26
+ def index_is_indexing?(index_uid)
27
+ stats_index(index_uid)['isIndexing']
28
+ end
29
+
30
+ def index_last_update(index_uid)
31
+ stats_index(index_uid)['lastUpdate']
32
+ end
33
+
34
+ def index_fields_frequency(index_uid)
35
+ stats_index(index_uid)['fieldsFrequency']
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httparty'
4
+
5
+ require 'meilisearch/error'
6
+ require 'meilisearch/client/keys'
7
+ require 'meilisearch/client/stats'
8
+ require 'meilisearch/client/health'
9
+ require 'meilisearch/client/indexes'
10
+ require 'meilisearch/client/documents'
11
+ require 'meilisearch/client/prepare'
12
+ require 'meilisearch/client/search'
13
+
14
+ module MeiliSearch
15
+ class Client
16
+ include HTTParty
17
+
18
+ include MeiliSearch::Client::Keys
19
+ include MeiliSearch::Client::Stats
20
+ include MeiliSearch::Client::Health
21
+ include MeiliSearch::Client::Indexes
22
+ include MeiliSearch::Client::Documents
23
+ include MeiliSearch::Client::Prepare
24
+ include MeiliSearch::Client::Search
25
+
26
+ def initialize(url, api_key = nil)
27
+ # api_key is is for basic api authorization
28
+ @headers = {}
29
+ @headers['X-Meili-Api-Key'] = api_key if api_key
30
+ @headers['Content-Type'] = 'application/json'
31
+ @base_url = url
32
+ end
33
+
34
+ def get(path = '', query = {})
35
+ response = self.class.get(
36
+ (@base_url + path),
37
+ query: query,
38
+ headers: @headers
39
+ )
40
+ validate(response)
41
+ end
42
+
43
+ def post(path = '', body = nil)
44
+ if body.nil?
45
+ response = self.class.post(
46
+ (@base_url + path),
47
+ headers: @headers
48
+ )
49
+ else
50
+ response = self.class.post(
51
+ (@base_url + path),
52
+ body: body.to_json,
53
+ headers: @headers
54
+ )
55
+ end
56
+ validate(response)
57
+ end
58
+
59
+ def put(path = '', body = {})
60
+ response = self.class.put(
61
+ (@base_url + path),
62
+ body: body.to_json,
63
+ headers: @headers
64
+ )
65
+ validate(response)
66
+ end
67
+
68
+ def delete(path = '')
69
+ response = self.class.delete(
70
+ (@base_url + path),
71
+ headers: @headers
72
+ )
73
+ validate(response)
74
+ end
75
+
76
+ private
77
+
78
+ def validate(response)
79
+ unless response.success?
80
+ raise ClientError, "#{response.code}: #{response.message}\n#{response.body}"
81
+ end
82
+
83
+ response.parsed_response
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ # This class represents the dataset we can index
5
+ class Dataset
6
+ class NotEnumerable < StandardError; end
7
+ class CannotDetermineHeader < StandardError; end
8
+ class ExtensionNotRecognized < StandardError; end
9
+
10
+ attr_accessor :data
11
+
12
+ def self.new_from_s3(s3_file)
13
+ filename = s3_file.filename.to_s
14
+ if filename.match?(/.csv$/)
15
+ data = CSV.parse(s3_file.download, headers: true)
16
+ elsif filename.match?(/.json$/)
17
+ data = JSON.parse(s3_file.download)
18
+ else
19
+ raise Dataset::ExtensionNotRecognized
20
+ end
21
+ new(data)
22
+ end
23
+
24
+ def initialize(data)
25
+ @data = data
26
+ raise Dataset::NotEnumerable unless enumerable?
27
+ end
28
+
29
+ def clean
30
+ encode_to_utf8
31
+ replace_nil_values
32
+ @data
33
+ end
34
+
35
+ def headers
36
+ if @data.class == Array
37
+ @data.first.keys
38
+ elsif @data.class == CSV::Table
39
+ @data.headers
40
+ else
41
+ raise CannotDetermineHeader
42
+ end
43
+ end
44
+
45
+ def schema
46
+ schema = headers.map do |attribute|
47
+ [attribute, [:indexed, :displayed]]
48
+ end.to_h
49
+
50
+ # Find first attribute containing id
51
+ identifier = headers.detect { |attribute| attribute[/id/i] }
52
+
53
+ # Then give it the :identifier attribute
54
+ schema[identifier].push :identifier
55
+ schema
56
+ end
57
+
58
+ private
59
+
60
+ def replace_nil_values
61
+ @data = @data.map do |record|
62
+ record.each do |key, value|
63
+ record[key] = '' if value.nil?
64
+ end
65
+ end
66
+ end
67
+
68
+ def encode_to_utf8
69
+ @data = @data.map(&:to_h).map(&:to_utf8)
70
+ end
71
+
72
+ def enumerable?
73
+ @data.respond_to? :each
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ class MeiliSearchError < StandardError; end
5
+ class ClientError < MeiliSearchError; end
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meilisearch/version'
4
+ require 'meilisearch/client'
5
+
6
+ module MeiliSearch
7
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meilisearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Meili
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.17.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.17.1
27
+ description: A simple ruby client for Meilisearch API. See https://github.com/meilisearch/MeiliDB
28
+ email: bonjour@meilisearch.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/meilisearch.rb
34
+ - lib/meilisearch/client.rb
35
+ - lib/meilisearch/client/documents.rb
36
+ - lib/meilisearch/client/health.rb
37
+ - lib/meilisearch/client/indexes.rb
38
+ - lib/meilisearch/client/keys.rb
39
+ - lib/meilisearch/client/objects.rb
40
+ - lib/meilisearch/client/prepare.rb
41
+ - lib/meilisearch/client/search.rb
42
+ - lib/meilisearch/client/stats.rb
43
+ - lib/meilisearch/dataset.rb
44
+ - lib/meilisearch/error.rb
45
+ - lib/meilisearch/version.rb
46
+ homepage: https://github.com/meilisearch/ruby-meili-api
47
+ licenses:
48
+ - MIT
49
+ metadata: {}
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.0.3
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: A simple ruby client for Meilisearch API
69
+ test_files: []