act_as_api_client 1.0.0 → 1.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2879b607f0a39fdba8f0b5c92097320aacafd5e98a23e8082f051e9b95340765
4
- data.tar.gz: c694503be26586f6c184f64b1df4084d261c1dae82aede31951fe7aa023d2c10
3
+ metadata.gz: a90b4aea75a3d4fffe79dc9d882cc6560c464409cfa07aa9227806573cef5055
4
+ data.tar.gz: 70429d7b213697175b2283bfa2aabca4b019a7c7272b097e34fa9786904ae6cd
5
5
  SHA512:
6
- metadata.gz: 8d94a6752470991a895526ed0a371e34c44a5db3cc7c1f6d9a81a3e38c4d1ba7a3b39ab0a2406277aa407037744b60f2bbe0408197eaf6cccd625b9f80ef767d
7
- data.tar.gz: fc1abaa4b3ae8541dd3a67de89d0a74035ebc8d909aab2d1d48f1d2d34b609bd8406aa28a5a864eff3402aa5a922abcfecf6169b022c9408d6eebc8620d9b65d
6
+ metadata.gz: b2f6b525f14bf39b4463d40cba93aa2cf84d98b92e5e5a77ddc9bc34cb8ba8f02a5e098d38788657317b6b5f0774a22f5345de6338e4b47e2548896b9216c794
7
+ data.tar.gz: 64a64300293bf60782357e32c7909dc8d01a95e47e22c6df36226f6278d4dc941449d38d6fc135e42620ecf7efa9a8a874dbad4d523e175cba22a90f7c762c99
@@ -36,7 +36,7 @@ jobs:
36
36
  strategy:
37
37
  matrix:
38
38
  os: [ubuntu-latest, macos-latest]
39
- ruby-version: ["2.6", "2.7", "3.0", "3.1", "3.2"]
39
+ ruby-version: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3"]
40
40
  steps:
41
41
  - uses: actions/checkout@v3
42
42
  - name: Set up Ruby
data/.gitignore CHANGED
@@ -14,4 +14,6 @@
14
14
  .byebug_history
15
15
  spec/credentials.yml
16
16
 
17
- *.gem
17
+ *.gem
18
+
19
+ .DS_Store
data/.rubocop.yml CHANGED
@@ -20,3 +20,8 @@ AllCops:
20
20
 
21
21
  Style/Documentation:
22
22
  Enabled: false
23
+
24
+ Metrics/BlockLength:
25
+ Exclude:
26
+ - 'spec/**/*'
27
+ - 'act_as_api_client.gemspec'
data/.rubocop_todo.yml CHANGED
@@ -12,17 +12,6 @@ Metrics/AbcSize:
12
12
  Exclude:
13
13
  - "lib/act_as_api_client/clients/github_repositories_client.rb"
14
14
 
15
- # Offense count: 5
16
- # Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods.
17
- # ExcludedMethods: refine
18
- Metrics/BlockLength:
19
- Exclude:
20
- - "**/*.gemspec"
21
- - "spec/act_as_api_client/clients/authorize_net/authorize_net_notifications_client_spec.rb"
22
- - "spec/act_as_api_client/clients/github_client/find_by_spec.rb"
23
- - "spec/act_as_api_client/clients/github_client/find_spec.rb"
24
- - "spec/act_as_api_client/clients/github_client/where_spec.rb"
25
-
26
15
  # Offense count: 1
27
16
  # Configuration parameters: IgnoredMethods, Max.
28
17
  Metrics/CyclomaticComplexity:
@@ -63,12 +52,6 @@ RSpec/NestedGroups:
63
52
  Exclude:
64
53
  - "spec/act_as_api_client/clients/github_client/find_by_spec.rb"
65
54
 
66
- # Offense count: 1
67
- # Configuration parameters: MinBodyLength.
68
- Style/GuardClause:
69
- Exclude:
70
- - "lib/act_as_api_client/clients/authorize_net_webhooks_client.rb"
71
-
72
55
  # Offense count: 4
73
56
  # Cop supports --auto-correct.
74
57
  # Configuration parameters: AutoCorrect, Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- act_as_api_client (1.0.0)
4
+ act_as_api_client (1.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -68,7 +68,4 @@ DEPENDENCIES
68
68
  rubocop (~> 0.80)
69
69
  rubocop-rspec
70
70
  vcr (~> 6.1)
71
- webmock (~> 3.14)
72
-
73
- BUNDLED WITH
74
- 1.17.2
71
+ webmock (~> 3.14)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "act_as_api_client"
5
- spec.version = "1.0.0"
5
+ spec.version = "1.3.0"
6
6
  spec.authors = ["Max Rukomoynikov"]
7
7
  spec.email = ["rukomoynikov@gmail.com"]
8
8
 
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Run it with `ruby anthropic_playground.rb`
4
+ # See Anthropic development API documentation on https://docs.anthropic.com/en/api/messages
5
+
6
+ require "bundler/inline"
7
+
8
+ gemfile(true) do
9
+ source "https://rubygems.org"
10
+
11
+ gem "act_as_api_client", path: "../"
12
+ end
13
+
14
+ require "act_as_api_client"
15
+
16
+ class AnthropicClient < ApiClient
17
+ act_as_api_client for: %i[anthropic messages],
18
+ with: { x_api_key: ENV["ANTHROPIC_API_KEY"] }
19
+ end
20
+
21
+ anthropic_client = AnthropicClient.new
22
+
23
+ pp anthropic_client.create(
24
+ model: "claude-3-5-sonnet-20241022",
25
+ messages: [
26
+ { "role": "user", "content": "Hello there." },
27
+ { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" },
28
+ { "role": "user", "content": "Can you explain LLMs in plain English?" }
29
+ ],
30
+ max_tokens: 1024
31
+ )
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Run it with `ruby github_repositories.rb`
4
+
5
+ require "bundler/inline"
6
+
7
+ gemfile(true) do
8
+ source "https://rubygems.org"
9
+
10
+ gem "act_as_api_client", path: "./"
11
+ gem "tabled"
12
+ end
13
+
14
+ require "act_as_api_client"
15
+
16
+ class GithubApiClient < ApiClient
17
+ act_as_api_client for: :github_repositories
18
+ end
19
+
20
+ github_api_client = GithubApiClient.new
21
+ pp github_api_client.find("Rukomoynikov/tabled")
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActAsApiClient
4
+ class ClientLoader
5
+ attr_reader :client_for
6
+
7
+ def initialize(client_for:)
8
+ @client_for = client_for
9
+ end
10
+
11
+ def class_name
12
+ case client_for.class.to_s
13
+ when "String", "Symbol"
14
+ "#{convert_underscore_to_camelcase(client_for)}Client"
15
+ when "Array"
16
+ client_for
17
+ .map { |item| convert_underscore_to_camelcase(item) }
18
+ .join("::")
19
+ .concat("Client")
20
+ end
21
+ end
22
+
23
+ def path
24
+ case client_for.class.to_s
25
+ when "String", "Symbol"
26
+ File.expand_path("clients/#{client_for}_client", File.dirname(__FILE__))
27
+ when "Array"
28
+ client_path = client_for.join("/")
29
+
30
+ File.expand_path("clients/#{client_path}_client", File.dirname(__FILE__))
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # Converting from authorize_net_webhooks_client to AuthorizeNetWebhooksClient
37
+ #
38
+ # @param value [String] string with underscores
39
+ # @return [String] transformed in camel case format string
40
+ def convert_underscore_to_camelcase(value)
41
+ value.to_s.capitalize.gsub(/_(.)/) do |s|
42
+ s.upcase.gsub("_", "")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../http_client"
4
+
5
+ # See the documentation on https://docs.anthropic.com/en/api/messages
6
+
7
+ module ActAsApiClient
8
+ module Clients
9
+ module Anthropic
10
+ module MessagesClient
11
+ ANTHROPIC_VERSION = "2023-06-01"
12
+ BASE_URL = "https://api.anthropic.com/v1/messages"
13
+
14
+ include HttpClient
15
+
16
+ # Sends request to Anthropic API https://docs.anthropic.com/en/api/messages
17
+ #
18
+ # @param model [String] The model that will complete your prompt
19
+ # @param messages [Array] Input messages
20
+ # @param max_tokens [Integer] The maximum number of tokens to generate before stopping
21
+ # @param metadata [Hash] An object describing metadata about the request
22
+ # @param stop_sequences [Array<String>] Custom text sequences that will cause the model to stop generating
23
+ # @param stream [Boolean] Whether to incrementally stream the response using server-sent events
24
+ # @param system [String] System prompt
25
+ # @param temperature [Float] Amount of randomness injected into the response
26
+ # @param tool_choice [Hash] How the model should use the provided tools
27
+ # @param tools [Array<Hash>] Definitions of tools that the model may use
28
+ # @param top_k [Integer] Only sample from the top K options for each subsequent token
29
+ # @param top_p [Float] Use nucleus sampling
30
+ #
31
+ # @return [Hash] Response from Anthropic API
32
+ def create(**params)
33
+ post(BASE_URL, headers: headers, body: body(**params))
34
+ end
35
+
36
+ private
37
+
38
+ def headers
39
+ default = {
40
+ "Content-Type": "application/json",
41
+ "x-api-key" => options[:x_api_key],
42
+ "anthropic-version" => options[:anthropic_version] || ANTHROPIC_VERSION
43
+ }
44
+
45
+ default["anthropic-beta"] = options[:anthropic_beta] if options[:anthropic_beta]
46
+
47
+ default
48
+ end
49
+
50
+ # rubocop:disable Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/MethodLength
51
+ def body(model:,
52
+ messages:,
53
+ max_tokens:,
54
+ metadata: nil,
55
+ stop_sequences: nil,
56
+ stream: false,
57
+ system: nil,
58
+ temperature: 1.0,
59
+ tool_choice: nil,
60
+ tools: nil,
61
+ top_k: nil,
62
+ top_p: nil)
63
+ default = {
64
+ model: model,
65
+ messages: messages,
66
+ max_tokens: max_tokens,
67
+ stream: stream,
68
+ temperature: temperature
69
+ }
70
+
71
+ default[:metadata] = metadata if metadata
72
+ default[:stop_sequences] = stop_sequences if stop_sequences
73
+ default[:system] = system if system
74
+ default[:tool_choice] = tool_choice if tool_choice
75
+ default[:tools] = tools if tools
76
+ default[:top_k] = top_k if top_k
77
+ default[:top_p] = top_p if top_p
78
+
79
+ default
80
+ end
81
+ # rubocop:enable Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/MethodLength
82
+ end
83
+ end
84
+ end
85
+ end
@@ -3,19 +3,22 @@
3
3
  require "net/http"
4
4
  require "json"
5
5
 
6
+ require "act_as_api_client/errors/invalid_response_error"
7
+ require "act_as_api_client/errors/network_error"
8
+
6
9
  module ActAsApiClient
7
10
  module Clients
8
11
  module HttpClient
9
12
  private
10
13
 
11
- def get(url, options = {})
14
+ def get(url, **options)
12
15
  # Request part
13
16
  uri = URI(url)
14
17
  uri.query = URI.encode_www_form(options.fetch(:params, {}))
15
18
 
16
19
  request = Net::HTTP::Get.new(uri)
17
- request_headers(headers: options.fetch(:headers, {}),
18
- request: request)
20
+ set_request_headers(headers: options.fetch(:headers, {}),
21
+ request: request)
19
22
 
20
23
  # Response part
21
24
  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
@@ -28,8 +31,31 @@ module ActAsApiClient
28
31
  end
29
32
  end
30
33
 
31
- def post
32
- # HTTParty.post
34
+ def post(url, headers: {}, **options) # rubocop:disable Metrics/AbcSize
35
+ # Request part
36
+ uri = URI(url)
37
+ uri.query = URI.encode_www_form(options.fetch(:params, {}))
38
+
39
+ request = Net::HTTP::Post.new(uri)
40
+
41
+ request.body = options.fetch(:body, {}).to_json
42
+ set_request_headers(headers: headers, request: request)
43
+
44
+ # Response part
45
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
46
+ http.request(request)
47
+ end
48
+
49
+ case response
50
+ when Net::HTTPSuccess
51
+ ::JSON.parse(response.body)
52
+ when Net::HTTPNotFound, Net::HTTPUnprocessableEntity, Net::HTTPUnauthorized
53
+ ::JSON.parse(response.body)
54
+ end
55
+ rescue Net::OpenTimeout, Net::ReadTimeout, SocketError => e
56
+ raise ActAsApiClient::NetworkError, "Network error occurred: #{e.message}"
57
+ rescue JSON::ParserError => e
58
+ raise ActAsApiClient::InvalidResponseError, "Invalid JSON response: #{e.message}"
33
59
  end
34
60
 
35
61
  def put
@@ -44,7 +70,7 @@ module ActAsApiClient
44
70
  # HTTParty.delete
45
71
  end
46
72
 
47
- def request_headers(headers:, request:)
73
+ def set_request_headers(headers:, request:)
48
74
  headers.each do |key, value|
49
75
  request[key] = value
50
76
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActAsApiClient
4
+ module Errors
5
+ class InvalidResponseError < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActAsApiClient
4
+ module Errors
5
+ class NetworkError < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActAsApiClient
4
+ module Errors
5
+ class NonExistingClient < StandardError
6
+ def initialize(requested_client:)
7
+ @requested_client = requested_client
8
+ super
9
+ end
10
+
11
+ def message
12
+ "The requested client (#{@requested_client}) doesn't exist"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "act_as_api_client/base_api_methods"
4
+ require "act_as_api_client/errors/non_existing_client_error"
5
+ require "act_as_api_client/client_loader"
4
6
 
5
7
  class ApiClient
6
8
  include ActAsApiClient::BaseApiMethods
@@ -16,26 +18,16 @@ class ApiClient
16
18
  def set_general_client(client_for:)
17
19
  return if client_for.nil?
18
20
 
19
- class_name = convert_underscore_to_camelcase(client_for)
21
+ client_loader = ActAsApiClient::ClientLoader.new(client_for: client_for)
20
22
 
21
- require(File.expand_path("act_as_api_client/clients/#{client_for}_client",
22
- File.dirname(__FILE__)))
23
- include const_get("ActAsApiClient::Clients::#{class_name}Client")
23
+ require(client_loader.path)
24
+ include const_get("ActAsApiClient::Clients::#{client_loader.class_name}")
25
+ rescue LoadError
26
+ raise ActAsApiClient::Errors::NonExistingClient.new(requested_client: client_for)
24
27
  end
25
28
 
26
29
  def set_options(options:)
27
30
  define_method("options") { options }
28
31
  end
29
-
30
- # Converting from authorize_net_webhooks_client to AuthorizeNetWebhooksClient
31
- #
32
- # @param value [String] string with underscores
33
- #
34
- # @return [String] transformed in camel case format string
35
- def convert_underscore_to_camelcase(value)
36
- value.to_s.capitalize.gsub(/_(.)/) do |s|
37
- s.upcase.gsub("_", "")
38
- end
39
- end
40
32
  end
41
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: act_as_api_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Rukomoynikov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-22 00:00:00.000000000 Z
11
+ date: 2024-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -134,10 +134,17 @@ files:
134
134
  - bin/setup
135
135
  - demo.rb
136
136
  - docker-compose.yml
137
+ - examples/anthropic_playground.rb
138
+ - examples/github_repositories.rb
137
139
  - lib/act_as_api_client.rb
138
140
  - lib/act_as_api_client/base_api_methods.rb
141
+ - lib/act_as_api_client/client_loader.rb
142
+ - lib/act_as_api_client/clients/anthropic/messages_client.rb
139
143
  - lib/act_as_api_client/clients/github_repositories_client.rb
140
144
  - lib/act_as_api_client/clients/http_client.rb
145
+ - lib/act_as_api_client/errors/invalid_response_error.rb
146
+ - lib/act_as_api_client/errors/network_error.rb
147
+ - lib/act_as_api_client/errors/non_existing_client_error.rb
141
148
  homepage: https://rubygems.org/gems/act_as_api_client
142
149
  licenses:
143
150
  - MIT