weaviate-ruby 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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