mirror of
https://github.com/symfony/ai.git
synced 2026-03-23 23:42:18 +01:00
Add asFile() method to BinaryResult and DeferredResult
This commit is contained in:
@@ -820,7 +820,16 @@ Binary Results
|
||||
);
|
||||
|
||||
$result = $platform->invoke('gpt-4o-mini', 'generate PDF document');
|
||||
$binary = $result->asBinary(); // Returns Binary object with content and MIME type
|
||||
$binary = $result->asBinary(); // Returns the binary data as string
|
||||
|
||||
You can also save binary results directly to a file using
|
||||
:method:`Symfony\\AI\\Platform\\Result\\DeferredResult::asFile`::
|
||||
|
||||
$result = $platform->invoke('gemini-2.5-flash-image', $messages);
|
||||
$result->asFile('/path/to/output.png'); // Saves the binary content to a file
|
||||
|
||||
The method throws a :class:`Symfony\\AI\\Platform\\Exception\\RuntimeException` if the
|
||||
target directory does not exist or is not writable.
|
||||
|
||||
Raw Results
|
||||
~~~~~~~~~~~
|
||||
|
||||
@@ -26,6 +26,6 @@ $messages = new MessageBag(
|
||||
);
|
||||
$result = $platform->invoke('gemini-2.5-flash-image', $messages);
|
||||
|
||||
file_put_contents(__DIR__.'/result.png', $result->asBinary());
|
||||
$result->asFile(__DIR__.'/result.png');
|
||||
|
||||
echo 'Result image saved to result.png'.\PHP_EOL;
|
||||
|
||||
@@ -4,6 +4,7 @@ CHANGELOG
|
||||
0.7
|
||||
---
|
||||
|
||||
* Add `asFile()` method to `BinaryResult` and `DeferredResult` for saving binary content to a file
|
||||
* Add reranking support via `RerankingResult`, `RerankingEntry`, and `Capability::RERANKING`
|
||||
* Add `description` and `example` properties to `#[With]` attribute
|
||||
|
||||
|
||||
19
src/platform/src/Exception/IOException.php
Normal file
19
src/platform/src/Exception/IOException.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\AI\Platform\Exception;
|
||||
|
||||
/**
|
||||
* @author Christopher Hertel <mail@christopher-hertel.de>
|
||||
*/
|
||||
class IOException extends RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\AI\Platform\Result;
|
||||
|
||||
use Symfony\AI\Platform\Exception\IOException;
|
||||
use Symfony\AI\Platform\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
@@ -50,6 +51,23 @@ final class BinaryResult extends BaseResult
|
||||
return base64_encode($this->data);
|
||||
}
|
||||
|
||||
public function asFile(string $path): void
|
||||
{
|
||||
$directory = \dirname($path);
|
||||
|
||||
if (!is_dir($directory)) {
|
||||
throw new IOException(\sprintf('The directory "%s" does not exist.', $directory));
|
||||
}
|
||||
|
||||
if (!is_writable($directory)) {
|
||||
throw new IOException(\sprintf('The directory "%s" is not writable.', $directory));
|
||||
}
|
||||
|
||||
if (false === file_put_contents($path, $this->data)) {
|
||||
throw new IOException(\sprintf('Failed to write file to "%s".', $path));
|
||||
}
|
||||
}
|
||||
|
||||
public function toDataUri(?string $mimeType = null): string
|
||||
{
|
||||
if (null === ($mimeType ?? $this->mimeType)) {
|
||||
|
||||
@@ -109,6 +109,18 @@ final class DeferredResult
|
||||
return $this->as(BinaryResult::class)->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ExceptionInterface
|
||||
*/
|
||||
public function asFile(string $path): void
|
||||
{
|
||||
$result = $this->as(BinaryResult::class);
|
||||
|
||||
\assert($result instanceof BinaryResult);
|
||||
|
||||
$result->asFile($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ExceptionInterface
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace Symfony\AI\Platform\Tests\Result;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\AI\Platform\Exception\IOException;
|
||||
use Symfony\AI\Platform\Result\BinaryResult;
|
||||
|
||||
final class BinaryResultTest extends TestCase
|
||||
@@ -67,4 +68,32 @@ final class BinaryResultTest extends TestCase
|
||||
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
public function testAsFile()
|
||||
{
|
||||
$data = 'binary file content';
|
||||
$result = new BinaryResult($data, 'image/png');
|
||||
$path = sys_get_temp_dir().'/symfony_ai_test_'.uniqid().'.png';
|
||||
|
||||
try {
|
||||
$result->asFile($path);
|
||||
|
||||
$this->assertFileExists($path);
|
||||
$this->assertSame($data, file_get_contents($path));
|
||||
} finally {
|
||||
if (file_exists($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testAsFileThrowsExceptionWhenDirectoryDoesNotExist()
|
||||
{
|
||||
$result = new BinaryResult('binary data');
|
||||
|
||||
$this->expectException(IOException::class);
|
||||
$this->expectExceptionMessage('The directory "/non/existent/directory" does not exist.');
|
||||
|
||||
$result->asFile('/non/existent/directory/file.png');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user