ruby-openai 2.3.0 → 3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9f91687f2b4e37ef74018f8454392416afbe43ad08f5f8d671a1a9dc8feba82
4
- data.tar.gz: 902a8bbd495d8ee56800f695aa3a264a8ded26475c11874040871b4765c8dacf
3
+ metadata.gz: 2a823ba01c0dbec587f96e5d2d59b6eb67e48c348b00a7e78f415c6b65583d05
4
+ data.tar.gz: 98e7ae98831997f66bcbd73c644c78b0f5ed291b5b98c6ca01e5152596ca7b25
5
5
  SHA512:
6
- metadata.gz: 5b631c7f78b6de8d7c20acc61e4fc22eca4f372e488ba55e10267cedfd91c9b340334c69403fd28a26c71cfaa52678e7ea9c8410121139e9069abdadf5f37cf8
7
- data.tar.gz: 40cb9e2f2848a954e5f786979d207a08b698ef6c5fb787afd564cd7945e5e758555ec2d99967a507bd2ae05b63ee8a7b518a197d8b2b6d39b19839c4398caf48
6
+ metadata.gz: 15a75647453b2b526680b5e2d3b7bc3d5ef6b05f223bdef0194e751f829228d9db7d17d5c483db66bf7706983c4d996ff4c348b505e6d52b6cbb5ef523e68133
7
+ data.tar.gz: a7362b11bfeefa471e70369696d746d5c89c201ef374799a6163dbad814f405d7642861d588ef6360f088e21d41ba4b10e7f40467d2a4d515767ea66bf52b4d3
data/.rubocop.yml CHANGED
@@ -12,9 +12,7 @@ Layout/LineLength:
12
12
 
13
13
  Metrics/BlockLength:
14
14
  Exclude:
15
- - "Rakefile"
16
- - "**/*.rake"
17
- - "spec/**/*.rb"
15
+ - "spec/**/*"
18
16
 
19
17
  Style/StringLiterals:
20
18
  EnforcedStyle: double_quotes
