Skip to main content

Vision

O módulo Vision fornece um cliente para extrair dados estruturados de documentos (PDFs, imagens, etc.) utilizando layouts configurados na plataforma Tech4.ai. Ele encapsula a chamada HTTP para o serviço de extração e retorna um objeto tipado com os dados extraídos e o status da operação.


📋 Método Principal​

extract(layout_id, file_url=None, file_id=None, timeout=45)​

Realiza a extração de dados de um documento com base em um layout configurado e retorna VisionExtractResponse.

Parâmetros:

  • layout_id (str): Obrigatório. ID do layout Vision que define os campos a serem extraídos
  • file_url (str | None): URL pública do arquivo a ser analisado. Mutuamente exclusivo com file_id
  • file_id (str | None): ID de um arquivo já enviado para a plataforma. Mutuamente exclusivo com file_url
  • timeout (int): Tempo limite da requisição em segundos (padrão: 45, máximo: 45)
Atenção

Exatamente um entre file_url e file_id deve ser fornecido. Passar ambos ou nenhum levanta ValueError.

Retorno (VisionExtractResponse):

  • status (Literal["ok", "partial", "nodata"]): Resultado da extração — "ok" (todos os campos extraídos), "partial" (alguns campos ausentes), "nodata" (nenhum campo pôde ser extraído)
  • extracted_data (dict): Dicionário cujas chaves e tipos de valor dependem do layout configurado

Status de Extração​

O campo status indica a qualidade do resultado retornado pelo serviço de extração.

StatusSignificado
"ok"Todos os campos do layout foram extraídos com sucesso
"partial"Parte dos campos foi extraída; campos ausentes ficam com valor None ou são omitidos
"nodata"Nenhum campo pôde ser extraído do documento (documento ilegível, fora do escopo do layout, etc.)
Boas práticas

Sempre verifique o status antes de usar extracted_data. Com "partial" ou "nodata", trate a ausência de campos antes de prosseguir com a lógica de negócio.


📥 Exemplo de Entrada e Saída​

Entrada​

vision.extract(
layout_id="3f2504e0-4f89-11d3-9a0c-0305e82c3301",
file_url="https://example.com/nota-fiscal.pdf",
)

Saída (exemplo real)​

{
"status": "ok",
"extracted_data": {
"numero_nota": "3524",
"data_emissao": "2024-03-15",
"valor_total": 1250.00,
"cnpj_emitente": "12.345.678/0001-99",
"razao_social": "Empresa Exemplo LTDA"
}
}

Saída com extração parcial​

{
"status": "partial",
"extracted_data": {
"numero_nota": "3524",
"data_emissao": null,
"valor_total": 1250.00,
"cnpj_emitente": null,
"razao_social": "Empresa Exemplo LTDA"
}
}

📝 Exemplo Prático​

Extrair dados de uma nota fiscal a partir de URL​

def extrair_dados_nota_fiscal(file_url: str):
"""
Extrai dados estruturados de uma nota fiscal usando Vision
"""
try:
extract_span = action_span.span("extração vision", {"file_url": file_url})

response = vision.extract(
layout_id=secrets["VISION_LAYOUT_ID"],
file_url=file_url,
)

extract_span.end({"status": response.status})
action_span.event("vision_response", {"status": response.status})

if response.status == "nodata":
return ResponseToUser(
message="Não foi possível extrair informações do documento enviado.",
status=ResponseStatus.SUCCESS,
)

dados = response.extracted_data

if response.status == "partial":
action_span.event("partial_extraction", {"dados": dados})

numero = dados.get("numero_nota", "N/D")
valor = dados.get("valor_total", "N/D")
mensagem = f"Nota fiscal {numero} processada com sucesso. Valor total: R$ {valor}."

return ResponseToUser(message=mensagem, status=ResponseStatus.SUCCESS)

except Exception as e:
action_span.event("error", {"error": str(e)})
return ResponseToUser(
message=(
"Peço desculpas, não foi possível processar o documento no momento. "
"Tente novamente em alguns instantes."
),
status=ResponseStatus.ERROR,
metadata={
"error_type": "vision_extraction_error",
"error_message": str(e),
},
)

Extrair dados usando ID de arquivo já enviado​

def extrair_dados_por_file_id(file_id: str):
"""
Extrai dados de um arquivo já presente na plataforma
"""
response = vision.extract(
layout_id=secrets["VISION_LAYOUT_ID"],
file_id=file_id,
timeout=45,
)

if response.status != "ok":
return ResponseToUser(
message="Extração incompleta ou sem dados.",
status=ResponseStatus.SUCCESS,
)

return ResponseToUser(
message=str(response.extracted_data),
status=ResponseStatus.SUCCESS,
)

💡 Dicas de Uso​

Melhores Práticas
  • Status antes dos dados: verifique sempre response.status antes de acessar extracted_data
  • file_url vs file_id: prefira file_id quando o arquivo já foi enviado via FileManagement para evitar reprocessamento
  • Timeout: o limite máximo é 45 s; documentos longos que excedam esse tempo resultarão em erro
  • Layout ID via secrets: armazene o layout_id como segredo (secrets["VISION_LAYOUT_ID"]) para facilitar troca entre ambientes

📊 Estruturas de Dados​

Classes Principais​

  • VisionExtractResponse: status, extracted_data
    • status (Literal["ok", "partial", "nodata"]): resultado da extração
    • extracted_data (dict): campos extraídos conforme definido no layout

Erros​

  • Exception: levantado em falhas HTTP (4xx/5xx), erros de rede ou respostas malformadas. Capture-o para tratar erros de extração sem derrubar a action.