ruby-openai 2.2.0 → 3.0.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 +4 -4
- data/.rubocop.yml +1 -3
- data/CHANGELOG.md +20 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +4 -4
- data/README.md +43 -17
- data/lib/ruby/openai/client.rb +56 -41
- data/lib/ruby/openai/engines.rb +6 -29
- data/lib/ruby/openai/files.rb +12 -45
- data/lib/ruby/openai/finetunes.rb +12 -57
- data/lib/ruby/openai/images.rb +16 -17
- data/lib/ruby/openai/models.rb +6 -29
- data/lib/ruby/openai/version.rb +1 -1
- data/lib/ruby/openai.rb +34 -2
- data/ruby-openai.gemspec +0 -1
- metadata +2 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50fc900251b1e7c0c1a9f1f18c779871cba3691c9e3cd32a022286f6ee5978f2
|
4
|
+
data.tar.gz: '015428f6b586a0c504f839c6b38eb6842bd7c964805049ec8af706bf18fe8307'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab310b17e7282ba6885b468373b10d27f33ef50effff6b61d07d5d677e2b4153346ca355c66803521dc55bed87c8799a1da1513dd04ff8e4d36a53ec382b9d77
|
7
|
+
data.tar.gz: f29975d47364d66ca01ffebdf6adfeb2b660b808ec4cf704f35aaa775be73bfb0aff09673a3b0ee540dd8c35e70c2af24e909ba336c8cdbe22a2f9c6bd868781
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,26 @@ 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.0] - 2022-12-26
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Add ability to set access_token via gem configuration.
|
13
|
+
- 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.
|
14
|
+
|
15
|
+
### Removed
|
16
|
+
|
17
|
+
- [BREAKING] Remove ability to include access_token directly via ENV vars.
|
18
|
+
- [BREAKING] Remove deprecated answers, classifications, embeddings, engines and search endpoints.
|
19
|
+
- [BREAKING] Remove ability to pass engine to completions and embeddings outside of the parameters hash.
|
20
|
+
- [BREAKING] Remove ability to pass API version directly to endpoints.
|
21
|
+
|
22
|
+
## [2.3.0] - 2022-12-23
|
23
|
+
|
24
|
+
### Added
|
25
|
+
|
26
|
+
- Add Images#edit and Images#variations endpoint to modify images with DALL·E.
|
27
|
+
|
8
28
|
## [2.2.0] - 2022-12-15
|
9
29
|
|
10
30
|
### Added
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-openai (
|
5
|
-
dotenv (>= 2.7.6, < 2.9.0)
|
4
|
+
ruby-openai (3.0.0)
|
6
5
|
httparty (>= 0.18.1, < 0.21.0)
|
7
6
|
|
8
7
|
GEM
|
@@ -46,7 +45,7 @@ GEM
|
|
46
45
|
diff-lcs (>= 1.2.0, < 2.0)
|
47
46
|
rspec-support (~> 3.12.0)
|
48
47
|
rspec-support (3.12.0)
|
49
|
-
rubocop (1.
|
48
|
+
rubocop (1.41.1)
|
50
49
|
json (~> 2.3)
|
51
50
|
parallel (~> 1.10)
|
52
51
|
parser (>= 3.1.2.1)
|
@@ -71,9 +70,10 @@ 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
|
-
rubocop (~> 1.
|
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
|
[](https://circleci.com/gh/alexrudall/ruby-openai)
|
6
6
|
[](https://codeclimate.com/github/codeclimate/codeclimate/maintainability)
|
7
7
|
|
8
|
-
Use the [OpenAI
|
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
|
|
@@ -38,30 +40,29 @@ and require with:
|
|
38
40
|
- Get your API key from [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys)
|
39
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)
|
40
42
|
|
41
|
-
###
|
43
|
+
### Quickstart
|
42
44
|
|
43
|
-
|
45
|
+
For a quick test you can pass your token directly to a new client:
|
44
46
|
|
45
|
-
```
|
46
|
-
|
47
|
-
OPENAI_ORGANIZATION_ID=organization_id_goes_here # Optional.
|
47
|
+
```ruby
|
48
|
+
client = OpenAI::Client.new(access_token: "access_token_goes_here")
|
48
49
|
```
|
49
50
|
|
50
|
-
|
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.
|
51
54
|
|
52
55
|
```ruby
|
53
|
-
|
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
|
54
60
|
```
|
55
61
|
|
56
|
-
|
57
|
-
|
58
|
-
Alternatively you can pass your key directly to a new client:
|
62
|
+
Then you can create a client like this:
|
59
63
|
|
60
64
|
```ruby
|
61
|
-
client = OpenAI::Client.new
|
62
|
-
access_token: "access_token_goes_here",
|
63
|
-
organization_id: "organization_id_goes_here"
|
64
|
-
)
|
65
|
+
client = OpenAI::Client.new
|
65
66
|
```
|
66
67
|
|
67
68
|
### Models
|
@@ -199,7 +200,7 @@ This fine-tuned model name can then be used in classifications:
|
|
199
200
|
JSON.parse(response.body)["choices"].map { |c| c["text"] }
|
200
201
|
```
|
201
202
|
|
202
|
-
###
|
203
|
+
### Image Generation
|
203
204
|
|
204
205
|
Generate an image using DALL·E!
|
205
206
|
|
@@ -209,7 +210,32 @@ Generate an image using DALL·E!
|
|
209
210
|
=> "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
|
210
211
|
```
|
211
212
|
|
212
|
-

|
214
|
+
|
215
|
+
### Image Edit
|
216
|
+
|
217
|
+
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...
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
response = client.images.edit(parameters: { prompt: "A solid red Ruby on a blue background", image: "image.png", mask: "mask.png" })
|
221
|
+
puts response.dig("data", 0, "url")
|
222
|
+
=> "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
|
223
|
+
```
|
224
|
+
|
225
|
+

|
226
|
+
|
227
|
+
### Image Variations
|
228
|
+
|
229
|
+
Create n variations of an image.
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
response = client.images.variations(parameters: { image: "image.png", n: 2 })
|
233
|
+
puts response.dig("data", 0, "url")
|
234
|
+
=> "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
|
235
|
+
```
|
236
|
+
|
237
|
+

|
238
|
+

|
213
239
|
|
214
240
|
### Moderations
|
215
241
|
|
data/lib/ruby/openai/client.rb
CHANGED
@@ -1,80 +1,111 @@
|
|
1
1
|
module OpenAI
|
2
2
|
class Client
|
3
|
-
|
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
|
-
|
8
|
-
|
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(
|
10
|
+
def answers(parameters: {})
|
12
11
|
warn "[DEPRECATION WARNING] [ruby-openai] `Client#answers` is deprecated and will
|
13
12
|
be removed from the OpenAI API on 3 December 2022 and from ruby-openai v3.0.
|
14
13
|
More information: https://help.openai.com/en/articles/6233728-answers-transition-guide"
|
15
14
|
|
16
|
-
post(
|
15
|
+
OpenAI::Client.post(path: "/answers", parameters: parameters)
|
17
16
|
end
|
18
17
|
|
19
|
-
def classifications(
|
18
|
+
def classifications(parameters: {})
|
20
19
|
warn "[DEPRECATION WARNING] [ruby-openai] `Client#classifications` is deprecated and will
|
21
20
|
be removed from the OpenAI API on 3 December 2022 and from ruby-openai v3.0.
|
22
21
|
More information: https://help.openai.com/en/articles/6272941-classifications-transition-guide"
|
23
22
|
|
24
|
-
post(
|
23
|
+
OpenAI::Client.post(path: "/classifications", parameters: parameters)
|
25
24
|
end
|
26
25
|
|
27
|
-
def completions(engine: nil,
|
26
|
+
def completions(engine: nil, parameters: {})
|
28
27
|
parameters = deprecate_engine(engine: engine, method: "completions", parameters: parameters)
|
29
28
|
|
30
|
-
post(
|
29
|
+
OpenAI::Client.post(path: "/completions", parameters: parameters)
|
31
30
|
end
|
32
31
|
|
33
|
-
def edits(
|
34
|
-
post(
|
32
|
+
def edits(parameters: {})
|
33
|
+
OpenAI::Client.post(path: "/edits", parameters: parameters)
|
35
34
|
end
|
36
35
|
|
37
|
-
def embeddings(engine: nil,
|
36
|
+
def embeddings(engine: nil, parameters: {})
|
38
37
|
parameters = deprecate_engine(engine: engine, method: "embeddings", parameters: parameters)
|
39
38
|
|
40
|
-
post(
|
39
|
+
OpenAI::Client.post(path: "/embeddings", parameters: parameters)
|
41
40
|
end
|
42
41
|
|
43
42
|
def engines
|
44
43
|
warn "[DEPRECATION WARNING] [ruby-openai] `Client#engines` is deprecated and will
|
45
44
|
be removed from ruby-openai v3.0. Use `Client#models` instead."
|
46
45
|
|
47
|
-
@engines ||= OpenAI::Engines.new
|
48
|
-
organization_id: @organization_id)
|
46
|
+
@engines ||= OpenAI::Engines.new
|
49
47
|
end
|
50
48
|
|
51
49
|
def files
|
52
|
-
@files ||= OpenAI::Files.new
|
50
|
+
@files ||= OpenAI::Files.new
|
53
51
|
end
|
54
52
|
|
55
53
|
def finetunes
|
56
|
-
@finetunes ||= OpenAI::Finetunes.new
|
57
|
-
organization_id: @organization_id)
|
54
|
+
@finetunes ||= OpenAI::Finetunes.new
|
58
55
|
end
|
59
56
|
|
60
57
|
def images
|
61
|
-
@images ||= OpenAI::Images.new
|
58
|
+
@images ||= OpenAI::Images.new
|
62
59
|
end
|
63
60
|
|
64
61
|
def models
|
65
|
-
@models ||= OpenAI::Models.new
|
62
|
+
@models ||= OpenAI::Models.new
|
66
63
|
end
|
67
64
|
|
68
|
-
def moderations(
|
69
|
-
post(
|
65
|
+
def moderations(parameters: {})
|
66
|
+
OpenAI::Client.post(path: "/moderations", parameters: parameters)
|
70
67
|
end
|
71
68
|
|
72
|
-
def search(engine:,
|
69
|
+
def search(engine:, parameters: {})
|
73
70
|
warn "[DEPRECATION WARNING] [ruby-openai] `Client#search` is deprecated and will
|
74
71
|
be removed from the OpenAI API on 3 December 2022 and from ruby-openai v3.0.
|
75
72
|
More information: https://help.openai.com/en/articles/6272952-search-transition-guide"
|
76
73
|
|
77
|
-
post(
|
74
|
+
OpenAI::Client.post(path: "/engines/#{engine}/search", parameters: parameters)
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.get(path:)
|
78
|
+
HTTParty.get(
|
79
|
+
uri(path: path),
|
80
|
+
headers: headers
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.post(path:, parameters: nil)
|
85
|
+
HTTParty.post(
|
86
|
+
uri(path: path),
|
87
|
+
headers: headers,
|
88
|
+
body: parameters.to_json
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.delete(path:)
|
93
|
+
HTTParty.delete(
|
94
|
+
uri(path: path),
|
95
|
+
headers: headers
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
private_class_method def self.uri(path:)
|
100
|
+
URI_BASE + Ruby::OpenAI.configuration.api_version + path
|
101
|
+
end
|
102
|
+
|
103
|
+
private_class_method def self.headers
|
104
|
+
{
|
105
|
+
"Content-Type" => "application/json",
|
106
|
+
"Authorization" => "Bearer #{Ruby::OpenAI.configuration.access_token}",
|
107
|
+
"OpenAI-Organization" => Ruby::OpenAI.configuration.organization_id
|
108
|
+
}
|
78
109
|
end
|
79
110
|
|
80
111
|
private
|
@@ -91,24 +122,8 @@ module OpenAI
|
|
91
122
|
parameters
|
92
123
|
end
|
93
124
|
|
94
|
-
def default_version
|
95
|
-
"v1".freeze
|
96
|
-
end
|
97
|
-
|
98
125
|
def documents_or_file(documents: nil, file: nil)
|
99
126
|
documents ? { documents: documents } : { file: file }
|
100
127
|
end
|
101
|
-
|
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
|
-
)
|
112
|
-
end
|
113
128
|
end
|
114
129
|
end
|
data/lib/ruby/openai/engines.rb
CHANGED
@@ -1,39 +1,16 @@
|
|
1
1
|
module OpenAI
|
2
2
|
class Engines
|
3
|
-
include HTTParty
|
4
|
-
base_uri "https://api.openai.com"
|
5
|
-
|
6
3
|
def initialize(access_token: nil, organization_id: nil)
|
7
|
-
|
8
|
-
|
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
|
-
)
|
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
|
23
|
-
|
24
|
-
"/#{version}/engines/#{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: "/engines")
|
31
10
|
end
|
32
11
|
|
33
|
-
|
34
|
-
|
35
|
-
def default_version
|
36
|
-
"v1".freeze
|
12
|
+
def retrieve(id:)
|
13
|
+
OpenAI::Client.get(path: "/engines/#{id}")
|
37
14
|
end
|
38
15
|
end
|
39
16
|
end
|
data/lib/ruby/openai/files.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
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
|
12
|
-
|
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(
|
12
|
+
def upload(parameters: {})
|
23
13
|
validate(file: parameters[:file])
|
24
14
|
|
25
|
-
|
26
|
-
"
|
27
|
-
|
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
|
37
|
-
|
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
|
48
|
-
|
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
|
-
|
8
|
-
|
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
|
23
|
-
|
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
|
35
|
-
|
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
|
46
|
-
|
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
|
57
|
-
|
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
|
-
|
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
|
data/lib/ruby/openai/images.rb
CHANGED
@@ -1,29 +1,28 @@
|
|
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
|
-
|
8
|
-
|
4
|
+
Ruby::OpenAI.configuration.access_token = access_token if access_token
|
5
|
+
Ruby::OpenAI.configuration.organization_id = organization_id if organization_id
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate(parameters: {})
|
9
|
+
OpenAI::Client.post(path: "/images/generations", parameters: parameters.to_json)
|
10
|
+
end
|
11
|
+
|
12
|
+
def edit(parameters: {})
|
13
|
+
OpenAI::Client.post(path: "/images/edits", parameters: open_files(parameters))
|
9
14
|
end
|
10
15
|
|
11
|
-
def
|
12
|
-
|
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
|
-
)
|
16
|
+
def variations(parameters: {})
|
17
|
+
OpenAI::Client.post(path: "/images/variations", parameters: open_files(parameters))
|
21
18
|
end
|
22
19
|
|
23
20
|
private
|
24
21
|
|
25
|
-
def
|
26
|
-
|
22
|
+
def open_files(parameters)
|
23
|
+
parameters = parameters.merge(image: File.open(parameters[:image]))
|
24
|
+
parameters = parameters.merge(mask: File.open(parameters[:mask])) if parameters[:mask]
|
25
|
+
parameters
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
data/lib/ruby/openai/models.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
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
|
23
|
-
|
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
|
-
|
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
|
data/lib/ruby/openai/version.rb
CHANGED
data/lib/ruby/openai.rb
CHANGED
@@ -1,15 +1,47 @@
|
|
1
1
|
require "httparty"
|
2
|
+
require "ruby/openai/client"
|
2
3
|
require "ruby/openai/engines"
|
3
4
|
require "ruby/openai/files"
|
4
5
|
require "ruby/openai/finetunes"
|
5
6
|
require "ruby/openai/images"
|
6
7
|
require "ruby/openai/models"
|
7
|
-
require "ruby/openai/client"
|
8
8
|
require "ruby/openai/version"
|
9
|
-
require "dotenv/load"
|
10
9
|
|
11
10
|
module Ruby
|
12
11
|
module OpenAI
|
13
12
|
class Error < StandardError; end
|
13
|
+
class ConfigurationError < Error; end
|
14
|
+
|
15
|
+
class Configuration
|
16
|
+
attr_writer :access_token
|
17
|
+
attr_accessor :api_version, :organization_id
|
18
|
+
|
19
|
+
DEFAULT_API_VERSION = "v1".freeze
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@access_token = nil
|
23
|
+
@api_version = DEFAULT_API_VERSION
|
24
|
+
@organization_id = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def access_token
|
28
|
+
return @access_token if @access_token
|
29
|
+
|
30
|
+
error_text = "OpenAI access token missing! See https://github.com/alexrudall/ruby-openai#usage"
|
31
|
+
raise ConfigurationError, error_text
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class << self
|
36
|
+
attr_writer :configuration
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.configuration
|
40
|
+
@configuration ||= OpenAI::Configuration.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.configure
|
44
|
+
yield(configuration)
|
45
|
+
end
|
14
46
|
end
|
15
47
|
end
|
data/ruby-openai.gemspec
CHANGED
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:
|
4
|
+
version: 3.0.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-12-
|
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
|