Skip to content

Crie uma API de Geração de Imagens DALL-E com Laravel: Guia Passo a Passo

Neste guia, vamos percorrer o processo de criação de um endpoint de API Laravel que gera imagens DALL-E e as armazena no sistema de arquivos local. Esta funcionalidade pode ser útil para aplicações que requerem imagens geradas por IA sob demanda, como ferramentas de criação de conteúdo ou chatbots.

Introdução

DALL-E é um modelo de IA desenvolvido pela OpenAI que pode criar imagens únicas a partir de descrições textuais. Integrar essa capacidade em uma aplicação Laravel abre possibilidades para conteúdo visual dinâmico e alimentado por IA.

Problema

Muitos desenvolvedores acham desafiador incorporar capacidades de geração de imagens de IA em suas aplicações Laravel. O processo envolve não apenas gerar as imagens, mas também armazená-las eficientemente, fornecer acesso a elas e lidar com possíveis erros. Este artigo visa simplificar esse processo fornecendo um guia abrangente.

Solução

Vamos dividir a solução nas seguintes etapas:

Etapa 1: Configurar a API OpenAI

Antes de começarmos, você precisa obter uma chave de API da API OpenAI. Visite o site da OpenAI, crie uma conta e gere uma chave de API.

Depois de obter sua chave de API, adicione-a à sua configuração de ambiente do Laravel:

OPENAI_API_KEY=sua_chave_api_aqui

Etapa 2: Criar a Classe Auxiliar OpenAIProvider

Crie um novo arquivo chamado app/AI/Providers/OpenAIProvider.php e adicione o seguinte código:

php
<?php

namespace App\AI\Providers;

use App\Exceptions\Errors;
use OpenAI;
use Exception;

class OpenAIProvider
{
    const array MODEL_RETRY_TIMES = [3000, 7000, 10000];

    private static function getApiKey(): string
    {
        return config('openai.api_key');
    }

    private static function getClient(): OpenAI\Client
    {
        return OpenAI::client(self::getApiKey());
    }

    public static function images(
        string $prompt,
        int $n = 1,
        string $model = 'dall-e-3',
        string $quality = 'hd',
        string $size = '1792x1024',
        string $style = 'natural',
        string $response_format = 'url',
        ?string $user = null
    ): ?array {
        $urls = [];
        $parameters = [
            'prompt' => $prompt,
            'model' => $model,
            'n' => $n,
            'quality' => $quality,
            'size' => $size,
            'style' => $style,
            'response_format' => $response_format,
        ];

        if ($user !== null) {
            $parameters['user'] = $user;
        }

        try {
            $response = retry(
                times: self::MODEL_RETRY_TIMES,
                callback: function () use ($parameters) {
                    return self::getClient()->images()->create($parameters);
                },
            );

            foreach ($response->data as $data) {
                $urls[] = $data->url;
            }
        } catch (Exception $e) {
            Errors::captureException($e);
        }

        return $urls;
    }
}

Esta classe lida com a interação com a API OpenAI, incluindo a repetição da solicitação se necessário e capturando quaisquer exceções que ocorram.

Etapa 3: Implementar o Tratamento de Erros

Crie um novo arquivo chamado app/Exceptions/Errors.php e adicione o seguinte código:

php
<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Support\Facades\Log;

use function Sentry\captureException;

class Errors
{
    public static function captureException(Exception $e): void
    {
        captureException($e);

        if (config('app.env') === 'local') {
            Log::error($e);
        }
    }
}

Esta classe captura exceções e as registra usando o rastreamento de erros Sentry, com registro local adicional para ambientes de desenvolvimento.

Etapa 4: Configurar o Controlador

Crie um novo controlador chamado app/Http/Controllers/ChatbotController.php e adicione o seguinte código:

php
<?php

namespace App\Http\Controllers;

use App\AI\Providers\OpenAIProvider;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;

class ChatbotController extends Controller
{
    public function v1Dalle(Request $request): JsonResponse
    {
        $v = $request->validate([
            'prompt' => 'required|string',
        ]);

        $chatbot_api_key = config('integrations.chatbot_api_key');
        $incoming_api_key = $request->headers->get('X-Api-Key');

        if ($chatbot_api_key !== $incoming_api_key) {
            return response()->json([
                'error' => 'Unauthorized',
            ], 401);
        }

        $prompt = $v['prompt'];
        $app_url = config('app.url');
        $public_url = null;

        $images = OpenAIProvider::images(
            prompt: $prompt,
        );

        foreach ($images as $image) {
            $image_contents = Http::get($image)->body();

            $filename = 'dalle3/'.uniqid().'.png';
            $public_filename = 'public/'.$filename;

            Storage::put($public_filename, $image_contents);

            $public_url = $app_url.Storage::url($public_filename);
        }

        return response()->json([
            'url' => $public_url,
        ]);
    }
}

