chroma-db 0.2.0 → 0.4.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: 9273343cf2f29991d61d8e5393dfd06541211c84e03769162fa984c9ca2c8620
4
- data.tar.gz: 3dd3e94d5914e5776aef673f18b06bbb6f61254bbe4eb51ae25f8675f6c9c72b
3
+ metadata.gz: 81e14d1d408077096602201fb386612b9d511a0294726efcba2942491a164763
4
+ data.tar.gz: bc06c130d7ad215d5a2264527813e10900bda1b6d8975de8c59712a7cb438a99
5
5
  SHA512:
6
- metadata.gz: 8c94d838879f22cae956b9a4b7e66f8b8a8d76792770dda6eb9a91b197aa0eb3b8408256653402feb750732f35fb221ae2ebedfe05ab49d89896b80579228ed0
7
- data.tar.gz: f5ad7421b54da9909a3a1c76d36d07738ccd44aaa934a7e960e5b102608e24c61e36243b59c0d2ba469e01c34b2cc360e2a07a82516d1a4a2d73cfffa49334fa
6
+ metadata.gz: 109074182103666dca9fb201c0dc473220b0a5ee6849ff3022203a4debea1388347b98d74a0ce14d75361953a1c70b6c1a24ab62387c317e394712fe677e082a
7
+ data.tar.gz: f075cf97229240b6d38ff72946188ec436a0010b8f0925d1b30a63e6c2b3dc0b6bf8436a16d0c3abf5c89cabe64951b73bd10eb036b95a3ae9a40b8f2c778cdd
data/.rbnextrc ADDED
@@ -0,0 +1,5 @@
1
+ nextify: |
2
+ ./lib
3
+ --min-version=2.6
4
+ --edge
5
+ --proposed
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] 2023-05-23
4
+
5
+ - This version implements Chroma's API change where Collection uses its collection id for many operations. Changes in the
6
+ gem are internals, public API remains the same. Just be aware you need Chroma 0.3.25 or better with this gem version.
7
+
8
+ ## [0.3.0] 2023-05-19
9
+
10
+ - Uses Ruby Next to transpile newer Ruby to older Ruby versions in order to support Ruby 2.7, 3.0, and 3.1
11
+
12
+ ## [0.2.0] 2023-05-12
13
+
14
+ - Complete API to communicate with Chroma database via its API interface
15
+
3
16
  ## [0.1.0] - 2023-05-04
4
17
 
5
18
  - Initial release
data/Gemfile CHANGED
@@ -13,4 +13,6 @@ gem "standard", "~> 1.3"
13
13
 
14
14
  gem "rbs", "~> 3.1"
15
15
 
16
+ gem "sdoc", "~> 2.6", ">= 2.6.1"
17
+
16
18
  gem "webmock", "~> 3.18", ">= 3.18.1"
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- chroma-db (0.2.0)
4
+ chroma-db (0.4.0)
5
5
  dry-monads (~> 1.6)
6
+ ruby-next (>= 0.15.0)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
@@ -13,6 +14,7 @@ GEM
13
14
  concurrent-ruby (1.2.2)
14
15
  crack (0.4.5)
15
16
  rexml
17
+ diff-lcs (1.5.0)
16
18
  dry-core (1.0.0)
17
19
  concurrent-ruby (~> 1.0)
18
20
  zeitwerk (~> 2.6)
@@ -28,10 +30,14 @@ GEM
28
30
  parallel (1.23.0)
29
31
  parser (3.2.2.1)
30
32
  ast (~> 2.4.1)
33
+ psych (5.1.0)
34
+ stringio
31
35
  public_suffix (5.0.1)
32
36
  rainbow (3.1.1)
33
37
  rake (13.0.6)
34
38
  rbs (3.1.0)
39
+ rdoc (6.5.0)
40
+ psych (>= 4.0.0)
35
41
  regexp_parser (2.8.0)
36
42
  rexml (3.2.5)
37
43
  rubocop (1.50.2)
@@ -49,7 +55,16 @@ GEM
49
55
  rubocop-performance (1.16.0)
