ruby-openai 2.1.0 → 2.3.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: 141a4b28c980797b7b04fd8434e03755341fdfbc542e7ba2425b8d467662ef34
4
- data.tar.gz: 934ed9a6b66897c370c8d5c8787d2508a95f55e695d312bab2c4227af5f820ca
3
+ metadata.gz: e9f91687f2b4e37ef74018f8454392416afbe43ad08f5f8d671a1a9dc8feba82
4
+ data.tar.gz: 902a8bbd495d8ee56800f695aa3a264a8ded26475c11874040871b4765c8dacf
5
5
  SHA512:
6
- metadata.gz: f4bccb5f8b6ac3fc05ac592af972412a284dfb2aa4015657faa8358d7e00e060b508153413c8d8416e991886724e795a5c26125485ffec3181dcb2fd3d84e298
7
- data.tar.gz: 7a2138265ae5235d870d6ddae69acf016132c71bef8b5781d5854c6ad970396d3b466b59cd14f82891b11d81b8833483ccf757f899be71cbb9f12f6608aaffd8
6
+ metadata.gz: 5b631c7f78b6de8d7c20acc61e4fc22eca4f372e488ba55e10267cedfd91c9b340334c69403fd28a26c71cfaa52678e7ea9c8410121139e9069abdadf5f37cf8
7
+ data.tar.gz: 40cb9e2f2848a954e5f786979d207a08b698ef6c5fb787afd564cd7945e5e758555ec2d99967a507bd2ae05b63ee8a7b518a197d8b2b6d39b19839c4398caf48
data/CHANGELOG.md CHANGED
@@ -5,6 +5,19 @@ 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
+ ## [2.3.0] - 2022-12-23
9
+
10
+ ### Added
11
+
12
+ - Add Images#edit and Images#variations endpoint to modify images with DALL·E.
13
+
14
+ ## [2.2.0] - 2022-12-15
15
+
16
+ ### Added
17
+
18
+ - Add Organization ID to headers so users can charge credits to the correct organization.
19
+ - Thanks [@mridul911](https://github.com/mridul911) for raising this and [@maks112v](https://github.com/maks112v) for adding it!
20
+
8
21
  ## [2.1.0] - 2022-11-13
9
22
 
10
23
  ### Added
data/Gemfile CHANGED
@@ -6,6 +6,6 @@ gemspec
6
6
  gem "byebug", "~> 11.1.3"
7
7
  gem "rake", "~> 13.0"
8
8
  gem "rspec", "~> 3.12"
9
- gem "rubocop", "~> 1.38.0"
9
+ gem "rubocop", "~> 1.41.1"
10
10
  gem "vcr", "~> 6.1.0"
11
11
  gem "webmock", "~> 3.18.1"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-openai (2.1.0)
4
+ ruby-openai (2.3.0)
5
5
  dotenv (>= 2.7.6, < 2.9.0)
6
6
  httparty (>= 0.18.1, < 0.21.0)
7
7
 
@@ -20,18 +20,18 @@ GEM
20
20
  httparty (0.20.0)
21
21
  mime-types (~> 3.0)
22
22
  multi_xml (>= 0.5.2)
23
- json (2.6.2)
23
+ json (2.6.3)
24
24
  mime-types (3.4.1)
25
25
  mime-types-data (~> 3.2015)
26
26
  mime-types-data (3.2022.0105)
27
27
  multi_xml (0.6.0)
28
28
  parallel (1.22.1)
29
- parser (3.1.2.1)
29
+ parser (3.1.3.0)
30
30
  ast (~> 2.4.1)
31
31
  public_suffix (4.0.7)
32
32
  rainbow (3.1.1)
33
33
  rake (13.0.6)
34
- regexp_parser (2.6.0)
34
+ regexp_parser (2.6.1)
35
35
  rexml (3.2.5)
36
36
  rspec (3.12.0)
37
37
  rspec-core (~> 3.12.0)
@@ -46,7 +46,7 @@ GEM
46
46
  diff-lcs (>= 1.2.0, < 2.0)
47
47
  rspec-support (~> 3.12.0)
48
48
  rspec-support (3.12.0)
49
- rubocop (1.38.0)
49
+ rubocop (1.41.1)
50
50
  json (~> 2.3)
51
51
  parallel (~> 1.10)
52
52
  parser (>= 3.1.2.1)
@@ -56,7 +56,7 @@ GEM
56
56
  rubocop-ast (>= 1.23.0, < 2.0)
57
57
  ruby-progressbar (~> 1.7)
58
58
  unicode-display_width (>= 1.4.0, < 3.0)
59
- rubocop-ast (1.23.0)
59
+ rubocop-ast (1.24.0)
60
60
  parser (>= 3.1.1.0)
61
61
  ruby-progressbar (1.11.0)
62
62
  unicode-display_width (2.3.0)
@@ -73,7 +73,7 @@ DEPENDENCIES
73
73
  byebug (~> 11.1.3)
74
74
  rake (~> 13.0)
75
75
  rspec (~> 3.12)
76
- rubocop (~> 1.38.0)
76
+ rubocop (~> 1.41.1)
77
77
  ruby-openai!
78
78
  vcr (~> 6.1.0)
79
79
  webmock (~> 3.18.1)
data/README.md CHANGED
@@ -5,7 +5,9 @@
5
5
  [![CircleCI Build Status](https://circleci.com/gh/alexrudall/ruby-openai.svg?style=shield)](https://circleci.com/gh/alexrudall/ruby-openai)
6
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/a99a88d28ad37a79dbf6/maintainability)](https://codeclimate.com/github/codeclimate/codeclimate/maintainability)
7
7
 
8
- Use the [OpenAI GPT-3 API](https://openai.com/blog/openai-api/) with Ruby! 🤖❤️
8
+ Use the [OpenAI API](https://openai.com/blog/openai-api/) with Ruby! 🤖❤️
9
+
10
+ Generate text with GPT-3, create images with DALL·E, or write code with Codex...
9
11
 
10
12
  ## Installation
11
13
 
@@ -35,14 +37,16 @@ and require with:
35
37
 
36
38
  ## Usage
37
39
 
38
- Get your API key from [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys)
40
+ - Get your API key from [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys)
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)
39
42
 
40
43
  ### With dotenv
41
44
 
42
- If you're using [dotenv](https://github.com/motdotla/dotenv), you can add your secret key to your .env file:
45
+ If you're using [dotenv](https://github.com/motdotla/dotenv), you can add your secret keys to your .env file:
43
46
 
44
47
  ```
45
48
  OPENAI_ACCESS_TOKEN=access_token_goes_here
49
+ OPENAI_ORGANIZATION_ID=organization_id_goes_here # Optional.
46
50
  ```
47
51
 
48
52
  And create a client:
@@ -56,7 +60,10 @@ And create a client:
56
60
  Alternatively you can pass your key directly to a new client:
57
61
 
58
62
  ```ruby
59
- client = OpenAI::Client.new(access_token: "access_token_goes_here")
63
+ client = OpenAI::Client.new(
64
+ access_token: "access_token_goes_here",
65
+ organization_id: "organization_id_goes_here"
66
+ )
60
67
  ```
61
68
 
62
69
  ### Models
@@ -194,17 +201,42 @@ This fine-tuned model name can then be used in classifications:
194
201
  JSON.parse(response.body)["choices"].map { |c| c["text"] }
195
202
  ```
196
203
 
197
- ### Images
204
+ ### Image Generation
198
205
 
199
206
  Generate an image using DALL·E!
200
207
 
201
208
  ```ruby
202
209
  response = client.images.generate(parameters: { prompt: "A baby sea otter cooking pasta wearing a hat of some sort" })
203
- puts response.dig("data", 0, "url") }
210
+ puts response.dig("data", 0, "url")
211
+ => "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
212
+ ```
213
+
214
+ ![Ruby](https://i.ibb.co/6y4HJFx/img-d-Tx-Rf-RHj-SO5-Gho-Cbd8o-LJvw3.png)
215
+
216
+ ### Image Edit
217
+
218
+ Fill in the transparent part of an image, or upload a mask with transparent sections to indicate the parts of an image that can be changed according to your prompt...
219
+
220
+ ```ruby
221
+ response = client.images.edit(parameters: { prompt: "A solid red Ruby on a blue background", image: "image.png", mask: "mask.png" })
222
+ puts response.dig("data", 0, "url")
223
+ => "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
224
+ ```
225
+
226
+ ![Ruby](https://i.ibb.co/sWVh3BX/dalle-ruby.png)
227
+
228
+ ### Image Variations
229
+
230
+ Create n variations of an image.
231
+
232
+ ```ruby
233
+ response = client.images.variations(parameters: { image: "image.png", n: 2 })
234
+ puts response.dig("data", 0, "url")
204
235
  => "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
205
236
  ```
206
237
 
207
- ![Otter Chef](https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhhQPMiIQ0Es8OwrH/user-jxM65ijkZc1qRfHC0IJ8mOIc/img-UrDvFC4tDnuhTieF7TrTJ2gq.png?st=2022-11-13T15%3A55%3A34Z&se=2022-11-13T17%3A55%3A34Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-13T01%3A32%3A30Z&ske=2022-11-14T01%3A32%3A30Z&sks=b&skv=2021-08-06&sig=tLdggckHl20CnnpCleoeiAEQjy4zMjuZJiUdovmkoF0%3D)
238
+ ![Ruby](https://i.ibb.co/TWJLP2y/img-miu-Wk-Nl0-QNy-Xtj-Lerc3c0l-NW.png)
239
+ ![Ruby](https://i.ibb.co/ScBhDGB/img-a9-Be-Rz-Au-Xwd-AV0-ERLUTSTGdi.png)
208
240
 
209
241
  ### Moderations
210
242
 
@@ -276,7 +308,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
276
308
 
277
309
  ## Contributing
278
310
 
279
- Bug reports and pull requests are welcome on GitHub at https://github.com/alexrudall/ruby-openai. 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/alexrudall/ruby-openai/blob/main/CODE_OF_CONDUCT.md).
311
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/alexrudall/ruby-openai>. 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/alexrudall/ruby-openai/blob/main/CODE_OF_CONDUCT.md).
280
312
 
281
313
  ## License
282
314
 
@@ -3,8 +3,9 @@ module OpenAI
3
3
  include HTTParty
4
4
  base_uri "https://api.openai.com"
5
5
 
6
- def initialize(access_token: nil)
6
+ def initialize(access_token: nil, organization_id: nil)
7
7
  @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
8
9
  end
9
10
 
10
11
  def answers(version: default_version, parameters: {})
@@ -43,23 +44,25 @@ module OpenAI
43
44
  warn "[DEPRECATION WARNING] [ruby-openai] `Client#engines` is deprecated and will
44
45
  be removed from ruby-openai v3.0. Use `Client#models` instead."
45
46
 
46
- @engines ||= OpenAI::Engines.new(access_token: @access_token)
47
+ @engines ||= OpenAI::Engines.new(access_token: @access_token,
48
+ organization_id: @organization_id)
47
49
  end
48
50
 
49
51
  def files
50
- @files ||= OpenAI::Files.new(access_token: @access_token)
52
+ @files ||= OpenAI::Files.new(access_token: @access_token, organization_id: @organization_id)
51
53
  end
52
54
 
53
55
  def finetunes
54
- @finetunes ||= OpenAI::Finetunes.new(access_token: @access_token)
56
+ @finetunes ||= OpenAI::Finetunes.new(access_token: @access_token,
57
+ organization_id: @organization_id)
55
58
  end
56
59
 
57
60
  def images
58
- @images ||= OpenAI::Images.new(access_token: @access_token)
61
+ @images ||= OpenAI::Images.new(access_token: @access_token, organization_id: @organization_id)
59
62
  end
60
63
 
61
64
  def models
62
- @models ||= OpenAI::Models.new(access_token: @access_token)
65
+ @models ||= OpenAI::Models.new(access_token: @access_token, organization_id: @organization_id)
63
66
  end
64
67
 
65
68
  def moderations(version: default_version, parameters: {})
@@ -101,7 +104,8 @@ module OpenAI
101
104
  url,
102
105
  headers: {
103
106
  "Content-Type" => "application/json",
104
- "Authorization" => "Bearer #{@access_token}"
107
+ "Authorization" => "Bearer #{@access_token}",
108
+ "OpenAI-Organization" => @organization_id
105
109
  },
106
110
  body: parameters.to_json
107
111
  )
@@ -3,8 +3,9 @@ module OpenAI
3
3
  include HTTParty
4
4
  base_uri "https://api.openai.com"
5
5
 
6
- def initialize(access_token: nil)
6
+ def initialize(access_token: nil, organization_id: nil)
7
7
  @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
8
9
  end
9
10
 
10
11
  def list(version: default_version)
@@ -12,7 +13,8 @@ module OpenAI
12
13
  "/#{version}/engines",
13
14
  headers: {
14
15
  "Content-Type" => "application/json",
15
- "Authorization" => "Bearer #{@access_token}"
16
+ "Authorization" => "Bearer #{@access_token}",
17
+ "OpenAI-Organization" => @organization_id
16
18
  }
17
19
  )
