azure-speech-to-text-rest-py
microsoft/skills
Transcribe archivos de audio cortos (hasta 60 segundos) utilizando la API REST de Speech-to-Text de Azure con Python, sin necesidad de usar el SDK de Speech.
...Expandir todoAPI REST de Azure Speech to Text para audio corto
API REST sencilla para la transcripción de audio a texto de archivos de audio cortos (hasta 60 segundos). No se requiere SDK, solo peticiones HTTP.
Requisitos previos
- Suscripción de Azure - Crea una gratuita
- Recurso de Speech - Crea uno en el Portal de Azure
- Obtén las credenciales - Tras el despliegue, ve al recurso > Claves y punto de conexión
Variables de entorno
# Obligatorio
AZURE_SPEECH_KEY=<tu-clave-de-recurso-de-speech>
AZURE_SPEECH_REGION=<región> # ej., eastus, westus2, westeurope
# Alternativa: Utilizar el punto de conexión directamente
AZURE_SPEECH_ENDPOINT=https://<región>.stt.speech.microsoft.com
</region></region></tu-clave-de-recurso-de-speech>Instalación
pip install requests
Inicio rápido
import os
import requests
def transcribe_audio(audio_file_path: str, language: str = "en-US") -> dict:
"""Transcribe un archivo de audio corto (máximo 60 segundos) utilizando la API REST."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
headers = {
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
}
params = {
"language": language,
"format": "detailed" # o "simple"
}
with open(audio_file_path, "rb") as audio_file:
response = requests.post(url, headers=headers, params=params, data=audio_file)
response.raise_for_status()
return response.json()
# Uso
result = transcribe_audio("audio.wav", "en-US")
print(result["DisplayText"])
Requisitos de audio
| Formato | Codec | Tasa de muestreo | Notas |
|---|---|---|---|
| WAV | PCM | 16 kHz, mono | **Recomendado** |
| OGG | OPUS | 16 kHz, mono | Tamaño de archivo más pequeño |
Limitaciones:
- Máximo 60 segundos de audio
- Para la evaluación de pronunciación: máximo 30 segundos
- Sin resultados parciales/provisionales (solo final)
Cabeceras Content-Type
# WAV PCM 16kHz
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000"
# OGG OPUS
"Content-Type": "audio/ogg; codecs=opus"
Formatos de respuesta
Formato simple (predeterminado)
params = {"language": "en-US", "format": "simple"}
{
"RecognitionStatus": "Success",
"DisplayText": "Recuérdame comprar 5 lápices.",
"Offset": "1236645672289",
"Duration": "1236645672289"
}
Formato detallado
params = {"language": "en-US", "format": "detailed"}
{
"RecognitionStatus": "Success",
"Offset": "1236645672289",
"Duration": "1236645672289",
"NBest": [
{
"Confidence": 0.9052885,
"Display": "¿Cómo está el clima?",
"ITN": "¿cómo está el clima?",
"Lexical": "¿cómo está el clima?",
"MaskedITN": "¿cómo está el clima?"
}
]
}
Transferencia fragmentada (Recomendado)
Para una menor latencia, transmite audio en fragmentos:
import os
import requests
def transcribe_chunked(audio_file_path: str, language: str = "en-US") -> dict:
"""Transmite audio en fragmentos para reducir la latencia."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
headers = {
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json",
"Transfer-Encoding": "chunked",
"Expect": "100-continue"
}
params = {"language": language, "format": "detailed"}
def generate_chunks(file_path: str, chunk_size: int = 1024):
with open(file_path, "rb") as f:
while chunk := f.read(chunk_size):
yield chunk
response = requests.post(
url,
headers=headers,
params=params,
data=generate_chunks(audio_file_path)
)
response.raise_for_status()
return response.json()
Opciones de autenticación
Opción 1: Clave de suscripción (Sencilla)
headers = {
"Ocp-Apim-Subscription-Key": os.environ["AZURE_SPEECH_KEY"]
}
Opción 2: Token Bearer
import requests
import os
def get_access_token() -> str:
"""Obtén un token de acceso desde el punto de conexión de tokens."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
token_url = f"https://{region}.api.cognitive.microsoft.com/sts/v1.0/issueToken"
response = requests.post(
token_url,
headers={
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "0"
}
)
response.raise_for_status()
return response.text
# Utiliza el token en las peticiones (válido durante 10 minutos)
token = get_access_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
}
Parámetros de consulta
| Parámetro | Obligatorio | Valores | Descripción |
|---|---|---|---|
| `language` | **Sí** | `en-US`, `de-DE`, etc. | Idioma del habla |
| `format` | No | `simple`, `detailed` | Formato del resultado (predeterminado: simple) |
| `profanity` | No | `masked`, `removed`, `raw` | Gestión de lenguaje soez (predeterminado: enmascarado) |
Valores de estado de reconocimiento
| Estado | Descripción |
|---|---|
| `Success` | Reconocimiento exitoso |
| `NoMatch` | Se detectó habla pero no se coincidieron palabras |
| `InitialSilenceTimeout` | Solo se detectó silencio |
| `BabbleTimeout` | Solo se detectó ruido |
| `Error` | Error interno del servicio |
Gestión de lenguaje soez
# Enmascara el lenguaje soez con asteriscos (predeterminado)
params = {"language": "en-US", "profanity": "masked"}
# Elimina el lenguaje soez por completo
params = {"language": "en-US", "profanity": "removed"}
# Incluye el lenguaje soez tal cual
params = {"language": "en-US", "profanity": "raw"}
Manejo de errores
import requests
def transcribe_with_error_handling(audio_path: str, language: str = "en-US") -> dict | None:
"""Transcribe con un manejo de errores adecuado."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
try:
with open(audio_path, "rb") as audio_file:
response = requests.post(
url,
headers={
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
},
params={"language": language, "format": "detailed"},
data=audio_file
)
if response.status_code == 200:
result = response.json()
if result.get("RecognitionStatus") == "Success":
return result
else:
print(f"El reconocimiento falló: {result.get('RecognitionStatus')}")
return None
elif response.status_code == 400:
print(f"Solicitud incorrecta: Verifica el código de idioma o el formato de audio")
elif response.status_code == 401:
print(f"No autorizado: Verifica la clave API o el token")
elif response.status_code == 403:
print(f"Prohibido: Falta la cabecera de autorización")
else:
print(f"Error {response.status_code}: {response.text}")
return None
except requests.exceptions.RequestException as e:
print(f"La solicitud falló: {e}")
return None
Versión asíncrona
import os
import aiohttp
import asyncio
async def transcribe_async(audio_file_path: str, language: str = "en-US") -> dict:
"""Versión asíncrona utilizando aiohttp."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
headers = {
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
}
params = {"language": language, "format": "detailed"}
async with aiohttp.ClientSession() as session:
with open(audio_file_path, "rb") as f:
audio_data = f.read()
async with session.post(url, headers=headers, params=params, data=audio_data) as response:
response.raise_for_status()
return await response.json()
# Uso
result = asyncio.run(transcribe_async("audio.wav", "en-US"))
print(result["DisplayText"])
Idiomas compatibles
Códigos de idioma comunes (ver lista completa):
| Código | Idioma |
|---|---|
| `en-US` | Inglés (EE. UU.) |
| `en-GB` | Inglés (Reino Unido) |
| `de-DE` | Alemán |
| `fr-FR` | Francés |
| `es-ES` | Español (España) |
| `es-MX` | Español (México) |
| `zh-CN` | Chino (Mandarín) |
| `ja-JP` | Japonés |
| `ko-KR` | Coreano |
| `pt-BR` | Portugués (Brasil) |
Mejores prácticas
- Elige sincrónico O asíncrono y mantén la coherencia. No mezcles clientes sincrónicos
azure.xxxcon clientes asíncronosazure.xxx.aioen la misma ruta de llamada. Elige un modo por módulo. - Utiliza siempre gestores de contexto para los clientes. Usa
with httpx.Client(...) as client:(sincrónico) oasync with httpx.AsyncClient(...) as client:(asíncrono) para que las conexiones se agrupen y cierren de forma determinista. - Utiliza WAV PCM 16 kHz mono para la mejor compatibilidad
- Habilita la transferencia fragmentada para una menor latencia
- Almacena en caché los tokens de acceso durante 9 minutos (válidos durante 10)
- Especifica el idioma correcto para un reconocimiento preciso
- Utiliza el formato detallado cuando necesites puntuaciones de confianza
- Gestiona todos los valores de RecognitionStatus en el código de producción
Cuándo NO utilizar esta API
Utiliza el SDK de Speech o la API de transcripción por lotes en su lugar cuando necesites:
- Audio superior a 60 segundos
- Transcripción en streaming en tiempo real
- Resultados parciales/provisionales
- Traducción de voz
- Modelos de voz personalizados
- Transcripción por lotes de muchos archivos
Archivos de referencia
| Archivo | Contenido |
|---|---|
| references/pronunciation-assessment.md | Parámetros y puntuación de la evaluación de pronunciación |
---
name: azure-speech-to-text-rest-py
description: Transcribe short audio files (up to 60 seconds) using Azure Speech-to-Text REST API with Python, without requiring the Speech SDK.
license: MIT
---
# Azure Speech to Text REST API for Short Audio
Simple REST API for speech-to-text transcription of short audio files (up to 60 seconds). No SDK required - just HTTP requests.
## Prerequisites
1. **Azure subscription** - [Create one free](https://azure.microsoft.com/free/)
2. **Speech resource** - Create in [Azure Portal](https://portal.azure.com/#create/Microsoft.CognitiveServicesSpeechServices)
3. **Get credentials** - After deployment, go to resource > Keys and Endpoint
## Environment Variables
```bash
# Required
AZURE_SPEECH_KEY=<your-speech-resource-key>
AZURE_SPEECH_REGION=<region> # e.g., eastus, westus2, westeurope
# Alternative: Use endpoint directly
AZURE_SPEECH_ENDPOINT=https://<region>.stt.speech.microsoft.com
```
## Installation
```bash
pip install requests
```
## Quick Start
```python
import os
import requests
def transcribe_audio(audio_file_path: str, language: str = "en-US") -> dict:
"""Transcribe short audio file (max 60 seconds) using REST API."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
headers = {
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
}
params = {
"language": language,
"format": "detailed" # or "simple"
}
with open(audio_file_path, "rb") as audio_file:
response = requests.post(url, headers=headers, params=params, data=audio_file)
response.raise_for_status()
return response.json()
# Usage
result = transcribe_audio("audio.wav", "en-US")
print(result["DisplayText"])
```
## Audio Requirements
| Format | Codec | Sample Rate | Notes |
|--------|-------|-------------|-------|
| WAV | PCM | 16 kHz, mono | **Recommended** |
| OGG | OPUS | 16 kHz, mono | Smaller file size |
**Limitations:**
- Maximum 60 seconds of audio
- For pronunciation assessment: maximum 30 seconds
- No partial/interim results (final only)
## Content-Type Headers
```python
# WAV PCM 16kHz
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000"
# OGG OPUS
"Content-Type": "audio/ogg; codecs=opus"
```
## Response Formats
### Simple Format (default)
```python
params = {"language": "en-US", "format": "simple"}
```
```json
{
"RecognitionStatus": "Success",
"DisplayText": "Remind me to buy 5 pencils.",
"Offset": "1236645672289",
"Duration": "1236645672289"
}
```
### Detailed Format
```python
params = {"language": "en-US", "format": "detailed"}
```
```json
{
"RecognitionStatus": "Success",
"Offset": "1236645672289",
"Duration": "1236645672289",
"NBest": [
{
"Confidence": 0.9052885,
"Display": "What's the weather like?",
"ITN": "what's the weather like",
"Lexical": "what's the weather like",
"MaskedITN": "what's the weather like"
}
]
}
```
## Chunked Transfer (Recommended)
For lower latency, stream audio in chunks:
```python
import os
import requests
def transcribe_chunked(audio_file_path: str, language: str = "en-US") -> dict:
"""Stream audio in chunks for lower latency."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
headers = {
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json",
"Transfer-Encoding": "chunked",
"Expect": "100-continue"
}
params = {"language": language, "format": "detailed"}
def generate_chunks(file_path: str, chunk_size: int = 1024):
with open(file_path, "rb") as f:
while chunk := f.read(chunk_size):
yield chunk
response = requests.post(
url,
headers=headers,
params=params,
data=generate_chunks(audio_file_path)
)
response.raise_for_status()
return response.json()
```
## Authentication Options
### Option 1: Subscription Key (Simple)
```python
headers = {
"Ocp-Apim-Subscription-Key": os.environ["AZURE_SPEECH_KEY"]
}
```
### Option 2: Bearer Token
```python
import requests
import os
def get_access_token() -> str:
"""Get access token from the token endpoint."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
token_url = f"https://{region}.api.cognitive.microsoft.com/sts/v1.0/issueToken"
response = requests.post(
token_url,
headers={
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "0"
}
)
response.raise_for_status()
return response.text
# Use token in requests (valid for 10 minutes)
token = get_access_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
}
```
## Query Parameters
| Parameter | Required | Values | Description |
|-----------|----------|--------|-------------|
| `language` | **Yes** | `en-US`, `de-DE`, etc. | Language of speech |
| `format` | No | `simple`, `detailed` | Result format (default: simple) |
| `profanity` | No | `masked`, `removed`, `raw` | Profanity handling (default: masked) |
## Recognition Status Values
| Status | Description |
|--------|-------------|
| `Success` | Recognition succeeded |
| `NoMatch` | Speech detected but no words matched |
| `InitialSilenceTimeout` | Only silence detected |
| `BabbleTimeout` | Only noise detected |
| `Error` | Internal service error |
## Profanity Handling
```python
# Mask profanity with asterisks (default)
params = {"language": "en-US", "profanity": "masked"}
# Remove profanity entirely
params = {"language": "en-US", "profanity": "removed"}
# Include profanity as-is
params = {"language": "en-US", "profanity": "raw"}
```
## Error Handling
```python
import requests
def transcribe_with_error_handling(audio_path: str, language: str = "en-US") -> dict | None:
"""Transcribe with proper error handling."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
try:
with open(audio_path, "rb") as audio_file:
response = requests.post(
url,
headers={
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
},
params={"language": language, "format": "detailed"},
data=audio_file
)
if response.status_code == 200:
result = response.json()
if result.get("RecognitionStatus") == "Success":
return result
else:
print(f"Recognition failed: {result.get('RecognitionStatus')}")
return None
elif response.status_code == 400:
print(f"Bad request: Check language code or audio format")
elif response.status_code == 401:
print(f"Unauthorized: Check API key or token")
elif response.status_code == 403:
print(f"Forbidden: Missing authorization header")
else:
print(f"Error {response.status_code}: {response.text}")
return None
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
return None
```
## Async Version
```python
import os
import aiohttp
import asyncio
async def transcribe_async(audio_file_path: str, language: str = "en-US") -> dict:
"""Async version using aiohttp."""
region = os.environ["AZURE_SPEECH_REGION"]
api_key = os.environ["AZURE_SPEECH_KEY"]
url = f"https://{region}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1"
headers = {
"Ocp-Apim-Subscription-Key": api_key,
"Content-Type": "audio/wav; codecs=audio/pcm; samplerate=16000",
"Accept": "application/json"
}
params = {"language": language, "format": "detailed"}
async with aiohttp.ClientSession() as session:
with open(audio_file_path, "rb") as f:
audio_data = f.read()
async with session.post(url, headers=headers, params=params, data=audio_data) as response:
response.raise_for_status()
return await response.json()
# Usage
result = asyncio.run(transcribe_async("audio.wav", "en-US"))
print(result["DisplayText"])
```
## Supported Languages
Common language codes (see [full list](https://learn.microsoft.com/azure/ai-services/speech-service/language-support)):
| Code | Language |
|------|----------|
| `en-US` | English (US) |
| `en-GB` | English (UK) |
| `de-DE` | German |
| `fr-FR` | French |
| `es-ES` | Spanish (Spain) |
| `es-MX` | Spanish (Mexico) |
| `zh-CN` | Chinese (Mandarin) |
| `ja-JP` | Japanese |
| `ko-KR` | Korean |
| `pt-BR` | Portuguese (Brazil) |
## Best Practices
1. **Pick sync OR async and stay consistent.** Do not mix `azure.xxx` sync clients with `azure.xxx.aio` async clients in the same call path. Choose one mode per module.
2. **Always use context managers for clients.** Use `with httpx.Client(...) as client:` (sync) or `async with httpx.AsyncClient(...) as client:` (async) so connections are pooled and closed deterministically.
3. **Use WAV PCM 16kHz mono** for best compatibility
4. **Enable chunked transfer** for lower latency
5. **Cache access tokens** for 9 minutes (valid for 10)
6. **Specify the correct language** for accurate recognition
7. **Use detailed format** when you need confidence scores
8. **Handle all RecognitionStatus values** in production code
## When NOT to Use This API
Use the Speech SDK or Batch Transcription API instead when you need:
- Audio longer than 60 seconds
- Real-time streaming transcription
- Partial/interim results
- Speech translation
- Custom speech models
- Batch transcription of many files
## Reference Files
| File | Contents |
|------|----------|
| [references/pronunciation-assessment.md](references/pronunciation-assessment.md) | Pronunciation assessment parameters and scoring |
Todos los archivos
0 archivosInstalar azure-speech-to-text-rest-py
Descarga y extrae los archivos de habilidades en tu directorio .claude/skills/.
Descargar ZIPClona el repositorio y copia los archivos de la habilidad a tu proyecto.
git clone https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-python/skills/azure-speech-to-text-rest-py # Copy SKILL.md to your .claude/skills/ directory
Copiar





Hogar
