Skip to content

Azure File Upload empty content type #521

Open
@wynk182

Description

@wynk182

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions