openai_ruby 0.5.2 → 0.5.4

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: 91361df72462f49209491acf92303a7fb6f47ab9a947303da373b8345b7736c4
4
- data.tar.gz: 5bb2b48ff21f949605e2fe9072dfd9d324c0ce4803462fc6c3c83a19b8fd2d1a
3
+ metadata.gz: 594ce65bf8ef1e8ef1202b306b400a231bfd0977ca26677bbc2e4420fb8c8d72
4
+ data.tar.gz: 852da6bdffa4213f39eb830929377718b043d411a837cca4dc0fab134620ed0e
5
5
  SHA512:
6
- metadata.gz: cb209a9bafe457eebd91e7467e96e3b87433d6e8807a0b0be2e9427fa4b1b4e7cd782ea8aaea21c6283009188aecf7721b025dd62414cc940bb8d03fe6de8888
7
- data.tar.gz: '03186808fd04b88f991d53eed795f0fe56ca801d67bb4db7e7eae3f615cafe5473c6c7121d9b4d0d975acf450bd7e3bed587ffff6846dcd72e3a47aa82ea523f'
6
+ metadata.gz: 9496bd88696075720d6f1a79d7a15723f8eaa9663b8a629e74190248d6d4180ff8f51ff631bc66280acc74196ebaf305b087d49626a29c281a1e0449ec3515a9
7
+ data.tar.gz: 7aca0a20dd3bc82051aa2c101f2f4d407a108e55ad823aa893fe444b8ea140df579226c23b63b26b2a11b5ec795be76bc0cc8ba4a6b17854144be15f94db296a
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openai_ruby (0.5.2)
4
+ openai_ruby (0.5.4)
5
5
  event_stream_parser (~> 1.0)
6
6
  faraday (~> 2.7)
7
+ faraday-multipart (~> 1.1)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -14,8 +15,11 @@ GEM
14
15
  faraday (2.7.4)
15
16
  faraday-net_http (>= 2.0, < 3.1)
16
17
  ruby2_keywords (>= 0.0.4)
18
+ faraday-multipart (1.2.0)
19
+ multipart-post (~> 2.0)
17
20
  faraday-net_http (3.0.2)
18
21
  json (2.6.3)
22
+ multipart-post (2.4.1)
19
23
  parallel (1.22.1)
20
24
  parser (3.2.1.0)
21
25
  ast (~> 2.4.1)
data/README.md CHANGED
@@ -92,8 +92,57 @@ p response.dig("choices", 0, "text") # "What is the date today?\n"
92
92
 
93
93
  ### Image
94
94
 
95
+ https://platform.openai.com/docs/api-reference/images
96
+
97
+ Generate an image:
98
+
95
99
  ```ruby
100
+ require "base64"
101
+
102
+ res = client.images.generate(
103
+ model: "gpt-image-2",
104
+ prompt: "A watercolor painting of a ruby gem on a desk",
105
+ size: "1024x1024"
106
+ )
107
+
108
+ response = JSON.parse(res.body)
109
+ image_data = response.dig("data", 0, "b64_json")
110
+
111
+ File.binwrite("ruby-gem.png", Base64.decode64(image_data)) if image_data
112
+ ```
96
113
 
114
+ Edit one or more images:
115
+
116
+ ```ruby
117
+ require "base64"
118
+
119
+ File.open("ruby-gem.png", "rb") do |image|
120
+ res = client.images.edit(
121
+ model: "gpt-image-2",
122
+ image: image,
123
+ prompt: "Add a small OpenAI logo sticker to the desk",
124
+ size: "1024x1024"
125
+ )
126
+
127
+ response = JSON.parse(res.body)
128
+ image_data = response.dig("data", 0, "b64_json")
129
+
130
+ File.binwrite("ruby-gem-edited.png", Base64.decode64(image_data)) if image_data
131
+ end
132
+ ```
133
+
134
+ You can also pass multiple images when editing:
135
+
136
+ ```ruby
137
+ File.open("image-1.png", "rb") do |image_1|
138
+ File.open("image-2.png", "rb") do |image_2|
139
+ client.images.edit(
140
+ model: "gpt-image-2",
141
+ image: [image_1, image_2],
142
+ prompt: "Combine these images into one cohesive scene"
143
+ )
144
+ end
145
+ end
97
146
  ```
98
147
 
99
148
  ## Development
@@ -61,17 +61,15 @@ module OpenAI
61
61
  end
62
62
 
