Open
Description
Describe the bug
When attempting to upload a file to Azure OpenAi API, the content type of the file is required.
OpenAI HTTP Error (spotted in ruby-openai 7.1.0): {"error"=>{"code"=>"invalidPayload", "message"=>"The file has no or an empty content type specified."}}
Looks like this might be a TODO item, based on this comment in OpenAI::HTTP
# 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.
In the Azure docs the content type of the file is passed as application/json
curl -X POST https://YOUR_RESOURCE_NAME.openai.azure.com/openai/files?api-version=2024-07-01-preview \
-H "Content-Type: multipart/form-data" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-F "purpose=batch" \
-F "file=@C:\\batch\\test.jsonl;type=application/json"
To Reproduce
client = OpenAI::Client.new(
uri_base: ENV['AZURE_OPENAI_URI_BASE'],
access_token: ENV['AZURE_OPENAI_API_KEY'], # azure api key
api_type: :azure,
api_version: '2024-07-01-preview',
log_errors: true,
)
file = Faraday::UploadIO.new(File.open('test_file.jsonl'), 'application/json')
res = client.files.upload(parameters: {file: file, purpose: 'batch' })
# results in this error
# OpenAI HTTP Error (spotted in ruby-openai 7.1.0): {"error"=>{"code"=>"invalidPayload", "message"=>"The file has no or an empty content type specified."}}
# Faraday::BadRequestError: the server responded with status 400
Expected behavior
The file should upload to Azure
Currently I'm patching the gem like this, but maybe Faraday::UploadIO
class could be passed as an option.
module OpenAI
module HTTP
private
# Override the multipart_parameters method to set the correct content type for .jsonl files
def multipart_parameters(parameters)
parameters&.transform_values do |value|
next value unless value.respond_to?(:close) # File or IO object.
path = value.respond_to?(:path) ? value.path : nil
# Set the correct MIME type for .jsonl files
mime_type = 'application/json' if path&.end_with?('.jsonl')
Faraday::UploadIO.new(value, mime_type || '', path)
end
end
end
end