Integração Básica com a API

Este exemplo mostra como integrar a API em diferentes linguagens de programação para processar consultas veterinárias.

Configuração Inicial

Variáveis de Ambiente

# .env
CONNECTVETS_API_KEY=sua_api_key_aqui
CONNECTVETS_BASE_URL=https://api-sandbox.connectvets.com.br/notes/v1

Implementações por Linguagem

JavaScript/Node.js

const fetch = require('node-fetch');
const FormData = require('form-data');
const fs = require('fs');

class ConnectVetsClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api-sandbox.connectvets.com.br/notes/v1';
  }

  async createNote(audioFilePath, metadata = {}) {
    const formData = new FormData();
    formData.append('audio', fs.createReadStream(audioFilePath));
    formData.append('metadata', JSON.stringify(metadata));

    const response = await fetch(`${this.baseUrl}/notes`, {
      method: 'POST',
      headers: {
        'X-API-KEY': this.apiKey,
        ...formData.getHeaders()
      },
      body: formData
    });

    return await response.json();
  }

  async getNote(noteId) {
    const response = await fetch(`${this.baseUrl}/notes/${noteId}`, {
      headers: {
        'X-API-KEY': this.apiKey,
        'Content-Type': 'application/json'
      }
    });

    return await response.json();
  }

  async waitForCompletion(noteId, maxWaitTime = 300000) {
    const startTime = Date.now();
    
    while (Date.now() - startTime < maxWaitTime) {
      const note = await this.getNote(noteId);
      
      if (note.data.transcription_status === 'completed') {
        return note.data;
      }
      
      if (note.data.transcription_status === 'failed') {
        throw new Error('Processamento falhou');
      }
      
      await new Promise(resolve => setTimeout(resolve, 10000)); // Aguarda 10s
    }
    
    throw new Error('Timeout: Processamento demorou muito');
  }
}

// Exemplo de uso
async function processConsultation() {
  const client = new ConnectVetsClient(process.env.CONNECTVETS_API_KEY);
  
  try {
    // Criar nota
    const result = await client.createNote('./audio_consulta.mp3', {
      patient_name: 'Rex',
      owner_name: 'João Silva',
      veterinarian: 'Dr. Santos'
    });
    
    console.log('Nota criada:', result.data.id);
    
    // Aguardar processamento
    const completedNote = await client.waitForCompletion(result.data.id);
    
    // Exibir resultados
    completedNote.note_sections.forEach(section => {
      console.log(`${section.title}: ${section.content}`);
    });
    
  } catch (error) {
    console.error('Erro:', error.message);
  }
}

processConsultation();

Python

import requests
import time
import os
from typing import Dict, Any, Optional

class ConnectVetsClient:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api-sandbox.connectvets.com.br/notes/v1"
        self.session = requests.Session()
        self.session.headers.update({"X-API-KEY": api_key})
    
    def create_note(self, audio_file_path: str, metadata: Dict[str, Any] = None) -> Dict:
        """Criar uma nova nota com arquivo de áudio"""
        files = {
            'audio': ('audio.mp3', open(audio_file_path, 'rb'), 'audio/mpeg')
        }
        
        data = {
            'metadata': str(metadata or {})
        }
        
        response = self.session.post(
            f"{self.base_url}/notes",
            files=files,
            data=data
        )
        
        response.raise_for_status()
        return response.json()
    
    def get_note(self, note_id: str) -> Dict:
        """Obter detalhes de uma nota"""
        response = self.session.get(f"{self.base_url}/notes/{note_id}")
        response.raise_for_status()
        return response.json()
    
    def wait_for_completion(self, note_id: str, max_wait_time: int = 300) -> Dict:
        """Aguardar processamento da nota"""
        start_time = time.time()
        
        while time.time() - start_time < max_wait_time:
            note = self.get_note(note_id)
            status = note['data']['transcription_status']
            
            if status == 'completed':
                return note['data']
            elif status == 'failed':
                raise Exception('Processamento falhou')
            
            time.sleep(10)  # Aguarda 10 segundos
        
        raise Exception('Timeout: Processamento demorou muito')

