epsilla 0.0.2

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: d9735534acaf9e3a5999efd311c5196490ba03dc496c6cf58b3036aa6efa91a3
4
+ data.tar.gz: 510f3196a738e8a5b15e70dc2e08e760117ac03b460c73e9225182094d9760f7
5
+ SHA512:
6
+ metadata.gz: 64233f486d746bbab551b38aeec8941eccd40df601387ebbb77429ae83a8a6f7666536552f4f4cc972b585a238d79ab6c04b22e4e4a4a43778ec0030d156a2a9
7
+ data.tar.gz: 3139f12945ac88a04f347d8944a8a0b68db957ce70c392868894e9119fb8b2ff10d125212bc049b9322de6dc10c75fe5fce66dbb8fba9d057f6bd70d34f17f6b
data/CHANGELOG.md ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Epsilla Ruby SDK
2
+
3
+ Welcome to Ruby SDK for Epsilla Vector Database!
4
+ https://rubygems.org/gems/epsilla-ruby
5
+
6
+
7
+ ## Installation
8
+ ```shell
9
+ bundle add epsilla-ruby
10
+ gem install epsilla-ruby
11
+ ```
12
+
13
+
14
+ ## Usage
15
+
16
+ ### Run Epsilla Vectordb using Docker
17
+ ```shell
18
+ docker run --pull=always -d -p 8888:8888 epsilla/vectordb
19
+ ```
20
+
21
+ ### Use epsilla-ruby to connect to and interact with vector database
22
+ ```ruby
23
+
24
+ require "epsilla"
25
+
26
+ # Connect to Epsilla VectorDB
27
+ client = Epsilla::Client.new(protocol="http", host="127.0.0.1", port="8888")
28
+ # puts client.live?
29
+
30
+ # Load DB with path
31
+ status_code, response = client.database.load_db(db_name="MyDB", db_path="/tmp/epsilla")
32
+ puts status_code, response
33
+
34
+ # Set DB to current DB
35
+ client.database.use_db(db_name="MyDB")
36
+
37
+ # Create a table with schema in current DB
38
+ table_fields= [
39
+ {"name" => "ID", "dataType" => "INT"},
40
+ {"name" => "Doc", "dataType" => "STRING"},
41
+ {"name" => "Embedding", "dataType" => "VECTOR_FLOAT", "dimensions" => 4}
42
+ ]
43
+ # table_fields.each { |x| puts "==#{x}"}
44
+ status_code, response = client.database.create_table(table_name="MyTable", table_fields=table_fields)
45
+ puts status_code, response
46
+
47
+ # Insert new vector records into table
48
+ table_records = [
49
+ {"ID" => 1, "Doc" => "Berlin", "Embedding" => [0.05, 0.61, 0.76, 0.74]},
50
+ {"ID" => 2, "Doc" => "London", "Embedding" => [0.19, 0.81, 0.75, 0.11]},
51
+ {"ID" => 3, "Doc" => "Moscow", "Embedding" => [0.36, 0.55, 0.47, 0.94]},
52
+ {"ID" => 4, "Doc" => "San Francisco", "Embedding" => [0.18, 0.01, 0.85, 0.80]},
53
+ {"ID" => 5, "Doc" => "Shanghai", "Embedding" => [0.24, 0.18, 0.22, 0.44]}
54
+ ]
55
+
56
+ status_code, response = client.database.insert(table_name="MyTable", table_records=table_records)
57
+ puts status_code, response
58
+
59
+ # Rebuild
60
+ status_code, response = client.database.rebuild()
61
+ puts status_code, response
62
+
63
+ # Query Vectors
64
+ query_field = "Embedding"
65
+ response_fields = ["Doc"]
66
+ query_vector=[0.35, 0.55, 0.47, 0.94]
67
+ limit=1
68
+ status_code, response = client.database.query(table_name="MyTable", query_field=query_field, query_vector=query_vector, response_fields=response_fields, limit=limit, with_distance=true)
69
+ puts status_code, response
70
+
71
+
72
+ # Drop table
73
+ #status_code, response = client.database.drop_table("MyTable")
74
+ #puts status_code, response
75
+
76
+ # Unload db
77
+ #status_code, response = client.database.unload_db("MyDB")
78
+ #puts status_code, response
79
+
80
+ ```
81
+
82
+ ## Contributing
83
+ Bug reports and pull requests are welcome on GitHub at https://github.com/epsilla-cloud/epsilla-ruby.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Try this simple example
4
+ # 1. docker run --pull=always -d -p 8888:8888 epsilla/vectordb
5
+ # 2. gem install epsilla-ruby && gem update epsilla-ruby
6
+ # 3. ruby hello_epsilla.rb
7
+
8
+
9
+ require "epsilla"
10
+
11
+
12
+ # Connect to Epsilla VectorDB
13
+ client = Epsilla::Client.new(protocol="http", host="127.0.0.1", port="8888")
14
+ # puts client.live?
15
+
16
+ # Load DB with path
17
+ status_code, response = client.database.load_db(db_name="MyDB", db_path="/tmp/epsilla")
18
+ puts status_code, response
19
+
20
+ # Set DB to current DB
21
+ client.database.use_db(db_name="MyDB")
22
+
23
+ # Create a table with schema in current DB
24
+ table_fields= [
25
+ {"name" => "ID", "dataType" => "INT"},
26
+ {"name" => "Doc", "dataType" => "STRING"},
27
+ {"name" => "Embedding", "dataType" => "VECTOR_FLOAT", "dimensions" => 4}
28
+ ]
29
+ # table_fields.each { |x| puts "==#{x}"}
30
+ status_code, response = client.database.create_table(table_name="MyTable", table_fields=table_fields)
31
+ puts status_code, response
32
+
33
+ # Insert new vector records into table
34
+ table_records = [
35
+ {"ID" => 1, "Doc" => "Berlin", "Embedding" => [0.05, 0.61, 0.76, 0.74]},
36
+ {"ID" => 2, "Doc" => "London", "Embedding" => [0.19, 0.81, 0.75, 0.11]},
37
+ {"ID" => 3, "Doc" => "Moscow", "Embedding" => [0.36, 0.55, 0.47, 0.94]},
38
+ {"ID" => 4, "Doc" => "San Francisco", "Embedding" => [0.18, 0.01, 0.85, 0.80]},
39
+ {"ID" => 5, "Doc" => "Shanghai", "Embedding" => [0.24, 0.18, 0.22, 0.44]}
40
+ ]
41
+
42
+ status_code, response = client.database.insert(table_name="MyTable", table_records=table_records)
43
+ puts status_code, response
44
+
45
+ # Rebuild
46
+ status_code, response = client.database.rebuild()
47
+ puts status_code, response
48
+
49
+ # Query vectors
50
+ query_field = "Embedding"
51
+ query_vector=[0.35, 0.55, 0.47, 0.94]
52
+ response_fields = ["Doc"]
53
+ limit=2
54
+ status_code, response = client.database.query(table_name="MyTable", query_field=query_field, query_vector=query_vector, response_fields=response_fields, limit=limit, with_distance=true)
55
+ puts status_code, response
56
+
57
+
58
+ # Drop table
59
+ status_code, response = client.database.drop_table("MyTable")
60
+ puts status_code, response
61
+
62
+ # Unload db
63
+ status_code, response = client.database.unload_db("MyDB")
64
+ puts status_code, response
65
+
66
+
67
+
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Epsilla
4
+ class Base
5
+ attr_reader :client
6
+
7
+ def initialize(client:)
8
+ @client = client
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+
5
+
6
+ module Epsilla
7
+ class Client
8
+ attr_reader :protocol, :host, :port, :adapter, :debug
9
+
10
+ def self.welcome
11
+ puts "WELCOME To EPSILLA VECTOR DATABASE!"
12
+ end
13
+
14
+ def initialize(protocol, host, port, adapter: Faraday.default_adapter, debug: false)
15
+ @url = "#{protocol}://#{host}:#{port}"
16
+ @adapter = adapter
17
+ @debug = debug
18
+ end
19
+
20
+
21
+ def connection
22
+ @conn ||= Faraday.new(url: "#{@url}", request: { timeout: 30 }) do |faraday|
23
+ faraday.request :json
24
+ faraday.response :logger if @debug
25
+ faraday.response :json, content_type: /\bjson$/
26
+ faraday.adapter @adapter
27
+ faraday.options.timeout = 30 # 30s
28
+ faraday.options.open_timeout = 30 # 30s
29
+ faraday.headers['Content-type'] = 'application/json'
30
+ end
31
+ end
32
+
33
+ def live?
34
+ @health ||= Epsilla::Health.new(client: self)
35
+ @health.live?
36
+ end
37
+
38
+ def state
39
+ @health ||= Epsilla::Health.new(client: self)
40
+ @health.state
41
+ end
42
+
43
+ def database
44
+ @database ||= Epsilla::DataBase.new(client: self)
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Epsilla
4
+ class DataBase < Base
5
+
6
+ # use db
7
+ def use_db(db_name)
8
+ @db_name = db_name
9
+ end
10
+
11
+ # load db
12
+ def load_db(db_name, db_path, vector_scale: nil, wal_enabled: false)
13
+ response = client.connection.post do |req|
14
+ req.url "/api/load"
15
+ req.body = {"name": db_name, "path": db_path}.to_json
16
+ req.body["vectorScale"] = vector_scale if vector_scale
17
+ req.body["walEnabled"] = wal_enabled if wal_enabled
18
+ end
19
+ return response.status, response.body
20
+ end
21
+
22
+ # unload db
23
+ def unload_db(db_name)
24
+ @db_name = nil
25
+ response = client.connection.post do |req|
26
+ req.url "/api/#{db_name}/unload"
27
+ end
28
+ return response.status, response.body
29
+ end
30
+
31
+ # create table in the db
32
+ def create_table(table_name = "MyTable", table_fields = nil)
33
+ unless @db_name
34
+ raise Exception("[ERROR] Please use_db() first!")
35
+ end
36
+ unless table_fields
37
+ table_fields = Array.new
38
+ end
39
+
40
+ response = client.connection.post do |req|
41
+ req.url "/api/#{@db_name}/schema/tables"
42
+ req.body = {"name": table_name, "fields": table_fields}.to_json
43
+ end
44
+
45
+ return response.status, response.body
46
+ end
47
+
48
+ # insert data into table
49
+ def insert(table_name = "MyTable", table_records = nil)
50
+ unless @db_name
51
+ raise Exception("[ERROR] Please use_db() first!")
52
+ end
53
+ unless table_records
54
+ table_records = Array.new
55
+ end
56
+ response = client.connection.post do |req|
57
+ req.url "/api/#{@db_name}/data/insert"
58
+ req.body = {"table": table_name, "data": table_records}.to_json
59
+ end
60
+
61
+ return response.status, response.body
62
+ end
63
+
64
+ # rebuild the table
65
+ def rebuild
66
+ # puts "[INFO] waiting until rebuild is finished ..."
67
+ response = client.connection.post do |req|
68
+ req.url '/api/rebuild'
69
+ req.options.timeout = 7200 # 7200s
70
+ end
71
+ return response.status, response.body
72
+ end
73
+
74
+ # query
75
+ def query(table_name = "MyTable", query_field = "", query_vector = nil, response_fields = nil, limit = 1, with_distance = false)
76
+ unless @db_name
77
+ raise Exception("[ERROR] Please use_db() first!")
78
+ end
79
+ unless query_vector
80
+ query_vector = ""
81
+ end
82
+ unless response_fields
83
+ response_fields = Array.new
84
+ end
85
+
86
+ response = client.connection.post do |req|
87
+ req.url "/api/#{@db_name}/data/query"
88
+ req.body = {"table": table_name, "queryField": query_field, "queryVector": query_vector, "response": response_fields, "limit": limit, "withDistance": with_distance}.to_json
89
+ end
90
+ return response.status, response.body
91
+ end
92
+
93
+ # get
94
+ def get(table_name= "MyTable", response_fields = nil)
95
+ unless @db_name
96
+ raise Exception("[ERROR] Please use_db() first!")
97
+ end
98
+ unless response_fields
99
+ response_fields = Array.new
100
+ end
101
+ response = client.connection.post do |req|
102
+ req.url "/api/#{@db_name}/data/get"
103
+ req.body = {"table": table_name, "response": response_fields}.to_json
104
+ end
105
+ return response.status, response.body
106
+ end
107
+
108
+ # drop table
109
+ def drop_table(table_name)
110
+ unless @db_name
111
+ raise Exception("[ERROR] Please use_db() first!")
112
+ end
113
+ response = client.connection.delete do |req|
114
+ req.url "/api/#{@db_name}/schema/tables/#{table_name}"
115
+ end
116
+ return response.status, response.body
117
+ end
118
+
119
+ # drop db
120
+ def drop_db(db_name)
121
+ response = client.connection.delete do |req|
122
+ req.url "/api/#{@db_name}/drop"
123
+ end
124
+ return response.status, response.body
125
+ end
126
+
127
+ end
128
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Epsilla
4
+ class Error < StandardError
5
+ end
6
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Epsilla
4
+ class Health < Base
5
+
6
+ def live?
7
+ response = client.connection.get do |req|
8
+ req.url '/'
9
+ end
10
+ if response.status != 200
11
+ raise Exception.new "[ERROR] Failed to connect to #{@url}"
12
+ else
13
+ true
14
+ end
15
+ end
16
+
17
+ def state
18
+ response = client.connection.get("/state")
19
+ response.status == 200
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Epsilla
4
+ VERSION = "0.0.2"
5
+ end
data/lib/epsilla.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "epsilla/version"
4
+
5
+ module Epsilla
6
+ autoload :Base, "epsilla/base"
7
+ autoload :Client, "epsilla/client"
8
+ autoload :DataBase, "epsilla/database"
9
+ autoload :Health, "epsilla/health"
10
+ autoload :Error, "epsilla/error"
11
+ end
data/sig/epsilla.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Epsilla
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: epsilla
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Epsilla Team
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ description: EpsillaDB is a scalable, high-performance, and cost-effective vector
28
+ database
29
+ email:
30
+ - eric@epsilla.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - CHANGELOG.md
36
+ - README.md
37
+ - Rakefile
38
+ - examples/hello_epsilla.rb
39
+ - lib/epsilla.rb
40
+ - lib/epsilla/base.rb
41
+ - lib/epsilla/client.rb
42
+ - lib/epsilla/database.rb
43
+ - lib/epsilla/error.rb
44
+ - lib/epsilla/health.rb
45
+ - lib/epsilla/version.rb
46
+ - sig/epsilla.rbs
47
+ homepage: https://github.com/epsilla-cloud/vectordb
48
+ licenses:
49
+ - MIT
50
+ metadata:
51
+ homepage_uri: https://github.com/epsilla-cloud/vectordb
52
+ source_code_uri: https://github.com/epsilla-cloud/epsilla-ruby-client
53
+ changelog_uri: https://github.com/epsilla-cloud/epsilla-ruby-client/blob/main/CHANGELOG.md
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.6.0
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubygems_version: 3.4.18
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Ruby client for Epsilla Vector Database
73
+ test_files: []