Skip to content

Commit

Permalink
Add batches API endpoint
Browse files Browse the repository at this point in the history
Co-authored-by: Mehrdad Garebaghi <mehrdad@dev.tribes.work>
  • Loading branch information
gehrisandro and The-LoneWolf committed May 24, 2024
1 parent 7b5652b commit d429a76
Show file tree
Hide file tree
Showing 23 changed files with 1,216 additions and 0 deletions.
128 changes: 128 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
- [Threads Messages Files Resource](#threads-messages-files-resource)
- [Threads Runs Resource](#threads-runs-resource)
- [Threads Runs Steps Resource](#threads-runs-steps-resource)
- [Batches Resource](#batches-resource)
- [FineTunes Resource (deprecated)](#finetunes-resource-deprecated)
- [Edits Resource (deprecated)](#edits-resource-deprecated)
- [Meta Information](#meta-information)
Expand Down Expand Up @@ -1726,6 +1727,133 @@ foreach ($response->data as $result) {
$response->toArray(); // ['object' => 'list', ...]]
```


### `Batches` Resource

#### `create`

Creates a batch.

```php

$fileResponse = $client->files()->upload(
parameters: [
'purpose' => 'batch',
'file' => fopen('commands.jsonl', 'r'),
]
);

$fileId = $fileResponse->id;

$response = $client->batches()->create(
parameters: [
'input_file_id' => $fileId,
'endpoint' => '/v1/chat/completions',
'completion_window' => '24h'
]
);

$response->id; // 'batch_abc123'
$response->object; // 'batch'
$response->endpoint; // /v1/chat/completions
$response->errors; // null
$response->completionWindow; // '24h'
$response->status; // 'validating'
$response->outputFileId; // null
$response->errorFileId; // null
$response->createdAt; // 1714508499
$response->inProgressAt; // null
$response->expiresAt; // 1714536634
$response->completedAt; // null
$response->failedAt; // null
$response->expiredAt; // null
$response->requestCounts; // null
$response->metadata; // ['name' => 'My batch name']

$response->toArray(); // ['id' => 'batch_abc123', ...]
```

#### `retrieve`

Retrieves a batch.

```php
$response = $client->batches()->retrieve(id: 'batch_abc123');

$response->id; // 'batch_abc123'
$response->object; // 'batch'
$response->endpoint; // /v1/chat/completions
$response->errors; // null
$response->completionWindow; // '24h'
$response->status; // 'validating'
$response->outputFileId; // null
$response->errorFileId; // null
$response->createdAt; // 1714508499
$response->inProgressAt; // null
$response->expiresAt; // 1714536634
$response->completedAt; // null
$response->failedAt; // null
$response->expiredAt; // null
$response->requestCounts->total; // 100
$response->requestCounts->completed; // 95
$response->requestCounts->failed; // 5
$response->metadata; // ['name' => 'My batch name']

$response->toArray(); // ['id' => 'batch_abc123', ...]
```

#### `cancel`

Cancels a batch.

```php
$response = $client->batches()->cancel(id: 'batch_abc123');

$response->id; // 'batch_abc123'
$response->object; // 'batch'
$response->endpoint; // /v1/chat/completions
$response->errors; // null
$response->completionWindow; // '24h'
$response->status; // 'cancelling'
$response->outputFileId; // null
$response->errorFileId; // null
$response->createdAt; // 1711471533
$response->inProgressAt; // 1711471538
$response->expiresAt; // 1711557933
$response->cancellingAt; // 1711475133
$response->cancelledAt; // null
$response->requestCounts->total; // 100
$response->requestCounts->completed; // 23
$response->requestCounts->failed; // 1
$response->metadata; // ['name' => 'My batch name']

$response->toArray(); // ['id' => 'batch_abc123', ...]
```

#### `list`

Returns a list of batches.

```php
$response = $client->batches()->list(
parameters: [
'limit' => 10,
],
);

$response->object; // 'list'
$response->firstId; // 'batch_abc123'
$response->lastId; // 'batch_abc456'
$response->hasMore; // true

foreach ($response->data as $result) {
$result->id; // 'batch_abc123'
// ...
}

$response->toArray(); // ['object' => 'list', ...]]
```

### `Edits` Resource (deprecated)

> OpenAI has deprecated the Edits API and will stop working by January 4, 2024.
Expand Down
11 changes: 11 additions & 0 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use OpenAI\Contracts\TransporterContract;
use OpenAI\Resources\Assistants;
use OpenAI\Resources\Audio;
use OpenAI\Resources\Batches;
use OpenAI\Resources\Chat;
use OpenAI\Resources\Completions;
use OpenAI\Resources\Edits;
Expand Down Expand Up @@ -163,4 +164,14 @@ public function threads(): ThreadsContract
{
return new Threads($this->transporter);
}

/**
* Create large batches of API requests for asynchronous processing. The Batch API returns completions within 24 hours.
*
* @see https://platform.openai.com/docs/api-reference/batch
*/
public function batches(): Batches
{
return new Batches($this->transporter);
}
}
8 changes: 8 additions & 0 deletions src/Contracts/ClientContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use OpenAI\Contracts\Resources\AssistantsContract;
use OpenAI\Contracts\Resources\AudioContract;
use OpenAI\Contracts\Resources\BatchesContract;
use OpenAI\Contracts\Resources\ChatContract;
use OpenAI\Contracts\Resources\CompletionsContract;
use OpenAI\Contracts\Resources\EditsContract;
Expand Down Expand Up @@ -113,4 +114,11 @@ public function assistants(): AssistantsContract;
* @see https://platform.openai.com/docs/api-reference/threads
*/
public function threads(): ThreadsContract;

/**
* Create large batches of API requests for asynchronous processing. The Batch API returns completions within 24 hours.
*
* @see https://platform.openai.com/docs/api-reference/batch
*/
public function batches(): BatchesContract;
}
41 changes: 41 additions & 0 deletions src/Contracts/Resources/BatchesContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace OpenAI\Contracts\Resources;

use OpenAI\Responses\Batches\BatchListResponse;
use OpenAI\Responses\Batches\BatchResponse;

interface BatchesContract
{
/**
* Creates and executes a batch from an uploaded file of requests
*
* @see https://platform.openai.com/docs/api-reference/batch/create
*
* @param array<string, mixed> $parameters
*/
public function create(array $parameters): BatchResponse;

/**
* Retrieves a batch.
* *
* @see https://platform.openai.com/docs/api-reference/batch/retrieve
*/
public function retrieve(string $id): BatchResponse;

/**
* Cancels an in-progress batch.
* *
* @see https://platform.openai.com/docs/api-reference/batch/cancel
*/
public function cancel(string $id): BatchResponse;

/**
* List your organization's batches.
*
* @see https://platform.openai.com/docs/api-reference/batch/list
*
* @param array<string, mixed> $parameters
*/
public function list(array $parameters = []): BatchListResponse;
}
80 changes: 80 additions & 0 deletions src/Resources/Batches.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace OpenAI\Resources;

use OpenAI\Contracts\Resources\BatchesContract;
use OpenAI\Responses\Batches\BatchListResponse;
use OpenAI\Responses\Batches\BatchResponse;
use OpenAI\ValueObjects\Transporter\Payload;
use OpenAI\ValueObjects\Transporter\Response;

final class Batches implements BatchesContract
{
use Concerns\Transportable;

/**
* Creates and executes a batch from an uploaded file of requests
*
* @see https://platform.openai.com/docs/api-reference/batch/create
*
* @param array<string, mixed> $parameters
*/
public function create(array $parameters): BatchResponse
{
$payload = Payload::create('batches', $parameters);

/** @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 */
$response = $this->transporter->requestObject($payload);

return BatchResponse::from($response->data(), $response->meta());
}

/**
* Retrieves a batch.
* *
* @see https://platform.openai.com/docs/api-reference/batch/retrieve
*/
public function retrieve(string $id): BatchResponse
{
$payload = Payload::retrieve('batches', $id);

/** @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 */
$response = $this->transporter->requestObject($payload);

return BatchResponse::from($response->data(), $response->meta());
}

/**
* Cancels an in-progress batch.
* *
* @see https://platform.openai.com/docs/api-reference/batch/cancel
*/
public function cancel(string $id): BatchResponse
{
$payload = Payload::cancel('batches', $id);

/** @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 */
$response = $this->transporter->requestObject($payload);

return BatchResponse::from($response->data(), $response->meta());
}

/**
* List your organization's batches.
*
* @see https://platform.openai.com/docs/api-reference/batch/list
*
* @param array<string, mixed> $parameters
*/
public function list(array $parameters = []): BatchListResponse
{
$payload = Payload::list('batches', $parameters);

/** @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 */
$response = $this->transporter->requestObject($payload);

return BatchListResponse::from($response->data(), $response->meta());
}
}
78 changes: 78 additions & 0 deletions src/Responses/Batches/BatchListResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace OpenAI\Responses\Batches;

use OpenAI\Contracts\ResponseContract;
use OpenAI\Contracts\ResponseHasMetaInformationContract;
use OpenAI\Responses\Concerns\ArrayAccessible;
use OpenAI\Responses\Concerns\HasMetaInformation;
use OpenAI\Responses\Meta\MetaInformation;
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @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}>
*/
final class BatchListResponse implements ResponseContract, ResponseHasMetaInformationContract
{
/**
* @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}>
*/
use ArrayAccessible;

use Fakeable;
use HasMetaInformation;

/**
* @param array<int, BatchResponse> $data
*/
private function __construct(
public readonly string $object,
public readonly array $data,
public readonly ?string $firstId,
public readonly ?string $lastId,
public readonly bool $hasMore,
private readonly MetaInformation $meta,
) {
}

/**
* Acts as static factory, and returns a new Response instance.
*
* @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
*/
public static function from(array $attributes, MetaInformation $meta): self
{
$data = array_map(fn (array $result): BatchResponse => BatchResponse::from(
$result,
$meta,
), $attributes['data']);

return new self(
$attributes['object'],
$data,
$attributes['first_id'],
$attributes['last_id'],
$attributes['has_more'],
$meta,
);
}

/**
* {@inheritDoc}
*/
public function toArray(): array
{
return [
'object' => $this->object,
'data' => array_map(
static fn (BatchResponse $response): array => $response->toArray(),
$this->data,
),
'first_id' => $this->firstId,
'last_id' => $this->lastId,
'has_more' => $this->hasMore,
];
}
}
Loading

0 comments on commit d429a76

Please sign in to comment.