Skip to content

Commit

Permalink
Sets headers and query params correctly for hosted version (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariochavez authored Oct 16, 2024
1 parent 92e1aa8 commit 0182576
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 27 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
/spec/reports/
/tmp/

/test/hosted.rb

.rbnext/

.rubocop.yml
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## [Unreleased]

## 0.8.1 2024-10-16

- Adds support for Chroma hosted service. See README for more details how to set your `api_key`, `tenant`, and `database`.

## [0.6.0] 2023-06-05

- Fix failure to rescue from API call exceptions.
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
chroma-db (0.8.0)
chroma-db (0.8.1)
dry-monads (~> 1.6)
ruby-next (~> 1.0, >= 1.0.3)
zeitwerk (~> 2.6.0)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Chroma.database = "my_database" # Optional

## Requirements

- Ruby 3.0.6 or newer
- Ruby 3.1.4 or newer
- Chroma Database 0.4.24 or later running as a client/server model.

For Chroma database 0.3.22 or older, please use version 0.3.0 of this gem.
Expand Down
9 changes: 6 additions & 3 deletions lib/chroma/api_operations/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ def execute_request(method, url, params = {}, options = {})

case response
in Net::HTTPSuccess
return Success(response_data)
Success(response_data)
else
return Failure(response_data)
Failure(response_data)
end
end

Expand All @@ -107,6 +107,8 @@ def execute_request(method, url, params = {}, options = {})
end

private def build_request(method, uri, params)
uri.query = URI.encode_www_form(tenant: Chroma.tenant, database: Chroma.database) unless Chroma.api_key.nil?

request = case method
when :post then Net::HTTP::Post.new(uri)
when :put then Net::HTTP::Put.new(uri)
Expand All @@ -115,10 +117,11 @@ def execute_request(method, url, params = {}, options = {})
Net::HTTP::Get.new(uri)
end

api_key = ENV.fetch("CHROMA_SERVER_AUTHN_CREDENTIALS", Chroma.api_key)
request.content_type = "application/json"
request.body = params.to_json if params.size > 0
request.basic_auth(uri.user, uri.password) if !uri.user.nil?
request['X-Chroma-Token'] = ENV.fetch('CHROMA_SERVER_AUTHN_CREDENTIALS', nil) if ENV.fetch('CHROMA_SERVER_AUTHN_CREDENTIALS', nil)
request["X-Chroma-Token"] = api_key unless api_key.nil?
request
end
end
Expand Down
13 changes: 1 addition & 12 deletions lib/chroma/chroma.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,7 @@ class << self
end

def self.api_url
base_url = "#{connect_host}/#{api_base}/#{api_version}"
uri = URI(base_url)

unless api_key.nil?
query_params = {
tenant: tenant,
database: database
}
query_params["x-chroma-token"] = api_key
uri.query = URI.encode_www_form(query_params)
end
uri.to_s
"#{connect_host}/#{api_base}/#{api_version}"
end

Chroma.log_level = ENV["CHROMA_LOG"].to_i unless ENV["CHROMA_LOG"].nil?
Expand Down
2 changes: 1 addition & 1 deletion lib/chroma/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Chroma
VERSION = "0.8.0"
VERSION = "0.8.1"
end
12 changes: 12 additions & 0 deletions test/chroma/api_operations/test_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,16 @@ def test_it_handles_successuful_request
assert response.success?
assert_equal(200, response.success.status)
end

def test_it_adds_api_key_to_request
Chroma.api_key = "1234abcd"

url = "#{@url}/collection"
stub_successful_request(url, {tenant: Chroma.tenant, database: Chroma.database, "X-Chroma-Token": Chroma.api_key})
subject = Class.new.include(Chroma::APIOperations::Request)

response = subject.execute_request(:get, url)

assert response.success?
end
end
28 changes: 21 additions & 7 deletions test/chroma/test_chroma.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ def test_it_build_an_url_with_api_url
assert_equal("https://chroma-server.org/other/api/v2", Chroma.api_url)
end

def test_it_allows_to_set_api_key
api_key = "1234abcd"
Chroma.api_key = api_key

assert_equal(api_key, Chroma.api_key)
end

def test_it_allows_to_set_tenant_and_database
assert_equal("default_tenant", Chroma.tenant)
assert_equal("default_database", Chroma.database)

tenant = "test_tenant"
database = "test_database"

Chroma.tenant = tenant
Chroma.database = database

assert_equal(tenant, Chroma.tenant)
assert_equal(database, Chroma.database)
end

def test_it_allows_log_level_configuration
Chroma.log_level = 0
assert_equal ::Logger::DEBUG, Chroma.log_level
Expand All @@ -49,13 +70,6 @@ def test_it_allows_logger_configuration
assert_equal logger, Chroma.logger
end

def test_it_sets_default_database_and_tenant_when_api_key_is_set
Chroma.connect_host = "https://chroma-server.org"
Chroma.api_key = "1234abcd"

assert_equal("https://chroma-server.org/api/v1?tenant=default_tenant&database=default_database&x-chroma-token=1234abcd", Chroma.api_url)
end

def test_it_sets_default_database_and_tenant_when_api_key_is_not_set
Chroma.connect_host = "https://chroma-server.org"
Chroma.api_key = nil
Expand Down
12 changes: 10 additions & 2 deletions test/support/stub_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ def stub_network_error(url)
@stubs << stub_request(:any, url).to_timeout
end

def stub_successful_request(url)
@stubs << stub_request(:any, url).to_return(status: 200, body: %({"name": "data-index"}), headers: {"Content-Type": "application/json"})
def stub_successful_request(url, query = {})
@stubs << if query.empty?
stub_request(:any, url)
.to_return(status: 200, body: %({"name": "data-index"}), headers: {"Content-Type": "application/json"})
else
api_key = query.delete(:"X-Chroma-Token")
stub_request(:any, url)
.with(query: hash_including(query), headers: {"X-Chroma-Token": api_key})
.to_return(status: 200, body: %({"name": "data-index"}), headers: {"Content-Type": "application/json"})
end
end
end

0 comments on commit 0182576

Please sign in to comment.