Skip to content

Commit 850dad2

Browse files
authored
feat(OpenAI): Add Container File API (#648)
* feat: add container files api * chore: fix urls * chore: improve typing on enums * chore: add missing ClientFake for containers * fix: support file (object) or file_id (uploaded prior) * test: add test for file_id / file * chore: prefer named args * chore: correct test mocks for create * chore: cleanup tests from invalid params * feat: add fixtures * docs: stub out new docs for container & container files * docs: add container and container files
1 parent 0e1ec5a commit 850dad2

25 files changed

+1211
-39
lines changed

README.md

Lines changed: 174 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ If you or your business relies on this package, it's important to support the de
2929
- [Usage](#usage)
3030
- [Models Resource](#models-resource)
3131
- [Responses Resource](#responses-resource)
32+
- [Containers Resource](#containers-resource)
33+
- [Containers Files Resource](#container-files-resource)
3234
- [Chat Resource](#chat-resource)
3335
- [Audio Resource](#audio-resource)
3436
- [Embeddings Resource](#embeddings-resource)
@@ -76,14 +78,12 @@ Then, interact with OpenAI's API:
7678
$yourApiKey = getenv('YOUR_API_KEY');
7779
$client = OpenAI::client($yourApiKey);
7880

79-
$result = $client->chat()->create([
81+
$response = $client->responses()->create([
8082
'model' => 'gpt-4o',
81-
'messages' => [
82-
['role' => 'user', 'content' => 'Hello!'],
83-
],
83+
'input' => 'Hello!',
8484
]);
8585

86-
echo $result->choices[0]->message->content; // Hello! How can I assist you today?
86+
echo $response->outputText; // Hello! How can I assist you today?
8787
```
8888

8989
If necessary, it is possible to configure and create a separate client.
@@ -187,6 +187,7 @@ $response->object; // 'response'
187187
$response->createdAt; // 1741476542
188188
$response->status; // 'completed'
189189
$response->model; // 'gpt-4o-mini'
190+
$response->outputText; // 'The combined response text of any `output_text` content.'
190191

191192
foreach ($response->output as $output) {
192193
$output->type; // 'message'
@@ -308,58 +309,192 @@ $response->hasMore; // false
308309
$response->toArray(); // ['object' => 'list', 'data' => [...], ...]
309310
```
310311

311-
### `Completions` Resource
312+
### `Containers` Resource
312313

313314
#### `create`
314315

315-
Creates a completion for the provided prompt and parameters.
316+
Creates a container for use with the Code Interpreter tool.
316317

317318
```php
318-
$response = $client->completions()->create([
319-
'model' => 'gpt-3.5-turbo-instruct',
320-
'prompt' => 'Say this is a test',
321-
'max_tokens' => 6,
322-
'temperature' => 0
319+
$response = $client->containers()->create([
320+
'name' => 'My Container',
321+
'expires_after' => [
322+
'anchor' => 'last_active_at',
323+
'minutes' => 60,
324+
],
323325
]);
324326

325-
$response->id; // 'cmpl-uqkvlQyYK7bGYrRHQ0eXlWi7'
326-
$response->object; // 'text_completion'
327-
$response->created; // 1589478378
328-
$response->model; // 'gpt-3.5-turbo-instruct'
327+
$response->id; // 'container_abc123'
328+
$response->object; // 'container'
329+
$response->createdAt; // 1690000000
330+
$response->status; // 'active'
331+
$response->expiresAfter->anchor; // 'last_active_at'
332+
$response->expiresAfter->minutes; // 60
333+
$response->lastActiveAt; // 1690001000
334+
$response->name; // 'My Container'
329335

330-
foreach ($response->choices as $choice) {
331-
$choice->text; // '\n\nThis is a test'
332-
$choice->index; // 0
333-
$choice->logprobs; // null
334-
$choice->finishReason; // 'length' or null
336+
$response->toArray(); // ['id' => 'container_abc123', 'object' => 'container', ...]
337+
```
338+
339+
#### `list`
340+
341+
Returns a list of containers.
342+
343+
```php
344+
$response = $client->containers()->list([
345+
'limit' => 10,
346+
'order' => 'desc',
347+
]);
348+
349+
$response->object; // 'list'
350+
351+
foreach ($response->data as $container) {
352+
$container->id; // 'container_abc123'
353+
$container->object; // 'container'
354+
$container->createdAt; // 1690000000
355+
$container->status; // 'active'
356+
$container->expiresAfter->anchor; // 'last_active_at'
357+
$container->expiresAfter->minutes; // 60
358+
$container->lastActiveAt; // 1690001000
359+
$container->name; // 'Test Container'
335360
}
336361

337-
$response->usage->promptTokens; // 5,
338-
$response->usage->completionTokens; // 6,
339-
$response->usage->totalTokens; // 11
362+
$response->firstId; // 'container_abc123'
363+
$response->lastId; // 'container_def456'
364+
$response->hasMore; // false
340365

341-
$response->toArray(); // ['id' => 'cmpl-uqkvlQyYK7bGYrRHQ0eXlWi7', ...]
366+
$response->toArray(); // ['object' => 'list', 'data' => [...], ...]
342367
```
343368

344-
#### `create streamed`
369+
#### `retrieve`
345370

346-
Creates a streamed completion for the provided prompt and parameters.
371+
Retrieves a container with the given ID.
347372

348373
```php
349-
$stream = $client->completions()->createStreamed([
350-
'model' => 'gpt-3.5-turbo-instruct',
351-
'prompt' => 'Hi',
352-
'max_tokens' => 10,
353-
]);
374+
$response = $client->containers()->retrieve('container_abc123');
354375

355-
foreach($stream as $response){
356-
$response->choices[0]->text;
376+
$response->id; // 'container_abc123'
377+
$response->object; // 'container'
378+
$response->createdAt; // 1690000000
379+
$response->status; // 'active'
380+
$response->expiresAfter->anchor; // 'last_active_at'
381+
$response->expiresAfter->minutes; // 60
382+
$response->lastActiveAt; // 1690001000
383+
$response->name; // 'Test Container'
384+
385+
$response->toArray(); // ['id' => 'container_abc123', 'object' => 'container', ...]
386+
```
387+
388+
#### `delete`
389+
390+
Delete a container with the given ID.
391+
392+
```php
393+
$response = $client->containers()->delete('container_abc123');
394+
395+
$response->id; // 'container_abc123'
396+
$response->object; // 'container'
397+
$response->deleted; // true
398+
399+
$response->toArray(); // ['id' => 'container_abc123', 'object' => 'container', 'deleted' => true]
400+
```
401+
402+
### `Containers Files` Resource
403+
404+
#### `create`
405+
406+
Create or upload a file into a container.
407+
408+
```php
409+
$response = $client->containers()->files()->create('container_abc123', [
410+
'file' => fopen('path/to/local-file.txt', 'r'),
411+
]);
412+
$response = $client->containers()->files()->create('container_abc123', [
413+
'file_id' => 'file_XjGxS3KTG0uNmNOK362iJua3',
414+
]);
415+
416+
$response->id; // 'cfile_682e0e8a43c88191a7978f477a09bdf5'
417+
$response->object; // 'container.file'
418+
$response->createdAt; // 1747848842
419+
$response->bytes; // 880
420+
$response->containerId; // 'container_abc123'
421+
$response->path; // '/mnt/data/local-file.txt'
422+
$response->source; // 'user'
423+
424+
$response->toArray(); // ['id' => 'cfile_...', 'object' => 'container.file', ...]
425+
```
426+
427+
> [!NOTE]
428+
> You must provide either `file` or `file_id`, but not both.
429+
430+
#### `list`
431+
432+
Returns a list of files in the container.
433+
434+
```php
435+
$response = $client->containers()->files()->list('container_abc123', [
436+
'limit' => 10,
437+
'order' => 'desc',
438+
]);
439+
440+
$response->object; // 'list'
441+
442+
foreach ($response->data as $file) {
443+
$file->id; // 'cfile_682e0e8a43c88191a7978f477a09bdf5'
444+
$file->object; // 'container.file'
445+
$file->createdAt; // 1747848842
446+
$file->bytes; // 880
447+
$file->containerId; // 'container_abc123'
448+
$file->path; // '/mnt/data/...'
449+
$file->source; // 'user'
357450
}
358-
// 1. iteration => 'I'
359-
// 2. iteration => ' am'
360-
// 3. iteration => ' very'
361-
// 4. iteration => ' excited'
362-
// ...
451+
452+
$response->firstId; // 'cfile_...'
453+
$response->lastId; // 'cfile_...'
454+
$response->hasMore; // false
455+
456+
$response->toArray(); // ['object' => 'list', 'data' => [...], ...]
457+
```
458+
459+
#### `retrieve`
460+
461+
Retrieve information about a container file.
462+
463+
```php
464+
$response = $client->containers()->files()->retrieve('container_abc123', 'cfile_682e0e8a43c88191a7978f477a09bdf5');
465+
466+
$response->id; // 'cfile_682e0e8a43c88191a7978f477a09bdf5'
467+
$response->object; // 'container.file'
468+
$response->createdAt; // 1747848842
469+
$response->bytes; // 880
470+
$response->containerId; // 'container_abc123'
471+
$response->path; // '/mnt/data/...'
472+
$response->source; // 'user'
473+
474+
$response->toArray(); // ['id' => 'cfile_...', 'object' => 'container.file', ...]
475+
```
476+
477+
#### `retrieve content`
478+
479+
Returns the raw content of the specified container file.
480+
481+
```php
482+
$content = $client->containers()->files()->content('container_abc123', 'cfile_682e0e8a43c88191a7978f477a09bdf5');
483+
// $content => string
484+
```
485+
486+
#### `delete`
487+
488+
Delete a container file.
489+
490+
```php
491+
$response = $client->containers()->files()->delete('container_abc123', 'cfile_682e0e8a43c88191a7978f477a09bdf5');
492+
493+
$response->id; // 'cfile_682e0e8a43c88191a7978f477a09bdf5'
494+
$response->object; // 'container.file.deleted'
495+
$response->deleted; // true
496+
497+
$response->toArray(); // ['id' => 'cfile_...', 'object' => 'container.file.deleted', 'deleted' => true]
363498
```
364499

365500
### `Chat` Resource
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace OpenAI\Contracts\Resources;
4+
5+
use OpenAI\Responses\Containers\Files\ContainerFileDeleteResponse;
6+
use OpenAI\Responses\Containers\Files\ContainerFileListResponse;
7+
use OpenAI\Responses\Containers\Files\ContainerFileResponse;
8+
9+
interface ContainerFileContract
10+
{
11+
/**
12+
* Create a container file
13+
*
14+
* @see https://platform.openai.com/docs/api-reference/container_files/createContainerFile
15+
*
16+
* @param array<string, mixed> $parameters
17+
*/
18+
public function create(string $containerId, array $parameters = []): ContainerFileResponse;
19+
20+
/**
21+
* List container files
22+
*
23+
* @see https://platform.openai.com/docs/api-reference/container_files/listContainerFiles
24+
*
25+
* @param array<string, mixed> $parameters
26+
*/
27+
public function list(string $containerId, array $parameters = []): ContainerFileListResponse;
28+
29+
/**
30+
* Retrieve a container file
31+
*
32+
* @see https://platform.openai.com/docs/api-reference/container_files/retrieveContainerFile
33+
*/
34+
public function retrieve(string $containerId, string $fileId): ContainerFileResponse;
35+
36+
/**
37+
* Retrieve container file content
38+
*
39+
* @see https://platform.openai.com/docs/api-reference/container_files/retrieveContainerFileContent
40+
*/
41+
public function content(string $containerId, string $fileId): string;
42+
43+
/**
44+
* Delete a container file
45+
*
46+
* @see https://platform.openai.com/docs/api-reference/container_files/deleteContainerFile
47+
*/
48+
public function delete(string $containerId, string $fileId): ContainerFileDeleteResponse;
49+
}

src/Contracts/Resources/ContainersContract.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,11 @@ public function delete(string $id): DeleteContainer;
4242
* @param array<string, mixed> $parameters
4343
*/
4444
public function list(array $parameters = []): ListContainers;
45+
46+
/**
47+
* Manage the files related to the container
48+
*
49+
* @see https://platform.openai.com/docs/api-reference/container-files
50+
*/
51+
public function files(): ContainerFileContract;
4552
}

0 commit comments

Comments
 (0)