13. Creating method set api url

 

Tutorial para Principiantes: Configurando URLs de API y Métodos de Comunicación

📚 Tema del Tutorial:

"Diseñando la Comunicación con APIs: Cómo Crear Métodos para Conectar con Servicios Externos"


🎯 Objetivo de Aprendizaje

Al final de este tutorial entenderás:

  • Qué son los endpoints de API y para qué sirven

  • Cómo diseñar métodos flexibles para diferentes tipos de solicitudes

  • La diferencia entre ASR (reconocimiento de voz) y traducción de texto

  • Cómo organizar propiedades y métodos en clases PHP

  • Dónde encontrar la documentación oficial de APIs


📡 Parte 1: ¿Por qué Necesitamos Diferentes URLs de API?

La Analogía del Restaurante con Dos Menús:

Imagina que la API de OpenAI es como un restaurante especializado:

text

🍽️  RESTAURANTE OPENAI (Servicio de IA)

├── 🅰️ MENÚ A: "Cocina de Transcripción" (ASR)

│   ├️️ 🎤 Entrada: Archivo de audio

│   ├️️ 👨‍🍳 Chef: Whisper AI

│   └️️ 🍝 Plato: Texto transcrito (mismo idioma)


├── 🅱️ MENÚ B: "Cocina de Traducción" (Translate)

│   ├️️ 📝 Entrada: Texto en cualquier idioma

│   ├️️ 👩‍🍳 Chef: GPT-3.5/GPT-4

│   └️️ 🌍 Plato: Texto traducido (a inglés u otros)


└️️ 📍 DIRECCIÓN DEL RESTAURANTE:

    ├── 🅰️ Cocina ASR: https://api.openai.com/v1/audio/transcriptions

    └── 🅱️ Cocina Translate: https://api.openai.com/v1/chat/completions

El Problema:

Nuestra aplicación necesita hacer DOS tipos de trabajos diferentes:

  1. 🎤 Convertir audio → texto (Transcripción)

  2. 🌍 Convertir texto → otro idioma (Traducción)

Cada trabajo necesita ir a una cocina diferente (endpoint diferente) dentro del restaurante OpenAI.


🗺️ Parte 2: Encontrando las Direcciones Correctas - La Documentación

Navegando la Documentación de OpenAI:

Ruta exacta para encontrar los endpoints:

text

🌐 platform.openai.com

    ↓ (haz clic en)

📚 Documentation (en el menú)

    ↓ (haz clic en)

🎤 Speech to text (en la barra lateral)

    ↓ (busca)

📋 API Reference

    ↓ (encontrarás)

📍 Endpoints:

    ├── 🎯 /v1/audio/transcriptions

    └── 🌍 /v1/chat/completions (para traducción)

Visualización de la Documentación:

text

📄 PÁGINA DOCUMENTACIÓN OPENAI

├── 🎤 Speech to text

│   ├── 📋 Overview

│   ├── 🚀 Quickstart

│   ├── 🔧 API reference ← ¡CLIC AQUÍ!

│   └── 📝 Guides

🔧 API REFERENCE (al hacer clic)

├── 🎯 POST /v1/audio/transcriptions

│   ├── 📝 Description: Transcribes audio into...

│   ├── 🔗 URL: https://api.openai.com/v1/audio/transcriptions

│   └── 📦 Parameters: file, model, language, etc.

└── 🌍 POST /v1/chat/completions

    ├── 📝 Description: Creates a chat completion...

    ├── 🔗 URL: https://api.openai.com/v1/chat/completions

    └── 📦 Parameters: model, messages, temperature, etc.

Los Dos Endpoints que Necesitamos:

1. 🎤 Endpoint de Transcripción (ASR):

text

🔗 URL: https://api.openai.com/v1/audio/transcriptions

🎯 Qué hace: Audio → Texto (mismo idioma)

📁 Recibe: Archivo de audio (MP3, WAV, MP4, etc.)

📤 Devuelve: {"text": "El audio transcrito"}

2. 🌍 Endpoint de Traducción (Chat Completions):

text

🔗 URL: https://api.openai.com/v1/chat/completions  

🎯 Qué hace: Texto → Texto en otro idioma

📁 Recibe: {"messages": [{"role": "user", "content": "Texto a traducir"}]}

