Skip to content

Commit 5b17e19

Browse files
Add batches API endpoint (#403)
Co-authored-by: Mehrdad Garebaghi <[email protected]>
1 parent 7b5652b commit 5b17e19

23 files changed

+1216
-0
lines changed

README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
- [Threads Messages Files Resource](#threads-messages-files-resource)
3434
- [Threads Runs Resource](#threads-runs-resource)
3535
- [Threads Runs Steps Resource](#threads-runs-steps-resource)
36+
- [Batches Resource](#batches-resource)
3637
- [FineTunes Resource (deprecated)](#finetunes-resource-deprecated)
3738
- [Edits Resource (deprecated)](#edits-resource-deprecated)
3839
- [Meta Information](#meta-information)
@@ -1726,6 +1727,133 @@ foreach ($response->data as $result) {
17261727
$response->toArray(); // ['object' => 'list', ...]]
17271728
```
17281729

1730+
1731+
### `Batches` Resource
1732+
1733+
#### `create`
1734+
1735+
Creates a batch.
1736+
1737+
```php
1738+
1739+
$fileResponse = $client->files()->upload(
1740+
parameters: [
1741+
'purpose' => 'batch',
1742+
'file' => fopen('commands.jsonl', 'r'),
1743+
]
1744+
);
1745+
1746+
$fileId = $fileResponse->id;
1747+
1748+
$response = $client->batches()->create(
1749+
parameters: [
1750+
'input_file_id' => $fileId,
1751+
'endpoint' => '/v1/chat/completions',
1752+
'completion_window' => '24h'
1753+
]
1754+
);
1755+
1756+
$response->id; // 'batch_abc123'
1757+
$response->object; // 'batch'
1758+
$response->endpoint; // /v1/chat/completions
1759+
$response->errors; // null
1760+
$response->completionWindow; // '24h'
1761+
$response->status; // 'validating'
1762+
$response->outputFileId; // null
1763+
$response->errorFileId; // null
1764+
$response->createdAt; // 1714508499
1765+
$response->inProgressAt; // null
1766+
$response->expiresAt; // 1714536634
1767+
$response->completedAt; // null
1768+
$response->failedAt; // null
1769+
$response->expiredAt; // null
1770+
$response->requestCounts; // null
1771+
$response->metadata; // ['name' => 'My batch name']
1772+
1773+
$response->toArray(); // ['id' => 'batch_abc123', ...]
1774+
```
1775+
1776+
#### `retrieve`
1777+
1778+
Retrieves a batch.
1779+
1780+
```php
1781+
$response = $client->batches()->retrieve(id: 'batch_abc123');
1782+
1783+
$response->id; // 'batch_abc123'
1784+
$response->object; // 'batch'
1785+
$response->endpoint; // /v1/chat/completions
1786+
$response->errors; // null
1787+
$response->completionWindow; // '24h'
1788+
$response->status; // 'validating'
1789+
$response->outputFileId; // null
1790+
$response->errorFileId; // null
1791+
$response->createdAt; // 1714508499
1792+
$response->inProgressAt; // null
1793+
$response->expiresAt; // 1714536634
1794+
$response->completedAt; // null
1795+
$response->failedAt; // null
1796+
$response->expiredAt; // null
1797+
$response->requestCounts->total; // 100
1798+
$response->requestCounts->completed; // 95
1799+
$response->requestCounts->failed; // 5
1800+
$response->metadata; // ['name' => 'My batch name']
1801+
1802+
$response->toArray(); // ['id' => 'batch_abc123', ...]
1803+
```
1804+
1805+
#### `cancel`
1806+
1807+
Cancels a batch.
1808+
1809+
```php
1810+
$response = $client->batches()->cancel(id: 'batch_abc123');
1811+
1812+
$response->id; // 'batch_abc123'
1813+
$response->object; // 'batch'
1814+
$response->endpoint; // /v1/chat/completions
1815+
$response->errors; // null
1816+
$response->completionWindow; // '24h'
1817+
$response->status; // 'cancelling'
1818+
$response->outputFileId; // null
1819+
$response->errorFileId; // null
1820+
$response->createdAt; // 1711471533
1821+
$response->inProgressAt; // 1711471538
1822+
$response->expiresAt; // 1711557933
1823+
$response->cancellingAt; // 1711475133
1824+
$response->cancelledAt; // null
1825+
$response->requestCounts->total; // 100
1826+
$response->requestCounts->completed; // 23
1827+
$response->requestCounts->failed; // 1
1828+
$response->metadata; // ['name' => 'My batch name']
1829+
1830+
$response->toArray(); // ['id' => 'batch_abc123', ...]
1831+
```
1832+
1833+
#### `list`
1834+
1835+
Returns a list of batches.
1836+
1837+
```php
1838+
$response = $client->batches()->list(
1839+
parameters: [
1840+
'limit' => 10,
1841+
],
1842+
);
1843+
1844+
$response->object; // 'list'
1845+
$response->firstId; // 'batch_abc123'
1846+
$response->lastId; // 'batch_abc456'
1847+
$response->hasMore; // true
1848+
1849+
foreach ($response->data as $result) {
1850+
$result->id; // 'batch_abc123'
1851+
// ...
1852+
}
1853+
1854+
$response->toArray(); // ['object' => 'list', ...]]
1855+
```
1856+
17291857
### `Edits` Resource (deprecated)
17301858

17311859
> OpenAI has deprecated the Edits API and will stop working by January 4, 2024.

src/Client.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use OpenAI\Contracts\TransporterContract;
1010
use OpenAI\Resources\Assistants;
1111
use OpenAI\Resources\Audio;
12+
use OpenAI\Resources\Batches;
1213
use OpenAI\Resources\Chat;
1314
use OpenAI\Resources\Completions;
1415
use OpenAI\Resources\Edits;
@@ -163,4 +164,14 @@ public function threads(): ThreadsContract
163164
{
164165
return new Threads($this->transporter);
165166
}
167+
168+
/**
169+
* Create large batches of API requests for asynchronous processing. The Batch API returns completions within 24 hours.
170+
*
171+
* @see https://platform.openai.com/docs/api-reference/batch
172+
*/
173+
public function batches(): Batches
174+
{
175+
return new Batches($this->transporter);
176+
}
166177
}

src/Contracts/ClientContract.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use OpenAI\Contracts\Resources\AssistantsContract;
66
use OpenAI\Contracts\Resources\AudioContract;
7+
use OpenAI\Contracts\Resources\BatchesContract;
78
use OpenAI\Contracts\Resources\ChatContract;
89
use OpenAI\Contracts\Resources\CompletionsContract;
910
use OpenAI\Contracts\Resources\EditsContract;
@@ -113,4 +114,11 @@ public function assistants(): AssistantsContract;
113114
* @see https://platform.openai.com/docs/api-reference/threads
114115
*/
115116
public function threads(): ThreadsContract;
117+
118+
/**
119+
* Create large batches of API requests for asynchronous processing. The Batch API returns completions within 24 hours.
120+
*
121+
* @see https://platform.openai.com/docs/api-reference/batch
122+
*/
123+
public function batches(): BatchesContract;
116124
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace OpenAI\Contracts\Resources;
4+
5+
use OpenAI\Responses\Batches\BatchListResponse;
6+
use OpenAI\Responses\Batches\BatchResponse;
7+
8+
interface BatchesContract
9+
{
10+
/**
11+
* Creates and executes a batch from an uploaded file of requests
12+
*
13+
* @see https://platform.openai.com/docs/api-reference/batch/create
14+
*
15+
* @param array<string, mixed> $parameters
16+
*/
17+
public function create(array $parameters): BatchResponse;
18+
19+
/**
20+
* Retrieves a batch.
21+
* *
22+
* @see https://platform.openai.com/docs/api-reference/batch/retrieve
23+
*/
24+
public function retrieve(string $id): BatchResponse;
25+
26+
/**
27+
* Cancels an in-progress batch.
28+
* *
29+
* @see https://platform.openai.com/docs/api-reference/batch/cancel
30+
*/
31+
public function cancel(string $id): BatchResponse;
32+
33+
/**
34+
* List your organization's batches.
35+
*
36+
* @see https://platform.openai.com/docs/api-reference/batch/list
37+
*
38+
* @param array<string, mixed> $parameters
39+
*/
40+
public function list(array $parameters = []): BatchListResponse;
41+
}

src/Resources/Batches.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenAI\Resources;
6+
7+
use OpenAI\Contracts\Resources\BatchesContract;
8+
use OpenAI\Responses\Batches\BatchListResponse;
9+
use OpenAI\Responses\Batches\BatchResponse;
10+
use OpenAI\ValueObjects\Transporter\Payload;
11+
use OpenAI\ValueObjects\Transporter\Response;
12+
13+
final class Batches implements BatchesContract
14+
{
15+
use Concerns\Transportable;
16+
17+
/**
18+
* Creates and executes a batch from an uploaded file of requests
19+
*
20+
* @see https://platform.openai.com/docs/api-reference/batch/create
21+
*
22+
* @param array<string, mixed> $parameters
23+
*/
24+
public function create(array $parameters): BatchResponse
25+
{
26+
$payload = Payload::create('batches', $parameters);
27+
28+
/** @var Response<array{id: string, object: string, endpoint: string, errors?: array{object: string, data: array<array-key, array{code: string, message: string, param: ?string, line: ?int}>}, input_file_id: string, completion_window: string, status: string, output_file_id: ?string, error_file_id: ?string, created_at: int, in_progress_at: ?int, expires_at: ?int, finalizing_at: ?int, completed_at: ?int, failed_at: ?int, expired_at: ?int, cancelling_at: ?int, cancelled_at: ?int, request_counts?: array{total: int, completed: int, failed: int}, metadata: ?array<string, string>}> $response */
29+
$response = $this->transporter->requestObject($payload);
30+
31+
return BatchResponse::from($response->data(), $response->meta());
32+
}
33+
34+
/**
35+
* Retrieves a batch.
36+
* *
37+
* @see https://platform.openai.com/docs/api-reference/batch/retrieve
38+
*/
39+
public function retrieve(string $id): BatchResponse
40+
{
41+
$payload = Payload::retrieve('batches', $id);
42+
43+
/** @var Response<array{id: string, object: string, endpoint: string, errors?: array{object: string, data: array<array-key, array{code: string, message: string, param: ?string, line: ?int}>}, input_file_id: string, completion_window: string, status: string, output_file_id: ?string, error_file_id: ?string, created_at: int, in_progress_at: ?int, expires_at: ?int, finalizing_at: ?int, completed_at: ?int, failed_at: ?int, expired_at: ?int, cancelling_at: ?int, cancelled_at: ?int, request_counts?: array{total: int, completed: int, failed: int}, metadata: ?array<string, string>}> $response */
44+
$response = $this->transporter->requestObject($payload);
45+
46+
return BatchResponse::from($response->data(), $response->meta());
47+
}
48+
49+
/**
50+
* Cancels an in-progress batch.
51+
* *
52+
* @see https://platform.openai.com/docs/api-reference/batch/cancel
53+
*/
54+
public function cancel(string $id): BatchResponse
55+
{
56+
$payload = Payload::cancel('batches', $id);
57+
58+
/** @var Response<array{id: string, object: string, endpoint: string, errors?: array{object: string, data: array<array-key, array{code: string, message: string, param: ?string, line: ?int}>}, input_file_id: string, completion_window: string, status: string, output_file_id: ?string, error_file_id: ?string, created_at: int, in_progress_at: ?int, expires_at: ?int, finalizing_at: ?int, completed_at: ?int, failed_at: ?int, expired_at: ?int, cancelling_at: ?int, cancelled_at: ?int, request_counts?: array{total: int, completed: int, failed: int}, metadata: ?array<string, string>}> $response */
59+
$response = $this->transporter->requestObject($payload);
60+
61+
return BatchResponse::from($response->data(), $response->meta());
62+
}
63+
64+
/**
65+
* List your organization's batches.
66+
*
67+
* @see https://platform.openai.com/docs/api-reference/batch/list
68+
*
69+
* @param array<string, mixed> $parameters
70+
*/
71+
public function list(array $parameters = []): BatchListResponse
72+
{
73+
$payload = Payload::list('batches', $parameters);
74+
75+
/** @var Response<array{object: string, data: array<int, array{id: string, object: string, endpoint: string, errors?: array{object: string, data: array<array-key, array{code: string, message: string, param: ?string, line: ?int}>}, input_file_id: string, completion_window: string, status: string, output_file_id: ?string, error_file_id: ?string, created_at: int, in_progress_at: ?int, expires_at: ?int, finalizing_at: ?int, completed_at: ?int, failed_at: ?int, expired_at: ?int, cancelling_at: ?int, cancelled_at: ?int, request_counts?: array{total: int, completed: int, failed: int}, metadata: ?array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */
76+
$response = $this->transporter->requestObject($payload);
77+
78+
return BatchListResponse::from($response->data(), $response->meta());
79+
}
80+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenAI\Responses\Batches;
6+
7+
use OpenAI\Contracts\ResponseContract;
8+
use OpenAI\Contracts\ResponseHasMetaInformationContract;
9+
use OpenAI\Responses\Concerns\ArrayAccessible;
10+
use OpenAI\Responses\Concerns\HasMetaInformation;
11+
use OpenAI\Responses\Meta\MetaInformation;
12+
use OpenAI\Testing\Responses\Concerns\Fakeable;
13+
14+
/**
15+
* @implements ResponseContract<array{object: string, data: array<int, array{id: string, object: string, endpoint: string, errors: ?array{object: string, data: array<array-key, array{code: string, message: string, param: ?string, line: ?int}>}, input_file_id: string, completion_window: string, status: string, output_file_id: ?string, error_file_id: ?string, created_at: int, in_progress_at: ?int, expires_at: ?int, finalizing_at: ?int, completed_at: ?int, failed_at: ?int, expired_at: ?int, cancelling_at: ?int, cancelled_at: ?int, request_counts: ?array{total: int, completed: int, failed: int}, metadata: ?array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
16+
*/
17+
final class BatchListResponse implements ResponseContract, ResponseHasMetaInformationContract
18+
{
19+
/**
20+
* @use ArrayAccessible<array{object: string, data: array<int, array{id: string, object: string, endpoint: string, errors: ?array{object: string, data: array<array-key, array{code: string, message: string, param: ?string, line: ?int}>}, input_file_id: string, completion_window: string, status: string, output_file_id: ?string, error_file_id: ?string, created_at: int, in_progress_at: ?int, expires_at: ?int, finalizing_at: ?int, completed_at: ?int, failed_at: ?int, expired_at: ?int, cancelling_at: ?int, cancelled_at: ?int, request_counts: ?array{total: int, completed: int, failed: int}, metadata: ?array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
21+
*/
22+
use ArrayAccessible;
23+
24+
use Fakeable;
25+
use HasMetaInformation;
26+
27+
/**
28+
* @param array<int, BatchResponse> $data
29+
*/
30+
private function __construct(
31+
public readonly string $object,
32+
public readonly array $data,
33+
public readonly ?string $firstId,
34+
public readonly ?string $lastId,
35+
public readonly bool $hasMore,
36+
private readonly MetaInformation $meta,
37+
) {
38+
}
39+
40+
/**
41+
* Acts as static factory, and returns a new Response instance.
42+
*
43+
* @param array{object: string, data: array<int, array{id: string, object: string, endpoint: string, errors?: array{object: string, data: array<array-key, array{code: string, message: string, param: ?string, line: ?int}>}, input_file_id: string, completion_window: string, status: string, output_file_id: ?string, error_file_id: ?string, created_at: int, in_progress_at: ?int, expires_at: ?int, finalizing_at: ?int, completed_at: ?int, failed_at: ?int, expired_at: ?int, cancelling_at: ?int, cancelled_at: ?int, request_counts?: array{total: int, completed: int, failed: int}, metadata: ?array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes
44+
*/
45+
public static function from(array $attributes, MetaInformation $meta): self
46+
{
47+
$data = array_map(fn (array $result): BatchResponse => BatchResponse::from(
48+
$result,
49+
$meta,
50+
), $attributes['data']);
51+
52+
return new self(
53+
$attributes['object'],
54+
$data,
55+
$attributes['first_id'],
56+
$attributes['last_id'],
57+
$attributes['has_more'],
58+
$meta,
59+
);
60+
}
61+
62+
/**
63+
* {@inheritDoc}
64+
*/
65+
public function toArray(): array
66+
{
67+
return [
68+
'object' => $this->object,
69+
'data' => array_map(
70+
static fn (BatchResponse $response): array => $response->toArray(),
71+
$this->data,
72+
),
73+
'first_id' => $this->firstId,
74+
'last_id' => $this->lastId,
75+
'has_more' => $this->hasMore,
76+
];
77+
}
78+
}

0 commit comments

Comments
 (0)