Atualização Importante Sobre Como Usar Links de Download de Arquivos Gerados

Caros Usuários da Tripo,

Estamos escrevendo para informar sobre uma próxima mudança que pode afetar como vocês acessam e usam os recursos de nossa plataforma.

O Que Está Mudando?

Vamos aplicar a política CORS em todos os URLs de artefatos gerados. Isso significa que todos os recursos hospedados em nossa plataforma exigirão tratamento apropriado para requisições de origem cruzada, ou seja, vocês não poderão servir diretamente arquivos de modelos gerados usando o link que a API da Tripo retorna.

Por Que Isso Está Sendo Implementado?

Esta mudança faz parte de nosso compromisso em melhorar a segurança e prevenir acesso não autorizado a recursos em diferentes origens. CORS (Cross-Origin Resource Sharing) é um mecanismo que permite que servidores especifiquem quais domínios externos podem acessar recursos.
Para mais informações sobre o que é CORS, vocês podem consultar o guia do MDN.

Impacto no Seu Fluxo de Trabalho

Atualmente, não fornecemos cabeçalhos CORS para URLs de artefatos. Como resultado, se vocês estiverem usando ou linkando diretamente para esses recursos em um navegador ou de domínios externos, poderão ter problemas.
Para garantir o acesso contínuo a esses ativos, vocês precisarão tomar uma das seguintes ações:

  1. Baixar e Salvar Artefatos Localmente: Vocês podem baixar os artefatos e armazená-los em seu backend. Uma vez salvos localmente, vocês podem servir esses ativos de seu servidor sem restrições CORS.
  2. Usar um Proxy de Borda (ex: Next.js API Route, Cloudflare Workers): Vocês podem usar um proxy de borda para buscar e servir os artefatos, adicionando os cabeçalhos CORS necessários às respostas. Por exemplo:
    • Next.js API Route: Configure uma rota de API para buscar recursos de nossa plataforma e encaminhá-los com os cabeçalhos CORS apropriados.
    • Cloudflare Workers: Use Cloudflare Workers para adicionar cabeçalhos CORS ao servir nossos ativos de seu servidor.

Como Se Preparar:

  • Revisem sua integração: Certifiquem-se de que seu sistema é capaz de lidar com CORS para URLs de artefatos.
  • Baixem e salvem artefatos: Se não estiverem usando um proxy de borda, considerem baixar e armazenar os artefatos em seu backend.
  • Configurem um proxy de borda: Se estiverem usando soluções como Next.js ou Cloudflare Workers, atualizem sua configuração para garantir que os ativos sejam servidos com os cabeçalhos CORS apropriados.
  • Testem seu sistema: Verifiquem se todas as requisições de origem cruzada para nossa plataforma funcionam como esperado.

Precisam de exemplos de código práticos? Se estiverem inseguros sobre como começar ou acharem o processo difícil de implementar, fornecemos trechos de código práticos para ajudar vocês a iniciar. Por favor, consultem o Apêndice para mais detalhes.

Perguntas Frequentes

  • Meu arquivo gerado foi perdido?

    Não. Vocês sempre podem recuperar um novo URL da API a qualquer momento.

  • Eu não retorno seu URL diretamente, mas faço algum pós-processamento. Devo me preocupar?

    Se vocês não estiverem retornando nosso URL diretamente para seus usuários, podem ignorar esta mudança. No entanto, recomendamos monitorar seu uso, especialmente se notarem quaisquer picos de erro ou comportamento anormal em seu sistema.

Precisa de Assistência?

Entendemos que esta mudança pode exigir atualizações em seu fluxo de trabalho. Se precisarem de ajuda para configurar um proxy de borda ou tiverem alguma dúvida sobre esta transição, entrem em contato com nossa equipe de suporte em support@tripo3d.ai.
Agradecemos sua cooperação enquanto trabalhamos para aprimorar a segurança em nossa plataforma! Mantenham-se seguros e produtivos!
Atenciosamente,
A Equipe Tripo

Apêndice A: Abordagem de ressalvamento no Backend

Se você estiver usando FastAPI (o que é fácil de portar ou traduzir para qualquer outro framework ou linguagem), veja como você pode ajustar seu código existente para lidar com CORS e salvar o artefato localmente:

Código Atual:

@app.post("/")
def generate(prompt: str) -> str:
    resp = ...  # API works
    return resp.json()['url']

Você pode facilmente modificá-lo para:

import httpx
import uuid

from fastapi.responses import FileResponse
from fastapi import HTTPException

@app.post("/")
def generate(prompt: str) -> str:
    resp = ...  # same as above

    # Add the code below
    file_id = str(uuid.uuid4())
    with httpx.Client() as client:
        # Download the artifact
        response = client.get(url)

        # Check if the request was successful
        if response.status_code == 200:
            # Then resave it
            with open(f"./downloaded/{file_id}.glb", "wb") as file:
                file.write(response.content)

    return file_id

@app.get("/artifact/{file_id}")
def download(file_id: str) -> FileResponse:
    if os.path.exists(f"./downloaded/{file_id}.glb"):
      return FileResponse(f"./downloaded/{file_id}.glb")
    raise HTTPException(status_code=404, detail="Item not found")

