> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datasnap.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload de Arquivos

> Faça upload de arquivos JSONL usando URL pré-assinada obtida através do endpoint de geração de token.

## Visão Geral

Este processo permite fazer upload de arquivos JSONL utilizando **URLs pré-assinadas** obtidas através do endpoint de geração de token. O upload é feito diretamente para o Oracle Cloud Storage via método HTTP PUT.

<CardGroup cols={2}>
  <Card title="Método" icon="upload">
    Upload via HTTP PUT para URL pré-assinada
  </Card>

  <Card title="Performance" icon="bolt">
    Upload direto para Oracle Cloud Storage
  </Card>

  <Card title="Segurança" icon="shield">
    URLs temporárias com expiração automática
  </Card>

  <Card title="Escalabilidade" icon="arrows-up-down">
    Suporte a arquivos de qualquer tamanho
  </Card>
</CardGroup>

## Processo de Upload

<Steps>
  <Step title="Gerar Token de Upload">
    Use o endpoint `POST /api/v1/schemas/{slug}/generate-upload-token` para obter uma URL pré-assinada
  </Step>

  <Step title="Fazer Upload Direto">
    Use a URL retornada com método PUT para fazer upload direto do arquivo
  </Step>

  <Step title="Processamento Assíncrono">
    O arquivo é processado em segundo plano e fica disponível para consulta
  </Step>
</Steps>

## Método HTTP

<ParamField method="PUT" type="string" required>
  Método HTTP utilizado para upload
</ParamField>

## Parâmetros da URL

<ParamField path="pre_SIGNED_url" type="string" required>
  URL pré-assinada obtida do endpoint de geração de token
</ParamField>

<ParamField path="file_name" type="string" required>
  Nome do arquivo JSONL a ser enviado (deve incluir extensão .jsonl)
</ParamField>

## Exemplo de URL

```
PUT https://objectstorage.sa-saopaulo-1.oraclecloud.com/p/.../dados.jsonl
```

## Corpo da Requisição

<ParamField body="file" type="binary" required>
  Conteúdo binário do arquivo JSONL a ser enviado
</ParamField>

## Como Funciona

O upload de arquivos utiliza um sistema de **URLs pré-assinadas** que oferece:

<CardGroup cols={2}>
  <Card title="Performance" icon="bolt">
    Upload direto para Oracle Cloud Storage
  </Card>

  <Card title="Segurança" icon="shield">
    URLs temporárias com expiração automática
  </Card>

  <Card title="Escalabilidade" icon="arrows-up-down">
    Suporte a arquivos de qualquer tamanho (recomendamos arquivos de até 10MB para máxima performance)
  </Card>

  <Card title="Eficiência" icon="chart-line">
    Processamento assíncrono em segundo plano
  </Card>
</CardGroup>

## Fluxo de Upload

<Steps>
  <Step title="1. Gerar Token">
    Primeiro, gere um token de upload:

    ```bash theme={null}
    curl -X POST \
      "https://api.datasnap.cloud/api/v1/schemas/meu-schema/generate-upload-token" \
      -H "Authorization: Bearer SEU_TOKEN_AQUI" \
      -H "Content-Type: application/json" \
      -d '{"minutes": 15}'
    ```
  </Step>

  <Step title="2. Extrair URL">
    Da resposta, extraia a `upload_url`:

    ```bash theme={null}
    UPLOAD_URL=$(echo $TOKEN_RESPONSE | jq -r '.upload_url')
    ```
  </Step>

  <Step title="3. Fazer Upload">
    Use a URL para upload via PUT:

    ```bash theme={null}
    curl -X PUT \
      "${UPLOAD_URL}/dados.jsonl" \
      -H "Content-Type: application/octet-stream" \
      --data-binary "@dados.jsonl"
    ```
  </Step>
</Steps>

## Requisitos de Formato de Arquivo

<Warning>
  Os arquivos devem estar no formato JSONL (JSON Lines) onde cada linha contém um objeto JSON válido.
</Warning>

### Exemplo JSONL Válido

```text theme={null}
{"data_evento": "2024-10-01", "nome": "João Silva", "idade": 30, "cidade": "São Paulo"}
{"data_evento": "2024-10-02", "nome": "Maria Santos", "idade": 25, "cidade": "Rio de Janeiro"}
{"data_evento": "2024-10-03", "nome": "Carlos Oliveira", "idade": 35, "cidade": "Belo Horizonte"}
```

### Exemplos Inválidos

```text theme={null}
// Inválido - JSON incorreto
{nome: "João", idade: 30}

// Inválido - múltiplos objetos em uma linha
{"nome": "João"} {"idade": 30}

// Inválido - formato array em vez de linha por linha
[{"nome": "João"}, {"nome": "Maria"}]
```

## Exemplos de Implementação

<CodeGroup>
  ```bash cURL (Upload com URL Pré-assinada) theme={null}
  # 1. Criar arquivo JSONL de exemplo
  echo '{"data_evento": "2024-10-01", "produto": "Notebook", "preco": 2500.00, "categoria": "Eletrônicos"}
  {"data_evento": "2024-10-02", "produto": "Mouse", "preco": 50.00, "categoria": "Periféricos"}
  {"data_evento": "2024-10-03", "produto": "Teclado", "preco": 120.00, "categoria": "Periféricos"}' > produtos.jsonl

  # 2. Gerar token de upload (válido por 15 minutos)
  TOKEN_RESPONSE=$(curl -X POST \
    "https://api.datasnap.cloud/api/v1/schemas/meu-schema/generate-upload-token" \
    -H "Authorization: Bearer SEU_TOKEN_AQUI" \
    -H "Content-Type: application/json" \
    -d '{"minutes": 15}')

  echo "Token gerado:"
  echo $TOKEN_RESPONSE | jq '.'

  # 3. Extrair URL de upload
  UPLOAD_URL=$(echo $TOKEN_RESPONSE | jq -r '.upload_url')

  # 4. Fazer upload direto via PUT
  echo "Fazendo upload..."
  curl -X PUT \
    "${UPLOAD_URL}/produtos.jsonl" \
    -H "Content-Type: application/octet-stream" \
    --data-binary "@produtos.jsonl"

  echo "Upload concluído!"
  ```

  ```javascript JavaScript (Upload com URL Pré-assinada) theme={null}
  async function uploadFileWithPresignedUrl(file, schemaSlug, authToken) {
    try {
      // 1. Gerar token de upload
      const tokenResponse = await fetch(
        `https://api.datasnap.cloud/api/v1/schemas/${schemaSlug}/generate-upload-token`,
        {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${authToken}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ minutes: 15 })
        }
      );

      if (!tokenResponse.ok) {
        throw new Error(`Erro ao gerar token: ${tokenResponse.status}`);
      }

      const tokenData = await tokenResponse.json();
      console.log('Token gerado:', tokenData);

      // 2. Fazer upload direto via PUT
      const uploadResponse = await fetch(
        `${tokenData.upload_url}/${file.name}`,
        {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/octet-stream'
          },
          body: file
        }
      );

      if (uploadResponse.ok) {
        console.log('✅ Upload realizado com sucesso!');
        return { success: true, fileName: file.name };
      } else {
        throw new Error(`Erro no upload: ${uploadResponse.status}`);
      }

    } catch (error) {
      console.error('❌ Erro no processo:', error.message);
      return { success: false, error: error.message };
    }
  }

  // Uso
  const fileInput = document.getElementById('fileInput');
  const file = fileInput.files[0];

  if (file) {
    uploadFileWithPresignedUrl(file, 'meu-schema', 'SEU_TOKEN_AQUI');
  }
  ```

  ```python Python (Upload com URL Pré-assinada) theme={null}
  import requests
  import json

  def upload_file_with_presigned_url(file_path, schema_slug, auth_token, minutes=15):
      """
      Faz upload de arquivo usando URL pré-assinada

      Args:
          file_path: Caminho para o arquivo JSONL
          schema_slug: Slug do schema
          auth_token: Token de autenticação
          minutes: Minutos para expiração do token

      Returns:
          bool: True se upload foi bem-sucedido
      """

      # 1. Gerar token de upload
      token_url = f"https://api.datasnap.cloud/api/v1/schemas/{schema_slug}/generate-upload-token"

      token_response = requests.post(
          token_url,
          headers={
              "Authorization": f"Bearer {auth_token}",
              "Content-Type": "application/json"
          },
          json={"minutes": minutes}
      )

      if token_response.status_code != 200:
          print(f"❌ Erro ao gerar token: {token_response.status_code}")
          return False

      token_data = token_response.json()
      upload_url = token_data["upload_url"]
      print(f"✅ Token gerado! Válido até: {token_data['expires_at']}")

      # 2. Fazer upload direto via PUT
      file_name = file_path.split('/')[-1]  # Extrair nome do arquivo

      with open(file_path, 'rb') as arquivo:
          upload_response = requests.put(
              f"{upload_url}/{file_name}",
              headers={"Content-Type": "application/octet-stream"},
              data=arquivo
          )

      if upload_response.status_code == 200:
          print("✅ Upload realizado com sucesso!")
          return True
      else:
          print(f"❌ Erro no upload: {upload_response.status_code}")
          return False

  # Uso
  success = upload_file_with_presigned_url(
      file_path="dados.jsonl",
      schema_slug="meu-schema",
      auth_token="SEU_TOKEN_AQUI"
  )
  ```
</CodeGroup>

## Resposta do Upload

O upload via PUT retorna diretamente o status HTTP:

<ResponseField name="200" type="Success">
  Upload realizado com sucesso - arquivo enviado para Oracle Cloud Storage
</ResponseField>

<ResponseField name="401" type="Error">
  Não autorizado - URL de upload expirada ou inválida
</ResponseField>

<ResponseField name="413" type="Error">
  Arquivo muito grande - tamanho excede limite do storage
</ResponseField>

<RequestExample>
  ```bash cURL (Fluxo Completo com Token) theme={null}
  # 1. Criar arquivo JSONL de exemplo
  echo '{"data_evento": "2024-10-01", "produto": "Notebook", "preco": 2500.00, "categoria": "Eletrônicos"}
  {"data_evento": "2024-10-02", "produto": "Mouse", "preco": 50.00, "categoria": "Periféricos"}
  {"data_evento": "2024-10-03", "produto": "Teclado", "preco": 120.00, "categoria": "Periféricos"}' > produtos.jsonl

  # 2. Gerar token de upload (válido por 15 minutos)
  TOKEN_RESPONSE=$(curl -X POST \
    "https://api.datasnap.cloud/api/v1/schemas/meu-schema/generate-upload-token" \
    -H "Authorization: Bearer SEU_TOKEN_AQUI" \
    -H "Content-Type: application/json" \
    -d '{"minutes": 15}')

  echo "Token gerado:"
  echo $TOKEN_RESPONSE | jq '.'

  # 3. Extrair URL de upload
  UPLOAD_URL=$(echo $TOKEN_RESPONSE | jq -r '.upload_url')

  # 4. Fazer upload direto para Oracle Cloud Storage
  echo "Fazendo upload..."
  curl -X PUT \
    "${UPLOAD_URL}/produtos.jsonl" \
    -H "Content-Type: application/octet-stream" \
    --data-binary "@produtos.jsonl"

  echo "Upload concluído!"
  ```

  ```javascript JavaScript (Fluxo Completo com Token) theme={null}
  async function uploadWithToken(file, schemaSlug, authToken) {
    try {
      // 1. Gerar token de upload
      const tokenResponse = await fetch(
        `https://api.datasnap.cloud/api/v1/schemas/${schemaSlug}/generate-upload-token`,
        {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${authToken}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ minutes: 15 })
        }
      );

      const tokenData = await tokenResponse.json();
      console.log('Token gerado:', tokenData);

      // 2. Fazer upload direto
      const uploadResponse = await fetch(
        `${tokenData.upload_url}/${file.name}`,
        {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/octet-stream'
          },
          body: file
        }
      );

      if (uploadResponse.ok) {
        console.log('✅ Upload realizado com sucesso!');
        return { success: true, fileName: file.name };
      } else {
        console.error('❌ Erro no upload:', uploadResponse.status);
        return { success: false, error: uploadResponse.status };
      }
    } catch (error) {
      console.error('Erro no processo:', error);
      return { success: false, error: error.message };
    }
  }

  // Uso
  const fileInput = document.getElementById('fileInput');
  const file = fileInput.files[0];

  uploadWithToken(file, 'meu-schema', 'SEU_TOKEN_AQUI');
  ```

  ```python Python (Fluxo Completo com Token) theme={null}
  import requests
  import json

  def upload_with_token(file_path, schema_slug, auth_token):
      """
      Faz upload de arquivo usando token pré-assinado
      """

      # 1. Gerar token de upload
      token_url = f"https://api.datasnap.cloud/api/v1/schemas/{schema_slug}/generate-upload-token"

      token_response = requests.post(
          token_url,
          headers={
              "Authorization": f"Bearer {auth_token}",
              "Content-Type": "application/json"
          },
          json={"minutes": 15}
      )

      if token_response.status_code != 200:
          print(f"Erro ao gerar token: {token_response.status_code}")
          return False

      token_data = token_response.json()
      upload_url = token_data["upload_url"]
      print(f"Token gerado! Válido até: {token_data['expires_at']}")

      # 2. Fazer upload direto
      file_name = file_path.split('/')[-1]  # Extrair nome do arquivo

      with open(file_path, 'rb') as arquivo:
          upload_response = requests.put(
              f"{upload_url}/{file_name}",
              headers={"Content-Type": "application/octet-stream"},
              data=arquivo
          )

      if upload_response.status_code == 200:
          print("✅ Upload realizado com sucesso!")
          return True
      else:
          print(f"❌ Erro no upload: {upload_response.status_code}")
          return False

  # Uso
  success = upload_with_token(
      file_path="dados.jsonl",
      schema_slug="meu-schema",
      auth_token="SEU_TOKEN_AQUI"
  )
  ```
</RequestExample>

<ResponseExample>
  ```json Resposta de Sucesso (Resultados Mistos) theme={null}
  {
    "uploaded": [
      {
        "id": 456,
        "file_name": "dados.jsonl",
        "size_bytes": 1048576,
        "md5": "d41d8cd98f00b204e9800998ecf8427e",
        "schema_slug": "meu-schema",
        "schema_version": "1.0.0",
        "validation": "ok",
        "errors": [],
        "upload_status": "pending"
      },
      {
        "file_name": "invalido.jsonl",
        "size_bytes": 2048,
        "md5": "098f6bcd4621d373cade4e832627b4f6",
        "schema_slug": "meu-schema",
        "schema_version": "1.0.0",
        "validation": "error",
        "errors": [
          "A linha 5 do arquivo não é um JSON válido. O arquivo deve estar no formato JSONL (um objeto JSON por linha)."
        ]
      },
      {
        "id": 123,
        "file_name": "duplicado.jsonl",
        "size_bytes": 5120,
        "md5": "5d41402abc4b2a76b9719d911017c592",
        "schema_slug": "meu-schema",
        "schema_version": "1.0.0",
        "validation": "ok",
        "errors": ["Arquivo já foi enviado anteriormente."],
        "duplicate": true,
        "upload_status": "completed"
      }
    ],
    "success": true
  }
  ```

  ```json Erro de Validação (422) theme={null}
  {
    "errors": {
      "files": ["É necessário enviar pelo menos um arquivo."]
    }
  }
  ```

  ```json Arquivo Muito Grande (422) theme={null}
  {
    "errors": {
      "files.0": ["O tamanho máximo permitido para cada arquivo é 100MB."]
    }
  }
  ```

  ```json Schema Não Encontrado (404) theme={null}
  {
    "errors": {
      "schema": ["O esquema solicitado não foi encontrado."]
    }
  }
  ```

  ```json Não Autorizado (401) theme={null}
  {
    "error": "Não autenticado."
  }
  ```
</ResponseExample>

## Códigos de Resposta

| Código | Significado          | Descrição                          |
| ------ | -------------------- | ---------------------------------- |
| `200`  | Sucesso              | Upload realizado com sucesso       |
| `401`  | Não autorizado       | URL de upload expirada ou inválida |
| `413`  | Arquivo muito grande | Tamanho excede limite do storage   |
| `422`  | Formato inválido     | Arquivo não está no formato JSONL  |

## Boas Práticas

<Tip>
  **Valide arquivos localmente** - Teste o formato JSONL antes do upload para evitar erros.
</Tip>

<Tip>
  **Use nomes únicos** - Evite conflitos dando nomes descritivos e únicos aos arquivos.
</Tip>

<Tip>
  **Monitore expiração** - URLs pré-assinadas expiram em 1-60 minutos. Complete o upload dentro do prazo.
</Tip>

<Warning>
  **URLs são temporárias** - Certifique-se de que o upload seja concluído antes da expiração da URL.
</Warning>

## Limites Técnicos

| Característica         | Valor/Limite       | Descrição                              |
| ---------------------- | ------------------ | -------------------------------------- |
| **Tamanho de arquivo** | Sem limite prático | Suporte a arquivos de qualquer tamanho |
| **Duração do token**   | 1-60 minutos       | Tempo de validade da URL pré-assinada  |
| **Método HTTP**        | PUT obrigatório    | Use apenas PUT para upload             |
| **Formato**            | JSONL obrigatório  | Um objeto JSON por linha               |

<Tip>
  **Para máxima performance**, recomendamos dividir arquivos muito grandes (>10MB) em múltiplos uploads menores.
</Tip>

## Próximos Passos

Após o upload bem-sucedido:

1. **✅ Upload concluído** - Arquivo enviado para Oracle Cloud Storage
2. **🔄 Processamento em background** - Dados sendo preparados para consulta
3. **📊 Consulta disponível** - Use endpoint de consultas para analisar dados
4. **📁 Monitoramento** - Liste arquivos para verificar status de processamento

## Endpoints Relacionados

* **[Geração de Token de Upload](/generate-upload-token-endpoint)** - Gerar URLs pré-assinadas
* **[Executar Consultas](/api-reference/endpoint/schema-query-endpoint)** - Consultar dados enviados
* **[Listar Arquivos](/api-reference/endpoint/schema-files-endpoint)** - Gerenciar arquivos enviados
