Skip to content

Commit

Permalink
Add files api
Browse files Browse the repository at this point in the history
  • Loading branch information
joyqi committed Mar 8, 2023
1 parent 7216a21 commit b775fb2
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 23 deletions.
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ An elegant Node.js library written in TypeScript for the OpenAI API.
- [Chat](#chat)
- [Edits](#edits)
- [Images](#images)
- [Embeddings](#embeddings)
- [Audio](#audio)
- [Files](#files)

## Installation

Expand Down Expand Up @@ -141,4 +144,67 @@ const imageVariation = await v1.images.variation({
n: 1,
size: '512x512',
}, '/path/to/image.png');
```

### Embeddings

Create an embedding:

```javascript
const embedding = await v1.embeddings.create({
model: 'text-embedding-ada-002',
input: 'This is a test',
});
```

### Audio

Create transcription:

```javascript
const transcription = await v1.audio.createTranscription({
model: 'whisper-1',
prompt: 'This is a test',
}, '/path/to/audio.mp3');
```

Create translation:

```javascript
const translation = await v1.audio.createTranslation({
model: 'whisper-1',
prompt: 'This is a test',
}, '/path/to/audio.mp3');
```

### Files

List all available files:

```javascript
const files = await v1.files.list();
```

Retrieve a file:

```javascript
const file = await v1.files.retrieve('file-123');
```

Upload a file:

```javascript
const file = await v1.files.upload('/path/to/file.txt', 'fine-tune');
```

Delete a file:

```javascript
const file = await v1.files.delete('file-123');
```

Retrieve a file's contents:

```javascript
const content = await v1.files.retrieveContents('file-123');
```
15 changes: 11 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type ApiConfig = {
// ApiVersion defines the version of the OpenAI API
export type ApiVersion = "v1" | "v2";

export type ApiClient = (path: string, options: AxiosRequestConfig) => Promise<any>;
export type ApiClient = (path: string, options: AxiosRequestConfig, direct?: boolean) => Promise<any>;

// OpenAI is the main class for the OpenAI API
export class OpenAI {
Expand Down Expand Up @@ -58,20 +58,27 @@ export class OpenAI {
audio: {
createTranscription: v1.createAudioTranscription(client),
createTranslation: v1.createAudioTranslation(client)
},
files: {
list: v1.listFiles(client),
retrieve: v1.retrieveFile(client),
upload: v1.uploadFile(client),
delete: v1.deleteFile(client),
retrieveContent: v1.retrieveFileContent(client)
}
};
}

// Generate a client for the given version of the OpenAI API
private makeClient(version: ApiVersion): ApiClient {
return async (path: string, options: AxiosRequestConfig) => {
return async (path: string, options: AxiosRequestConfig, direct = false) => {
const url = `${this.config.endpoint}/${version}/${path}`;
const response = await axios(Object.assign({ url }, this.config.options, options));

if (response.headers["content-type"] !== "application/json") {
if (!direct && response.headers["content-type"] !== "application/json") {
throw new Error(`Unexpected Content-Type: ${response.headers["content-type"]}`);
} else if (response.status !== 200) {
throw new Error(response.data.error.message);
throw new Error(direct ? response.statusText : response.data.error.message);
} else {
return response.data;
}
Expand Down
16 changes: 8 additions & 8 deletions src/v1/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,28 @@ type Audio = Partial<{

export function createAudioTranscription(client: ApiClient) {
return async (request: CreateAudioTranscriptionRequest, file: string): Promise<Audio> => {
const form = new FormData();
const data = new FormData();

for (const key in request) {
form.append(key, '' + request[key as keyof CreateAudioTranscriptionRequest]);
data.append(key, '' + request[key as keyof CreateAudioTranscriptionRequest]);
}

form.append('file', createReadStream(file));
data.append('file', createReadStream(file));

return await client("audio/transcriptions", { method: "POST", data: form });
return await client("audio/transcriptions", { method: "POST", data });
}
}

export function createAudioTranslation(client: ApiClient) {
return async (request: CreateAudioTranslationRequest, file: string): Promise<Audio> => {
const form = new FormData();
const data = new FormData();

for (const key in request) {
form.append(key, '' + request[key as keyof CreateAudioTranslationRequest]);
data.append(key, '' + request[key as keyof CreateAudioTranslationRequest]);
}

form.append('file', createReadStream(file));
data.append('file', createReadStream(file));

return await client("audio/translations", { method: "POST", data: form });
return await client("audio/translations", { method: "POST", data });
}
}
57 changes: 56 additions & 1 deletion src/v1/files.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,58 @@
import { createReadStream } from "fs";
import { ApiClient } from "..";
import FormData from "form-data";
import FormData from "form-data";

type File = {
id: string;
object: string;
bytes: number;
created_at: number;
filename: string;
purpose: string;
};

type DeletedFile = {
id: string;
object: string;
deleted: boolean;
};

type FileList = {
data: File[];
object: string;
};

export function listFiles(client: ApiClient) {
return async (): Promise<FileList> => {
return await client("files", { method: "GET" });
}
}

export function uploadFile(client: ApiClient) {
return async (file: string, purpose: string): Promise<File> => {
const data = new FormData();

data.append('purpose', purpose);
data.append('file', createReadStream(file));

return await client("files", { method: "POST", data });
}
}

export function deleteFile(client: ApiClient) {
return async (id: string): Promise<DeletedFile> => {
return await client(`files/${id}`, { method: "DELETE" });
}
}

export function retrieveFile(client: ApiClient) {
return async (id: string): Promise<File> => {
return await client(`files/${id}`, { method: "GET" });
}
}

export function retrieveFileContent(client: ApiClient) {
return async (id: string): Promise<Buffer> => {
return await client(`files/${id}/content`, { method: "GET" }, true);
}
}
18 changes: 9 additions & 9 deletions src/v1/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,32 +46,32 @@ export function createImage(client: ApiClient) {

export function editImage(client: ApiClient) {
return async (request: EditImageRequest, image: string, mask?: string): Promise<Image> => {
const form = new FormData();
const data = new FormData();

for (const key in request) {
form.append(key, '' + request[key as keyof EditImageRequest]);
data.append(key, '' + request[key as keyof EditImageRequest]);
}

form.append('image', createReadStream(image));
data.append('image', createReadStream(image));

if (mask) {
form.append('mask', createReadStream(mask));
data.append('mask', createReadStream(mask));
}

return await client("images/edits", { method: "POST", data: form });
return await client("images/edits", { method: "POST", data });
}
}

export function createImageVariation(client: ApiClient) {
return async (request: CreateImageVariationRequest, image: string): Promise<Image> => {
const form = new FormData();
const data = new FormData();

for (const key in request) {
form.append(key, '' + request[key as keyof CreateImageVariationRequest]);
data.append(key, '' + request[key as keyof CreateImageVariationRequest]);
}

form.append('image', createReadStream(image));
data.append('image', createReadStream(image));

return await client("images/variations", { method: "POST", data: form });
return await client("images/variations", { method: "POST", data });
}
}
3 changes: 2 additions & 1 deletion src/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export * from "./chat";
export * from "./edits";
export * from "./images";
export * from "./embeddings";
export * from "./audio";
export * from "./audio";
export * from "./files";
6 changes: 6 additions & 0 deletions src/v1/moderations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ApiClient } from "..";

type ModerationRequest = {
input: string;
model?: string;
};

0 comments on commit b775fb2

Please sign in to comment.