18
20
  end
@@ -22,7 +24,8 @@ module OpenAI
22
24
  "/#{version}/engines/#{id}",
23
25
  headers: {
24
26
  "Content-Type" => "application/json",
25
- "Authorization" => "Bearer #{@access_token}"
27
+ "Authorization" => "Bearer #{@access_token}",
28
+ "OpenAI-Organization" => @organization_id
26
29
  }
27
30
  )
28
31
  end
@@ -3,8 +3,9 @@ module OpenAI
3
3
  include HTTParty
4
4
  base_uri "https://api.openai.com"
5
5
 
6
- def initialize(access_token: nil)
6
+ def initialize(access_token: nil, organization_id: nil)
7
7
  @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
8
9
  end
9
10
 
10
11
  def list(version: default_version)
@@ -12,7 +13,8 @@ module OpenAI
12
13
  "/#{version}/files",
13
14
  headers: {
14
15
  "Content-Type" => "application/json",
15
- "Authorization" => "Bearer #{@access_token}"
16
+ "Authorization" => "Bearer #{@access_token}",
17
+ "OpenAI-Organization" => @organization_id
16
18
  }
17
19
  )
18
20
  end
@@ -24,7 +26,8 @@ module OpenAI
24
26
  "/#{version}/files",
25
27
  headers: {
26
28
  "Content-Type" => "application/json",
27
- "Authorization" => "Bearer #{@access_token}"
29
+ "Authorization" => "Bearer #{@access_token}",
30
+ "OpenAI-Organization" => @organization_id
28
31
  },
29
32
  body: parameters.merge(file: File.open(parameters[:file]))
30
33
  )
@@ -35,7 +38,8 @@ module OpenAI
35
38
  "/#{version}/files/#{id}",
36
39
  headers: {
37
40
  "Content-Type" => "application/json",
38
- "Authorization" => "Bearer #{@access_token}"
41
+ "Authorization" => "Bearer #{@access_token}",
42
+ "OpenAI-Organization" => @organization_id
39
43
  }
40
44
  )
41
45
  end
@@ -45,7 +49,8 @@ module OpenAI
45
49
  "/#{version}/files/#{id}",
46
50
  headers: {
47
51
  "Content-Type" => "application/json",
48
- "Authorization" => "Bearer #{@access_token}"
52
+ "Authorization" => "Bearer #{@access_token}",
53
+ "OpenAI-Organization" => @organization_id
49
54
  }
50
55
  )
51
56
  end
@@ -3,8 +3,9 @@ module OpenAI
3
3
  include HTTParty
4
4
  base_uri "https://api.openai.com"
5
5
 
6
- def initialize(access_token: nil)
6
+ def initialize(access_token: nil, organization_id: nil)
7
7
  @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
8
9
  end
9
10
 
10
11
  def list(version: default_version)
@@ -12,7 +13,8 @@ module OpenAI
12
13
  "/#{version}/fine-tunes",