Este controlador lida com a solicitação recebida, valida a chave de API, gera a imagem usando o OpenAIProvider, salva-a no sistema de arquivos local usando o Laravel Storage e retorna a URL pública da imagem salva.

Etapa 5: Configurar a Rota

Adicione a seguinte rota ao seu arquivo routes/api.php:

php
Route::post('/v1/dalle', [ChatbotController::class, 'v1Dalle']);

Etapa 6: Configurar a Chave de API

Adicione o seguinte ao seu arquivo .env:

CHATBOT_API_KEY=sua_chave_api_chatbot_aqui

Em seguida, em config/integrations.php (crie este arquivo se ele não existir), adicione:

php
<?php

return [
    'chatbot_api_key' => env('CHATBOT_API_KEY'),
];

Etapa 7: Atualizar a Configuração Local

Para garantir que as novas variáveis de ambiente sejam carregadas na aplicação, execute o comando php artisan optimize:clear. Isso executará algumas ações, uma delas é garantir que as novas variáveis de ambiente sejam armazenadas em cache.

Etapa 8: Testar o Endpoint

Você pode testar o endpoint usando uma ferramenta como Postman ou curl. Envie uma solicitação POST para /api/v1/dalle com os seguintes cabeçalhos e corpo:

Cabeçalhos:

X-Api-Key: sua_chave_api_chatbot_aqui
Content-Type: application/json

Corpo:

json
{
  "prompt": "Uma paisagem urbana futurista com carros voadores"
}

A resposta deve conter uma URL para a imagem gerada.

Considerações de Segurança

Ao implementar esta API, é crucial seguir as melhores práticas de segurança de API:

  1. Sempre use HTTPS para solicitações de API para proteger chaves de API e outros dados sensíveis.
  2. Armazene chaves de API com segurança em variáveis de ambiente, nunca no controle de versão.
  3. Implemente limitação de taxa no Laravel em seu endpoint para evitar abusos.

Considerações de Desempenho

Para garantir o desempenho ideal da sua API de geração de imagens DALL-E:

  1. Considere implementar cache para imagens frequentemente solicitadas para reduzir chamadas de API e operações de armazenamento.
  2. Use filas do Laravel para tarefas de geração de imagens se você espera alto tráfego para evitar bloquear a thread principal.

Limitações Desta Abordagem

Embora a solução apresentada neste guia forneça uma API funcional de geração de imagens DALL-E, é importante estar ciente de suas limitações:

  1. Chave de API Fixa Única: O exemplo usa uma única variável de ambiente fixa (CHATBOT_API_KEY) para autenticar solicitações. Esta abordagem carece de flexibilidade e pode não ser adequada para sistemas multi-usuário ou aplicações que requerem diferentes níveis de acesso.

  2. Armazenamento de Arquivos Local: As imagens são armazenadas no sistema de arquivos local, o que pode não ser escalável ou adequado para sistemas distribuídos. Em um ambiente de produção, você pode precisar considerar o uso de soluções de armazenamento em nuvem como AWS S3 ou Google Cloud Storage.

  3. Tratamento de Erros: Embora o tratamento básico de erros seja implementado, ele não cobre todos os casos de borda possíveis ou fornece mensagens de erro detalhadas ao cliente.

  4. Parâmetros de Imagem Fixos: Os parâmetros DALL-E (como tamanho e qualidade) são codificados neste exemplo, sinta-se à vontade para adicionar parâmetros adicionais na solicitação conforme necessário.

  5. Validação de Prompt Limitada: O exemplo apenas verifica se o prompt é uma string não vazia, sem moderação de conteúdo ou restrições de comprimento.

  6. Sem Rastreamento de Uso: O exemplo não rastreia o uso da API, o que poderia ser importante para fins de faturamento ou monitoramento.

Conclusão

Seguindo estas etapas, criamos com sucesso um endpoint de API que gera imagens DALL-E e as armazena no sistema de arquivos local usando Laravel.

Este endpoint pode ser facilmente integrado em aplicações Laravel existentes, permitindo a geração e armazenamento sob demanda de imagens de IA.

Lembre-se de lidar com erros graciosamente, implementar medidas de segurança adequadas e considerar otimizações de desempenho à medida que sua aplicação escala.