weaviate-ruby 0.1.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4eb276e9b3dd49bfbdfbbe59abfba8f63c3e4d9f93f1942aede595c991300626
4
- data.tar.gz: 7ed2ed88ae192a6b7cd52bdf01fd683cae274b78f61f1a19bf2703c63adc6dad
3
+ metadata.gz: 52fb7ba7147345178fa220aa2bbed2ce66a7903a4df42b8cf5a016ddd329ff3f
4
+ data.tar.gz: c03e3a537651f2c9e5beb4febdf826f22eadbce6cc1c96ed983b8e0311140604
5
5
  SHA512:
6
- metadata.gz: cac32112b0c05d70ff0862c70b63567bd1688c8518617d263a3262711f5919a73e6a94eb5e0161e18a791249b89607a69a110f78caa7532088ab5329bede4d01
7
- data.tar.gz: eb14f8b055ed26adb286d54232922d0bb883c11654b15261fc694391bc8ea36d21627d09416f6d81db8030cf956fd7c440db69bd6b33037e4a499f2f39654685
6
+ metadata.gz: f53cf142fa41ce9236e865c251c8e183669b0c3fea0b8b3fe0720a8e9b30dedfd0e37fea888a86b75e9e3d8c5a7118592e5d4b14b1dcfc36221c85a996e332c6
7
+ data.tar.gz: a71fa15a01d2d75c51de572b2f87d231862ae442a5841a2022ef25c7b20400cc3469217c1ca6d5af42a4995d5b4393f4f33795e846361cdfb663cdf6431edeed
data/Gemfile.lock CHANGED
@@ -1,23 +1,40 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- weaviate-ruby (0.1.0)
4
+ weaviate-ruby (0.3.0)
5
5
  faraday (~> 2.7)
6
+ graphlient (~> 0.7.0)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
11
+ activesupport (7.0.4.3)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
10
16
  ast (2.4.2)
11
17
  byebug (11.1.3)
12
18
  coderay (1.1.3)
19
+ concurrent-ruby (1.2.2)
13
20
  diff-lcs (1.5.0)
14
21
  faraday (2.7.4)
15
22
  faraday-net_http (>= 2.0, < 3.1)
16
23
  ruby2_keywords (>= 0.0.4)
17
24
  faraday-net_http (3.0.2)
25
+ graphlient (0.7.0)
26
+ faraday (~> 2.0)
27
+ graphql-client
28
+ graphql (2.0.19)
29
+ graphql-client (0.18.0)
30
+ activesupport (>= 3.0)
31
+ graphql
32
+ i18n (1.12.0)
33
+ concurrent-ruby (~> 1.0)
18
34
  json (2.6.3)
19
35
  language_server-protocol (3.17.0.3)
20
36
  method_source (1.0.0)
37
+ minitest (5.18.0)
21
38
  parallel (1.22.1)
22
39
  parser (3.2.1.1)
23
40
  ast (~> 2.4.1)
@@ -65,6 +82,8 @@ GEM
65
82
  language_server-protocol (~> 3.17.0.2)
66
83
  rubocop (~> 1.48.1)
67
84
  rubocop-performance (~> 1.16.0)
85
+ tzinfo (2.0.6)
86
+ concurrent-ruby (~> 1.0)
68
87
  unicode-display_width (2.4.2)
69
88
 
70
89
  PLATFORMS
data/README.md CHANGED
@@ -48,7 +48,9 @@ client.schema.create(
48
48
  "description": "The category",
49
49
  "name": "category"
50
50
  }
51
- ]
51
+ ],
52
+ # Possible values: 'text2vec-cohere', 'text2vec-openai', 'text2vec-huggingface', 'text2vec-transformers', 'text2vec-contextionary', 'img2vec-neural', 'multi2vec-clip', 'ref2vec-centroid'
53
+ vectorizer: "text2vec-openai"
52
54
  )
53
55
 
54
56
  # Get a single class from the schema
