diff --git a/src/Contracts/Transporter.php b/src/Contracts/Transporter.php index 27bd041f..a17ac550 100644 --- a/src/Contracts/Transporter.php +++ b/src/Contracts/Transporter.php @@ -22,4 +22,12 @@ interface Transporter * @throws ErrorException|UnserializableResponse|TransporterException */ public function request(Payload $payload): array; + + /** + * Sends a content request to a server. + ** + * + * @throws ErrorException|UnserializableResponse|TransporterException + */ + public function requestContent(Payload $payload): string; } diff --git a/src/Resources/Files.php b/src/Resources/Files.php index 839201fb..947d44d1 100644 --- a/src/Resources/Files.php +++ b/src/Resources/Files.php @@ -26,4 +26,46 @@ public function list(): array return $result; } + + /** + * Returns information about a specific file. + * + * @see https://beta.openai.com/docs/api-reference/files/retrieve + * + * @return array + */ + public function retrieve(string $file): array + { + $payload = Payload::retrieve('files', $file); + + return $this->transporter->request($payload); + } + + /** + * Returns the contents of the specified file. + * + * @see https://beta.openai.com/docs/api-reference/files/retrieve-content + * + * @return string + */ + public function retrieveContent(string $file): string + { + $payload = Payload::retrieveContent('files', $file); + + return $this->transporter->requestContent($payload); + } + + /** + * Delete a file. + * + * @see https://beta.openai.com/docs/api-reference/files/delete + * + * @return array + */ + public function delete(string $file): array + { + $payload = Payload::delete('files', $file); + + return $this->transporter->request($payload); + } } diff --git a/src/Transporters/HttpTransporter.php b/src/Transporters/HttpTransporter.php index 97caa803..832a0f51 100644 --- a/src/Transporters/HttpTransporter.php +++ b/src/Transporters/HttpTransporter.php @@ -56,4 +56,20 @@ public function request(Payload $payload): array return $response; } + + /** + * {@inheritDoc} + */ + public function requestContent(Payload $payload): string + { + $request = $payload->toRequest($this->baseUri, $this->headers); + + try { + $response = $this->client->sendRequest($request); + } catch (ClientExceptionInterface $clientException) { + throw new TransporterException($clientException); + } + + return $response->getBody()->getContents(); + } } diff --git a/src/ValueObjects/ResourceUri.php b/src/ValueObjects/ResourceUri.php index 25385c04..ffb125a8 100644 --- a/src/ValueObjects/ResourceUri.php +++ b/src/ValueObjects/ResourceUri.php @@ -51,6 +51,22 @@ public static function retrieve(string $resource, string $id): self return new self("{$resource}/{$id}"); } + /** + * Creates a new ResourceUri value object that retrieves the given resource content. + */ + public static function retrieveContent(string $resource, string $id): self + { + return new self("{$resource}/{$id}/content"); + } + + /** + * Creates a new ResourceUri value object that deletes the given resource. + */ + public static function delete(string $resource, string $id): self + { + return new self("{$resource}/{$id}"); + } + /** * {@inheritDoc} */ diff --git a/src/ValueObjects/Transporter/Payload.php b/src/ValueObjects/Transporter/Payload.php index d0f6004c..e3442596 100644 --- a/src/ValueObjects/Transporter/Payload.php +++ b/src/ValueObjects/Transporter/Payload.php @@ -52,6 +52,18 @@ public static function retrieve(string $resource, string $id): self return new self($contentType, $method, $uri); } + /** + * Creates a new Payload value object from the given parameters. + */ + public static function retrieveContent(string $resource, string $id): self + { + $contentType = ContentType::JSON; + $method = Method::GET; + $uri = ResourceUri::retrieveContent($resource, $id); + + return new self($contentType, $method, $uri); + } + /** * Creates a new Payload value object from the given parameters. * @@ -80,6 +92,18 @@ public static function upload(string $resource, array $parameters): self return new self($contentType, $method, $uri, $parameters); } + /** + * Creates a new Payload value object from the given parameters. + */ + public static function delete(string $resource, string $id): self + { + $contentType = ContentType::JSON; + $method = Method::DELETE; + $uri = ResourceUri::delete($resource, $id); + + return new self($contentType, $method, $uri); + } + /** * Creates a new Psr 7 Request instance. */ diff --git a/tests/Fixtures/File.php b/tests/Fixtures/File.php index 7ad1a75a..3f891f21 100644 --- a/tests/Fixtures/File.php +++ b/tests/Fixtures/File.php @@ -14,3 +14,23 @@ function fileResource(): array 'purpose' => 'fine-tune', ]; } + +/** + * @return string + */ +function fileContentResource(): string +{ + return file_get_contents(__DIR__.'/MyFile.json'); +} + +/** + * @return array + */ +function fileDeleteResource(): array +{ + return [ + 'id' => 'file-XjGxS3KTG0uNmNOK362iJua3', + 'object' => 'file', + 'deleted' => true, + ]; +} diff --git a/tests/Pest.php b/tests/Pest.php index f2ede99d..197f4abf 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -7,12 +7,12 @@ use OpenAI\ValueObjects\Transporter\Headers; use OpenAI\ValueObjects\Transporter\Payload; -function mockClient(string $method, string $resource, array $params, array $response) +function mockClient(string $method, string $resource, array $params, array|string $response, $methodName = 'request') { $transporter = Mockery::mock(Transporter::class); $transporter - ->shouldReceive('request') + ->shouldReceive($methodName) ->once() ->withArgs(function (Payload $payload) use ($method, $resource) { $baseUri = BaseUri::from('api.openai.com/v1'); @@ -26,3 +26,8 @@ function mockClient(string $method, string $resource, array $params, array $resp return new Client($transporter); } + +function mockContentClient(string $method, string $resource, array $params, string $response) +{ + return mockClient($method, $resource, $params, $response, 'requestContent'); +} diff --git a/tests/Resources/Files.php b/tests/Resources/Files.php index 909f6983..ae3440d2 100644 --- a/tests/Resources/Files.php +++ b/tests/Resources/Files.php @@ -19,3 +19,27 @@ ], ]); }); + +test('retreive', function () { + $client = mockClient('GET', 'files/file-XjGxS3KTG0uNmNOK362iJua3', [], fileResource()); + + $result = $client->files()->retrieve('file-XjGxS3KTG0uNmNOK362iJua3'); + + expect($result)->toBeArray()->toBe(fileResource()); +}); + +test('retreive content', function () { + $client = mockContentClient('GET', 'files/file-XjGxS3KTG0uNmNOK362iJua3/content', [], fileContentResource()); + + $result = $client->files()->retrieveContent('file-XjGxS3KTG0uNmNOK362iJua3'); + + expect($result)->toBeString()->toBe(fileContentResource()); +}); + +test('delete', function () { + $client = mockClient('DELETE', 'files/file-XjGxS3KTG0uNmNOK362iJua3', [], fileDeleteResource()); + + $result = $client->files()->delete('file-XjGxS3KTG0uNmNOK362iJua3'); + + expect($result)->toBeArray()->toBe(fileDeleteResource()); +});