module OpenAI::HTTP
def azure_headers
def azure_headers { "Content-Type" => "application/json", "api-key" => OpenAI.configuration.access_token } end
def conn(multipart: false)
def conn(multipart: false) Faraday.new do |f| f.options[:timeout] = OpenAI.configuration.request_timeout f.request(:multipart) if multipart end end
def delete(path:)
def delete(path:) to_json(conn.delete(uri(path: path)) do |req| req.headers = headers end&.body) end
def get(path:)
def get(path:) to_json(conn.get(uri(path: path)) do |req| req.headers = headers end&.body) end
def headers
def headers return azure_headers if OpenAI.configuration.api_type == :azure { "Content-Type" => "application/json", "Authorization" => "Bearer #{OpenAI.configuration.access_token}", "OpenAI-Organization" => OpenAI.configuration.organization_id }.merge(OpenAI.configuration.extra_headers) end
def json_post(path:, parameters:)
def json_post(path:, parameters:) to_json(conn.post(uri(path: path)) do |req| if parameters[:stream].respond_to?(:call) req.options.on_data = to_json_stream(user_proc: parameters[:stream]) parameters[:stream] = true # Necessary to tell OpenAI to stream. elsif parameters[:stream] raise ArgumentError, "The stream parameter must be a Proc or have a #call method" end req.headers = headers req.body = parameters.to_json end&.body) end
def multipart_parameters(parameters)
def multipart_parameters(parameters) parameters&.transform_values do |value| next value unless value.respond_to?(:close) # File or IO object. # Doesn't seem like OpenAI needs mime_type yet, so not worth # the library to figure this out. Hence the empty string # as the second argument. Faraday::UploadIO.new(value, "", value.path) end end
def multipart_post(path:, parameters: nil)
def multipart_post(path:, parameters: nil) to_json(conn(multipart: true).post(uri(path: path)) do |req| req.headers = headers.merge({ "Content-Type" => "multipart/form-data" }) req.body = multipart_parameters(parameters) end&.body) end
def to_json(string)
def to_json(string) return unless string JSON.parse(string) rescue JSON::ParserError # Convert a multiline string of JSON objects to a JSON array. JSON.parse(string.gsub("}\n{", "},{").prepend("[").concat("]")) end
def to_json_stream(user_proc:)
-
(Proc)
- An outer proc that iterates over a raw stream, converting it to JSON.
Parameters:
-
user_proc
(Proc
) -- The inner proc to call for each JSON object in the chunk.
def to_json_stream(user_proc:) proc do |chunk, _| chunk.scan(/(?:data|error): (\{.*\})/i).flatten.each do |data| user_proc.call(JSON.parse(data)) rescue JSON::ParserError # Ignore invalid JSON. end end end
def uri(path:)
def uri(path:) if OpenAI.configuration.api_type == :azure base = File.join(OpenAI.configuration.uri_base, path) "#{base}?api-version=#{OpenAI.configuration.api_version}" else File.join(OpenAI.configuration.uri_base, OpenAI.configuration.api_version, path) end end