📤 Devuelve: {"choices": [{"message": {"content": "Texto traducido"}}]}

Nota importante: OpenAI no tiene un endpoint directo "audio → texto en otro idioma". Nosotros creamos nuestro propio flujo:

  1. Audio → Transcripción (endpoint 1)

  2. Texto → Traducción (endpoint 2)


🏗️ Parte 3: Propiedades de Clase - Las "Etiquetas" de Nuestros Objetos

¿Qué es una Propiedad en una Clase?

Una propiedad es como una etiqueta adhesiva que pegas en un objeto para recordar información sobre él:

text

📦 CAJA (Objeto PHP)

├── 🏷️ ETIQUETA 1: $error = "" (mensajes de error)

├── 🏷️ ETIQUETA 2: $dataType = "ASR" (tipo de trabajo)

├── 🏷️ ETIQUETA 3: $file = null (archivo a procesar)

├── 🏷️ ETIQUETA 4: $lang = "English" (idioma destino)

└️️ 🏷️ ETIQUETA 5: $content = "" (texto a traducir)

Añadiendo la Propiedad $dataType:

Código en Whisper.php:

php

class Whisper{

    // 🏷️ PROPIEDADES (etiquetas del objeto)

    public $error;       // 🚨 Para mensajes de error

    public $dataType;    // 🎯 Tipo: "ASR" o "Translate"

    public $file;        // 📁 Archivo de audio

    public $lang;        // 🌍 Idioma para traducción

    public $content;     // 📝 Texto a traducir

    private $DB;         // 🗄️ Conexión a base de datos

    

    // ... resto del código

}

Valores Posibles de $dataType:

text

🎯 $dataType = "ASR" (Automatic Speech Recognition)

   Significado: "Quiero transcribir audio a texto"

   Ejemplo: Audio español → Texto español


🌍 $dataType = "Translate"

   Significado: "Quiero traducir texto a otro idioma"

   Ejemplo: Texto español → Texto inglés

Cómo y Cuándo Establecemos Estas Propiedades:

php

// 📋 EJEMPLO DE USO:


// Caso 1: Transcripción de audio

$whisperObj->dataType = 'ASR';      // 🎯 Tipo: transcripción

$whisperObj->file = 'audio.mp3';    // 📁 Archivo a transcribir


// Caso 2: Traducción de texto

$whisperObj->dataType = 'Translate'; // 🌍 Tipo: traducción

$whisperObj->content = 'Hola mundo'; // 📝 Texto a traducir

$whisperObj->lang = 'English';       // 🌍 Idioma destino


🧭 Parte 4: Creando el Método getApiUrl() - El "GPS" de Nuestra Aplicación

La Analogía del GPS para APIs:

El método getApiUrl() es como el GPS de tu coche que te dice a qué dirección ir:

text

🚗 TU APLICACIÓN (conduciendo)

├── 🎯 DESTINO A: Transcripción de audio

├── 🌍 DESTINO B: Traducción de texto

└️️ 🧭 GPS (getApiUrl()):

    "Si vas a transcripción → Toma esta ruta: [URL ASR]

     Si vas a traducción → Toma esta otra: [URL Translate]"

Código del Método getApiUrl():

php

public function getApiUrl(){

    // Pregunta: ¿A dónde quieres ir?

    if($this->dataType === "ASR"){

        // 🎯 Si destino es "Transcripción"

        return "https://api.openai.com/v1/audio/transcriptions";

    } else {

        // 🌍 Si destino es "Traducción" (o cualquier otra cosa)

        return "https://api.openai.com/v1/chat/completions";

    }

}

Explicación Paso a Paso:

php

public function getApiUrl(){

    // 1️⃣ "Pregúntale al objeto: ¿qué tipo de trabajo eres?"

    if($this->dataType === "ASR"){

        // 2️⃣ "Si eres de tipo ASR (transcripción)..."

        

        // 3️⃣ "...toma esta dirección del restaurante ASR"

        return "https://api.openai.com/v1/audio/transcriptions";

        

    } else {

        // 4️⃣ "Si eres cualquier otro tipo (traducción)..."

        

        // 5️⃣ "...toma esta dirección del restaurante de traducción"

        return "https://api.openai.com/v1/chat/completions";

    }

}

Visualización del Flujo de Decisiones:

text