13
14
  headers: {
14
15
  "Content-Type" => "application/json",
15
- "Authorization" => "Bearer #{@access_token}"
16
+ "Authorization" => "Bearer #{@access_token}",
17
+ "OpenAI-Organization" => @organization_id
16
18
  }
17
19
  )
18
20
  end
@@ -22,7 +24,8 @@ module OpenAI
22
24
  "/#{version}/fine-tunes",
23
25
  headers: {
24
26
  "Content-Type" => "application/json",
25
- "Authorization" => "Bearer #{@access_token}"
27
+ "Authorization" => "Bearer #{@access_token}",
28
+ "OpenAI-Organization" => @organization_id
26
29
  },
27
30
  body: parameters.to_json
28
31
  )
@@ -33,7 +36,8 @@ module OpenAI
33
36
  "/#{version}/fine-tunes/#{id}",
34
37
  headers: {
35
38
  "Content-Type" => "application/json",
36
- "Authorization" => "Bearer #{@access_token}"
39
+ "Authorization" => "Bearer #{@access_token}",
40
+ "OpenAI-Organization" => @organization_id
37
41
  }
38
42
  )
39
43
  end
@@ -43,7 +47,8 @@ module OpenAI
43
47
  "/#{version}/fine-tunes/#{id}/cancel",
