Enviar arquivos para um Armazenamento Vetorial
Carregar o conteúdo do arquivo para o Vector Store com operações em lote
Last updated
Carregar o conteúdo do arquivo para o Vector Store com operações em lote
Last updated
curl -X POST \
https://api.rememberizer.ai/api/v1/vector-stores/vs_abc123/documents/upload \
-H "x-api-key: SUA_CHAVE_API" \
-F "files=@/caminho/para/documento1.pdf" \
-F "files=@/caminho/para/documento2.docx"
Substitua SUA_CHAVE_API
pela sua chave API real do Vector Store, vs_abc123
pelo seu ID do Vector Store e forneça os caminhos para seus arquivos locais.
const uploadFiles = async (vectorStoreId, files) => {
const formData = new FormData();
// Adicione múltiplos arquivos aos dados do formulário
for (const file of files) {
formData.append('files', file);
}
const response = await fetch(`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`, {
method: 'POST',
headers: {
'x-api-key': 'SUA_CHAVE_API'
// Nota: Não defina o cabeçalho Content-Type, ele será definido automaticamente com o limite correto
},
body: formData
});
const data = await response.json();
console.log(data);
};
// Exemplo de uso com elemento de entrada de arquivo
const fileInput = document.getElementById('fileInput');
uploadFiles('vs_abc123', fileInput.files);
Substitua SUA_CHAVE_API
pela sua chave API real do Vector Store e vs_abc123
pelo seu ID do Vector Store.
import requests
def upload_files(vector_store_id, file_paths):
headers = {
"x-api-key": "SUA_CHAVE_API"
}
files = [('files', (file_path.split('/')[-1], open(file_path, 'rb'))) for file_path in file_paths]
response = requests.post(
f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
headers=headers,
files=files
)
data = response.json()
print(data)
upload_files('vs_abc123', ['/caminho/para/documento1.pdf', '/caminho/para/documento2.docx'])
Substitua SUA_CHAVE_API
pela sua chave API real do Vector Store, vs_abc123
pelo seu ID do Vector Store e forneça os caminhos para seus arquivos locais.
require 'net/http'
require 'uri'
require 'json'
def upload_files(vector_store_id, file_paths)
uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/upload")
# Crie um novo objeto HTTP
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
# Crie uma requisição multipart-form
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = 'SUA_CHAVE_API'
# Crie um limite multipart
boundary = "RubyFormBoundary#{rand(1000000)}"
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
# Construa o corpo da requisição
body = []
file_paths.each do |file_path|
file_name = File.basename(file_path)
file_content = File.read(file_path, mode: 'rb')
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
body << "Content-Type: #{get_content_type(file_name)}\r\n\r\n"
body << file_content
body << "\r\n"
end
body << "--#{boundary}--\r\n"
request.body = body.join
# Envie a requisição
response = http.request(request)
# Analise e retorne a resposta
JSON.parse(response.body)
end
def get_content_type(filename) ext = File.extname(filename).downcase case ext when '.pdf' then 'application/pdf' when '.doc' then 'application/msword' when '.docx' then 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' when '.txt' then 'text/plain' when '.md' then 'text/markdown' when '.json' then 'application/json' else 'application/octet-stream' end end
result = upload_files('vs_abc123', ['/caminho/para/documento1.pdf', '/caminho/para/documento2.docx']) puts result
<div data-gb-custom-block data-tag="hint" data-style='info'>
Substitua `YOUR_API_KEY` pela sua chave de API do Vector Store, `vs_abc123` pelo seu ID do Vector Store e forneça os caminhos para seus arquivos locais.
</div>
</div>
</div>
## Parâmetros de Caminho
| Parâmetro | Tipo | Descrição |
|-------------------|--------|---------------------------------------------------------------------------|
| vector-store-id | string | **Obrigatório.** O ID do armazenamento de vetores para o qual os arquivos serão enviados. |
## Corpo da Requisição
Este endpoint aceita uma requisição `multipart/form-data` com um ou mais arquivos no campo `files`.
## Formato de Resposta
```json
{
"documents": [
{
"id": 1234,
"name": "document1.pdf",
"type": "application/pdf",
"size": 250000,
"status": "processing",
"created": "2023-06-15T10:15:00Z",
"vector_store": "vs_abc123"
},
{
"id": 1235,
"name": "document2.docx",
"type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"size": 180000,
"status": "processing",
"created": "2023-06-15T10:15:00Z",
"vector_store": "vs_abc123"
}
],
"errors": []
}
Se alguns arquivos falharem ao serem enviados, eles serão listados no array errors
:
{
"documents": [
{
"id": 1234,
"name": "document1.pdf",
"type": "application/pdf",
"size": 250000,
"status": "processing",
"created": "2023-06-15T10:15:00Z",
"vector_store": "vs_abc123"
}
],
"errors": [
{
"file": "document2.docx",
"error": "Formato de arquivo não suportado"
}
]
}
Este endpoint requer autenticação usando uma chave de API no cabeçalho x-api-key
.
PDF (.pdf
)
Microsoft Word (.doc
, .docx
)
Microsoft Excel (.xls
, .xlsx
)
Microsoft PowerPoint (.ppt
, .pptx
)
Arquivos de texto (.txt
)
Markdown (.md
)
JSON (.json
)
HTML (.html
, .htm
)
Limite de tamanho de arquivo individual: 50MB
Limite de tamanho total da solicitação: 100MB
Número máximo de arquivos por solicitação: 20
400
Solicitação Inválida - Nenhum arquivo fornecido ou formato de solicitação inválido
401
Não Autorizado - Chave de API inválida ou ausente
404
Não Encontrado - Armazenamento Vetorial não encontrado
413
Payload Muito Grande - Arquivos excedem o limite de tamanho
415
Tipo de Mídia Não Suportado - Formato de arquivo não suportado
500
Erro Interno do Servidor
207
Multi-Status - Alguns arquivos foram enviados com sucesso, mas outros falharam
done
: O documento foi processado com sucesso
error
: Ocorreu um erro durante o processamento
processing
: O documento ainda está sendo processado
O tempo de processamento depende do tamanho e da complexidade do arquivo. O tempo de processamento típico varia de 30 segundos a 5 minutos por documento.
Para fazer o upload eficiente de vários arquivos para o seu Vector Store, o Rememberizer suporta operações em lote. Essa abordagem ajuda a otimizar o desempenho ao lidar com um grande número de documentos.
import os
import requests
import time
import concurrent.futures
from pathlib import Path
def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size=5, file_types=None):
"""
Carregar todos os arquivos de um diretório para um Armazenamento Vetorial em lotes
Args:
vector_store_id: ID do armazenamento vetorial
folder_path: Caminho para a pasta contendo os arquivos a serem carregados
batch_size: Número de arquivos a serem carregados em cada lote
file_types: Lista opcional de extensões de arquivo para filtrar (por exemplo, ['.pdf', '.docx'])
Returns:
Lista de resultados de upload
"""
api_key = "YOUR_API_KEY"
headers = {"x-api-key": api_key}
# Obter lista de arquivos no diretório
files = []
for entry in os.scandir(folder_path):
if entry.is_file():
file_path = Path(entry.path)
# Filtrar por extensão de arquivo se especificado
if file_types is None or file_path.suffix.lower() in file_types:
files.append(file_path)
print(f"Encontrados {len(files)} arquivos para carregar")
results = []
# Processar arquivos em lotes
for i in range(0, len(files), batch_size):
batch = files[i:i+batch_size]
print(f"Processando lote {i//batch_size + 1}/{(len(files) + batch_size - 1)//batch_size}: {len(batch)} arquivos")
# Carregar lote
upload_files = []
for file_path in batch:
upload_files.append(('files', (file_path.name, open(file_path, 'rb'))))
try:
response = requests.post(
f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
headers=headers,
files=upload_files
)
# Fechar todos os manipuladores de arquivo
for _, (_, file_obj) in upload_files:
file_obj.close()
if response.status_code in (200, 201, 207):
batch_result = response.json()
results.append(batch_result)
print(f"Lote carregado com sucesso - {len(batch_result.get('documents', []))} documentos processados")
# Verificar erros
if batch_result.get('errors') and len(batch_result['errors']) > 0:
print(f"Erros encontrados: {len(batch_result['errors'])}")
for error in batch_result['errors']:
print(f"- {error['file']}: {error['error']}")
else:
print(f"Falha no upload do lote com código de status {response.status_code}: {response.text}")
results.append({"error": f"Falha no lote: {response.text}"})
except Exception as e:
print(f"Exceção durante o upload em lote: {str(e)}")
results.append({"error": str(e)})
# Fechar quaisquer manipuladores de arquivo restantes em caso de exceção
for _, (_, file_obj) in upload_files:
try:
file_obj.close()
except:
pass
# Limitação de taxa - pausa entre lotes
if i + batch_size < len(files):
print("Pausando antes do próximo lote...")
time.sleep(2)
return results
# Exemplo de uso
results = batch_upload_to_vector_store(
'vs_abc123',
'/caminho/para/a/pasta/documentos',
batch_size=5,
file_types=['.pdf', '.docx', '.txt']
)
/**
* Fazer upload de arquivos para um Vector Store em lotes
*
* @param {string} vectorStoreId - ID do Vector Store
* @param {FileList|File[]} files - Arquivos a serem enviados
* @param {Object} options - Opções de configuração
* @returns {Promise<Array>} - Lista de resultados do upload
*/
async function batchUploadToVectorStore(vectorStoreId, files, options = {}) {
const {
batchSize = 5,
delayBetweenBatches = 2000,
onProgress = null
} = options;
const apiKey = 'YOUR_API_KEY';
const results = [];
const fileList = Array.from(files);
const totalBatches = Math.ceil(fileList.length / batchSize);
console.log(`Preparando para enviar ${fileList.length} arquivos em ${totalBatches} lotes`);
// Processar arquivos em lotes
for (let i = 0; i < fileList.length; i += batchSize) {
const batch = fileList.slice(i, i + batchSize);
const batchNumber = Math.floor(i / batchSize) + 1;
console.log(`Processando lote ${batchNumber}/${totalBatches}: ${batch.length} arquivos`);
if (onProgress) {
onProgress({
currentBatch: batchNumber,
totalBatches: totalBatches,
filesInBatch: batch.length,
totalFiles: fileList.length,
completedFiles: i
});
}
// Criar FormData para este lote
const formData = new FormData();
batch.forEach(file => {
formData.append('files', file);
});
try {
const response = await fetch(
`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`,
{
method: 'POST',
headers: {
'x-api-key': apiKey
},
body: formData
}
);
if (response.ok) {
const batchResult = await response.json();
results.push(batchResult);
console.log(`Lote enviado com sucesso - ${batchResult.documents?.length || 0} documentos processados`);
// Verificar erros
if (batchResult.errors && batchResult.errors.length > 0) {
console.warn(`Erros encontrados: ${batchResult.errors.length}`);
batchResult.errors.forEach(error => {
console.warn(`- ${error.file}: ${error.error}`);
});
}
} else {
console.error(`Falha no upload do lote com status ${response.status}: ${await response.text()}`);
results.push({ error: `Lote falhou com status: ${response.status}` });
}
} catch (error) {
console.error(`Exceção durante o upload do lote: ${error.message}`);
results.push({ error: error.message });
}
// Adicionar atraso entre os lotes para evitar limitação de taxa
if (i + batchSize < fileList.length) {
console.log(`Pausando por ${delayBetweenBatches}ms antes do próximo lote...`);
await new Promise(resolve => setTimeout(resolve, delayBetweenBatches));
}
}
console.log(`Upload completo. Processados ${fileList.length} arquivos.`);
return results;
}
// Exemplo de uso com elemento de entrada de arquivo
document.getElementById('upload-button').addEventListener('click', async () => {
const fileInput = document.getElementById('file-input');
const vectorStoreId = 'vs_abc123';
const progressBar = document.getElementById('progress-bar');
try {
const results = await batchUploadToVectorStore(vectorStoreId, fileInput.files, {
batchSize: 5,
onProgress: (progress) => {
// Atualizar UI de progresso
const percentage = Math.round((progress.completedFiles / progress.totalFiles) * 100);
progressBar.style.width = `${percentage}%`;
progressBar.textContent = `${percentage}% (Lote ${progress.currentBatch}/${progress.totalBatches})`;
}
});
console.log('Resultados do upload completo:', results);
} catch (error) {
console.error('Upload falhou:', error);
}
});
require 'net/http'
require 'uri'
require 'json'
require 'mime/types'
# Carregar arquivos em um Armazenamento Vetorial em lotes
#
# @param vector_store_id [String] ID do Armazenamento Vetorial
# @param folder_path [String] Caminho para a pasta contendo arquivos a serem enviados
# @param batch_size [Integer] Número de arquivos a serem enviados em cada lote
# @param file_types [Array<String>] Array opcional de extensões de arquivo para filtrar
# @param delay_between_batches [Float] Segundos a esperar entre os lotes
# @return [Array] Lista de resultados de upload
def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size: 5, file_types: nil, delay_between_batches: 2.0)
api_key = 'YOUR_API_KEY'
results = []
# Obter lista de arquivos no diretório
files = Dir.entries(folder_path)
.select { |f| File.file?(File.join(folder_path, f)) }
.select { |f| file_types.nil? || file_types.include?(File.extname(f).downcase) }
.map { |f| File.join(folder_path, f) }
puts "Encontrados #{files.count} arquivos para upload"
total_batches = (files.count.to_f / batch_size).ceil
# Processar arquivos em lotes
files.each_slice(batch_size).with_index do |batch, batch_index|
puts "Processando lote #{batch_index + 1}/#{total_batches}: #{batch.count} arquivos"
# Preparar a requisição HTTP
uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/upload")
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = api_key
# Criar um limite de formulário multipart
boundary = "RubyBoundary#{rand(1000000)}"
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
# Construir o corpo da requisição
body = []
batch.each do |file_path|
file_name = File.basename(file_path)
mime_type = MIME::Types.type_for(file_path).first&.content_type || 'application/octet-stream'
begin
file_content = File.binread(file_path)
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
body << "Content-Type: #{mime_type}\r\n\r\n"
body << file_content
body << "\r\n"
rescue => e
puts "Erro ao ler o arquivo #{file_path}: #{e.message}"
end
end
body << "--#{boundary}--\r\n"
request.body = body.join
# Enviar a requisição
begin
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.request(request)
if response.code.to_i == 200 || response.code.to_i == 201 || response.code.to_i == 207
batch_result = JSON.parse(response.body)
results << batch_result
puts "Lote enviado com sucesso - #{batch_result['documents']&.count || 0} documentos processados"
# Verificar por erros
if batch_result['errors'] && !batch_result['errors'].empty?
puts "Erros encontrados: #{batch_result['errors'].count}"
batch_result['errors'].each do |error|
puts "- #{error['file']}: #{error['error']}"
end
end
else
puts "Upload do lote falhou com código de status #{response.code}: #{response.body}"
results << { "error" => "Lote falhou: #{response.body}" }
end
rescue => e
puts "Exceção durante o upload do lote: #{e.message}"
results << { "error" => e.message }
end
# Limitação de taxa - pausa entre lotes
if batch_index < total_batches - 1
puts "Pausando por #{delay_between_batches} segundos antes do próximo lote..."
sleep(delay_between_batches)
end
end
puts "Upload completo. Processados #{files.count} arquivos."
results
end
# Exemplo de uso
results = batch_upload_to_vector_store(
'vs_abc123',
'/caminho/para/a/pasta/documentos',
batch_size: 5,
file_types: ['.pdf', '.docx', '.txt'],
delay_between_batches: 2.0
)
Para otimizar o desempenho e a confiabilidade ao fazer upload de grandes volumes de arquivos:
Gerenciar Tamanho do Lote: Mantenha os tamanhos dos lotes entre 5-10 arquivos para um desempenho ideal. Muitos arquivos em uma única solicitação aumentam o risco de timeouts.
Implementar Limitação de Taxa: Adicione atrasos entre os lotes (2-3 segundos recomendados) para evitar atingir os limites de taxa da API.
Adicionar Lógica de Retentativa de Erros: Para sistemas de produção, implemente lógica de retentativa para uploads falhados com retrocesso exponencial.
Validar Tipos de Arquivo: Pré-filtre os arquivos para garantir que sejam tipos suportados antes de tentar o upload.
Monitorar o Progresso do Lote: Para aplicações voltadas para o usuário, forneça feedback de progresso nas operações de lote.
Lidar com Sucesso Parcial: A API pode retornar um código de status 207 para sucesso parcial. Sempre verifique os status dos documentos individuais.
Limpar Recursos: Certifique-se de que todos os manipuladores de arquivos estejam devidamente fechados, especialmente quando ocorrem erros.
Paralelizar com Sabedoria: Para uploads muito grandes (milhares de arquivos), considere múltiplos processos de lote concorrentes direcionados a diferentes lojas de vetores, e depois combine os resultados mais tarde, se necessário.
Implementar Checksums: Para dados críticos, verifique a integridade do arquivo antes e depois do upload com checksums.
Registrar Resultados Abrangentes: Mantenha logs detalhados de todas as operações de upload para solução de problemas.
Seguindo estas melhores práticas, você pode gerenciar de forma eficiente a ingestão de documentos em grande escala em suas lojas de vetores.
Os arquivos são inicialmente aceitos com um status de processing
. Você pode verificar o status de processamento dos documentos usando o endpoint . O status final será um dos seguintes:
Upload files to a vector store.
The ID of the vector store.
The API key for authentication.
The files to upload.
POST /api/v1/vector-stores/{vector-store-id}/documents/upload HTTP/1.1
Host: api.rememberizer.ai
x-api-key: text
Content-Type: multipart/form-data
Accept: */*
Content-Length: 20
{
"files": [
"binary"
]
}
{
"documents": [
{
"id": 1,
"name": "text"
}
],
"errors": [
{
"file": "text",
"error": "text"
}
]
}