[👤 Desarrollador asigna] → $whisperObj->dataType = "ASR"

        ↓

[🧭 Se llama a] → $whisperObj->getApiUrl()

        ↓

[🤔 El método pregunta] → ¿$this->dataType === "ASR"?

        │

        ├── SI (true) → 🎯 Devuelve URL de transcripción

        │

        └── NO (false) → 🌍 Devuelve URL de traducción


🔧 Parte 5: El Método errors() - El "Sistema de Alarma"

¿Para Qué Sirve el Método errors()?

Es como el botón de alarma o luz de advertencia de tu coche:

text

🚗 COCHE (Objeto Whisper)

├️️ ✅ Todo bien: No hay errores ($this->error = null)

├️️ ⚠️ Problema: Hay un error ($this->error = "Mensaje")

└️️ 🚨 BOTÓN ALARMA: errors() → Te dice cuál es el problema

Código del Método errors():

php

public function errors(){

    // Simplemente devuelve lo que haya en la "etiqueta" $error

    return $this->error;

}

Cómo Se Usa en la Práctica:

php

// 📋 EJEMPLO COMPLETO:


// 1. Intentamos subir un archivo

$resultado = $whisperObj->upload($_FILES['file']);


// 2. Verificamos si hubo error

if($whisperObj->errors()){

    // 🚨 ¡HUBO ERROR!

    echo "Error: " . $whisperObj->errors();

} else {

    // ✅ ¡TODO BIEN!

    echo "Archivo subido: " . $resultado;

}

Dónde y Cuándo Se Establecen los Errores:

php

// En el método upload():

public function upload($file){

    if($file['size'] > 20971520){ // 20MB

        // 🚨 Establecemos el error

        $this->error = "¡El archivo es muy grande!";

        return false;

    }

    

    if(!in_array($file['type'], $allowedMedia)){

        // 🚨 Otro error posible

        $this->error = "Formato de archivo inválido!";

        return false;

    }

    

    // ✅ Si todo va bien, no tocamos $this->error

    return true;

}


📝 Parte 6: Código Completo Actualizado de Whisper.php

Estructura Actual de Nuestra Clase:

php

<?php 

class Whisper{

    // 🏷️ PROPIEDADES (variables internas)

    public $error;       // 🚨 Para mensajes de error

    public $dataType;    // 🎯 "ASR" o "Translate"

    public $file;        // 📁 Archivo de audio

    public $lang;        // 🌍 Idioma destino

    public $content;     // 📝 Texto a traducir

    private $DB;         // 🗄️ Conexión a base de datos

    

    // 🏗️ CONSTRUCTOR (se ejecuta automáticamente)

    public function __construct(){

        $db = new DB;

        $this->DB = $db->connect();

    }

    

    // 🧭 MÉTODO 1: Obtiene URL según tipo de trabajo

    public function getApiUrl(){

        if($this->dataType === "ASR"){

            return "https://api.openai.com/v1/audio/transcriptions";

        } else {

            return "https://api.openai.com/v1/chat/completions";

        }

    }

    

    // 🚨 MÉTODO 2: Devuelve errores si los hay

    public function errors(){

        return $this->error;

    }

    

    // 📤 MÉTODO 3: Sube archivos (ya existente)

    public function upload($file){

        // ... código de subida ...

    }

}

?>

Organización Visual de la Clase:

text

📁 Whisper.php (Nuestra clase principal)

├── 🏷️ PROPIEDADES (6)

│   ├── $error 🚨

│   ├── $dataType 🎯

│   ├── $file 📁

│   ├── $lang 🌍

│   ├── $content 📝

│   └── $DB 🗄️ (privada)

├── 🏗️ MÉTODOS (3+)

│   ├── __construct() 🏗️

│   ├── getApiUrl() 🧭

│   ├── errors() 🚨

│   └── upload() 📤 (y más que vendrán)

└── 🎯 PROPÓSITO: Gestionar todo el flujo de audio→texto→traducción


🧪 Parte 7: Probando Nuestros Nuevos Métodos

Prueba 1: Probando getApiUrl()

Código de prueba:

php

<?php

include 'backend/init.php';


// Prueba 1: URL para transcripción

$whisperObj->dataType = "ASR";

echo "URL para ASR: " . $whisperObj->getApiUrl() . "<br>";

// Debería mostrar: https://api.openai.com/v1/audio/transcriptions


// Prueba 2: URL para traducción

$whisperObj->dataType = "Translate";

echo "URL para Translate: " . $whisperObj->getApiUrl() . "<br>";

// Debería mostrar: https://api.openai.com/v1/chat/completions


// Prueba 3: Valor por defecto (si no establecemos dataType)

$whisperObj->dataType = ""; // o no establecer nada

echo "URL por defecto: " . $whisperObj->getApiUrl() . "<br>";

// Debería mostrar: https://api.openai.com/v1/chat/completions

?>

Prueba 2: Probando errors()

php

<?php

include 'backend/init.php';


// Prueba 1: Sin errores (debería ser null o vacío)

echo "Error inicial: " . ($whisperObj->errors() ?: "No hay errores") . "<br>";


// Prueba 2: Establecemos un error manualmente (solo para probar)

$whisperObj->error = "Archivo muy grande para subir";

echo "Error después: " . $whisperObj->errors() . "<br>";


// Prueba 3: Limpiamos el error

$whisperObj->error = null;

echo "Error limpiado: " . ($whisperObj->errors() ?: "No hay errores") . "<br>";

?>

Prueba 3: Flujo Completo Simulado

php

<?php

include 'backend/init.php';


// Simulación: Usuario quiere transcribir audio

echo "📋 SIMULACIÓN: TRANSCRIPCIÓN DE AUDIO<br>";

echo "====================================<br>";


$whisperObj->dataType = "ASR";

echo "1. Tipo de trabajo: " . $whisperObj->dataType . "<br>";

echo "2. URL a usar: " . $whisperObj->getApiUrl() . "<br>";

echo "3. ¿Hay errores?: " . ($whisperObj->errors() ?: "No") . "<br>";


echo "<br>";


// Simulación: Usuario quiere traducir texto

echo "📋 SIMULACIÓN: TRADUCCIÓN DE TEXTO<br>";

echo "==================================<br>";


$whisperObj->dataType = "Translate";

$whisperObj->content = "Hola, ¿cómo estás?";

$whisperObj->lang = "English";


echo "1. Tipo de trabajo: " . $whisperObj->dataType . "<br>";

echo "2. Texto a traducir: " . $whisperObj->content . "<br>";

echo "3. Idioma destino: " . $whisperObj->lang . "<br>";

echo "4. URL a usar: " . $whisperObj->getApiUrl() . "<br>";

?>


🎯 Parte 8: ¿Qué es ASR? - Explicación para Principiantes

ASR = Reconocimiento Automático de Voz

text

👂 ASR (Automatic Speech Recognition)

├── 🎯 Qué hace: Convierte voz hablada → texto escrito

├── 🔧 Cómo: Analiza ondas sonoras, identifica palabras

├── 🤖 Quién: Whisper AI en nuestro caso

├── 🌍 Idiomas: 100+ idiomas diferentes

└️️ 🏢 Aplicaciones: Asistentes de voz, transcripciones, subtítulos

Ejemplo Simple de Cómo Funciona ASR:

text

🎤 TÚ DICES: "Hola, ¿cómo estás hoy?"

    ↓ (tu voz crea ondas sonoras)

🎵 MICRÓFONO: Captura las ondas → archivo .mp3

    ↓ (enviamos a Whisper AI)

🧠 WHISPER AI: 

    1. Analiza patrones de sonido

    2. Reconoce fonemas (unidades de sonido)

    3. Forma palabras: "Hola" + "cómo" + "estás" + "hoy"

    4. Aplica gramática: "Hola, ¿cómo estás hoy?"

    ↓

📝 RESULTADO: {"text": "Hola, ¿cómo estás hoy?"}

Comparación: ASR vs Traducción

Característica

ASR (Transcripción)

Traducción

Entrada

Audio

Texto

Salida

Texto (mismo idioma)

Texto (otro idioma)

Ejemplo

Audio español → Texto español

Texto español → Texto inglés

API Endpoint

/audio/transcriptions

/chat/completions

Modelo usado

Whisper-1

GPT-3.5/GPT-4


🧩 Parte 9: Ejercicio Práctico - Extendiendo Nuestra Clase

Ejercicio 1: Crear Método setDataType()

Problema: Establecer $dataType directamente puede causar errores si usamos valores incorrectos.