44
48
  headers: {
45
49
  "Content-Type" => "application/json",
46
- "Authorization" => "Bearer #{@access_token}"
50
+ "Authorization" => "Bearer #{@access_token}",
51
+ "OpenAI-Organization" => @organization_id
47
52
  }
48
53
  )
49
54
  end
@@ -53,7 +58,8 @@ module OpenAI
53
58
  "/#{version}/fine-tunes/#{id}/events",
54
59
  headers: {
55
60
  "Content-Type" => "application/json",
56
- "Authorization" => "Bearer #{@access_token}"
61
+ "Authorization" => "Bearer #{@access_token}",
62
+ "OpenAI-Organization" => @organization_id
57
63
  }
58
64
  )
59
65
  end
@@ -3,8 +3,9 @@ module OpenAI
3
3
  include HTTParty
4
4
  base_uri "https://api.openai.com"
5
5
 
6
- def initialize(access_token: nil)
6
+ def initialize(access_token: nil, organization_id: nil)
7
7
  @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
8
9
  end
9
10
 
10
11
  def generate(version: default_version, parameters: {})
@@ -12,16 +13,51 @@ module OpenAI
12
13
  "/#{version}/images/generations",
13
14
  headers: {
14
15
  "Content-Type" => "application/json",
15
- "Authorization" => "Bearer #{@access_token}"
16
+ "Authorization" => "Bearer #{@access_token}",
17
+ "OpenAI-Organization" => @organization_id
16
18
  },
17
19
  body: parameters.to_json
18
20
  )
19
21
  end
20
22
 
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
+ )
35
+ end
36
+
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
+ )
49
+ end
50
+
21
51
  private
22
52
 
23
53
  def default_version
24
54
  "v1".freeze
25
55
  end
56
+
57
+ def open_files(parameters)
58
+ parameters = parameters.merge(image: File.open(parameters[:image]))
59
+ parameters = parameters.merge(mask: File.open(parameters[:mask])) if parameters[:mask]
60
+ parameters
61
+ end
26
62
  end
27
63
  end
@@ -3,8 +3,9 @@ module OpenAI
3
3
  include HTTParty
4
4
  base_uri "https://api.openai.com"
5
5
 
6
- def initialize(access_token: nil)
6
+ def initialize(access_token: nil, organization_id: nil)
7
7
  @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ @organization_id = organization_id || ENV.fetch("OPENAI_ORGANIZATION_ID", nil)
8
9
  end
9
10
 
10
11
  def list(version: default_version)
@@ -12,7 +13,8 @@ module OpenAI
12
13
  "/#{version}/models",
13
14
  headers: {
14
15
  "Content-Type" => "application/json",
15
- "Authorization" => "Bearer #{@access_token}"
16
+ "Authorization" => "Bearer #{@access_token}",
17
+ "OpenAI-Organization" => @organization_id
16
18
  }
17
19
  )
18
20
  end
@@ -22,7 +24,8 @@ module OpenAI
22
24
  "/#{version}/models/#{id}",
23
25
  headers: {
24
26
  "Content-Type" => "application/json",
25
- "Authorization" => "Bearer #{@access_token}"
27
+ "Authorization" => "Bearer #{@access_token}",
28
+ "OpenAI-Organization" => @organization_id
26
29
  }
27
30
  )
28
31
  end
@@ -1,5 +1,5 @@
1
1
  module Ruby
2
2
  module OpenAI
3
- VERSION = "2.1.0".freeze
3
+ VERSION = "2.3.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-13 00:00:00.000000000 Z
11
+ date: 2022-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv