# Carregar arquivos para um Armazenamento Vetorial

{% openapi src="/files/7wfxJNjaZYJgvBWvXvoQ" path="/vector-stores/{vector-store-id}/documents/upload" method="post" %}
[rememberizer\_openapi.yml](https://606058861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDrEOD8oYxrWDlC9WhJ3K%2Fuploads%2Fgit-blob-77b6137eeb641262ec8e531c78123c02b825b865%2Frememberizer_openapi.yml?alt=media\&token=85552d2b-b485-42dc-a027-aa2441b8ca9f)
{% endopenapi %}

## Exemplo de Requisições

{% tabs %}
{% tab title="cURL" %}

```bash
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"
```

{% hint style="info" %}
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.
{% endhint %}
{% endtab %}

{% tab title="JavaScript" %}

```javascript
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);
```

{% hint style="info" %}
Substitua `SUA_CHAVE_API` pela sua chave API real do Vector Store e `vs_abc123` pelo seu ID do Vector Store.
{% endhint %}
{% endtab %}

{% tab title="Python" %}

```python
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'])
```

{% hint style="info" %}
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.
{% endhint %}
{% endtab %}

{% tab title="Ruby" %}

```ruby
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
```

## Método auxiliar para determinar o tipo de conteúdo

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

## Exemplo de uso

result = upload\_files('vs\_abc123', \['/caminho/para/documento1.pdf', '/caminho/para/documento2.docx']) puts result

````

{% hint 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.
{% endhint %}
{% endtab %}
{% endtabs %}

## 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`:

```json
{
  "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"
    }
  ]
}
```

### Autenticação

Este endpoint requer autenticação usando uma chave de API no cabeçalho `x-api-key`.

### Formatos de Arquivo Suportados

* 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`)

### Limites de Tamanho de Arquivo

* 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

### Respostas de Erro

| Código de Status | Descrição                                                                          |
| ---------------- | ---------------------------------------------------------------------------------- |
| 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     |

### Status de Processamento

Os arquivos são inicialmente aceitos com um status de `processing`. Você pode verificar o status de processamento dos documentos usando o endpoint [Get a List of Documents in a Vector Store](/pt/recursos-para-desenvolvedores/api-docs/vector-store/get-a-list-of-documents-in-a-vector-store.md). O status final será um dos seguintes:

* `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.

### Operações em Lote

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.

#### Implementação de Upload em Lote

{% tabs %} {% tab title="Python" %}

```python
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']
)
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
/**
 * 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);
  }
});
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
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
)
```

{% endtab %}
{% endtabs %}

### Melhores Práticas para Upload em Lote

Para otimizar o desempenho e a confiabilidade ao fazer upload de grandes volumes de arquivos:

1. **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.
2. **Implementar Limitação de Taxa**: Adicione atrasos entre os lotes (2-3 segundos recomendados) para evitar atingir os limites de taxa da API.
3. **Adicionar Lógica de Retentativa de Erros**: Para sistemas de produção, implemente lógica de retentativa para uploads falhados com retrocesso exponencial.
4. **Validar Tipos de Arquivo**: Pré-filtre os arquivos para garantir que sejam tipos suportados antes de tentar o upload.
5. **Monitorar o Progresso do Lote**: Para aplicações voltadas para o usuário, forneça feedback de progresso nas operações de lote.
6. **Lidar com Sucesso Parcial**: A API pode retornar um código de status 207 para sucesso parcial. Sempre verifique os status dos documentos individuais.
7. **Limpar Recursos**: Certifique-se de que todos os manipuladores de arquivos estejam devidamente fechados, especialmente quando ocorrem erros.
8. **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.
9. **Implementar Checksums**: Para dados críticos, verifique a integridade do arquivo antes e depois do upload com checksums.
10. **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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rememberizer.ai/pt/recursos-para-desenvolvedores/api-docs/vector-store/upload-files-to-a-vector-store.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