# Exemplo de uso
def main():
    client = ConnectVetsClient(os.getenv('CONNECTVETS_API_KEY'))
    
    try:
        # Criar nota
        result = client.create_note('./audio_consulta.mp3', {
            'patient_name': 'Rex',
            'owner_name': 'João Silva',
            'veterinarian': 'Dr. Santos'
        })
        
        print(f"Nota criada: {result['data']['id']}")
        
        # Aguardar processamento
        completed_note = client.wait_for_completion(result['data']['id'])
        
        # Exibir resultados
        for section in completed_note['note_sections']:
            print(f"{section['title']}: {section['content']}")
            
    except Exception as e:
        print(f"Erro: {e}")

if __name__ == "__main__":
    main()

PHP

<?php

class ConnectVetsClient {
    private $apiKey;
    private $baseUrl = 'https://api-sandbox.connectvets.com.br/notes/v1';
    
    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
    }
    
    public function createNote($audioFilePath, $metadata = []) {
        $curl = curl_init();
        
        $postFields = [
            'audio' => new CURLFile($audioFilePath),
            'metadata' => json_encode($metadata)
        ];
        
        curl_setopt_array($curl, [
            CURLOPT_URL => $this->baseUrl . '/notes',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $postFields,
            CURLOPT_HTTPHEADER => [
                'X-API-KEY: ' . $this->apiKey
            ]
        ]);
        
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        if ($httpCode !== 200) {
            throw new Exception('Erro na criação da nota: ' . $response);
        }
        
        return json_decode($response, true);
    }
    
    public function getNote($noteId) {
        $curl = curl_init();
        
        curl_setopt_array($curl, [
            CURLOPT_URL => $this->baseUrl . '/notes/' . $noteId,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                'X-API-KEY: ' . $this->apiKey,
                'Content-Type: application/json'
            ]
        ]);
        
        $response = curl_exec($curl);
        curl_close($curl);
        
        return json_decode($response, true);
    }
    
    public function waitForCompletion($noteId, $maxWaitTime = 300) {
        $startTime = time();
        
        while (time() - $startTime < $maxWaitTime) {
            $note = $this->getNote($noteId);
            $status = $note['data']['transcription_status'];
            
            if ($status === 'completed') {
                return $note['data'];
            }
            
            if ($status === 'failed') {
                throw new Exception('Processamento falhou');
            }
            
            sleep(10); // Aguarda 10 segundos
        }
        
        throw new Exception('Timeout: Processamento demorou muito');
    }
}

// Exemplo de uso
try {
    $client = new ConnectVetsClient($_ENV['CONNECTVETS_API_KEY']);
    
    // Criar nota
    $result = $client->createNote('./audio_consulta.mp3', [
        'patient_name' => 'Rex',
        'owner_name' => 'João Silva',
        'veterinarian' => 'Dr. Santos'
    ]);
    
    echo "Nota criada: " . $result['data']['id'] . "\n";
    
    // Aguardar processamento
    $completedNote = $client->waitForCompletion($result['data']['id']);
    
    // Exibir resultados
    foreach ($completedNote['note_sections'] as $section) {
        echo $section['title'] . ": " . $section['content'] . "\n";
    }
    
} catch (Exception $e) {
    echo "Erro: " . $e->getMessage() . "\n";
}
?>

Tratamento de Erros

Códigos de Status HTTP

CódigoSignificadoComo tratar
200SucessoProcessar resposta normalmente
400Dados inválidosVerificar parâmetros enviados
401API Key inválidaVerificar autenticação
413Arquivo muito grandeReduzir tamanho do áudio
429Muitas requisiçõesImplementar retry com backoff
500Erro internoTentar novamente mais tarde

Exemplo de Tratamento

async function makeRequest(url, options) {
  const maxRetries = 3;
  let attempt = 0;
  
  while (attempt < maxRetries) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        // Rate limit - aguardar antes de tentar novamente
        const retryAfter = response.headers.get('Retry-After') || '30';
        await new Promise(resolve => setTimeout(resolve, parseInt(retryAfter) * 1000));
        attempt++;
        continue;
      }
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${await response.text()}`);
      }
      
      return await response.json();
      
    } catch (error) {
      attempt++;
      if (attempt >= maxRetries) {
        throw error;
      }
      
      // Backoff exponencial
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
    }
  }
}

Próximos Passos


Dica: Use webhooks ao invés de polling para uma integração mais eficiente e em tempo real.