[SOLVED] File upload REST API help?

Hi there,

I have built a simple web app (using Angular) to create illustrated stories for my kids using a simple form that creates prompts and retrieves text from Davinci and an image from Dall-E using the API.

I am keeping the best, edited versions of the Completions as a JSONL file somewhere online on my server.

I am now trying to build an admin page of this web app to upload, manage, delete training files and start fine tuning jobs, however I am unable to make the ā€˜file upload’ (POST method on the ā€œfileā€ endpoint) to work.

I am passing the JSONL file URL on my server as the ā€œfileā€ parameter of the request but I keep getting ā€œ400 OKā€ error response code with the following message : ā€œā€˜file’ is a required propertyā€

here is the request payload

{"file":"https://japansio.info/api/training_data.jsonl","purpose":"fine-tune"}

I have tried with an ā€œ@ā€ as in the documentation example but I’m guessing I’m missing something bigger like the fact that I should probably pass the ā€œcontentā€ of the file to the endpoint rather than it’s location ? But I have no idea how.

Any help would be appreciated :slight_smile:

The file has to be uploaded using the file end point

It will give you an ID that you use instead of the filename

Then you trigger the processing of the file you have uploaded using the ID

thank you for your reply but my problem is that I can’t make the upload work…
I am passing the file’s URL on my server as the ā€˜file’, parameter but it’s not taken into account :frowning:

right now I’m trying to get it as a string and stream it using form data but I’m running circles here

I understand now

you need to send the file as a byte stream. Tell me the programming language you are using and I will see if I have some sample code that will help

Here is a Python example

openai.File.create(
file=open(ā€œmydata.jsonlā€, ā€œrbā€),
purpose=ā€˜fine-tune’
)

Then you might back

file-XGinujblHPwGLSztz8cPS8XY

as the id

Then you call

openai.FineTune.create(
training_file = ā€œfile-XGinujblHPwGLSztz8cPS8XYā€,
model = ā€œadaā€,
suffix = ā€œchatbotā€,
)

and you get back

ada:ft-your-org:chatbot-2022-12-18-07-47-04

(or similar)

I’m using javascript/typescript (angular app).

This is some ā€œTypescriptā€ code for Dall-E. It uses files as well

const response = await openai.createImageEdit(
fs.createReadStream(ā€œsunlit_lounge.pngā€) as any,
fs.createReadStream(ā€œmask.pngā€) as any,
ā€œA sunlit indoor lounge area with a pool containing a flamingoā€,
1,
ā€œ1024x1024ā€
);

The key thing is that they are using a file system ReadStream (but it is an image). I suspect that if you are not using an openai library to help you, you will have to read the file at your end and feed its content instead of the filename.

Thank you for your help but i’m still struggling.

The content of file I wish to upload is entirely contained in a string object that I try to send as a Blob using the following code

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

    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
    );
  }

Which changes the request Payload to this :

…
Content-Disposition: form-data; name=ā€œpurposeā€

fine-tune
------WebKitFormBoundary4nWKI7Szoubzeqlg
Content-Disposition: form-data; name=ā€œfileā€; filename=ā€œmyTrainingFile.jsonlā€
Content-Type: application/jsonl

{ā€œpromptā€:"raconte moi une histoire pour enfant dont les hĆ©ros sont fifi la girafe et rhino le rhinocĆ©ros et qui vont Ć  la montagne pour faire du parapente avec le
…

I think I’m kind of close but no idea why the error is still ā€œā€˜file’ is a requirede propertyā€

I have posted the question in Stack Overflow as it doesn’t seem an OpenAI specific question (the Upload endpoint works fine from postman) but more a ā€œclient side implementationā€ of the endpoint.

If interested about the topic you can follow the question here at stackoverflow

Thank you.

Update : the issue was solved :partying_face: :partying_face: :partying_face: by removing the ā€˜Content-Type’: ā€˜multipart/form-data’ line in the above code. :rage:

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
    );
  }
3 Likes

Nice! Thanks for coming back to share with us.

The exact same problem I had, not adding anything solved it.