63
63
  def create_realtime_call(sdp_offer:, session: nil)
64
- uri = "#{base_uri}/v1/realtime/calls"
65
-
66
64
  if session
67
65
  boundary, body = build_multipart_body(sdp_offer, session)
68
- Faraday.post(uri) do |req|
66
+ connection.post("/v1/realtime/calls") do |req|
69
67
  req.headers["Authorization"] = "Bearer #{api_key}"
70
68
  req.headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
71
69
  req.body = body
72
70
  end
73
71
  else
74
- Faraday.post(uri) do |req|
72
+ connection.post("/v1/realtime/calls") do |req|
75
73
  req.headers["Content-Type"] = "application/sdp"
76
74
  req.headers["Authorization"] = "Bearer #{api_key}"
77
75
  req.body = sdp_offer
@@ -82,7 +80,9 @@ module OpenAI
82
80
  private
83
81
 
84
82
  def connection
85
- Faraday.new({ url: base_uri, headers: headers }.merge(options.except(:base_uri)))
83
+ Faraday.new({ url: base_uri, headers: headers }.merge(options.except(:base_uri))) do |faraday|
84
+ faraday.request :multipart
85
+ end
86
86
  end
87
87
 
88
88
  def headers
@@ -9,5 +9,50 @@ module OpenAI
9
9
  def generate(params = {})
10
10
  connection.post("/v1/images/generations", params.to_json)
11
11
  end
12
+
13
+ def edit(params = {})
14
+ connection.post("/v1/images/edits") do |req|
15
+ req.headers.delete("Content-Type")
16
+ req.body = multipart_params(params)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def multipart_params(params)
23
+ params.each_with_object({}) do |(key, value), body|
24
+ if key.to_s == "image"
25
+ body[:image] = Array(value).map { |image| file_part(image) }
26
+ elsif file_like?(value)
27
+ body[key] = file_part(value)
28
+ elsif value.is_a?(Array)
29
+ body[key] = value
30
+ elsif !value.nil?
31
+ body[key] = value
32
+ end
33
+ end
34
+ end
35
+
36
+ def file_part(file)
37
+ return file if file.is_a?(Faraday::Multipart::FilePart)
38
+
39
+ if file.respond_to?(:path) && file.path
40
+ Faraday::Multipart::FilePart.new(file.path, content_type_for(file))
41
+ else
42
+ Faraday::Multipart::FilePart.new(file, content_type_for(file), filename_for(file))
43
+ end
44
+ end
45
+
46
+ def file_like?(value)
47
+ value.respond_to?(:read) || value.is_a?(Faraday::Multipart::FilePart)
48
+ end
49
+
50
+ def content_type_for(file)
51
+ file.respond_to?(:content_type) && file.content_type ? file.content_type : "application/octet-stream"
52
+ end
53
+
54
+ def filename_for(file)
55
+ file.respond_to?(:original_filename) && file.original_filename ? file.original_filename : "image.png"
56
+ end
12
57
  end
13
58
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenAI
4
- VERSION = "0.5.2"
4
+ VERSION = "0.5.4"
5
5
  end
data/lib/openai_ruby.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "faraday"
4
+ require "faraday/multipart"
4
5
  require "event_stream_parser"
5
6
  require "openai_ruby/client"
6
7
  require "openai_ruby/images"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openai_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renny Ren
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2026-04-27 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: event_stream_parser
@@ -38,7 +37,20 @@ dependencies:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
39
  version: '2.7'
41
- description:
40
+ - !ruby/object:Gem::Dependency
41
+ name: faraday-multipart
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.1'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.1'
42
54
  email:
43
55
  - rennyrjh@gmail.com
44
56
  executables: []
@@ -66,7 +78,6 @@ metadata:
66
78
  homepage_uri: https://github.com/renny-ren/openai_ruby
67
79
  source_code_uri: https://github.com/renny-ren/openai_ruby
68
80
  changelog_uri: https://github.com/renny-ren/openai_ruby/blob/main/CHANGELOG.md
69
- post_install_message:
70
81
  rdoc_options: []
71
82
  require_paths:
72
83
  - lib
@@ -81,8 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
92
  - !ruby/object:Gem::Version
82
93
  version: '0'
83
94
  requirements: []
84
- rubygems_version: 3.4.19
85
- signing_key:
95
+ rubygems_version: 4.0.11
86
96
  specification_version: 4
87
97
  summary: A Ruby wrapper for OpenAI API
88
98
  test_files: []