3

I am building an Angular App around OPENAI APIs and I have trouble with their Upload function.

The Endpoint is called "files" and the documentation can be found here

It works well when I perform the request from my computer using postman passing a local file.

However in my angular app, the file is located and accessible on the web server and I am trying to post that file to the endpoint and I keep getting an error from the web server : 400 OK "file is a required parameter".

I have tried calling the API by passing the file's URL as the 'file' parameter but that obviously failed.

Now I retrieve the content of the file through an http GET, and have the content as a String in my app.

I have then implemented the following method on my service to send the String as a Blob using formdata :

UploadFile(token: string, file: string): Observable<TrainingFiles> {
    let fileblob = new Blob([file], {
      type: 'text/plain; charset=utf8',
    });

    let body = new FormData();

    body.append('purpose', 'fine-tune');
    body.append('file', fileblob, 'myTrainingFile.jsonl');

    let httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'multipart/form-data',
        Authorization: 'Bearer ' + token,
      }),
    };

    return this.http.post<TrainingFiles>(
      'https://api.openai.com/v1/files',
      body,
      httpOptions
    );
  }

he request payload now looks exactly the same than the one send from postman, however I keep getting the same error from the web server :

{ "error": { "message": "'file' is a required property", "type": "invalid_request_error", "param": null, "code": null } }

this is the payload of the SUCCESSFUL request sent by Postman :

POST /v1/files HTTP/1.1
Host: api.openai.com
Authorization: Bearer <my token>
Content-Length: 297
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="purpose"

fine-tune
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="training_data.jsonl"
Content-Type: <Content-Type header here>

(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW

and here is the FAILED payload sent by my browser when using the app :

------WebKitFormBoundaryJAv06rE853d4kdXC
Content-Disposition: form-data; name="purpose"

fine-tune
------WebKitFormBoundaryJAv06rE853d4kdXC
Content-Disposition: form-data; name="file"; filename="myTrainingFile.jsonl"
Content-Type: text/plain; charset=utf8

<here is the string as a JSONLINE formatted as a series of "{property: value}\n" >

------WebKitFormBoundaryJAv06rE853d4kdXC--

I guess the idea would be to send binary stream rather than the content of the string but I supposed that was what sending a Blob instead of the String was for...

I have tried several other "content type" headers such as "application/jsonline" whithout success.

Thank you all for your attention.

2

1 Answer 1

3

Removing the 'content type' header solved the issue...

Here is a working implementation :

UploadFile(token: string, file: string): Observable<TrainingFiles> {
    let fileblob = new Blob([file], {
      type: 'text/plain; charset=utf8',
    });

    let body = new FormData();

    body.append('purpose', 'fine-tune');
    body.append('file', fileblob, 'myTrainingFile.jsonl');

    let httpOptions = {
      headers: new HttpHeaders({
        Authorization: 'Bearer ' + token,
      }),
    };

    return this.http.post<TrainingFiles>(
      'https://api.openai.com/v1/files',
      body,
      httpOptions
    );
  }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.