data/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.0.1] - 2022-12-26
9
+
10
+ ### Removed
11
+
12
+ - [BREAKING] Remove deprecated answers, classifications, embeddings, engines and search endpoints.
13
+ - [BREAKING] Remove ability to pass engine to completions and embeddings outside of the parameters hash.
14
+
15
+ ## [3.0.0] - 2022-12-26
16
+
17
+ ### Added
18
+
19
+ - Add ability to set access_token via gem configuration.
20
+ - Thanks [@grjones](https://github.com/grjones) and [@aquaflamingo](https://github.com/aquaflamingo) for raising this and [@feministy](https://github.com/feministy) for the [excellent guide](https://github.com/feministy/lizabinante.com/blob/stable/source/2016-01-30-creating-a-configurable-ruby-gem.markdown#configuration-block-the-end-goal) to adding config to a gem.
21
+
22
+ ### Removed
23
+
24
+ - [BREAKING] Remove ability to include access_token directly via ENV vars.
25
+ - [BREAKING] Remove ability to pass API version directly to endpoints.
26
+
8
27
  ## [2.3.0] - 2022-12-23
9
28
 
10
29
  ### Added
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  gem "byebug", "~> 11.1.3"
7
+ gem "dotenv", "~> 2.8.1"
7
8
  gem "rake", "~> 13.0"
8
9
  gem "rspec", "~> 3.12"
9
10
  gem "rubocop", "~> 1.41.1"
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-openai (2.3.0)
5
- dotenv (>= 2.7.6, < 2.9.0)
4
+ ruby-openai (3.0.1)
6
5
  httparty (>= 0.18.1, < 0.21.0)
7
6
 
8
7
  GEM
@@ -71,6 +70,7 @@ PLATFORMS
71
70
 
72
71
  DEPENDENCIES
73
72
  byebug (~> 11.1.3)
73
+ dotenv (~> 2.8.1)
74
74
  rake (~> 13.0)
75
75
  rspec (~> 3.12)
76
76
  rubocop (~> 1.41.1)
data/README.md CHANGED
@@ -40,30 +40,29 @@ and require with:
40
40
  - Get your API key from [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys)
41
41
  - If you belong to multiple organizations, you can get your Organization ID from [https://beta.openai.com/account/org-settings](https://beta.openai.com/account/org-settings)
42
42
 
43
- ### With dotenv
43
+ ### Quickstart
44
44
 
45
- If you're using [dotenv](https://github.com/motdotla/dotenv), you can add your secret keys to your .env file:
45
+ For a quick test you can pass your token directly to a new client:
46
46
 
47
- ```
48
- OPENAI_ACCESS_TOKEN=access_token_goes_here
49
- OPENAI_ORGANIZATION_ID=organization_id_goes_here # Optional.
47
+ ```ruby
48
+ client = OpenAI::Client.new(access_token: "access_token_goes_here")
50
49
  ```
51
50
 
52
- And create a client:
51
+ ### With Config
52
+
53
+ For a more robust setup, you can configure the gem with your API keys, for example in an `openai.rb` initializer file. Never hardcode secrets into your codebase - instead use something like [dotenv](https://github.com/motdotla/dotenv) to pass the keys safely into your environments.
53
54
 
54
55
  ```ruby
55
- client = OpenAI::Client.new
56
+ Ruby::OpenAI.configure do |config|
57
+ config.access_token = ENV.fetch('OPENAI_ACCESS_TOKEN')
58
+ config.organization_id = ENV.fetch('OPENAI_ORGANIZATION_ID') # Optional.
59
+ end
56
60
  ```
57
61
 
58
- ### Without dotenv
59
-
60
- Alternatively you can pass your key directly to a new client:
62
+ Then you can create a client like this:
61
63
 
62
64
  ```ruby
63
- client = OpenAI::Client.new(
64
- access_token: "access_token_goes_here",
65
- organization_id: "organization_id_goes_here"
66
- )
65
+ client = OpenAI::Client.new
67
66
  ```
68
67
 
69
68
  ### Models
@@ -189,7 +188,7 @@ You may need to wait a short time for processing to complete. Once processed, yo
189
188
  fine_tuned_model = JSON.parse(response.body)["fine_tuned_model"]
190
189
  ```
191
190
 
192
- This fine-tuned model name can then be used in classifications:
191
+ This fine-tuned model name can then be used in completions:
193
192
 
194
193
  ```ruby
195
194
  response = client.completions(
@@ -248,58 +247,6 @@ Pass a string to check if it violates OpenAI's Content Policy:
248
247
  => 5.505014632944949e-05
249
248
  ```
250
249
 
251
- ### Classifications
252
-
253
- Pass examples and a query to predict the most likely labels:
254
-
255
- ```ruby
256
- response = client.classifications(parameters: {
257
- examples: [
258
- ["A happy moment", "Positive"],
259
- ["I am sad.", "Negative"],
260
- ["I am feeling awesome", "Positive"]
261
- ],
262
- query: "It is a raining day :(",
263
- model: "text-ada-001"
264
- })
265
- ```
266
-
267
- Or use the ID of a file you've uploaded:
268
-
269
- ```ruby
270
- response = client.classifications(parameters: {
271
- file: "123abc,
272
- query: "It is a raining day :(",
273
- model: "text-ada-001"
274
- })
275
- ```
276
-
277
- ### Answers
278
-
279
- Pass documents, a question string, and an example question/response to get an answer to a question:
280
-
281
- ```ruby
282
- response = client.answers(parameters: {
283
- documents: ["Puppy A is happy.", "Puppy B is sad."],
284
- question: "which puppy is happy?",
285
- model: "text-curie-001",
286
- examples_context: "In 2017, U.S. life expectancy was 78.6 years.",
287
- examples: [["What is human life expectancy in the United States?","78 years."]],
288
- })
289
- ```
290
-
291
- Or use the ID of a file you've uploaded:
292
-
293
- ```ruby
294
- response = client.answers(parameters: {
295
- file: "123abc",
296
- question: "which puppy is happy?",
297
- model: "text-curie-001",
298
- examples_context: "In 2017, U.S. life expectancy was 78.6 years.",
299
- examples: [["What is human life expectancy in the United States?","78 years."]],
300
- })
301
- ```
302
-
303
250
  ## Development
304
251
 
305
252
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,114 +1,76 @@
1
1
  module OpenAI
2
2
  class Client
3
- include HTTParty
4
- base_uri "https://api.openai.com"
3
+ URI_BASE = "https://api.openai.com/".freeze
5
4
 
6
5
  def initialize(access_token: nil, organization_id: nil)
7
- @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
- @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
6
+ Ruby::OpenAI.configuration.access_token = access_token if access_token
7
+ Ruby::OpenAI.configuration.organization_id = organization_id if organization_id
9
8
  end
10
9
 
11
- def answers(version: default_version, parameters: {})
12
- warn "[DEPRECATION WARNING] [ruby-openai] `Client#answers` is deprecated and will
13
- be removed from the OpenAI API on 3 December 2022 and from ruby-openai v3.0.
14
- More information: https://help.openai.com/en/articles/6233728-answers-transition-guide"
15
-
16
- post(url: "/#{version}/answers", parameters: parameters)
17
- end
18
-
19
- def classifications(version: default_version, parameters: {})
20
- warn "[DEPRECATION WARNING] [ruby-openai] `Client#classifications` is deprecated and will
21
- be removed from the OpenAI API on 3 December 2022 and from ruby-openai v3.0.
22
- More information: https://help.openai.com/en/articles/6272941-classifications-transition-guide"
23
-
24
- post(url: "/#{version}/classifications", parameters: parameters)
10
+ def completions(parameters: {})
11
+ OpenAI::Client.post(path: "/completions", parameters: parameters)
25
12
  end
26
13
 
27
- def completions(engine: nil, version: default_version, parameters: {})
28
- parameters = deprecate_engine(engine: engine, method: "completions", parameters: parameters)
29
-
30
- post(url: "/#{version}/completions", parameters: parameters)
14
+ def edits(parameters: {})
15
+ OpenAI::Client.post(path: "/edits", parameters: parameters)
31
16
  end
32
17
 
33
- def edits(version: default_version, parameters: {})
34
- post(url: "/#{version}/edits", parameters: parameters)
35
- end
36
-
37
- def embeddings(engine: nil, version: default_version, parameters: {})
38
- parameters = deprecate_engine(engine: engine, method: "embeddings", parameters: parameters)
39
-
40
- post(url: "/#{version}/embeddings", parameters: parameters)
41
- end
42
-
43
- def engines
44
- warn "[DEPRECATION WARNING] [ruby-openai] `Client#engines` is deprecated and will
45
- be removed from ruby-openai v3.0. Use `Client#models` instead."
46
-
47
- @engines ||= OpenAI::Engines.new(access_token: @access_token,
48
- organization_id: @organization_id)
18
+ def embeddings(parameters: {})
19
+ OpenAI::Client.post(path: "/embeddings", parameters: parameters)
49
20
  end
50
21
 
51
22
  def files
52
- @files ||= OpenAI::Files.new(access_token: @access_token, organization_id: @organization_id)
23
+ @files ||= OpenAI::Files.new
53
24
  end
54
25
 
55
26
  def finetunes
56
- @finetunes ||= OpenAI::Finetunes.new(access_token: @access_token,
57
- organization_id: @organization_id)
27
+ @finetunes ||= OpenAI::Finetunes.new
58
28
  end
59
29
 
60
30
  def images
61
- @images ||= OpenAI::Images.new(access_token: @access_token, organization_id: @organization_id)
31
+ @images ||= OpenAI::Images.new
62
32
  end
63
33
 
64
34
  def models
65
- @models ||= OpenAI::Models.new(access_token: @access_token, organization_id: @organization_id)
35
+ @models ||= OpenAI::Models.new
66
36
  end
67
37
 
68
- def moderations(version: default_version, parameters: {})
69
- post(url: "/#{version}/moderations", parameters: parameters)
38
+ def moderations(parameters: {})
39
+ OpenAI::Client.post(path: "/moderations", parameters: parameters)
70
40
  end
71
41
 
72
- def search(engine:, version: default_version, parameters: {})
73
- warn "[DEPRECATION WARNING] [ruby-openai] `Client#search` is deprecated and will
74
- be removed from the OpenAI API on 3 December 2022 and from ruby-openai v3.0.
75
- More information: https://help.openai.com/en/articles/6272952-search-transition-guide"
76
-
77
- post(url: "/#{version}/engines/#{engine}/search", parameters: parameters)
42
+ def self.get(path:)
43
+ HTTParty.get(
44
+ uri(path: path),
45
+ headers: headers
46
+ )
78
47
  end
79
48
 
80
- private
81
-
82
- def deprecate_engine(engine:, method:, parameters:)
83
- return parameters unless engine
84
-
85
- parameters = { model: engine }.merge(parameters)
86
-
87
- warn "[DEPRECATION WARNING] [ruby-openai] Passing `engine` directly to `Client##{method}` is
88
- deprecated and will be removed in ruby-openai 3.0. Pass `model` within `parameters` instead:
89
- client.completions(parameters: { #{parameters.map { |k, v| "#{k}: \"#{v}\"" }.join(', ')} })"
90
-
91
- parameters
49
+ def self.post(path:, parameters: nil)
50
+ HTTParty.post(
51
+ uri(path: path),
52
+ headers: headers,
53
+ body: parameters.to_json
54
+ )
92
55
  end
93
56
 
94
- def default_version
95
- "v1".freeze
57
+ def self.delete(path:)
58
+ HTTParty.delete(
59
+ uri(path: path),
60
+ headers: headers
61
+ )
96
62
  end
97
63
 
98
- def documents_or_file(documents: nil, file: nil)
99
- documents ? { documents: documents } : { file: file }
64
+ private_class_method def self.uri(path:)
65
+ URI_BASE + Ruby::OpenAI.configuration.api_version + path
100
66
  end
101
67
 
102
- def post(url:, parameters:)
103
- self.class.post(
104
- url,
105
- headers: {
106
- "Content-Type" => "application/json",
107
- "Authorization" => "Bearer #{@access_token}",
108
- "OpenAI-Organization" => @organization_id
109
- },
110
- body: parameters.to_json
111
- )
68
+ private_class_method def self.headers
69
+ {
70
+ "Content-Type" => "application/json",
71
+ "Authorization" => "Bearer #{Ruby::OpenAI.configuration.access_token}",
72
+ "OpenAI-Organization" => Ruby::OpenAI.configuration.organization_id
73
+ }
112
74
  end
113
75
  end
114
76
  end
@@ -1,66 +1,33 @@
1
1
  module OpenAI
2
2
  class Files
3
- include HTTParty
4
- base_uri "https://api.openai.com"
5
-
6
3
  def initialize(access_token: nil, organization_id: nil)
7
- @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
- @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
4
+ Ruby::OpenAI.configuration.access_token = access_token if access_token
5
+ Ruby::OpenAI.configuration.organization_id = organization_id if organization_id
9
6
  end
10
7
 
11
- def list(version: default_version)
12
- self.class.get(
13
- "/#{version}/files",
14
- headers: {
15
- "Content-Type" => "application/json",
16
- "Authorization" => "Bearer #{@access_token}",
17
- "OpenAI-Organization" => @organization_id
18
- }
19
- )
8
+ def list
9
+ OpenAI::Client.get(path: "/files")
20
10
  end
21
11
 
22
- def upload(version: default_version, parameters: {})
12
+ def upload(parameters: {})
23
13
  validate(file: parameters[:file])
24
14
 
25
- self.class.post(
26
- "/#{version}/files",
27
- headers: {
28
- "Content-Type" => "application/json",
29
- "Authorization" => "Bearer #{@access_token}",
30
- "OpenAI-Organization" => @organization_id
31
- },
32
- body: parameters.merge(file: File.open(parameters[:file]))
15
+ OpenAI::Client.post(
16
+ path: "/files",
17
+ parameters: parameters.merge(file: File.open(parameters[:file]))
33
18
  )
34
19
  end
35
20
 
36
- def retrieve(id:, version: default_version)
37
- self.class.get(
38
- "/#{version}/files/#{id}",
39
- headers: {
40
- "Content-Type" => "application/json",
41
- "Authorization" => "Bearer #{@access_token}",
42
- "OpenAI-Organization" => @organization_id
43
- }
44
- )
21
+ def retrieve(id:)
22
+ OpenAI::Client.get(path: "/files/#{id}")
45
23
  end
46
24
 
47
- def delete(id:, version: default_version)
48
- self.class.delete(
49
- "/#{version}/files/#{id}",
50
- headers: {
51
- "Content-Type" => "application/json",
52
- "Authorization" => "Bearer #{@access_token}",
53
- "OpenAI-Organization" => @organization_id
54
- }
55
- )
25
+ def delete(id:)
26
+ OpenAI::Client.delete(path: "/files/#{id}")
56
27
  end
57
28
 
58
29
  private
59
30
 
60
- def default_version
61
- "v1".freeze
62
- end
63
-
64
31
  def validate(file:)
65
32
  File.open(file).each_line.with_index do |line, index|
66
33
  JSON.parse(line)
@@ -1,73 +1,28 @@
1
1
  module OpenAI
2
2
  class Finetunes
3
- include HTTParty
4
- base_uri "https://api.openai.com"
5
-
6
3
  def initialize(access_token: nil, organization_id: nil)
7
- @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
- @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
9
- end
10
-
11
- def list(version: default_version)
12
- self.class.get(
13
- "/#{version}/fine-tunes",
14
- headers: {
15
- "Content-Type" => "application/json",
16
- "Authorization" => "Bearer #{@access_token}",
17
- "OpenAI-Organization" => @organization_id
18
- }
19
- )
4
+ Ruby::OpenAI.configuration.access_token = access_token if access_token
5
+ Ruby::OpenAI.configuration.organization_id = organization_id if organization_id
20
6
  end
21
7
 
22
- def create(version: default_version, parameters: {})
23
- self.class.post(
24
- "/#{version}/fine-tunes",
25
- headers: {
26
- "Content-Type" => "application/json",
27
- "Authorization" => "Bearer #{@access_token}",
28
- "OpenAI-Organization" => @organization_id
29
- },
30
- body: parameters.to_json
31
- )
8
+ def list
9
+ OpenAI::Client.get(path: "/fine-tunes")
32
10
  end
33
11
 
34
- def retrieve(id:, version: default_version)
35
- self.class.get(
36
- "/#{version}/fine-tunes/#{id}",
37
- headers: {
38
- "Content-Type" => "application/json",
39
- "Authorization" => "Bearer #{@access_token}",
40
- "OpenAI-Organization" => @organization_id
41
- }
42
- )
12
+ def create(parameters: {})
13
+ OpenAI::Client.post(path: "/fine-tunes", parameters: parameters.to_json)
43
14
  end
44
15
 
45
- def cancel(id:, version: default_version)
46
- self.class.post(
47
- "/#{version}/fine-tunes/#{id}/cancel",
48
- headers: {
49
- "Content-Type" => "application/json",
50
- "Authorization" => "Bearer #{@access_token}",
51
- "OpenAI-Organization" => @organization_id
52
- }
53
- )
16
+ def retrieve(id:)
17
+ OpenAI::Client.get(path: "/fine-tunes/#{id}")
54
18
  end
55
19
 
56
- def events(id:, version: default_version)
57
- self.class.get(
58
- "/#{version}/fine-tunes/#{id}/events",
59
- headers: {
60
- "Content-Type" => "application/json",
61
- "Authorization" => "Bearer #{@access_token}",
62
- "OpenAI-Organization" => @organization_id
63
- }
64
- )
20
+ def cancel(id:)
21
+ OpenAI::Client.post(path: "/fine-tunes/#{id}/cancel")
65
22
  end
66
23
 
67
- private
68
-
69
- def default_version
70
- "v1".freeze
24
+ def events(id:)
25
+ OpenAI::Client.get(path: "/fine-tunes/#{id}/events")
71
26
  end
72
27
  end
73
28
  end
@@ -1,59 +1,24 @@
1
1
  module OpenAI
2
2
  class Images
3
- include HTTParty
4
- base_uri "https://api.openai.com"
5
-
6
3
  def initialize(access_token: nil, organization_id: nil)
7
- @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
- @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
4
+ Ruby::OpenAI.configuration.access_token = access_token if access_token
5
+ Ruby::OpenAI.configuration.organization_id = organization_id if organization_id
9
6
  end
10
7
 
11
- def generate(version: default_version, parameters: {})
12
- self.class.post(
13
- "/#{version}/images/generations",
14
- headers: {
15
- "Content-Type" => "application/json",
16
- "Authorization" => "Bearer #{@access_token}",
17
- "OpenAI-Organization" => @organization_id
18
- },
19
- body: parameters.to_json
20
- )
8
+ def generate(parameters: {})
9
+ OpenAI::Client.post(path: "/images/generations", parameters: parameters.to_json)
21
10
  end
22
11
 
23
- def edit(version: default_version, parameters: {})
24
- parameters = open_files(parameters)
25
-
26
- self.class.post(
27
- "/#{version}/images/edits",
28
- headers: {
29
- "Content-Type" => "application/json",
30
- "Authorization" => "Bearer #{@access_token}",
31
- "OpenAI-Organization" => @organization_id
32
- },
33
- body: parameters
34
- )
12
+ def edit(parameters: {})
13
+ OpenAI::Client.post(path: "/images/edits", parameters: open_files(parameters))
35
14
  end
36
15
 
37
- def variations(version: default_version, parameters: {})
38
- parameters = open_files(parameters)
39
-
40
- self.class.post(
41
- "/#{version}/images/variations",
42
- headers: {
43
- "Content-Type" => "application/json",
44
- "Authorization" => "Bearer #{@access_token}",
45
- "OpenAI-Organization" => @organization_id
46
- },
47
- body: parameters
48
- )
16
+ def variations(parameters: {})
17
+ OpenAI::Client.post(path: "/images/variations", parameters: open_files(parameters))
49
18
  end
50
19
 
51
20
  private
52
21
 
53
- def default_version
54
- "v1".freeze
55
- end
56
-
57
22
  def open_files(parameters)
58
23
  parameters = parameters.merge(image: File.open(parameters[:image]))
59
24
  parameters = parameters.merge(mask: File.open(parameters[:mask])) if parameters[:mask]
@@ -1,39 +1,16 @@
1
1
  module OpenAI
2
2
  class Models
3
- include HTTParty
4
- base_uri "https://api.openai.com"
5
-
6
3
  def initialize(access_token: nil, organization_id: nil)
7
- @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
- @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
9
- end
10
-
11
- def list(version: default_version)
12
- self.class.get(
13
- "/#{version}/models",
14
- headers: {
15
- "Content-Type" => "application/json",
16
- "Authorization" => "Bearer #{@access_token}",
17
- "OpenAI-Organization" => @organization_id
18
- }
19
- )
4
+ Ruby::OpenAI.configuration.access_token = access_token if access_token
5
+ Ruby::OpenAI.configuration.organization_id = organization_id if organization_id
20
6
  end
21
7
 
22
- def retrieve(id:, version: default_version)
23
- self.class.get(
24
- "/#{version}/models/#{id}",
25
- headers: {
26
- "Content-Type" => "application/json",
27
- "Authorization" => "Bearer #{@access_token}",
28
- "OpenAI-Organization" => @organization_id
29
- }
30
- )
8
+ def list
9
+ OpenAI::Client.get(path: "/models")
31
10
  end
32
11
 
33
- private
34
-
35
- def default_version
36
- "v1".freeze
12
+ def retrieve(id:)
13
+ OpenAI::Client.get(path: "/models/#{id}")
37
14
  end
38
15
  end
39
16
  end
@@ -1,5 +1,5 @@
1
1
  module Ruby
2
2
  module OpenAI
3
- VERSION = "2.3.0".freeze
3
+ VERSION = "3.0.1".freeze
4
4
  end
5
5
  end
data/lib/ruby/openai.rb CHANGED
@@ -1,15 +1,46 @@
1
1
  require "httparty"
2
- require "ruby/openai/engines"
2
+ require "ruby/openai/client"
3
3
  require "ruby/openai/files"
4
4
  require "ruby/openai/finetunes"
5
5
  require "ruby/openai/images"
6
6
  require "ruby/openai/models"
7
- require "ruby/openai/client"
8
7
  require "ruby/openai/version"
9
- require "dotenv/load"
10
8
 
11
9
  module Ruby
12
10
  module OpenAI
13
11
  class Error < StandardError; end
12
+ class ConfigurationError < Error; end
13
+
14
+ class Configuration
15
+ attr_writer :access_token
16
+ attr_accessor :api_version, :organization_id
17
+
18
+ DEFAULT_API_VERSION = "v1".freeze
19
+
20
+ def initialize
21
+ @access_token = nil
22
+ @api_version = DEFAULT_API_VERSION
23
+ @organization_id = nil
24
+ end
25
+
26
+ def access_token
27
+ return @access_token if @access_token
28
+
29
+ error_text = "OpenAI access token missing! See https://github.com/alexrudall/ruby-openai#usage"
30
+ raise ConfigurationError, error_text
31
+ end
32
+ end
33
+
34
+ class << self
35
+ attr_writer :configuration
36
+ end
37
+
38
+ def self.configuration
39
+ @configuration ||= OpenAI::Configuration.new
40
+ end
41
+
42
+ def self.configure
43
+ yield(configuration)
44
+ end
14
45
  end
15
46
  end
data/ruby-openai.gemspec CHANGED
@@ -25,6 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
27
 
28
- spec.add_dependency "dotenv", ">= 2.7.6", "< 2.9.0"
29
28
  spec.add_dependency "httparty", ">= 0.18.1", "< 0.21.0"
30
29
  end
metadata CHANGED
@@ -1,35 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-23 00:00:00.000000000 Z
11
+ date: 2022-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: dotenv
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 2.7.6
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: 2.9.0
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 2.7.6
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: 2.9.0
33
13
  - !ruby/object:Gem::Dependency
34
14
  name: httparty
35
15
  requirement: !ruby/object:Gem::Requirement
@@ -77,7 +57,6 @@ files:
77
57
  - bin/setup
78
58
  - lib/ruby/openai.rb
79
59
  - lib/ruby/openai/client.rb
80
- - lib/ruby/openai/engines.rb
81
60
  - lib/ruby/openai/files.rb
82
61
  - lib/ruby/openai/finetunes.rb
83
62
  - lib/ruby/openai/images.rb
@@ -1,39 +0,0 @@
1
- module OpenAI
2
- class Engines
3
- include HTTParty
4
- base_uri "https://api.openai.com"
5
-
6
- def initialize(access_token: nil, organization_id: nil)
7
- @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
- @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
9
- end
10
-
11
- def list(version: default_version)
12
- self.class.get(
13
- "/#{version}/engines",
14
- headers: {
15
- "Content-Type" => "application/json",
16
- "Authorization" => "Bearer #{@access_token}",
17
- "OpenAI-Organization" => @organization_id
18
- }
19
- )
20
- end
21
-
22
- def retrieve(id:, version: default_version)
23
- self.class.get(
24
- "/#{version}/engines/#{id}",
25
- headers: {
26
- "Content-Type" => "application/json",
27
- "Authorization" => "Bearer #{@access_token}",
28
- "OpenAI-Organization" => @organization_id
29
- }
30
- )
31
- end
32
-
33
- private
34
-
35
- def default_version
36
- "v1".freeze
37
- end
38
- end
39
- end