Manejo de Contenido JSON
El formato JSON es el estándar en las APIs modernas. Este capítulo enseña cómo enviar datos JSON en tus peticiones POST y cómo decodificar automáticamente las respuestas JSON recibidas del servidor.
JSON es el estándar para el intercambio de datos en las APIs modernas. En este capítulo, aprenderás a dominar la integración de este formato con la biblioteca requests. Descubrirás cómo decodificar respuestas automáticamente para transformarlas en diccionarios de Python, y cómo realizar el proceso inverso enviando datos estructurados mediante peticiones POST sin lidiar con la serialización manual ni la configuración de cabeceras. Finalmente, veremos cómo dotar a tu código de la robustez necesaria implementando un manejo de errores eficiente ante respuestas malformadas o inesperadas.
6.1. Decodificación de respuestas JSON
En las arquitecturas de software modernas, JSON (JavaScript Object Notation) se ha consolidado como el formato estándar de intercambio de datos en las APIs web debido a su ligereza y facilidad de lectura. Cuando un servidor web responde con este formato, la biblioteca requests proporciona una solución nativa y directa para transformar esa cadena de texto en estructuras de datos puras de Python (como diccionarios y listas), abstrayendo por completo el proceso manual de deserialización.
El flujo de la información
Cuando realizas una petición a un endpoint que devuelve JSON, la respuesta viaja por la red como una secuencia de bytes. La biblioteca requests se encarga de recibir estos bytes y, mediante el método .json(), realiza la conversión interna.
TEXT
El método .json()
Para decodificar una respuesta, el objeto Response incluye el método .json(). Al invocarlo, la biblioteca utiliza internamente el módulo estándar json de Python para interpretar el cuerpo de la respuesta.
A continuación se muestra un ejemplo práctico realizando una petición a una API simulada:
Python
Equivalencia de tipos de datos
El proceso de decodificación mapea de forma automática los tipos de datos definidos en la especificación JSON a sus equivalentes exactos dentro del ecosistema de Python:
| Tipo en JSON | Tipo en Python | Ejemplo JSON | Ejemplo Python |
|---|---|---|---|
Objeto ({}) | Diccionario (dict) | {"activo": true} | {"activo": True} |
Arreglo ([]) | Lista (list) | [1, 2, 3] | [1, 2, 3] |
Cadena ("") | Cadena (str) | "Hola" | "Hola" |
| Número (Entero) | Entero (int) | 42 | 42 |
| Número (Real) | Flotante (float) | 3.1416 | 3.1416 |
Booleano (true) | Booleano (True) | true | True |
Booleano (false) | Booleano (False) | false | False |
Nulo (null) | Ninguno (None) | null | None |
Determinación automática de la codificación
Un aspecto crítico que requests resuelve en segundo plano es la codificación de caracteres. De acuerdo con la especificación del protocolo HTTP, si el servidor no define explícitamente una codificación en la cabecera Content-Type (por ejemplo, Content-Type: application/json; charset=utf-8), la biblioteca utiliza las pautas del estándar RFC 4627 para identificar la codificación del JSON basándose en los primeros bytes del flujo de datos.
Esto garantiza que los caracteres especiales, tildes o alfabetos no occidentales se decodifiquen correctamente sin necesidad de que configures manualmente la propiedad response.encoding antes de extraer la información.
Buenas prácticas al usar .json()
Es importante recordar que el método .json() intentará decodificar el contenido de response.text sin importar el estado de la petición. Si el servidor responde con un error de autorización (Código 401) o una página no encontrada (Código 404), pero incluye un cuerpo con formato JSON explicando el fallo, el método se ejecutará con éxito y devolverá dicha explicación.
Por lo tanto, se recomienda validar la integridad de la respuesta HTTP utilizando response.status_code o mecanismos de verificación de errores antes de proceder a la lógica de negocio con los datos estructurados.
6.2. Envío de diccionarios como JSON
Cuando interactúas con APIs RESTful, no solo necesitas consumir información, sino también enviarla. El método más común para transmitir datos estructurados hacia un servidor en peticiones de creación o modificación (como POST, PUT o PATCH) es empaquetarlos en formato JSON. La biblioteca requests simplifica este proceso permitiéndote enviar diccionarios de Python directamente, gestionando la conversión bajo el capó.
El proceso de serialización
El acto de convertir una estructura de datos en memoria (como un diccionario de Python) en una cadena de texto legible por la red se conoce como serialización. Al enviar datos, el flujo es inverso al de la recepción:
TEXT
Serialización manual vs. Serialización automática
Existen dos formas fundamentales de enviar un diccionario como JSON usando requests. Entender la diferencia entre ambas te ayudará a escribir un código más limpio y a evitar errores comunes de cabeceras en el servidor.
Enfoque 1: Conversión manual con el parámetro data
Tradicionalmente, podías usar el módulo nativo json de Python para transformar el diccionario en una cadena de texto (json.dumps()) y pasar ese resultado al parámetro data.
Si optas por este camino, es obligatorio definir manualmente la cabecera Content-Type, ya que de lo contrario el servidor no sabrá cómo interpretar los bytes recibidos.
Python
Enfoque 2: Automatización con el parámetro json (Recomendado)
Para evitar el trabajo repetitivo de serializar y configurar cabeceras, requests introdujo el parámetro json. Al pasar tu diccionario directamente a este parámetro, la biblioteca se encarga de todo de forma interna.
Python
¿Qué ocurre internamente con el parámetro json?
Cuando utilizas json=nuevo_producto, la biblioteca ejecuta automáticamente dos acciones críticas:
- Codificación de datos: Llama internamente a
json.dumps()para transformar tu diccionario de Python a una cadena JSON, asegurando que valores comoTrue,FalseoNonese traduzcan correctamente atrue,falseynull. - Inyección de cabeceras: Modifica las cabeceras de la petición para incluir
Content-Type: application/json. Si ya tenías configurado un diccionario de cabeceras personalizado,requestssimplemente añade o sobrescribe esta propiedad sin alterar las demás.
Regla de oro: Si el servidor espera recibir JSON, utiliza siempre el parámetro
json. Si pasas un diccionario directamente al parámetrodata(data=nuevo_producto),requestsasumirá que estás enviando un formulario web tradicional (application/x-www-form-urlencoded), lo que romperá la comunicación con la mayoría de las APIs modernas.
6.3. El parámetro json en peticiones POST
Aunque el parámetro json puede utilizarse en cualquier método HTTP que admita un cuerpo en la petición (como PUT o PATCH), su uso principal ocurre en las peticiones POST. El método POST se diseñó específicamente para enviar datos al servidor con el fin de crear un nuevo recurso o procesar información, y el parámetro json es la herramienta idónea para cumplir con este propósito de forma eficiente.
Comportamiento del parámetro json en detalle
Cuando pasas un objeto al parámetro json en una petición requests.post(), la biblioteca realiza un análisis de los datos para garantizar que la estructura sea válida según la especificación JSON antes de transmitirla.
A diferencia del parámetro data (que acepta cadenas, bytes u objetos tipo archivo), el parámetro json está diseñado para recibir estructuras de datos compuestas primariamente por diccionarios, listas, cadenas, enteros, flotantes, booleanos y valores nulos.
Ejemplo práctico: Registro de una entidad compleja
A menudo, las APIs requieren que los datos no se envíen en una estructura plana, sino con múltiples niveles de anidación. El parámetro json procesa estas jerarquías sin necesidad de configuraciones adicionales.
Python
Conflictos y precedencia de parámetros
Un error común cuando se empieza a trabajar con la biblioteca es intentar combinar los parámetros data y json en la misma petición POST. Es fundamental comprender qué sucede si ambos coinciden en el código:
- Si se usan ambos parámetros simultáneamente: El parámetro
datatiene absoluta prioridad. Si envíasrequests.post(url, data=un_diccionario, json=otro_diccionario), la biblioteca ignorará por completo el parámetrojson, serializarádatacomo un formulario tradicional y configurará la cabecera aapplication/x-www-form-urlencoded. - Datos adjuntos adicionales: Si necesitas enviar texto plano o binario junto con un JSON, no debes usar el parámetro
json. En su lugar, debes recurrir a la serialización manual e integrar todo dentro del parámetrodata, controlando tú mismo las cabeceras.
Verificación de lo enviado en la petición
Si alguna vez tienes dudas sobre si tus datos se están transmitiendo correctamente o si las cabeceras automáticas se han aplicado, puedes inspeccionar el objeto request interno que vive dentro de la respuesta (respuesta.request).
Python
Esta técnica de inspección es una herramienta excelente para depurar tu código antes de asumir que el fallo se encuentra en el servidor remoto.
6.4. Manejo de errores de decodificación
El intercambio de datos a través de la red siempre está expuesto a imprevistos. Aunque el servidor responda con un código de estado exitoso, existe la posibilidad de que el cuerpo de la respuesta no contenga un JSON válido. Intentar invocar el método .json() sobre una respuesta malformada, incompleta o que directamente consiste en HTML (muy común cuando un servidor falla y devuelve una página de error) provocará una excepción que interrumpirá la ejecución de tu programa si no se maneja adecuadamente.
La excepción requests.exceptions.JSONDecodeError
Históricamente, cuando el método .json() fallaba, lanzaba la excepción estándar de Python json.decoder.JSONDecodeError. Sin embargo, para mantener la consistencia y permitir que los desarrolladores capturen todos los fallos específicos de la biblioteca en un mismo bloque, requests incluye su propia excepción: requests.exceptions.JSONDecodeError.
Nota de compatibilidad: La excepción
requests.exceptions.JSONDecodeErrorhereda directamente de la claseValueErrorde Python (y en versiones derequestsprevias a la 2.27.0, también dejson.JSONDecodeError), lo que garantiza que tu código sea robusto ante capturas genéricas.
Capturando el error correctamente
La forma más segura de procesar el contenido JSON de una respuesta es envolver la invocación del método en una estructura try-except.
Python
Causas comunes de fallos en la decodificación
Comprender por qué falla la decodificación te ahorrará horas de depuración. Los escenarios más habituales son:
- Respuestas HTML encubiertas: Ocurre cuando un firewall, un proxy (como Cloudflare) o el propio servidor interceptan la petición debido a un error interno (500) o un mantenimiento, devolviendo una página HTML. El texto comienza con
<!DOCTYPE html>en lugar de{. - Problemas de codificación de caracteres: Si el servidor no especifica el juego de caracteres y el JSON contiene caracteres especiales mal formados, la biblioteca podría fallar al intentar reconstruir la cadena antes de deserializarla.
- Truncado de datos: Si la conexión de red se corta abruptamente mientras se descargaba el cuerpo de la respuesta, el JSON quedará incompleto (por ejemplo, perdiendo la llave de cierre
}), volviéndose ilegible.
Resumen del capítulo
En este capítulo hemos profundizado en el formato JSON como el pilar fundamental para la comunicación con APIs modernas utilizando la biblioteca requests.
- Aprendimos que el método
.json()automatiza por completo la decodificación y conversión de los tipos de datos de JSON a sus estructuras nativas equivalentes en Python (como diccionarios y listas), gestionando de manera transparente la codificación de caracteres. - Evaluamos la serialización y el envío de datos mediante el parámetro
jsonen peticiones POST, descubriendo cómo este mecanismo inyecta de forma automática la cabeceraContent-Type: application/jsony traduce correctamente estructuras complejas y anidadas. - Comprendimos la importancia de la precedencia de parámetros, destacando por qué no se deben mezclar los parámetros
datayjsonen una misma solicitud. - Finalmente, abordamos la gestión de excepciones mediante
requests.exceptions.JSONDecodeError, proporcionando técnicas esenciales para proteger nuestras aplicaciones frente a respuestas inesperadas, truncadas o con formato HTML inválido.
© 2026 Esdocu. Contenido bajo licencia MIT.
Editar esta página