ruby-openai 3.7.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +17 -13
- data/README.md +59 -37
- data/lib/openai/client.rb +2 -50
- data/lib/openai/http.rb +95 -0
- data/lib/openai/version.rb +1 -1
- data/lib/openai.rb +3 -1
- data/ruby-openai.gemspec +2 -3
- metadata +25 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '06199aaabd11e965f6d07f3948323b5226fdda82f09326c065cda4b5b2cc9237'
|
4
|
+
data.tar.gz: 59cce00dfeb08270e11b2c33b23af4558dfc53796c87ebb6cf64b1cb76739790
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d9b9409e915f49284f8acdf4be10cde81d7065fadb254dc135aeaad5572c2278c3bb6115752e8c43619d4ea60d696bc55a8128af8981ec544db2320c2d4b89a
|
7
|
+
data.tar.gz: a202ca506f515e8933f00e0302dcd8a59b8d15f6b11c13263499ac140b9b045162089141f27cab5dda2dbde3d5b960c05c8081415a721b29cbdffcd3d375ddd0
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,24 @@ 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
|
+
## [4.1.0] - 2023-05-15
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Add the ability to trigger any callable object as stream chunks come through, not just Procs. Big thanks to [@obie](https://github.com/obie) for this change.
|
13
|
+
|
14
|
+
## [4.0.0] - 2023-04-25
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- Add the ability to stream Chat responses from the API! Thanks to everyone who requested this and made suggestions.
|
19
|
+
- Added instructions for streaming to the README.
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
- Switch HTTP library from HTTParty to Faraday to allow streaming and future feature and performance improvements.
|
24
|
+
- [BREAKING] Endpoints now return JSON rather than HTTParty objects. You will need to update your code to handle this change, changing `JSON.parse(response.body)["key"]` and `response.parsed_response["key"]` to just `response["key"]`.
|
25
|
+
|
8
26
|
## [3.7.0] - 2023-03-25
|
9
27
|
|
10
28
|
### Added
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-openai (
|
5
|
-
|
4
|
+
ruby-openai (4.1.0)
|
5
|
+
faraday (>= 1)
|
6
|
+
faraday-multipart (>= 1)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
@@ -15,20 +16,22 @@ GEM
|
|
15
16
|
rexml
|
16
17
|
diff-lcs (1.5.0)
|
17
18
|
dotenv (2.8.1)
|
19
|
+
faraday (2.7.4)
|
20
|
+
faraday-net_http (>= 2.0, < 3.1)
|
21
|
+
ruby2_keywords (>= 0.0.4)
|
22
|
+
faraday-multipart (1.0.4)
|
23
|
+
multipart-post (~> 2)
|
24
|
+
faraday-net_http (3.0.2)
|
18
25
|
hashdiff (1.0.1)
|
19
|
-
httparty (0.21.0)
|
20
|
-
mini_mime (>= 1.0.0)
|
21
|
-
multi_xml (>= 0.5.2)
|
22
26
|
json (2.6.3)
|
23
|
-
|
24
|
-
multi_xml (0.6.0)
|
27
|
+
multipart-post (2.3.0)
|
25
28
|
parallel (1.22.1)
|
26
|
-
parser (3.2.
|
29
|
+
parser (3.2.2.0)
|
27
30
|
ast (~> 2.4.1)
|
28
31
|
public_suffix (5.0.1)
|
29
32
|
rainbow (3.1.1)
|
30
33
|
rake (13.0.6)
|
31
|
-
regexp_parser (2.
|
34
|
+
regexp_parser (2.8.0)
|
32
35
|
rexml (3.2.5)
|
33
36
|
rspec (3.12.0)
|
34
37
|
rspec-core (~> 3.12.0)
|
@@ -43,19 +46,20 @@ GEM
|
|
43
46
|
diff-lcs (>= 1.2.0, < 2.0)
|
44
47
|
rspec-support (~> 3.12.0)
|
45
48
|
rspec-support (3.12.0)
|
46
|
-
rubocop (1.
|
49
|
+
rubocop (1.50.2)
|
47
50
|
json (~> 2.3)
|
48
51
|
parallel (~> 1.10)
|
49
52
|
parser (>= 3.2.0.0)
|
50
53
|
rainbow (>= 2.2.2, < 4.0)
|
51
54
|
regexp_parser (>= 1.8, < 3.0)
|
52
55
|
rexml (>= 3.2.5, < 4.0)
|
53
|
-
rubocop-ast (>= 1.
|
56
|
+
rubocop-ast (>= 1.28.0, < 2.0)
|
54
57
|
ruby-progressbar (~> 1.7)
|
55
58
|
unicode-display_width (>= 2.4.0, < 3.0)
|
56
|
-
rubocop-ast (1.
|
59
|
+
rubocop-ast (1.28.0)
|
57
60
|
parser (>= 3.2.1.0)
|
58
61
|
ruby-progressbar (1.13.0)
|
62
|
+
ruby2_keywords (0.0.5)
|
59
63
|
unicode-display_width (2.4.2)
|
60
64
|
vcr (6.1.0)
|
61
65
|
webmock (3.18.1)
|
@@ -71,7 +75,7 @@ DEPENDENCIES
|
|
71
75
|
dotenv (~> 2.8.1)
|
72
76
|
rake (~> 13.0)
|
73
77
|
rspec (~> 3.12)
|
74
|
-
rubocop (~> 1.
|
78
|
+
rubocop (~> 1.50.2)
|
75
79
|
ruby-openai!
|
76
80
|
vcr (~> 6.1.0)
|
77
81
|
webmock (~> 3.18.1)
|
data/README.md
CHANGED
@@ -3,13 +3,16 @@
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/ruby-openai.svg)](https://badge.fury.io/rb/ruby-openai)
|
4
4
|
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/alexrudall/ruby-openai/blob/main/LICENSE.txt)
|
5
5
|
[![CircleCI Build Status](https://circleci.com/gh/alexrudall/ruby-openai.svg?style=shield)](https://circleci.com/gh/alexrudall/ruby-openai)
|
6
|
-
[![Maintainability](https://api.codeclimate.com/v1/badges/a99a88d28ad37a79dbf6/maintainability)](https://codeclimate.com/github/codeclimate/codeclimate/maintainability)
|
7
6
|
|
8
7
|
Use the [OpenAI API](https://openai.com/blog/openai-api/) with Ruby! 🤖❤️
|
9
8
|
|
10
|
-
|
9
|
+
Stream text with GPT-4, transcribe and translate audio with Whisper, or create images with DALL·E...
|
11
10
|
|
12
|
-
|
11
|
+
[Ruby AI Builders Discord](https://discord.gg/k4Uc224xVD)
|
12
|
+
|
13
|
+
[Quick guide to streaming ChatGPT with Rails 7 and Hotwire](https://gist.github.com/alexrudall/cb5ee1e109353ef358adb4e66631799d)
|
14
|
+
|
15
|
+
Follow me on [Twitter](https://twitter.com/alexrudall) for more Ruby / AI content
|
13
16
|
|
14
17
|
### Bundler
|
15
18
|
|
@@ -35,14 +38,10 @@ and require with:
|
|
35
38
|
require "openai"
|
36
39
|
```
|
37
40
|
|
38
|
-
## Upgrading
|
39
|
-
|
40
|
-
The `::Ruby::OpenAI` module has been removed and all classes have been moved under the top level `::OpenAI` module. To upgrade, change `require 'ruby/openai'` to `require 'openai'` and change all references to `Ruby::OpenAI` to `OpenAI`.
|
41
|
-
|
42
41
|
## Usage
|
43
42
|
|
44
|
-
- Get your API key from [https://
|
45
|
-
- If you belong to multiple organizations, you can get your Organization ID from [https://
|
43
|
+
- Get your API key from [https://platform.openai.com/account/api-keys](https://platform.openai.com/account/api-keys)
|
44
|
+
- If you belong to multiple organizations, you can get your Organization ID from [https://platform.openai.com/account/org-settings](https://platform.openai.com/account/org-settings)
|
46
45
|
|
47
46
|
### Quickstart
|
48
47
|
|
@@ -58,8 +57,8 @@ For a more robust setup, you can configure the gem with your API keys, for examp
|
|
58
57
|
|
59
58
|
```ruby
|
60
59
|
OpenAI.configure do |config|
|
61
|
-
config.access_token = ENV.fetch(
|
62
|
-
config.organization_id = ENV.fetch(
|
60
|
+
config.access_token = ENV.fetch("OPENAI_ACCESS_TOKEN")
|
61
|
+
config.organization_id = ENV.fetch("OPENAI_ORGANIZATION_ID") # Optional.
|
63
62
|
end
|
64
63
|
```
|
65
64
|
|
@@ -71,30 +70,30 @@ client = OpenAI::Client.new
|
|
71
70
|
|
72
71
|
#### Custom timeout or base URI
|
73
72
|
|
74
|
-
The default timeout for any
|
73
|
+
The default timeout for any request using this library is 120 seconds. You can change that by passing a number of seconds to the `request_timeout` when initializing the client. You can also change the base URI used for all requests, eg. to use observability tools like [Helicone](https://docs.helicone.ai/quickstart/integrate-in-one-line-of-code):
|
75
74
|
|
76
75
|
```ruby
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
76
|
+
client = OpenAI::Client.new(
|
77
|
+
access_token: "access_token_goes_here",
|
78
|
+
uri_base: "https://oai.hconeai.com/",
|
79
|
+
request_timeout: 240
|
80
|
+
)
|
82
81
|
```
|
83
82
|
|
84
83
|
or when configuring the gem:
|
85
84
|
|
86
85
|
```ruby
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
86
|
+
OpenAI.configure do |config|
|
87
|
+
config.access_token = ENV.fetch("OPENAI_ACCESS_TOKEN")
|
88
|
+
config.organization_id = ENV.fetch("OPENAI_ORGANIZATION_ID") # Optional
|
89
|
+
config.uri_base = "https://oai.hconeai.com/" # Optional
|
90
|
+
config.request_timeout = 240 # Optional
|
91
|
+
end
|
93
92
|
```
|
94
93
|
|
95
94
|
### Models
|
96
95
|
|
97
|
-
There are different models that can be used to generate text. For a full list and to retrieve information about a single
|
96
|
+
There are different models that can be used to generate text. For a full list and to retrieve information about a single model:
|
98
97
|
|
99
98
|
```ruby
|
100
99
|
client.models.list
|
@@ -131,6 +130,25 @@ puts response.dig("choices", 0, "message", "content")
|
|
131
130
|
# => "Hello! How may I assist you today?"
|
132
131
|
```
|
133
132
|
|
133
|
+
### Streaming ChatGPT
|
134
|
+
|
135
|
+
[Quick guide to streaming ChatGPT with Rails 7 and Hotwire](https://gist.github.com/alexrudall/cb5ee1e109353ef358adb4e66631799d)
|
136
|
+
|
137
|
+
You can stream from the API in realtime, which can be much faster and used to create a more engaging user experience. Pass a [Proc](https://ruby-doc.org/core-2.6/Proc.html) (or any object with a `#call` method) to the `stream` parameter to receive the stream of text chunks as they are generated. Each time one or more chunks is received, the proc will be called once with each chunk, parsed as a Hash. If OpenAI returns an error, `ruby-openai` will pass that to your proc as a Hash.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
client.chat(
|
141
|
+
parameters: {
|
142
|
+
model: "gpt-3.5-turbo", # Required.
|
143
|
+
messages: [{ role: "user", content: "Describe a character called Anna!"}], # Required.
|
144
|
+
temperature: 0.7,
|
145
|
+
stream: proc do |chunk, _bytesize|
|
146
|
+
print chunk.dig("choices", 0, "delta", "content")
|
147
|
+
end
|
148
|
+
})
|
149
|
+
# => "Anna is a young woman in her mid-twenties, with wavy chestnut hair that falls to her shoulders..."
|
150
|
+
```
|
151
|
+
|
134
152
|
### Completions
|
135
153
|
|
136
154
|
Hit the OpenAI API for a completion using other GPT-3 models:
|
@@ -189,9 +207,9 @@ and pass the path to `client.files.upload` to upload it to OpenAI, and then inte
|
|
189
207
|
```ruby
|
190
208
|
client.files.upload(parameters: { file: "path/to/sentiment.jsonl", purpose: "fine-tune" })
|
191
209
|
client.files.list
|
192
|
-
client.files.retrieve(id: 123)
|
193
|
-
client.files.content(id: 123)
|
194
|
-
client.files.delete(id: 123)
|
210
|
+
client.files.retrieve(id: "file-123")
|
211
|
+
client.files.content(id: "file-123")
|
212
|
+
client.files.delete(id: "file-123")
|
195
213
|
```
|
196
214
|
|
197
215
|
### Fine-tunes
|
@@ -209,9 +227,9 @@ You can then use this file ID to create a fine-tune model:
|
|
209
227
|
response = client.finetunes.create(
|
210
228
|
parameters: {
|
211
229
|
training_file: file_id,
|
212
|
-
model: "
|
230
|
+
model: "ada"
|
213
231
|
})
|
214
|
-
fine_tune_id =
|
232
|
+
fine_tune_id = response["id"]
|
215
233
|
```
|
216
234
|
|
217
235
|
That will give you the fine-tune ID. If you made a mistake you can cancel the fine-tune model before it is processed:
|
@@ -225,7 +243,7 @@ You may need to wait a short time for processing to complete. Once processed, yo
|
|
225
243
|
```ruby
|
226
244
|
client.finetunes.list
|
227
245
|
response = client.finetunes.retrieve(id: fine_tune_id)
|
228
|
-
fine_tuned_model =
|
246
|
+
fine_tuned_model = response["fine_tuned_model"]
|
229
247
|
```
|
230
248
|
|
231
249
|
This fine-tuned model name can then be used in completions:
|
@@ -237,7 +255,7 @@ response = client.completions(
|
|
237
255
|
prompt: "I love Mondays!"
|
238
256
|
}
|
239
257
|
)
|
240
|
-
|
258
|
+
response.dig("choices", 0, "text")
|
241
259
|
```
|
242
260
|
|
243
261
|
You can delete the fine-tuned model when you are done with it:
|
@@ -306,9 +324,9 @@ The translations API takes as input the audio file in any of the supported langu
|
|
306
324
|
response = client.translate(
|
307
325
|
parameters: {
|
308
326
|
model: "whisper-1",
|
309
|
-
file: File.open(
|
327
|
+
file: File.open("path_to_file", "rb"),
|
310
328
|
})
|
311
|
-
puts response
|
329
|
+
puts response["text"]
|
312
330
|
# => "Translation of the text"
|
313
331
|
```
|
314
332
|
|
@@ -320,9 +338,9 @@ The transcriptions API takes as input the audio file you want to transcribe and
|
|
320
338
|
response = client.transcribe(
|
321
339
|
parameters: {
|
322
340
|
model: "whisper-1",
|
323
|
-
file: File.open(
|
341
|
+
file: File.open("path_to_file", "rb"),
|
324
342
|
})
|
325
|
-
puts response
|
343
|
+
puts response["text"]
|
326
344
|
# => "Transcription of the text"
|
327
345
|
```
|
328
346
|
|
@@ -332,12 +350,16 @@ After checking out the repo, run `bin/setup` to install dependencies. You can ru
|
|
332
350
|
|
333
351
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
334
352
|
|
353
|
+
### Warning
|
354
|
+
|
355
|
+
If you have an `OPENAI_ACCESS_TOKEN` in your `ENV`, running the specs will use this to run the specs against the actual API, which will be slow and cost you money - 2 cents or more! Remove it from your environment with `unset` or similar if you just want to run the specs against the stored VCR responses.
|
356
|
+
|
335
357
|
## Release
|
336
358
|
|
337
|
-
First run the specs without VCR so they actually hit the API. This will cost
|
359
|
+
First run the specs without VCR so they actually hit the API. This will cost 2 cents or more. Set OPENAI_ACCESS_TOKEN in your environment or pass it in like this:
|
338
360
|
|
339
361
|
```
|
340
|
-
|
362
|
+
OPENAI_ACCESS_TOKEN=123abc bundle exec rspec
|
341
363
|
```
|
342
364
|
|
343
365
|
Then update the version number in `version.rb`, update `CHANGELOG.md`, run `bundle install` to update Gemfile.lock, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
data/lib/openai/client.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module OpenAI
|
2
2
|
class Client
|
3
|
+
extend OpenAI::HTTP
|
4
|
+
|
3
5
|
def initialize(access_token: nil, organization_id: nil, uri_base: nil, request_timeout: nil)
|
4
6
|
OpenAI.configuration.access_token = access_token if access_token
|
5
7
|
OpenAI.configuration.organization_id = organization_id if organization_id
|
@@ -50,55 +52,5 @@ module OpenAI
|
|
50
52
|
def translate(parameters: {})
|
51
53
|
OpenAI::Client.multipart_post(path: "/audio/translations", parameters: parameters)
|
52
54
|
end
|
53
|
-
|
54
|
-
def self.get(path:)
|
55
|
-
HTTParty.get(
|
56
|
-
uri(path: path),
|
57
|
-
headers: headers,
|
58
|
-
timeout: request_timeout
|
59
|
-
)
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.json_post(path:, parameters:)
|
63
|
-
HTTParty.post(
|
64
|
-
uri(path: path),
|
65
|
-
headers: headers,
|
66
|
-
body: parameters&.to_json,
|
67
|
-
timeout: request_timeout
|
68
|
-
)
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.multipart_post(path:, parameters: nil)
|
72
|
-
HTTParty.post(
|
73
|
-
uri(path: path),
|
74
|
-
headers: headers.merge({ "Content-Type" => "multipart/form-data" }),
|
75
|
-
body: parameters,
|
76
|
-
timeout: request_timeout
|
77
|
-
)
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.delete(path:)
|
81
|
-
HTTParty.delete(
|
82
|
-
uri(path: path),
|
83
|
-
headers: headers,
|
84
|
-
timeout: request_timeout
|
85
|
-
)
|
86
|
-
end
|
87
|
-
|
88
|
-
private_class_method def self.uri(path:)
|
89
|
-
OpenAI.configuration.uri_base + OpenAI.configuration.api_version + path
|
90
|
-
end
|
91
|
-
|
92
|
-
private_class_method def self.headers
|
93
|
-
{
|
94
|
-
"Content-Type" => "application/json",
|
95
|
-
"Authorization" => "Bearer #{OpenAI.configuration.access_token}",
|
96
|
-
"OpenAI-Organization" => OpenAI.configuration.organization_id
|
97
|
-
}
|
98
|
-
end
|
99
|
-
|
100
|
-
private_class_method def self.request_timeout
|
101
|
-
OpenAI.configuration.request_timeout
|
102
|
-
end
|
103
55
|
end
|
104
56
|
end
|
data/lib/openai/http.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
module OpenAI
|
2
|
+
module HTTP
|
3
|
+
def get(path:)
|
4
|
+
to_json(conn.get(uri(path: path)) do |req|
|
5
|
+
req.headers = headers
|
6
|
+
end&.body)
|
7
|
+
end
|
8
|
+
|
9
|
+
def json_post(path:, parameters:)
|
10
|
+
to_json(conn.post(uri(path: path)) do |req|
|
11
|
+
if parameters[:stream].respond_to?(:call)
|
12
|
+
req.options.on_data = to_json_stream(user_proc: parameters[:stream])
|
13
|
+
parameters[:stream] = true # Necessary to tell OpenAI to stream.
|
14
|
+
elsif parameters[:stream]
|
15
|
+
raise ArgumentError, "The stream parameter must be a Proc or have a #call method"
|
16
|
+
end
|
17
|
+
|
18
|
+
req.headers = headers
|
19
|
+
req.body = parameters.to_json
|
20
|
+
end&.body)
|
21
|
+
end
|
22
|
+
|
23
|
+
def multipart_post(path:, parameters: nil)
|
24
|
+
to_json(conn(multipart: true).post(uri(path: path)) do |req|
|
25
|
+
req.headers = headers.merge({ "Content-Type" => "multipart/form-data" })
|
26
|
+
req.body = multipart_parameters(parameters)
|
27
|
+
end&.body)
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete(path:)
|
31
|
+
to_json(conn.delete(uri(path: path)) do |req|
|
32
|
+
req.headers = headers
|
33
|
+
end&.body)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def to_json(string)
|
39
|
+
return unless string
|
40
|
+
|
41
|
+
JSON.parse(string)
|
42
|
+
rescue JSON::ParserError
|
43
|
+
# Convert a multiline string of JSON objects to a JSON array.
|
44
|
+
JSON.parse(string.gsub("}\n{", "},{").prepend("[").concat("]"))
|
45
|
+
end
|
46
|
+
|
47
|
+
# Given a proc, returns an outer proc that can be used to iterate over a JSON stream of chunks.
|
48
|
+
# For each chunk, the inner user_proc is called giving it the JSON object. The JSON object could
|
49
|
+
# be a data object or an error object as described in the OpenAI API documentation.
|
50
|
+
#
|
51
|
+
# If the JSON object for a given data or error message is invalid, it is ignored.
|
52
|
+
#
|
53
|
+
# @param user_proc [Proc] The inner proc to call for each JSON object in the chunk.
|
54
|
+
# @return [Proc] An outer proc that iterates over a raw stream, converting it to JSON.
|
55
|
+
def to_json_stream(user_proc:)
|
56
|
+
proc do |chunk, _|
|
57
|
+
chunk.scan(/(?:data|error): (\{.*\})/i).flatten.each do |data|
|
58
|
+
user_proc.call(JSON.parse(data))
|
59
|
+
rescue JSON::ParserError
|
60
|
+
# Ignore invalid JSON.
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def conn(multipart: false)
|
66
|
+
Faraday.new do |f|
|
67
|
+
f.options[:timeout] = OpenAI.configuration.request_timeout
|
68
|
+
f.request(:multipart) if multipart
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def uri(path:)
|
73
|
+
OpenAI.configuration.uri_base + OpenAI.configuration.api_version + path
|
74
|
+
end
|
75
|
+
|
76
|
+
def headers
|
77
|
+
{
|
78
|
+
"Content-Type" => "application/json",
|
79
|
+
"Authorization" => "Bearer #{OpenAI.configuration.access_token}",
|
80
|
+
"OpenAI-Organization" => OpenAI.configuration.organization_id
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
def multipart_parameters(parameters)
|
85
|
+
parameters&.transform_values do |value|
|
86
|
+
next value unless value.is_a?(File)
|
87
|
+
|
88
|
+
# Doesn't seem like OpenAI need mime_type yet, so not worth
|
89
|
+
# the library to figure this out. Hence the empty string
|
90
|
+
# as the second argument.
|
91
|
+
Faraday::UploadIO.new(value, "", value.path)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/openai/version.rb
CHANGED
data/lib/openai.rb
CHANGED
data/ruby-openai.gemspec
CHANGED
@@ -25,7 +25,6 @@ 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 "
|
29
|
-
|
30
|
-
spec.post_install_message = "Note if upgrading: The `::Ruby::OpenAI` module has been removed and all classes have been moved under the top level `::OpenAI` module. To upgrade, change `require 'ruby/openai'` to `require 'openai'` and change all references to `Ruby::OpenAI` to `OpenAI`."
|
28
|
+
spec.add_dependency "faraday", ">= 1"
|
29
|
+
spec.add_dependency "faraday-multipart", ">= 1"
|
31
30
|
end
|
metadata
CHANGED
@@ -1,30 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-openai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: faraday
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
-
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday-multipart
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1'
|
41
|
+
description:
|
28
42
|
email:
|
29
43
|
- alexrudall@users.noreply.github.com
|
30
44
|
executables: []
|
@@ -53,6 +67,7 @@ files:
|
|
53
67
|
- lib/openai/compatibility.rb
|
54
68
|
- lib/openai/files.rb
|
55
69
|
- lib/openai/finetunes.rb
|
70
|
+
- lib/openai/http.rb
|
56
71
|
- lib/openai/images.rb
|
57
72
|
- lib/openai/models.rb
|
58
73
|
- lib/openai/version.rb
|
@@ -67,10 +82,7 @@ metadata:
|
|
67
82
|
source_code_uri: https://github.com/alexrudall/ruby-openai
|
68
83
|
changelog_uri: https://github.com/alexrudall/ruby-openai/blob/main/CHANGELOG.md
|
69
84
|
rubygems_mfa_required: 'true'
|
70
|
-
post_install_message:
|
71
|
-
and all classes have been moved under the top level `::OpenAI` module. To upgrade,
|
72
|
-
change `require ''ruby/openai''` to `require ''openai''` and change all references
|
73
|
-
to `Ruby::OpenAI` to `OpenAI`.'
|
85
|
+
post_install_message:
|
74
86
|
rdoc_options: []
|
75
87
|
require_paths:
|
76
88
|
- lib
|
@@ -85,8 +97,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
97
|
- !ruby/object:Gem::Version
|
86
98
|
version: '0'
|
87
99
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
89
|
-
signing_key:
|
100
|
+
rubygems_version: 3.4.12
|
101
|
+
signing_key:
|
90
102
|
specification_version: 4
|
91
103
|
summary: "OpenAI API + Ruby! \U0001F916❤️"
|
92
104
|
test_files: []
|