pinecone 0.1.71 → 1.1.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: ea82946a00b57e8d81af48478eee15aa1f0a17a22316d982878f1033aa57dc7f
4
- data.tar.gz: 6db21ac3336d691bce0064f2c22a8e1f1f5ced9a725e5b76eec14a0752c5d488
3
+ metadata.gz: c9e5f89bdb821f056dde85c82168420d575599d116508b083fb987ea7b3b60da
4
+ data.tar.gz: b4d1da67d606505ca251db63cc63a9077d363e92425ddfeb4ea55263af30aac6
5
5
  SHA512:
6
- metadata.gz: 6265199be8db129c2b428cebef001249cc6827819643e19421eea23727484c69bd7054eb0eb0e3a3fc9e332eecfadaed900a618664bdb8fc61f320b9e4833c6b
7
- data.tar.gz: '0913f7fe938dddfc78a150847f73da703b375250d55150c1718ee408b0f8b2012321db7c10a4de2fbb5e6fdf8f15ec8a3e1c27067903b807a0574de85f2455da'
6
+ metadata.gz: c429ec85b521a797a73597a6cba93b77e4892e84176064079367605c8436b15709aa03fd7ab563240c96bc8406c6b805c3d43bb7cc7f91c8c7ad1b016724acfe
7
+ data.tar.gz: 749c157e0650086c2365023cf8a9626ef04fd4bce9b5eac886de5007480c64318aa0c3312ea1795713ca08475c5e2f5396130aaabe2bb84d5d853d52969c12d1
@@ -39,8 +39,9 @@ module Pinecone
39
39
  end
40
40
 
41
41
  # This is a very confusing naming convention
42
+ # Pinecone's reference now delineates between 'control plane' and 'data plane' which we'll reflect eventually
42
43
  def index(index_name)
43
- @index ||= Pinecone::Vector.new(index_name)
44
+ Pinecone::Vector.new(index_name)
44
45
  end
45
46
  end
46
- end
47
+ end
@@ -1,19 +1,20 @@
1
1
  module Pinecone
2
2
  class Collection
3
3
  include HTTParty
4
+ parser Pinecone::ResponseParser
4
5
 
5
6
  def initialize
6
- self.class.base_uri "https://controller.#{Pinecone.configuration.environment}.pinecone.io"
7
+ self.class.base_uri "https://api.pinecone.io"
7
8
 
8
9
  @headers = {
9
10
  "Content-Type" => "application/json",
10
11
  "Accept" => "application/json",
11
- "Api-Key" => Pinecone.configuration.api_key,
12
+ "Api-Key" => Pinecone.configuration.api_key
12
13
  }
13
14
  end
14
15
 
15
16
  def list
16
- self.class.get('/collections', options)
17
+ self.class.get("/collections", options)
17
18
  end
18
19
 
19
20
  def describe(collection_name)
@@ -22,7 +23,7 @@ module Pinecone
22
23
 
23
24
  def create(body)
24
25
  payload = options.merge(body: body.to_json)
25
- self.class.post('/collections', payload)
26
+ self.class.post("/collections", payload)
26
27
  end
27
28
 
28
29
  def delete(collection_name)
@@ -31,8 +32,8 @@ module Pinecone
31
32
 
32
33
  def options
33
34
  {
34
- headers: @headers,
35
+ headers: @headers
35
36
  }
36
37
  end
37
38
  end
38
- end
39
+ end
@@ -1,42 +1,43 @@
1
1
  module Pinecone
2
2
  class Index
3
3
  include HTTParty
4
+ parser Pinecone::ResponseParser
4
5
 
5
6
  def initialize
6
- self.class.base_uri "https://controller.#{Pinecone.configuration.environment}.pinecone.io"
7
+ self.class.base_uri "https://api.pinecone.io"
7
8
  @headers = {
8
9
  "Content-Type" => "application/json",
9
10
  "Accept" => "application/json",
10
- "Api-Key" => Pinecone.configuration.api_key,
11
+ "Api-Key" => Pinecone.configuration.api_key
11
12
  }
12
13
  end
13
14
 
14
15
  def list
15
- self.class.get('/databases', options)
16
+ self.class.get("/indexes", options)
16
17
  end
17
18
 
18
19
  def describe(index_name)
19
- self.class.get("/databases/#{index_name}", options)
20
+ self.class.get("/indexes/#{index_name}", options)
20
21
  end
21
-
22
+
22
23
  def create(body)
23
24
  payload = options.merge(body: body.to_json)
24
- self.class.post('/databases', payload)
25
+ self.class.post("/indexes", payload)
25
26
  end
26
27
 
27
28
  def delete(index_name)
28
- self.class.delete("/databases/#{index_name}", options)
29
+ self.class.delete("/indexes/#{index_name}", options)
29
30
  end
30
31
 
31
32
  def configure(index_name, body)
32
33
  payload = options.merge(body: body.to_json)
33
- self.class.patch("/databases/#{index_name}", payload)
34
+ self.class.patch("/indexes/#{index_name}", payload)
34
35
  end
35
36
 
36
37
  def options
37
38
  {
38
- headers: @headers,
39
+ headers: @headers
39
40
  }
40
41
  end
41
42
  end
42
- end
43
+ end
@@ -0,0 +1,16 @@
1
+ module Pinecone
2
+ class ResponseParser < HTTParty::Parser
3
+ # standard:disable Naming/ConstantName
4
+ SupportedFormats = {
5
+ "application/json" => :json,
6
+ "text/plain" => :json
7
+ }
8
+ # standard:enable Naming/ConstantName
9
+
10
+ def json
11
+ JSON.parse(body)
12
+ rescue
13
+ body
14
+ end
15
+ end
16
+ end
@@ -6,9 +6,9 @@ require "dry-validation"
6
6
  module Types
7
7
  include Dry.Types()
8
8
 
9
- StringOrNumberOrBoolean = Dry::Types['string'] | Dry::Types['integer'] | Dry::Types['float'] | Dry::Types['bool']
10
- StringOrNumber = Dry::Types['string'] | Dry::Types['integer'] | Dry::Types['float']
11
- Number = Dry::Types['integer'] | Dry::Types['float']
9
+ StringOrNumberOrBoolean = Dry::Types["string"] | Dry::Types["integer"] | Dry::Types["float"] | Dry::Types["bool"]
10
+ StringOrNumber = Dry::Types["string"] | Dry::Types["integer"] | Dry::Types["float"]
11
+ Number = Dry::Types["integer"] | Dry::Types["float"]
12
12
  end
13
13
 
14
14
  module Pinecone
@@ -50,14 +50,14 @@ module Pinecone
50
50
 
51
51
  def to_filter(input)
52
52
  return false unless input.is_a?(Hash)
53
- return Filter.new(input)
53
+ Filter.new(input)
54
54
  end
55
55
  end
56
56
 
57
57
  def self.new(input)
58
58
  validation = FilterContract.new.call(input)
59
59
  if validation.success?
60
- super(input)
60
+ super
61
61
  else
62
62
  raise ArgumentError.new(validation.errors.to_h.inspect)
63
63
  end
@@ -68,4 +68,4 @@ module Pinecone
68
68
  end
69
69
  end
70
70
  end
71
- end
71
+ end
@@ -29,22 +29,22 @@ module Pinecone
29
29
 
30
30
  schema schema.strict
31
31
 
32
- attribute :namespace, Dry::Types['string'].default("")
33
- attribute :include_values, Dry::Types['bool'].default(false)
34
- attribute :include_metadata, Dry::Types['bool'].default(true)
35
- attribute :top_k, Dry::Types['integer'].default(10)
36
- attribute? :vector, Dry::Types['array'].of(Dry::Types['float'] | Dry::Types['integer'])
32
+ attribute :namespace, Dry::Types["string"].default("")
33
+ attribute :include_values, Dry::Types["bool"].default(false)
34
+ attribute :include_metadata, Dry::Types["bool"].default(true)
35
+ attribute :top_k, Dry::Types["integer"].default(10)
36
+ attribute? :vector, Dry::Types["array"].of(Dry::Types["float"] | Dry::Types["integer"])
37
37
  # Disabled contract since it wasn't carrying forward attributes to to_json
38
38
  # See failing test in query_spec.rb
39
- # attribute? :filter, Filter
40
- attribute? :filter, Dry::Types['hash']
39
+ # attribute? :filter, Filter
40
+ attribute? :filter, Dry::Types["hash"]
41
41
  attribute? :sparse_vector, SparseVector
42
- attribute? :id, Dry::Types['string']
42
+ attribute? :id, Dry::Types["string"]
43
43
 
44
44
  def self.new(input)
45
45
  validation = QueryContract.new.call(input)
46
46
  if validation.success?
47
- super(input)
47
+ super
48
48
  else
49
49
  raise ArgumentError.new(validation.errors.to_h.inspect)
50
50
  end
@@ -53,10 +53,10 @@ module Pinecone
53
53
  def to_json
54
54
  to_h.map do |key, value|
55
55
  [key.to_s.split("_").map.with_index do |word, index|
56
- index == 0 ? word : word.capitalize
56
+ (index == 0) ? word : word.capitalize
57
57
  end.join.to_sym, value]
58
58
  end.to_h.to_json
59
59
  end
60
60
  end
61
61
  end
62
- end
62
+ end
@@ -24,17 +24,17 @@ module Pinecone
24
24
  end
25
25
  end
26
26
 
27
- attribute :indices, Dry::Types['array'].of(Dry::Types['integer'])
28
- attribute :values, Dry::Types['array'].of(Dry::Types['float'] | Dry::Types['integer'])
27
+ attribute :indices, Dry::Types["array"].of(Dry::Types["integer"])
28
+ attribute :values, Dry::Types["array"].of(Dry::Types["float"] | Dry::Types["integer"])
29
29
 
30
30
  def self.new(input)
31
31
  validation = SparseVectorContract.new.call(input)
32
32
  if validation.success?
33
- super(input)
33
+ super
34
34
  else
35
35
  raise ArgumentError.new(validation.errors.to_h.inspect)
36
36
  end
37
37
  end
38
38
  end
39
39
  end
40
- end
40
+ end
@@ -5,46 +5,103 @@ require "pinecone/vector/sparse_vector"
5
5
  module Pinecone
6
6
  class Vector
7
7
  include HTTParty
8
+ parser Pinecone::ResponseParser
9
+
10
+ attr_reader :base_uri
8
11
 
9
12
  def initialize(index_name)
10
- self.class.base_uri set_base_uri(index_name)
13
+ @base_uri = set_base_uri(index_name)
11
14
 
12
15
  @headers = {
13
16
  "Content-Type" => "application/json",
14
17
  "Accept" => "application/json",
15
- "Api-Key" => Pinecone.configuration.api_key,
18
+ "Api-Key" => Pinecone.configuration.api_key
16
19
  }
17
20
  end
18
21
 
19
- def delete(namespace: "", ids: [], delete_all: false)
22
+ def delete(namespace: "", ids: [], delete_all: false, filter: {})
20
23
  inputs = {
21
- "namespace": namespace,
22
- "ids": ids,
23
- "deleteAll": delete_all,
24
- }.to_json
25
- payload = options.merge(body: inputs)
26
- self.class.post('/vectors/delete', payload)
24
+ namespace: namespace,
25
+ ids: ids,
26
+ deleteAll: delete_all,
27
+ filter: filter
28
+ }
29
+ inputs.delete(:filter) if delete_all || ids.any?
30
+ payload = options.merge(body: inputs.to_json)
31
+ self.class.post("#{@base_uri}/vectors/delete", payload)
27
32
  end
28
33
 
29
34
  def fetch(namespace: "", ids: [])
30
- query_string = URI.encode_www_form({ namespace: namespace, ids: ids})
31
- self.class.get("/vectors/fetch?#{query_string}", options)
35
+ query_string = URI.encode_www_form({namespace: namespace, ids: ids})
36
+ self.class.get("#{@base_uri}/vectors/fetch?#{query_string}", options)
37
+ end
38
+
39
+ def list(prefix: nil, limit: nil, namespace: nil, &block)
40
+ all_ids = []
41
+ pagination_token = nil
42
+ total_fetched = 0
43
+
44
+ loop do
45
+ current_limit = limit.nil? ? 100 : [limit - total_fetched, 100].min
46
+
47
+ response = list_paginated(
48
+ prefix: prefix,
49
+ limit: current_limit,
50
+ pagination_token: pagination_token,
51
+ namespace: namespace
52
+ )
53
+
54
+ break unless response.success?
55
+
56
+ results = response.parsed_response
57
+ ids = results["vectors"]&.map { |v| v["id"] } || []
58
+
59
+ if block
60
+ yield ids
61
+ else
62
+ all_ids.concat(ids)
63
+ end
64
+
65
+ total_fetched += ids.length
66
+ pagination_token = results.dig("pagination", "next")
67
+
68
+ break if ids.empty?
69
+ break if limit && total_fetched >= limit
70
+ break if pagination_token.nil? || pagination_token.empty?
71
+ end
72
+
73
+ if block
74
+ nil
75
+ else
76
+ limit ? all_ids.first(limit) : all_ids
77
+ end
78
+ end
79
+
80
+ def list_paginated(prefix: nil, limit: nil, pagination_token: nil, namespace: nil)
81
+ query_params = {}
82
+ query_params["prefix"] = prefix if prefix
83
+ query_params["limit"] = limit if limit
84
+ query_params["paginationToken"] = pagination_token if pagination_token
85
+ query_params["namespace"] = namespace if namespace
86
+
87
+ query_string = URI.encode_www_form(query_params)
88
+ self.class.get("#{@base_uri}/vectors/list?#{query_string}", options)
32
89
  end
33
90
 
34
91
  def upsert(body)
35
92
  payload = options.merge(body: body.to_json)
36
- self.class.post('/vectors/upsert', payload)
93
+ self.class.post("#{@base_uri}/vectors/upsert", payload)
37
94
  end
38
95
 
39
96
  def query(query)
40
97
  object = query.is_a?(Pinecone::Vector::Query) ? query : Pinecone::Vector::Query.new(query)
41
98
  payload = options.merge(body: object.to_json)
42
- self.class.post('/query', payload)
99
+ self.class.post("#{@base_uri}/query", payload)
43
100
  end
44
101
 
45
102
  def update(id:, values: [], sparse_values: {indices: [], values: []}, set_metadata: {}, namespace: "")
46
103
  inputs = {
47
- "id": id
104
+ id: id
48
105
  }
49
106
  inputs["values"] = values unless values.empty?
50
107
  inputs["sparseValues"] = sparse_values unless sparse_values[:indices].empty? || sparse_values[:values].empty?
@@ -52,7 +109,7 @@ module Pinecone
52
109
  inputs["namespace"] = namespace unless namespace.empty?
53
110
 
54
111
  payload = options.merge(body: inputs.to_json)
55
- self.class.post('/vectors/update', payload)
112
+ self.class.post("#{@base_uri}/vectors/update", payload)
56
113
  end
57
114
 
58
115
  def describe_index_stats(filter: {})
@@ -61,13 +118,12 @@ module Pinecone
61
118
  else
62
119
  options.merge(body: {filter: filter}.to_json)
63
120
  end
64
- self.class.post('/describe_index_stats', payload)
121
+ self.class.post("#{@base_uri}/describe_index_stats", payload)
65
122
  end
66
123
 
67
-
68
124
  def options
69
125
  {
70
- headers: @headers,
126
+ headers: @headers
71
127
  }
72
128
  end
73
129
 
@@ -77,8 +133,8 @@ module Pinecone
77
133
  def set_base_uri(index_name)
78
134
  index_description = Pinecone::Index.new.describe(index_name)
79
135
  raise Pinecone::IndexNotFoundError, "Index #{index_name} does not exist" if index_description.code != 200
80
- uri = index_description.parsed_response["status"]["host"]
136
+ uri = index_description.parsed_response["host"]
81
137
  "https://#{uri}"
82
138
  end
83
139
  end
84
- end
140
+ end
@@ -1,3 +1,3 @@
1
1
  module Pinecone
2
- VERSION = "0.1.71".freeze
3
- end
2
+ VERSION = "1.1.0".freeze
3
+ end
data/lib/pinecone.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "httparty"
2
2
 
3
+ require "pinecone/response_parser"
3
4
  require "pinecone/client"
4
5
  require "pinecone/index"
5
6
  require "pinecone/vector"
@@ -8,14 +9,16 @@ require "pinecone/version"
8
9
 
9
10
  module Pinecone
10
11
  class ConfigurationError < StandardError; end
12
+
11
13
  class IndexNotFoundError < StandardError; end
14
+
12
15
  class Configuration
13
16
  attr_writer :api_key, :base_uri, :environment
14
17
 
15
18
  def initialize
16
- @api_key = nil
19
+ @api_key = nil
17
20
  @environment = nil
18
- @base_uri = nil
21
+ @base_uri = nil
19
22
  end
20
23
 
21
24
  def api_key
@@ -48,4 +51,4 @@ module Pinecone
48
51
  def self.configure
49
52
  yield(configuration)
50
53
  end
51
- end
54
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinecone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.71
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Carleton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-28 00:00:00.000000000 Z
11
+ date: 2024-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.21.0
19
+ version: 0.22.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.21.0
26
+ version: 0.22.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: dry-struct
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,104 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.10.0
55
- - !ruby/object:Gem::Dependency
56
- name: dotenv
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '2.8'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.8'
69
- - !ruby/object:Gem::Dependency
70
- name: awesome_print
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '1.9'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.9'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '13.0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '13.0'
97
- - !ruby/object:Gem::Dependency
98
- name: debug
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '1.7'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '1.7'
111
- - !ruby/object:Gem::Dependency
112
- name: rspec
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '3.12'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '3.12'
125
- - !ruby/object:Gem::Dependency
126
- name: webmock
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '3.14'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '3.14'
139
- - !ruby/object:Gem::Dependency
140
- name: vcr
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '6.1'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '6.1'
153
55
  description: Ruby client library which includes index and vector operations to upload
154
56
  embeddings into Pinecone and do similarity searches on them.
155
57
  email: scott@extrayarn.com
@@ -161,6 +63,7 @@ files:
161
63
  - lib/pinecone/client.rb
162
64
  - lib/pinecone/collection.rb
163
65
  - lib/pinecone/index.rb
66
+ - lib/pinecone/response_parser.rb
164
67
  - lib/pinecone/vector.rb
165
68
  - lib/pinecone/vector/filter.rb
166
69
  - lib/pinecone/vector/query.rb
@@ -179,14 +82,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
179
82
  requirements:
180
83
  - - ">="
181
84
  - !ruby/object:Gem::Version
182
- version: '0'
85
+ version: '3'
183
86
  required_rubygems_version: !ruby/object:Gem::Requirement
184
87
  requirements:
185
88
  - - ">="
186
89
  - !ruby/object:Gem::Version
187
90
  version: '0'
188
91
  requirements: []
189
- rubygems_version: 3.4.3
92
+ rubygems_version: 3.5.15
190
93
  signing_key:
191
94
  specification_version: 4
192
95
  summary: Ruby client library for Pinecone Vector DB