50
56
  rubocop (>= 1.7.0, < 2.0)
51
57
  rubocop-ast (>= 0.4.0)
58
+ ruby-next (0.15.3)
59
+ ruby-next-core (= 0.15.3)
60
+ ruby-next-parser (>= 3.1.1.0)
61
+ unparser (~> 0.6.0)
62
+ ruby-next-core (0.15.3)
63
+ ruby-next-parser (3.1.1.3)
64
+ parser (>= 3.0.3.1)
52
65
  ruby-progressbar (1.13.0)
66
+ sdoc (2.6.1)
67
+ rdoc (>= 5.0)
53
68
  standard (1.28.2)
54
69
  language_server-protocol (~> 3.17.0.2)
55
70
  lint_roller (~> 1.0)
@@ -61,7 +76,11 @@ GEM
61
76
  standard-performance (1.0.1)
62
77
  lint_roller (~> 1.0)
63
78
  rubocop-performance (~> 1.16.0)
79
+ stringio (3.0.6)
64
80
  unicode-display_width (2.4.2)
81
+ unparser (0.6.7)
82
+ diff-lcs (~> 1.3)
83
+ parser (>= 3.2.0)
65
84
  webmock (3.18.1)
66
85
  addressable (>= 2.8.0)
67
86
  crack (>= 0.3.2)
@@ -77,6 +96,8 @@ DEPENDENCIES
77
96
  minitest (~> 5.0)
78
97
  rake (~> 13.0)
79
98
  rbs (~> 3.1)
99
+ ruby-next (>= 0.15.0)
100
+ sdoc (~> 2.6, >= 2.6.1)
80
101
  standard (~> 1.3)
81
102
  webmock (~> 3.18, >= 3.18.1)
82
103
 