Após baixar e salvar o arquivo localmente, você deve servir aos seus usuários com o novo URL. Por exemplo, se seu aplicativo estiver hospedado em https://app.example.com, o URL que você deve servir será parecido com este:

https://app.example.com/artifact/<file_id>

Este trecho de código é apenas uma demonstração de como ajustar sua integração. No entanto, há algumas coisas importantes que você deve considerar:

  • Adicionar autenticação adequada: Certifique-se de que os links de download estejam protegidos pelos métodos de autenticação apropriados para evitar acesso não autorizado.
  • Usar armazenamento confiável: É recomendado salvar os arquivos em soluções de armazenamento mais confiáveis, como servidores dedicados ou opções de armazenamento em nuvem como buckets S3.
  • Armazenar metadados: Mantenha um registro dos metadados do artefato em seu banco de dados ou outro sistema de armazenamento para uso futuro (como rastreamento ou auditoria).

Apêndice B: Abordagem de Proxy de Borda

Se você está desenvolvendo um Single Page Application (SPA) ou um servidor Backend for Frontend (BFF) e prefere não lidar com downloads e armazenamento de arquivos diretamente em seu servidor, você pode usar uma abordagem de proxy de borda. Isso permite que você busque o arquivo de nosso servidor, aplique os cabeçalhos CORS necessários e, em seguida, o sirva aos seus usuários.

Solução 1: Baixar e Reenviar o Arquivo Usando Funções de Borda

Abaixo está um exemplo de como implementar esta abordagem usando Cloudflare Workers. Esta solução tratará os problemas de CORS baixando o arquivo e reenviando-o sob seu domínio.

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  // Parse the request URL
  const url = new URL(request.url);

  // Get the target URL from the 'url' query parameter
  const targetUrl = url.searchParams.get('url');

  // If no URL is provided, return an error
  if (!targetUrl) {
    return new Response('Please provide a URL parameter', {
      status: 400,
      headers: {
        'Content-Type': 'text/plain',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'
      }
    });
  }

  // Handle preflight OPTIONS request
  if (request.method === 'OPTIONS') {
    return handleCORS();
  }

  try {
    // Fetch the file from the target URL
    const response = await fetch(targetUrl);

    // If the fetch failed, return the error
    if (!response.ok) {
      return new Response(`Failed to fetch from target URL: ${response.statusText}`, {
        status: response.status,
        headers: corsHeaders()
      });
    }

    // Get the content type from the response or default to octet-stream
    const contentType = response.headers.get('Content-Type') || 'application/octet-stream';

    // Get the content disposition or create one from the URL
    let contentDisposition = response.headers.get('Content-Disposition');
    if (!contentDisposition) {
      // Extract filename from the URL
      const fileName = targetUrl.split('/').pop().split('?')[0] || 'file';
      contentDisposition = `attachment; filename="${fileName}"`;
    }

    // Create a new response with CORS headers
    const newResponse = new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers: {
        'Content-Type': contentType,
        'Content-Disposition': contentDisposition,
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type',
        'Cache-Control': 'public, max-age=3600' // Cache for 1 hour
      }
    });

    return newResponse;
  } catch (error) {
    return new Response(`Error fetching the file: ${error.message}`, {
      status: 500,
      headers: corsHeaders()
    });
  }
}

// Handle CORS preflight requests
function handleCORS() {
  return new Response(null, {
    status: 204, // No content
    headers: corsHeaders()
  });
}

// Create CORS headers object
function corsHeaders() {
  return {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type',
    'Access-Control-Max-Age': '86400' // 24 hours
  };
}

Uma vez que seu Cloudflare Worker esteja configurado, você pode integrá-lo em seu SPA usando o seguinte código JavaScript para buscar o arquivo:

fetch('https://your-worker-url.workers.dev/?url=<target_url>')
  .then(response => response.blob())
  .then(blob => {
    // Create a download link
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'downloaded-file.pdf';
    document.body.appendChild(a);
    a.click();
    a.remove();
  })
  .catch(error => console.error('Error:', error));

Esta solução é perfeita para SPAs ou servidores BFF que precisam contornar restrições CORS ao baixar e servir arquivos para usuários finais. O arquivo é buscado do URL de destino, passado pelo proxy de borda e servido com os cabeçalhos CORS necessários.

Solução 2: Configurar um proxy de cabeçalho CORS

Se você preferir configurar um proxy CORS simples, pode consultar este exemplo fornecido pelo Cloudflare: Cloudflare Workers - CORS Header Proxy
Isso permitirá que você lide com solicitações de origem cruzada mais facilmente, ainda em conformidade com as políticas CORS.

Considerações Importantes:

  • Autenticação: Certifique-se de proteger adequadamente suas funções de borda com métodos de autenticação (por exemplo, chaves de API, OAuth, etc.) para evitar acesso não autorizado aos seus arquivos.
  • Armazenamento: Embora esta abordagem funcione, ainda recomendamos salvar o artefato em seu servidor para uso futuro, especialmente se você precisar gerenciar downloads em larga escala ou garantir acesso confiável aos recursos.

Advancing 3D generation to new heights

moving at the speed of creativity, achieving the depths of imagination.