@@ -134,6 +136,57 @@ response = client.objects.batch_create(objects: [
134
136
  response.data
135
137
  ```
136
138
 
139
+ ### Querying
140
+
141
+ #### Get
142
+ ```ruby
143
+ near_text = '{ concepts: ["biology"] }'
144
+ sort_obj = '{ path: ["category"], order: desc }'
145
+ where_obj = '{ path: ["id"], operator: Equal, valueString: "..." }'
146
+
147
+ client.query.get(
148
+ class_name: 'Question',
149
+ fields: 'question answer category',
150
+ limit: "1",
151
+ offset: "1",
152
+ after: "id",
153
+ sort: sort_obj,
154
+ where_obj: where_obj,
155
+
156
+ # To use this parameter you must have created your schema by setting the `vectorizer:` property to
157
+ # either 'text2vec-transformers', 'text2vec-contextionary', 'text2vec-openai', 'multi2vec-clip', 'text2vec-huggingface' or 'text2vec-cohere'
158
+ near_text: near_text,
159
+
160
+ # To use this parameter you must have created your schema by setting the `vectorizer:` property to 'multi2vec-clip' or 'img2vec-neural'
161
+ # near_image: ...,
162
+
163
+ # hybrid: ...,
164
+
165
+ # bm25: ...,
166
+
167
+ # near_object: ...,
168
+ )
169
+
170
+ # Example queries:
171
+ client.query.get class_name: 'Question', where: '{ operator: Like, valueText: "SCIENCE", path: ["category"] }', fields: 'answer question category', limit: "2"
172
+
173
+ client.query.get class_name: 'Question', fields: 'answer question category _additional { id }', after: "3c5f7039-37f3-4244-b3e2-8f4a083e448d", limit: "1"
174
+
175
+
176
+
177
+ ```
178
+
179
+ #### Aggs
180
+ ```ruby
181
+ client.query.aggs(
182
+ class_name: "Question",
183
+ fields: 'meta { count }'
184
+ group_by: ["category"],
185
+ object_limit: "10",
186
+ near_text: "{ concepts: [\"knowledge\"] }"
187
+ )
188
+ ```
189
+
137
190
  ## Development
138
191
 
139
192
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "faraday"
4
+ require "graphlient"
4
5
 
5
6
  module Weaviate
6
7
  class Client
@@ -47,6 +48,26 @@ module Weaviate
47
48
  @objects ||= Weaviate::Objects.new(client: self)
48
49
  end
49
50
 
51
+ def query
52
+ @query ||= Weaviate::Query.new(client: self)
53
+ end
54
+
55
+ def graphql
56
+ headers = {}
57
+ if model_service && model_service_api_key
58
+ headers[API_KEY_HEADERS[model_service]] = model_service_api_key
59
+ end
60
+
61
+ @graphql ||= Graphlient::Client.new(
62
+ "#{scheme}://#{host}/#{API_VERSION}/graphql",
63
+ headers: headers,
64
+ http_options: {
65
+ read_timeout: 20,
66
+ write_timeout: 30
67
+ }
68
+ )
69
+ end
70
+
50
71
  def connection
51
72
  @connection ||= Faraday.new(url: "#{scheme}://#{host}/#{API_VERSION}/") do |faraday|
52
73
  faraday.request :json
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Weaviate
4
- class Error
4
+ class Error < StandardError
5
5
  end
6
6
  end
@@ -23,7 +23,7 @@ module Weaviate
23
23
  req.params["sort"] = sort unless sort.nil?
24
24
  req.params["order"] = order unless order.nil?
25
25
  end
26
- Response::Collection.from_response(response, key: "objects", type: Response::Object)
26
+ Response::Collection.from_response(response.body, key: "objects", type: Response::Object)
27
27
  end
28
28
 
29
29
  # Create a new data object. The provided meta-data and schema values are validated.
@@ -52,7 +52,7 @@ module Weaviate
52
52
  end
53
53
 
54
54
  if response.success?
55
- Response::Collection.from_response(response, type: Response::Object)
55
+ Response::Collection.from_response(response.body, type: Response::Object)
56
56
  end
57
57
  end
58
58
 
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Weaviate
4
+ class Query < Base
5
+ def get(
6
+ class_name:,
7
+ fields:,
8
+ after: nil,
9
+ limit: nil,
10
+ offset: nil,
11
+ sort: nil,
12
+ where: nil,
13
+ near_text: nil,
14
+ near_vector: nil,
15
+ near_object: nil
16
+ )
17
+ response = client.graphql.execute(
18
+ get_query(
19
+ class_name: class_name,
20
+ fields: fields,
21
+ sort: sort,
22
+ where: where,
23
+ near_text: near_text,
24
+ near_vector: near_vector,
25
+ near_object: near_object
26
+ ),
27
+ after: after,
28
+ limit: limit,
29
+ offset: offset
30
+ )
31
+ response.data.get.send(class_name.downcase)
32
+ rescue Graphlient::Errors::ExecutionError => error
33
+ raise Weaviate::Error.new(error.response.data.get.errors.messages.to_h)
34
+ end
35
+
36
+ def aggs(
37
+ class_name:,
38
+ fields: nil,
39
+ object_limit: nil,
40
+ near_text: nil,
41
+ near_vector: nil,
42
+ near_object: nil,
43
+ group_by: nil
44
+ )
45
+ response = client.graphql.execute(
46
+ aggs_query(
47
+ class_name: class_name,
48
+ fields: fields,
49
+ near_text: near_text,
50
+ near_vector: near_vector,
51
+ near_object: near_object
52
+ ),
53
+ group_by: group_by,
54
+ object_limit: object_limit
55
+ )
56
+ response.data.aggregate.send(class_name.downcase)
57
+ rescue Graphlient::Errors::ExecutionError => error
58
+ raise Weaviate::Error.new(error.response.data.aggregate.errors.messages.to_h)
59
+ end
60
+
61
+ private
62
+
63
+ def get_query(
64
+ class_name:,
65
+ fields:,
66
+ where: nil,
67
+ near_text: nil,
68
+ near_vector: nil,
69
+ near_object: nil,
70
+ sort: nil
71
+ )
72
+ client.graphql.parse <<~GRAPHQL
73
+ query(
74
+ $after: String,
75
+ $limit: Int,
76
+ $offset: Int,
77
+ ) {
78
+ Get {
79
+ #{class_name}(
80
+ after: $after,
81
+ limit: $limit,
82
+ offset: $offset,
83
+ #{near_text.present? ? "nearText: #{near_text}" : ""},
84
+ #{near_vector.present? ? "nearVector: #{near_vector}" : ""},
85
+ #{near_object.present? ? "nearObject: #{near_object}" : ""},
86
+ #{where.present? ? "where: #{where}" : ""},
87
+ #{sort.present? ? "sort: #{sort}" : ""}
88
+ ) {
89
+ #{fields}
90
+ }
91
+ }
92
+ }
93
+ GRAPHQL
94
+ end
95
+
96
+ def aggs_query(
97
+ class_name:,
98
+ fields:,
99
+ near_text: nil,
100
+ near_vector: nil,
101
+ near_object: nil
102
+ )
103
+ client.graphql.parse <<~GRAPHQL
104
+ query(
105
+ $group_by: [String],
106
+ $object_limit: Int,
107
+ ) {
108
+ Aggregate {
109
+ #{class_name}(
110
+ objectLimit: $object_limit,
111
+ groupBy: $group_by,
112
+ #{near_text.present? ? "nearText: #{near_text}" : ""},
113
+ #{near_vector.present? ? "nearVector: #{near_vector}" : ""},
114
+ #{near_object.present? ? "nearObject: #{near_object}" : ""}
115
+ ) {
116
+ #{fields}
117
+ }
118
+ }
119
+ }
120
+ GRAPHQL
121
+ end
122
+ end
123
+ end
@@ -5,8 +5,7 @@ module Weaviate
5
5
  class Collection
6
6
  attr_reader :data, :total_results
7
7
 
8
- def self.from_response(response, type:, key: nil)
9
- body = response.body
8
+ def self.from_response(body, type:, key: nil)
10
9
  new(
11
10
  data: (key.nil? ? body : body[key]).map { |attrs| type.new(attrs) }
12
11
  # TODO: Integrate and use the totalResults from the response.
@@ -7,7 +7,7 @@ module Weaviate
7
7
  # Dumps the current Weaviate schema. The result contains an array of objects.
8
8
  def list
9
9
  response = client.connection.get(PATH)
10
- Response::Collection.from_response(response, key: "classes", type: Response::Class)
10
+ Response::Collection.from_response(response.body, key: "classes", type: Response::Class)
11
11
  end
12
12
 
13
13
  # Get a single class from the schema
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Weaviate
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/weaviate.rb CHANGED
@@ -10,6 +10,7 @@ module Weaviate
10
10
  autoload :Meta, "weaviate/meta"
11
11
  autoload :Objects, "weaviate/objects"
12
12
  autoload :OIDC, "weaviate/oidc"
13
+ autoload :Query, "weaviate/query"
13
14
 
14
15
  module Response
15
16
  autoload :Base, "weaviate/response/base"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weaviate-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Bondarev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-25 00:00:00.000000000 Z
11
+ date: 2023-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: graphlient
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.7.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.7.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: pry-byebug
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +74,7 @@ files:
60
74
  - lib/weaviate/meta.rb
61
75
  - lib/weaviate/objects.rb
62
76
  - lib/weaviate/oidc.rb
77
+ - lib/weaviate/query.rb
63
78
  - lib/weaviate/response/base.rb
64
79
  - lib/weaviate/response/class.rb
65
80
  - lib/weaviate/response/collection.rb