epsilla-ruby 0.0.1

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: 02ec2167e8966de5929e21521bcd3640683d4ac7a4c27b42c811a85714d4d7bc
4
+ data.tar.gz: 1c665e9af8e44e1a5f16b965c0996075ad4aa5833f6c92207c3492488293dc70
5
+ SHA512:
6
+ metadata.gz: 72ad5416ad62fc593691288456294781a16aeb6aac85e12ef5257e133b2abd6df834963a3c2f40656d45235d7a5ea61b912716ba8b7250ad778192e403e09339
7
+ data.tar.gz: a805cb4f2ad872fbfeae05c7756bbb15f40d052cebc1c0fe68f4305e90078f0165095a104fec82de5759b5e43537bdf7544e65dd7f6ec899a4cc7ae8db4a05a5
data/CHANGELOG.md ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # Epsilla Ruby SDK
2
+
3
+ Welcome to Ruby SDK for Epsilla Vector Database!
4
+
5
+ ## Installation
6
+ ```shell
7
+ bundle add epsilla-ruby
8
+ gem install epsilla-ruby
9
+ ```
10
+
11
+
12
+ ## Usage
13
+
14
+ ### Run Epsilla Vectordb using Docker
15
+ ```shell
16
+ docker run --pull=always -d -p 8888:8888 epsilla/vectordb
17
+ ```
18
+
19
+ ### Use epsilla-ruby to connect to and interact with vector database
20
+ ```ruby
21
+
22
+ require "epsilla"
23
+
24
+ # Connect to Epsilla VectorDB
25
+ client = Epsilla::Client.new(protocol="http", host="127.0.0.1", port="8888")
26
+ # puts client.live?
27
+
28
+ # Load DB with path
29
+ status_code, response = client.database.load_db(db_name="MyDB", db_path="/tmp/epsilla")
30
+ puts status_code, response
31
+
32
+ # Set DB to current DB
33
+ client.database.use_db(db_name="MyDB")
34
+
35
+ # Create a table with schema in current DB
36
+ table_fields= [
37
+ {"name" => "ID", "dataType" => "INT"},
38
+ {"name" => "Doc", "dataType" => "STRING"},
39
+ {"name" => "Embedding", "dataType" => "VECTOR_FLOAT", "dimensions" => 4}
40
+ ]
41
+ # table_fields.each { |x| puts "==#{x}"}
42
+ status_code, response = client.database.create_table(table_name="MyTable", table_fields=table_fields)
43
+ puts status_code, response
44
+
45
+ # Insert new vector records into table
46
+ table_records = [
47
+ {"ID" => 1, "Doc" => "Berlin", "Embedding" => [0.05, 0.61, 0.76, 0.74]},
48
+ {"ID" => 2, "Doc" => "London", "Embedding" => [0.19, 0.81, 0.75, 0.11]},
49
+ {"ID" => 3, "Doc" => "Moscow", "Embedding" => [0.36, 0.55, 0.47, 0.94]},
50
+ {"ID" => 4, "Doc" => "San Francisco", "Embedding" => [0.18, 0.01, 0.85, 0.80]},
51
+ {"ID" => 5, "Doc" => "Shanghai", "Embedding" => [0.24, 0.18, 0.22, 0.44]}
52
+ ]
53
+
54
+ status_code, response = client.database.insert(table_name="MyTable", table_records=table_records)
55
+ puts status_code, response
56
+
57
+ # Rebuild
58
+ status_code, response = client.database.rebuild()
59
+ puts status_code, response
60
+
61
+ # Query Vectors
62
+ query_field = "Embedding"
63
+ response_fields = ["Doc"]
64
+ query_vector=[0.35, 0.55, 0.47, 0.94]
65
+ limit=1
66
+ 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)
67
+ puts status_code, response
68
+
69
+
70
+ # Drop table
71
+ status_code, response = client.database.drop_table("MyTable")
72
+ puts status_code, response
73
+
74
+ # Unload db
75
+ status_code, response = client.database.unload_db("MyDB")
76
+ puts status_code, response
77
+
78
+ ```
79
+
80
+ ## Contributing
81
+ 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,66 @@
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
+ # Connect to Epsilla VectorDB
12
+ client = Epsilla::Client.new(protocol="http", host="127.0.0.1", port="8888")
13
+ # puts client.live?
14
+
15
+ # Load DB with path
16
+ status_code, response = client.database.load_db(db_name="MyDB", db_path="/tmp/epsilla")
17
+ puts status_code, response
18
+
19
+ # Set DB to current DB
20
+ client.database.use_db(db_name="MyDB")
21
+
22
+ # Create a table with schema in current DB
23
+ table_fields= [
24
+ {"name" => "ID", "dataType" => "INT"},
25
+ {"name" => "Doc", "dataType" => "STRING"},
26
+ {"name" => "Embedding", "dataType" => "VECTOR_FLOAT", "dimensions" => 4}
27
+ ]
28
+ # table_fields.each { |x| puts "==#{x}"}
29
+ status_code, response = client.database.create_table(table_name="MyTable", table_fields=table_fields)
30
+ puts status_code, response
31
+
32
+ # Insert new vector records into table
33
+ table_records = [
34
+ {"ID" => 1, "Doc" => "Berlin", "Embedding" => [0.05, 0.61, 0.76, 0.74]},
35
+ {"ID" => 2, "Doc" => "London", "Embedding" => [0.19, 0.81, 0.75, 0.11]},
36
+ {"ID" => 3, "Doc" => "Moscow", "Embedding" => [0.36, 0.55, 0.47, 0.94]},
37
+ {"ID" => 4, "Doc" => "San Francisco", "Embedding" => [0.18, 0.01, 0.85, 0.80]},
38
+ {"ID" => 5, "Doc" => "Shanghai", "Embedding" => [0.24, 0.18, 0.22, 0.44]}
39
+ ]
40
+
41
+ status_code, response = client.database.insert(table_name="MyTable", table_records=table_records)
42
+ puts status_code, response
43
+
44
+ # Rebuild
45
+ status_code, response = client.database.rebuild()
46
+ puts status_code, response
47
+
48
+ # Query Vectors
49
+ query_field = "Embedding"
50
+ response_fields = ["Doc"]
51
+ query_vector=[0.35, 0.55, 0.47, 0.94]
52
+ limit=1
53
+ 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)
54
+ puts status_code, response
55
+
56
+
57
+ # Drop table
58
+ status_code, response = client.database.drop_table("MyTable")
59
+ puts status_code, response
60
+
61
+ # Unload db
62
+ status_code, response = client.database.unload_db("MyDB")
63
+ puts status_code, response
64
+
65
+
66
+
@@ -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.1"
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,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: epsilla-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Epsilla Team
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-08-13 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
+ - admin@epsilla.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - CHANGELOG.md
37
+ - README.md
38
+ - Rakefile
39
+ - examples/hello_epsilla.rb
40
+ - lib/epsilla.rb
41
+ - lib/epsilla/base.rb
42
+ - lib/epsilla/client.rb
43
+ - lib/epsilla/database.rb
44
+ - lib/epsilla/error.rb
45
+ - lib/epsilla/health.rb
46
+ - lib/epsilla/version.rb
47
+ - sig/epsilla.rbs
48
+ homepage: https://github.com/epsilla-cloud/vectordb
49
+ licenses:
50
+ - MIT
51
+ metadata:
52
+ homepage_uri: https://github.com/epsilla-cloud/vectordb
53
+ source_code_uri: https://github.com/epsilla-cloud/epsilla-ruby
54
+ changelog_uri: https://github.com/epsilla-cloud/epsilla-ruby/blob/main/CHANGELOG.md
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.6.0
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubygems_version: 3.4.18
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Ruby client for Epsilla Vector Database
74
+ test_files: []