data/README.md CHANGED
@@ -1,39 +1,78 @@
1
- # Chroma
1
+ # Chroma's Ruby client
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
3
+ Chroma is the open-source embedding database. Chroma makes it easy to build LLM apps by making knowledge, facts, and skills pluggable for LLMs.
4
4
 
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/chroma`. To experiment with that code, run `bin/console` for an interactive prompt.
5
+ This Ruby gem is a client to connect to Chroma's database via its API.
6
6
 
7
- ## Installation
7
+ Find more information about Chroma on how to install at their website. [https://www.trychroma.com/](https://www.trychroma.com/)
8
+
9
+ ## Description
10
+ Chroma-rb is a Ruby client for Chroma Database. It works with version 0.3.22 or better **(Please see requirements below)**.
11
+
12
+ A small example usage
13
+
14
+ ```ruby
15
+ require "logger"
16
+
17
+ # Requiere Chroma Ruby client.
18
+ require "chroma-db"
19
+
20
+ # Configure Chroma's host. Here you can specify your own host.
21
+ Chroma.connect_host = "http://localhost:8000"
22
+ Chroma.logger = Logger.new($stdout)
23
+ Chroma.log_level = Chroma::LEVEL_ERROR
24
+
25
+ # Check current Chrome server version
26
+ version = Chroma::Resources::Database.version
27
+ puts version
28
+
29
+ # Create a new collection
30
+ collection = Chroma::Resources::Collection.create(collection_name, {lang: "ruby", gem: "chroma-db"})
8
31
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
32
+ # Add embeddings
33
+ embeddings = [
34
+ Chroma::Resources::Embedding.new(id: "1", embedding: [1.3, 2.6, 3.1], metadata: {client: "chroma-rb"}, document: "ruby"),
35
+ Chroma::Resources::Embedding.new(id: "2", embedding: [3.7, 2.8, 0.9], metadata: {client: "chroma-rb"}, document: "rails")
36
+ ]
37
+ collection.add(embeddings)
38
+ ```
10
39
 
11
- Install the gem and add to the application's Gemfile by executing:
40
+ For a complete example, please refer to the Jupyter Noterbook [Chroma gem](https://github.com/mariochavez/chroma/blob/main/notebook/Chroma%20Gem.ipynb)
12
41
 
13
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
42
+ ## Requirements
43
+ - Ruby 2.7.8 or newer
44
+ - Chroma Database 0.3.25 or later running as a client/server model.
45
+
46
+ For Chroma database 0.3.22 or older, please use version 0.3.0 of this gem.
47
+
48
+ ## Installation
49
+ To install the gem and add to the application's Gemfile, execute:
50
+
51
+ $ bundle add chroma-db
14
52
 
15
53
  If bundler is not being used to manage dependencies, install the gem by executing:
16
54
 
17
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
55
+ $ gem install chroma-db
18
56
 
19
- ## Usage
57
+ ## Use the Jupyter notebook
58
+ To use the Jupyter Noterbook [Chroma gem](https://github.com/mariochavez/chroma/blob/main/notebook/Chroma%20Gem.ipynb) in this repository, please install python 3.9 or better, iruby and Jupyter notebook dependencies:
20
59
 
21
- TODO: Write usage instructions here
60
+ $ pip install jupyterlab notebook ipywidgets
61
+ $ gem install iruby
62
+ $ iruby register --force
22
63
 
23
- ## Development
64
+ ## Development 
65
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. 
24
66
 
25
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
67
+ To install this gem onto your local machine, run `bundle exec rake install`.
26
68
 
27
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
+ To generate Rdoc documentation for the gem, run `bundle exec rake rdoc`.
28
70
 
29
71
  ## Contributing
30
-
31
- Bug reports and pull requests are welcome on GitHub at https://github.com/mariochavez/chroma. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/mariochavez/chroma/blob/main/CODE_OF_CONDUCT.md).
72
+ Bug reports and pull requests are welcome on GitHub at https://github.com/mariochavez/chroma. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/mariochavez/chroma/blob/main/CODE_OF_CONDUCT.md). 
32
73
 
33
74
  ## License
34
-
35
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
75
+ The gem is available as open source under the terms of the [MIT License](https://github.com/mariochavez/chroma/blob/main/LICENSE.txt).
36
76
 
37
77
  ## Code of Conduct
38
-
39
78
  Everyone interacting in the Chroma project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mariochavez/chroma/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -12,3 +12,17 @@ end
12
12
  require "standard/rake"
13
13
 
14
14
  task default: %i[test standard]
15
+
16
+ require "sdoc" # and use your RDoc task the same way you used it before
17
+ require "rdoc/task" # ensure this file is also required in order to use `RDoc::Task`
18
+
19
+ RDoc::Task.new do |rdoc|
20
+ rdoc.rdoc_dir = "doc/rdoc" # name of output directory
21
+ rdoc.options << "--format=sdoc" # explictly set the sdoc generator
22
+ rdoc.template = "rails" # template used on api.rubyonrails.org
23
+ end
24
+
25
+ desc "Run Ruby Next nextify"
26
+ task :nextify do
27
+ sh "bundle exec ruby-next nextify -V"
28
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chroma
4
+ module APIOperations
5
+ using RubyNext
6
+
7
+ # Request's response Data object.
8
+ #
9
+ # status - HTTP status code. It is zero when a request fails due to network error.
10
+ # body - Parsed JSON object or response body.
11
+ # headers - HTTP response headers.
12
+ # error - Exception or Net::HTTPResponse object if the response is not Net::HTTPSuccess
13
+ #
14
+ # NOTE: Not supported yet by Ruby Next
15
+ # Response = Data.define(:status, :body, :headers, :error)
16
+ Response = Struct.new("Response", :status, :body, :headers, :error)
17
+
18
+ # Request module provides functionality to perform HTTP requests.
19
+ module Request
20
+ module ClassMethods
21
+ include Dry::Monads[:result]
22
+
23
+ # Execute an HTTP request and return a monad wrapping the response.
24
+ #
25
+ # method - The HTTP method to use (e.g. 'GET', 'POST'). Method must be a `Symbol`.
26
+ # url - The URL to send the request to.
27
+ # params - The query parameters or request body. Params needs to be in a form of a Hash.
28
+ # options - Additional options to pass to the request.
29
+ #
30
+ # A `Dry::Monads::Result` monad wrapping the response, either a success or failure.
31
+ # The response is a `Chroma::APIOperations::Response` Data object.
32
+ #
33
+ # Examples
34
+ #
35
+ # result = execute_request(:get, "https://example.com", {name: "test request"})
36
+ # if result.success?
37
+ # puts "Response status: #{result.success.status}"
38
+ # puts "Response body: #{result.success.body}"
39
+ # else
40
+ # puts "Request failed with error: #{result.failure.error}"
41
+ # end
42
+ def execute_request(method, url, params = {}, options = {})
43
+ uri = URI.parse(url)
44
+
45
+ request = build_request(method, uri, params)
46
+
47
+ use_ssl = options.delete(:use_ssl) || false
48
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
49
+ Chroma::Util.log_debug("Sending a request", {method: method, uri: uri, params: params})
50
+ http.request(request)
51
+ end
52
+
53
+ build_response(response)
54
+ rescue => ex
55
+ build_response(ex)
56
+ end
57
+
58
+ private def build_response(response)
59
+ case; when ((__m__ = response)) && false
60
+ when (((success_response,) = nil) || ((Net::HTTPSuccess === __m__) && ((success_response = __m__) || true)))
61
+
62
+
63
+ Chroma::Util.log_info("Successful response", code: success_response.code)
64
+
65
+ build_response_details(success_response)
66
+ when (((redirect_response,) = nil) || ((Net::HTTPRedirection === __m__) && ((redirect_response = __m__) || true)))
67
+
68
+
69
+ Chroma::Util.log_info("Server redirect response", code: redirect_response.code, location: redirect_response["location"])
70
+
71
+ build_response_details(redirect_response)
72
+ when (((client_error_response,) = nil) || ((Net::HTTPClientError === __m__) && ((client_error_response = __m__) || true)))
73
+
74
+
75
+ Chroma::Util.log_error("Client error response", code: client_error_response.code, body: client_error_response.body)
76
+
77
+ build_response_details(client_error_response)
78
+ when (((server_error_response,) = nil) || ((Net::HTTPServerError === __m__) && ((server_error_response = __m__) || true)))
79
+
80
+
81
+ Chroma::Util.log_error("Server error response", code: server_error_response.code)
82
+
83
+ build_response_details(server_error_response, parse_body: false)
84
+ else
85
+ Chroma::Util.log_error("An error happened", error: response.to_s)
86
+
87
+ build_response_details(response, exception: true, parse_body: false)
88
+ end
89
+ end
90
+
91
+ private def build_response_details(response, exception: false, parse_body: true)
92
+ response_data = Chroma::APIOperations::Response.new(
93
+ exception ? 0 : response.code.to_i,
94
+ if exception
95
+ exception.to_s
96
+ else
97
+ (parse_body ? body_to_json(response.body) : response.body)
98
+ end,
99
+ exception ? {} : response.each_header.to_h,
100
+ response.is_a?(Net::HTTPSuccess) ? nil : response
101
+ )
102
+
103
+ case; when ((__m__ = response)) && false
104
+ when (Net::HTTPSuccess === __m__)
105
+ return Success(response_data)
106
+ else
107
+ return Failure(response_data)
108
+ end
109
+ end
110
+
111
+ private def body_to_json(content)
112
+ JSON.parse(content, symbolize_keys: true)
113
+ rescue JSON::ParserError, TypeError
114
+ content
115
+ end
116
+
117
+ private def build_request(method, uri, params)
118
+ request = case method
119
+ when :post then Net::HTTP::Post.new(uri)
120
+ when :put then Net::HTTP::Put.new(uri)
121
+ when :delete then Net::HTTP::Delete.new(uri)
122
+ else
123
+ Net::HTTP::Get.new(uri)
124
+ end
125
+
126
+ request.content_type = "application/json"
127
+ request.body = params.to_json if params.size > 0
128
+
129
+ request
130
+ end
131
+ end
132
+
133
+ def self.included(base)
134
+ base.extend(ClassMethods)
135
+ end
136
+ end
137
+ end
138
+ end