Skip to content

Commit

Permalink
Refactor API classes and errors (#29)
Browse files Browse the repository at this point in the history
* Update base api class name

* Cleanup API errors
  • Loading branch information
dickdavis authored Jun 26, 2024
1 parent 115a9ad commit dff7700
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 120 deletions.
12 changes: 4 additions & 8 deletions .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@ detectors:
TooManyStatements:
exclude:
- 'Anthropic::Api::Concerns::Validatable#schema'
- 'Anthropic::BaseApi#beta_config'
- 'Anthropic::BaseApi#version_config'
- 'Anthropic::Api::Base#beta_config'
- 'Anthropic::Api::Base#version_config'
- 'Anthropic::Bootstrapper#self.load_betas'
- 'Anthropic::Bootstrapper#self.load_versions'
- 'Anthropic::Client::Standard#self.post'
- 'Anthropic::Client::Streaming#self.post'
BooleanParameter:
exclude:
- 'Anthropic::Messages#initialize'
DuplicateMethodCall:
exclude:
- 'Anthropic::BaseApi#version_config'
- 'Anthropic::Messages#create'
- 'Anthropic::Api::Base#version_config'
InstanceVariableAssumption:
exclude:
- 'Anthropic::BaseApi'
- 'Anthropic::Api::Base'
NestedIterators:
exclude:
- 'Anthropic::Bootstrapper#self.load_versions'
75 changes: 75 additions & 0 deletions lib/anthropic/api/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

require_relative 'concerns/requestable'
require_relative 'concerns/validatable'

module Anthropic
module Api
# Error for when a beta feature is configured incorrectly.
class InvalidBetaConfigurationError < StandardError; end

# Error for when API version is missing a schema.
class MissingSchemaError < StandardError; end

# Error for when the provided params do not match the API schema
class SchemaValidationError < StandardError; end

# Error for when the API version is not supported.
class UnsupportedApiVersionError < StandardError; end

# Error for when a beta feature is not used correctly.
class UnsupportedBetaUseError < StandardError; end

# Error for when the provided beta is not supported.
class UnsupportedBetaError < StandardError; end

##
# Provides a base class for APIs
class Base
include Anthropic::Api::Concerns::Requestable
include Anthropic::Api::Concerns::Validatable

def initialize(beta: nil)
@beta = beta
end

private

attr_reader :beta

def api
self.class.name.split('::').last.downcase
end

def version_config
return @version_config if defined?(@version_config)

@version_config ||= catch(:version_found) do
found_config = Anthropic.versions[api.to_sym].find { |config| config['version'] == Anthropic.api_version }
unless found_config
raise Anthropic::Api::UnsupportedApiVersionError, "Unsupported API version: #{Anthropic.api_version}"
end

throw :version_found, found_config
end
end

def beta_config
return @beta_config if defined?(@beta_config)

@beta_config = catch(:beta_found) do
found_config = Anthropic.betas.find { |config| config['id'] == beta }
raise Anthropic::Api::UnsupportedBetaError, "#{beta} not supported" unless found_config

throw :beta_found, found_config
end
end

def beta_loaded?(name)
return false unless beta

beta_config['id'] == name
end
end
end
end
55 changes: 0 additions & 55 deletions lib/anthropic/api/base_api.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/anthropic/api/completions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Anthropic
module Api
##
# Provides bindings for the Anthropic completions API
class Completions < BaseApi
class Completions < Base
def create(**params, &)
validate!(params)
return post(params) unless params[:stream]
Expand Down
2 changes: 1 addition & 1 deletion lib/anthropic/api/concerns/requestable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def beta_headers
return {} unless beta

header = beta_config['header']
raise Anthropic::Errors::InvalidBetaConfigurationError, "Missing header: #{beta}" unless header
raise Anthropic::Api::InvalidBetaConfigurationError, "Missing header: #{beta}" unless header

header
end
Expand Down
6 changes: 3 additions & 3 deletions lib/anthropic/api/concerns/validatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ module Validatable
def validate!(params)
JSON::Validator.validate!(schema, params)
rescue JSON::Schema::ValidationError => error
raise Anthropic::Errors::SchemaValidationError, error.message
raise Anthropic::Api::SchemaValidationError, error.message
end

def schema
api_schema = version_config['schema']

unless api_schema
raise Anthropic::Errors::MissingSchemaError, "Missing schema for API version: #{Anthropic.api_version}"
raise Anthropic::Api::MissingSchemaError, "Missing schema for API version: #{Anthropic.api_version}"
end

if beta
beta_schema = beta_config['schema']
raise Anthropic::Errors::InvalidBetaConfigurationError, "Missing beta schema: #{beta}" unless beta_schema
raise Anthropic::Api::InvalidBetaConfigurationError, "Missing beta schema: #{beta}" unless beta_schema

api_schema['properties'].merge!(beta_schema)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/anthropic/api/messages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ module Anthropic
module Api
##
# Provides bindings for the Anthropic messages API
class Messages < BaseApi
class Messages < Base
def create(**params, &)
streaming = params[:stream]
if streaming && beta_loaded?('tools-2024-04-04')
raise Anthropic::Errors::UnsupportedBetaUseError, 'Tool use is not yet supported in streaming mode'
raise Anthropic::Api::UnsupportedBetaUseError, 'Tool use is not yet supported in streaming mode'
end

validate!(params)
Expand Down
14 changes: 0 additions & 14 deletions lib/anthropic/errors/betas.rb

This file was deleted.

14 changes: 0 additions & 14 deletions lib/anthropic/errors/versions.rb

This file was deleted.

8 changes: 1 addition & 7 deletions spec/lib/anthropic/api/completions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@
describe '#create' do
subject(:call_method) { completions_api.create(**params) }

context 'with invalid params' do
let(:params) { { model: 'foo' } }

it 'raises an error' do
expect { call_method }.to raise_error(Anthropic::Errors::SchemaValidationError)
end
end
shared_examples 'validates the params against the specified API version'

context 'with valid params' do
# rubocop:disable RSpec/NestedGroups
Expand Down
17 changes: 2 additions & 15 deletions spec/lib/anthropic/api/messages_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@
describe '#create' do
subject(:call_method) { messages_api.create(**params) }

context 'with invalid params' do
let(:params) { { model: 'foo' } }

it 'raises an error' do
expect { call_method }.to raise_error(Anthropic::Errors::SchemaValidationError)
end
end
shared_examples 'validates the params against the specified API version'

context 'with beta option flagged' do
subject(:call_method) { described_class.new(beta: 'tools-2024-04-04').create(**params) }
Expand Down Expand Up @@ -63,7 +57,7 @@
end

it 'raises an error' do
expect { call_method }.to raise_error(Anthropic::Errors::UnsupportedBetaUseError)
expect { call_method }.to raise_error(Anthropic::Api::UnsupportedBetaUseError)
end
end
end
Expand Down Expand Up @@ -155,13 +149,6 @@
expect(response.body).to eq(response_body)
end
end

context 'with invalid API version configured' do
it 'raises an error' do
allow(Anthropic).to receive(:api_version).and_return('2023-06-02')
expect { call_method }.to raise_error(Anthropic::Errors::UnsupportedApiVersionError)
end
end
end
# rubocop:enable RSpec/NestedGroups
end
Expand Down
18 changes: 18 additions & 0 deletions spec/support/shared/api_shared_examples.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

RSpec.shared_examples 'validates the params against the specified API version' do
context 'with invalid params' do
let(:params) { { model: 'foo' } }

it 'raises an Anthropic::Api:SchemaValidationError' do
expect { call_method }.to raise_error(Anthropic::Api::SchemaValidationError)
end
end

context 'with invalid API version configured' do
it 'raises an Anthropic::Api::UnsupportedApiVersionError' do
allow(Anthropic).to receive(:api_version).and_return('2023-06-02')
expect { call_method }.to raise_error(Anthropic::Api::UnsupportedApiVersionError)
end
end
end

0 comments on commit dff7700

Please sign in to comment.