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:
🎤 Convertir audio → texto (Transcripción)
🌍 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:
Audio → Transcripción (endpoint 1)
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
🧩 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:
🌐 Dos URLs diferentes para dos trabajos diferentes
🎯 Propiedad $dataType para saber qué trabajo hacer
🧭 Método getApiUrl() que decide a dónde enviar la solicitud
🚨 Método errors() para manejar mensajes de error
📚 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:
🎤 Si es ASR → Endpoint de transcripción de audio
🌍 Si es Translate → Endpoint de chat para traducción
🚨 Si hay error → Método errors() lo reporta
🚀 Próximos Pasos - Lo que Viene
En la Próxima Lección Crearemos:
📦 Métodos para preparar datos según el tipo de solicitud
📤 Método para enviar solicitudes a la API correcta
📝 Manejo de respuestas de la API
💾 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
Publicar un comentario