Skip to content

Commit 0617711

Browse files
Merge pull request #2 from andreibondarev/query-graphql-integration
Adding support for the Weaviate GraphQL Get{} query endpoint
2 parents 0dac13f + d9415b6 commit 0617711

File tree

12 files changed

+177
-7
lines changed

12 files changed

+177
-7
lines changed

Gemfile.lock

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,38 @@ PATH
33
specs:
44
weaviate-ruby (0.1.0)
55
faraday (~> 2.7)
6+
graphlient (~> 0.7.0)
67

78
GEM
89
remote: https://rubygems.org/
910
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)
1016
ast (2.4.2)
1117
byebug (11.1.3)
1218
coderay (1.1.3)
19+
concurrent-ruby (1.2.2)
1320
diff-lcs (1.5.0)
1421
faraday (2.7.4)
1522
faraday-net_http (>= 2.0, < 3.1)
1623
ruby2_keywords (>= 0.0.4)
1724
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)
1834
json (2.6.3)
1935
language_server-protocol (3.17.0.3)
2036
method_source (1.0.0)
37+
minitest (5.18.0)
2138
parallel (1.22.1)
2239
parser (3.2.1.1)
2340
ast (~> 2.4.1)
@@ -65,6 +82,8 @@ GEM
6582
language_server-protocol (~> 3.17.0.2)
6683
rubocop (~> 1.48.1)
6784
rubocop-performance (~> 1.16.0)
85+
tzinfo (2.0.6)
86+
concurrent-ruby (~> 1.0)
6887
unicode-display_width (2.4.2)
6988

7089
PLATFORMS

README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ client.schema.create(
4848
"description": "The category",
4949
"name": "category"
5050
}
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"
5254
)
5355

5456
# Get a single class from the schema
@@ -134,6 +136,30 @@ response = client.objects.batch_create(objects: [
134136
response.data
135137
```
136138

139+
### Querying
140+
```ruby
141+
near_text = { "concepts": ["biology"] }
142+
143+
client.query.get(
144+
class_name: 'Question',
145+
fields: ['question', 'answer', 'category'],
146+
limit: 1,
147+
148+
# To use this parameter you must have created your schema by setting the `vectorizer:` property to
149+
# either 'text2vec-transformers', 'text2vec-contextionary', 'text2vec-openai', 'multi2vec-clip', 'text2vec-huggingface' or 'text2vec-cohere'
150+
near_text: near_text,
151+
152+
# To use this parameter you must have created your schema by setting the `vectorizer:` property to 'multi2vec-clip' or 'img2vec-neural'
153+
# near_image: ...,
154+
155+
# hybrid: ...,
156+
157+
# bm25: ...,
158+
159+
# near_object: ...,
160+
)
161+
```
162+
137163
## Development
138164

139165
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.

bin/console

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require "weaviate"
1212
# Pry.start
1313

1414
client = Weaviate::Client.new(
15-
scheme: "http",
15+
scheme: "https",
1616
host: ENV["WEAVIATE_HOST"],
1717
model_service: :openai,
1818
model_service_api_key: ENV["MODEL_SERVICE_API_KEY"]

lib/weaviate.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Weaviate
1010
autoload :Meta, "weaviate/meta"
1111
autoload :Objects, "weaviate/objects"
1212
autoload :OIDC, "weaviate/oidc"
13+
autoload :Query, "weaviate/query"
1314

1415
module Response
1516
autoload :Base, "weaviate/response/base"

lib/weaviate/client.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require "faraday"
4+
require "graphlient"
45

56
module Weaviate
67
class Client
@@ -47,6 +48,26 @@ def objects
4748
@objects ||= Weaviate::Objects.new(client: self)
4849
end
4950

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+
5071
def connection
5172
@connection ||= Faraday.new(url: "#{scheme}://#{host}/#{API_VERSION}/") do |faraday|
5273
faraday.request :json

lib/weaviate/objects.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def list(
2323
req.params["sort"] = sort unless sort.nil?
2424
req.params["order"] = order unless order.nil?
2525
end
26-
Response::Collection.from_response(response, key: "objects", type: Response::Object)
26+
Response::Collection.from_response(response.body, key: "objects", type: Response::Object)
2727
end
2828

2929
# Create a new data object. The provided meta-data and schema values are validated.
@@ -52,7 +52,7 @@ def batch_create(objects:)
5252
end
5353

5454
if response.success?
55-
Response::Collection.from_response(response, type: Response::Object)
55+
Response::Collection.from_response(response.body, type: Response::Object)
5656
end
5757
end
5858

lib/weaviate/query.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
module Weaviate
4+
class Query < Base
5+
def get(
6+
class_name:,
7+
fields:,
8+
limit: nil,
9+
near_text: nil
10+
)
11+
params = {}
12+
params["nearText"] = near_text unless near_text.nil?
13+
params["limit"] = limit unless limit.nil?
14+
# TODO implement the rest of the API params
15+
16+
response = client.graphql.execute(get_query(class_name, params, fields), near_text: near_text)
17+
response.data.get.send(class_name.downcase)
18+
end
19+
20+
private
21+
22+
def get_query(class_name, params, fields)
23+
client.graphql.parse do
24+
query do
25+
Get do
26+
public_send(class_name, params) do
27+
fields.map do |field|
28+
public_send(field)
29+
end
30+
end
31+
end
32+
end
33+
end
34+
end
35+
end
36+
end

lib/weaviate/response/collection.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ module Response
55
class Collection
66
attr_reader :data, :total_results
77

8-
def self.from_response(response, type:, key: nil)
9-
body = response.body
8+
def self.from_response(body, type:, key: nil)
109
new(
1110
data: (key.nil? ? body : body[key]).map { |attrs| type.new(attrs) }
1211
# TODO: Integrate and use the totalResults from the response.

lib/weaviate/schema.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class Schema < Base
77
# Dumps the current Weaviate schema. The result contains an array of objects.
88
def list
99
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)
1111
end
1212

1313
# Get a single class from the schema

spec/weaviate/client_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@
4747
end
4848
end
4949

50+
describe "#query" do
51+
it "returns a query client" do
52+
expect(client.query).to be_a(Weaviate::Query)
53+
end
54+
end
55+
5056
describe "#oidc" do
5157
let(:fixture) { JSON.parse(File.read("spec/fixtures/oidc.json")) }
5258
let(:response) { OpenStruct.new(body: fixture) }

0 commit comments

Comments
 (0)