Solución: Crear método que valide:

php

public function setDataType($type){

    $allowedTypes = ['ASR', 'Translate'];

    

    if(in_array($type, $allowedTypes)){

        $this->dataType = $type;

        return true;

    } else {

        $this->error = "Tipo de dato no válido. Use 'ASR' o 'Translate'";

        return false;

    }

}


// Uso mejorado:

$whisperObj->setDataType('ASR');  // ✅ Correcto

$whisperObj->setDataType('Transcribe');  // ❌ Error controlado

Ejercicio 2: Método getApiUrl() Mejorado

Mejora: Añadir validación y mensajes de debug:

php

public function getApiUrl(){

    if(empty($this->dataType)){

        $this->error = "No se ha establecido el tipo de dato (dataType)";

        return false;

    }

    

    if($this->dataType === "ASR"){

        error_log("📞 Usando endpoint de transcripción ASR");

        return "https://api.openai.com/v1/audio/transcriptions";

        

    } elseif($this->dataType === "Translate"){

        error_log("🌍 Usando endpoint de traducción");

        return "https://api.openai.com/v1/chat/completions";

        

    } else {

        $this->error = "Tipo de dato desconocido: " . $this->dataType;

        return false;

    }

}

Ejercicio 3: Sistema de Logging

php

class Whisper{

    private $logs = [];  // 🗒️ Nuevo array para logs

    

    public function getApiUrl(){

        $url = "";  // Inicializar vacío

        

        if($this->dataType === "ASR"){

            $url = "https://api.openai.com/v1/audio/transcriptions";

            $this->addLog("Seleccionado endpoint ASR: " . $url);

        } else {

            $url = "https://api.openai.com/v1/chat/completions";

            $this->addLog("Seleccionado endpoint Translate: " . $url);

        }

        

        return $url;

    }

    

    private function addLog($message){

        $this->logs[] = date('Y-m-d H:i:s') . ' - ' . $message;

    }

    

    public function getLogs(){

        return $this->logs;

    }

}


📊 Parte 10: Diagrama de Flujo de Nuestra Aplicación

Flujo Actual de Toma de Decisiones:

text

[👤 USUARIO interactúa con la app]

        ↓

[🤔 APLICACIÓN decide: ¿qué quiere el usuario?]

        │

        ├── 🎤 Si quiere transcribir audio:

        │       ↓

        │    $whisperObj->dataType = "ASR"

        │       ↓

        │    URL = https://api.openai.com/v1/audio/transcriptions

        │

        └── 🌍 Si quiere traducir texto:

                ↓

             $whisperObj->dataType = "Translate"

                ↓

             URL = https://api.openai.com/v1/chat/completions

Flujo Completo con Errores:

text

[1️⃣ Preparar solicitud]

        ↓

[2️⃣ $whisperObj->getApiUrl()] → ¿dataType establecido?

        │

        ├── NO → 🚨 $error = "Tipo no establecido"

        │        ↓

        │      [📤 Mostrar error al usuario]

        │

        └── SI → [🎯 Obtener URL correcta]

                ↓

             [3️⃣ Enviar solicitud a esa URL]

                ↓

             [4️⃣ Procesar respuesta]

                ↓

             [5️⃣ ¿Hubo error en API?]

                │

                ├── SI → 🚨 Guardar en $error

                │        ↓

                │      [📤 Mostrar error]

                │

                └── NO → [✅ Procesar éxito]


❓ Parte 11: Cuestionario de Evaluación

Pregunta 1:

¿Qué significa la sigla "ASR" en el contexto de Whisper AI?
a) Artificial Speech Recognition
b) Automatic Speech Recognition ✅
c) Audio Sound Recognition
d) Advanced Sound Recording

Explicación: ASR = Reconocimiento Automático de Voz, convierte voz a texto.

Pregunta 2:

¿Qué endpoint de OpenAI usamos para transcribir audio a texto?
a) /v1/images/generations
b) /v1/audio/transcriptions
c) /v1/embeddings
d) /v1/fine-tunes

Pregunta 3:

En nuestro método getApiUrl(), ¿qué devuelve si $dataType es "Translate"?
a) https://api.openai.com/v1/audio/transcriptions
b) https://api.openai.com/v1/chat/completions
c) https://api.openai.com/v1/models
d) https://api.openai.com/v1/files

Pregunta 4:

¿Para qué sirve el método errors() en nuestra clase?
a) Para generar errores aleatorios
b) Para devolver el mensaje de error almacenado ✅
c) Para enviar errores a OpenAI
d) Para registrar errores en la base de datos

Pregunta 5:

¿Dónde encontramos la documentación oficial de la API de Whisper?
a) En GitHub de OpenAI
b) En platform.openai.com/docs
c) En el código fuente de Whisper
d) En foros de programación


Pregunta 6:

¿Qué hace esta línea de código en nuestro método getApiUrl()?

php

if($this->dataType === "ASR")

a) Cambia el valor de $dataType a "ASR"
b) Compara si $dataType es exactamente igual a "ASR" ✅
c) Asigna "ASR" a una nueva variable
d) Verifica si $dataType existe

Pregunta 7:

¿Por qué usamos === en lugar de == en la comparación?
a) Porque es más rápido
b) Porque compara valor Y tipo exactamente ✅
c) Porque funciona mejor con strings
d) Porque es la nueva sintaxis de PHP

Explicación: === es comparación estricta (mismo valor y mismo tipo).


🏆 Resumen Final - Lo Esencial de Hoy

Lo que Aprendimos Hoy:

  1. 🌐 Dos URLs diferentes para dos trabajos diferentes

  2. 🎯 Propiedad $dataType para saber qué trabajo hacer

  3. 🧭 Método getApiUrl() que decide a dónde enviar la solicitud

  4. 🚨 Método errors() para manejar mensajes de error

  5. 📚 Documentación oficial en platform.openai.com/docs

Checklist de lo Implementado:

✅ Propiedad $dataType añadida a la clase
✅ Método getApiUrl() creado con lógica de decisión
✅ Método errors() implementado para manejo de errores
✅ URLs correctas copiadas de la documentación oficial
✅ Estructura de clase organizada y limpia
✅ Pruebas básicas realizadas para verificar funcionamiento

Las 3 Reglas de Nuestro Sistema de URLs:

  1. 🎤 Si es ASR → Endpoint de transcripción de audio

  2. 🌍 Si es Translate → Endpoint de chat para traducción

  3. 🚨 Si hay error → Método errors() lo reporta


🚀 Próximos Pasos - Lo que Viene

En la Próxima Lección Crearemos:

  1. 📦 Métodos para preparar datos según el tipo de solicitud

  2. 📤 Método para enviar solicitudes a la API correcta

  3. 📝 Manejo de respuestas de la API

  4. 💾 Guardado de resultados en base de datos

Código que Escribiremos Próximamente:

php

// Método para preparar los datos a enviar

public function getData(){

    if($this->dataType === "ASR"){

        // Preparar datos para transcripción

        return ['file' => $this->file, 'model' => 'whisper-1'];

    } else {

        // Preparar datos para traducción

        return [

            'model' => 'gpt-3.5-turbo',

            'messages' => [

                ['role' => 'system', 'content' => 'Translate to ' . $this->lang],

                ['role' => 'user', 'content' => $this->content]

            ]

        ];

    }

}


// Método para enviar a la API

public function sendRequest(){

    $url = $this->getApiUrl();

    $data = $this->getData();

    

    // Enviar con cURL y procesar respuesta

    // ... código que veremos en próxima lección

}

💡 Insight Importante: Hoy construimos el "sistema de navegación" de nuestra aplicación. Ahora sabe a dónde ir según lo que necesite hacer. En la próxima lección, aprenderemos a "conducir" hasta esos destinos y a "traer de vuelta" los resultados.


🎉 ¡Excelente Progreso!
Hoy diste un paso crucial: tu aplicación ahora puede tomar decisiones inteligentes sobre a dónde enviar las solicitudes. Esta arquitectura flexible te permitirá añadir fácilmente más tipos de procesamiento en el futuro (como análisis de sentimiento, resumen de texto, etc.) simplemente añadiendo nuevos valores a $dataType y nuevos endpoints a getApiUrl().

🧭 ¡Tu aplicación ya sabe navegar! 


Comentarios

Entradas más populares de este blog

1-7. Transforma tu audio a texto

10. Haz que tu asistente hable

8. NUEVO - Solución si tu micrófono no está captando tu audio