Lectura - API
Lectura - API
API
Listas
Se definen como
`lista = ["a", "b, "c"]
Tienen funciones que permiten manipular sus elementos:
Comprensiones:
map(f, list) : Permite crear transformaciones sin aplicar un loop, en 1 línea de código. Recibe
como argumentos una función y la lista sobre la que se va a operar. Devuelve una estructura
map que se puede convertir a una lista.
filter(f, list) : Permite filtrar listas sin aplicar un loop, en 1 línea de código. Recibe como
argumentos una función y la lista sobre la que se va a filtrar. Devuelve una estructura
filter que se puede convertir a una lista.
reduce(f, list) : Requiere ser importado desde functools. Devuelve un único valor como
resultado de una aplicación aplicada a todos los elementos de la lista. La función que se pasa
como primer argumento requiere tener una variable acumuladora.
Pandas
Librería orientada a la manipulación y limpieza de datos.
Se importa como import pandas as pd .
Sus principales estructuras son el DataFrame y las Series.
Se puede crear un DataFrame a partir de un csv con la función pd.read_csv().
Numpy
Librería para la computación numérica.
Usado por muchos módulos de Python.
Permiten crear arreglos n-dimensionales.
Poseen funciones matemáticas orientadas a la velocidad de implementación.
Permite trabajar con álgebra lineal.
Se importa como import numpy as pd .
Glosario
Diccionario
Diccionario: Contenedor o estructura de datos que permite guardar un conjunto no ordenado de
pares clave-valor. Cada par se define como "llave": "valor" , y cada par va separado por comas.
Los diccionarios se definen entre paréntesis de llaves {} .
Contenedor: Objeto dentro de Python que implementa __contains__. Se les puede aplicar el operador
i. En Python, los contenedores son las listas, los diccionarios, las tuplas y los sets.
Clave: O "llave", o "key". Identificador para cada elemento dentro de un diccionario. Puede ser un
objeto string, int, float, o bool, pero de manera general se usan string o int .
Valor: Objeto hacia el cual apunta la llave de un diccionario. Pueden ser de cualquier tipo de dato de
Python.
API
API: Application Programming Interface. Es una interfaz que permite a un programa de computador
conversar con otro, ya sea dentro del mismo computador o en otro computador a través de internet.
REST: Representation State Transfer. Usualmente utilizado como API REST. Es un estilo de arquitectura
de software para la construcción de servicios web.
Token: A menudo son strings largos combinando distintos caracteres, que se utilizan como
identificador único de autenticación para realizar una solicitud. Suelen expirar después de un tiempo.
Postman: Herramienta gratuita para probar APIs Rest
Recurso: En el contexto de API se refiere a los objetos que pueden ser consultados, por ejemplo posts,
fotos, usuarios, u cualquier otro objeto disponible.
Request (pedido): Es el inicio de la comunición cliente - servidor.
Capítulo 1: Introducción a diccionarios
Objetivos
Conocer la utilidad de un diccionario
Crear un diccionario
Conocer los conceptos de clave y valor
Acceder a elementos dentro de un diccionario a través de la clave
Diccionarios
Los diccionarios son una estructura de datos compuesta por pares de clave:valor , donde cada clave se
asocia con un elemento del diccionario. Como toda estructura de datos, permiten almacenar una gran
cantidad de datos en una sola variable.
Reciben este nombre porque se leen igual que uno de la vida real. En un diccionario buscamos una palabra
y esta nos lleva a la definición: la clave es equivalente a la palabra y el valor es equivalente a su definición.
La otra diferencia, es que en una lista los índices se generan automáticamente para cada elemento,
mientras que las claves de un diccionario no se generan automáticamente, sino que son definidas
explícitamente al crear el diccionario, o al asignar un nuevo elemento a la estructura.
Por último, las claves del diccionario pueden ser un string, un número, o incluso un booleano, pero con
frecuencia se utilizan los strings.
# En una lista usamos la posición para acceder a un elemento, y los índices se generan
en forma implícita
lista = [25, 31, "hola"]
lista[2] # "hola"
¿Para qué sirven los diccionarios?
Existen varios tipos de situaciones donde los diccionarios son mejores que las listas para resolver un
determinado problema, principalmente cuando se requiere identificar rápidamente un elemento a través
de un valor único, la clave.
En esta unidad, resolveremos algunos problemas utilizando ambas estrategias para poder compararlas e
identificar cuándo una solución conviene por sobre la otra y por qué.
Crear un diccionario
En Python, un diccionario (vacío) se define con llaves: {} . Cada par de clave y valor se asocia mediante : ,
en la forma llave: valor .
Si al momento de definir un diccionario tenemos muchas llaves, podemos definirlo en múltiples líneas para
facilitar la lectura de código.
notas = {
"Camila": 7,
"Antonio": 5,
"Felipe": 6,
"Daniela": 5,
"Vicente": 7,
}
notas["Felipe"] # 6
notas["felipe"] # KeyError: 'felipe'
La clave tiene que ser única
En un diccionario, solo puede haber un valor asociado a una clave.
Al usar dos veces la misma clave, Python se quedará con la última que definimos, ignorando
completamente la existencia del primer valor.
Para agregar un elemento a un diccionario, hace falta especificar una clave nueva, de forma que el nuevo
valor ingresado sea identificado con dicha clave.
diccionario["llave 2"] = 9
diccionario # {"llave 1": 5, "llave 2": 9}
Ojo con la sintaxis: para definir un diccionario usamos llaves ( {} ), pero para acceder a sus elementos
usamos corchetes [] .
Objetivos
Iterar un diccionario con una sola variable
Iterar un diccionario con dos variables
Transformar los valores dentro de un diccionario
Transformar los valores y generar un nuevo diciconario a partir de otro
Iterando un diccionario
Al iterar en un diccionario, la variable iteradora corresponde a la clave.
Es por esto que podemos verificar si una clave está en un diccionario de una forma similar a como lo
hacemos para saber si un elemento está en una lista: usando in
if "nombre" in diccionario:
print("La clave 'nombre' está en el diccionario")
else:
print("La clave 'nombre' no está en el diccionario")
if "peso" in diccionario:
print("La clave '´peso' está en el diccionario")
else:
print("La clave 'peso' no está en el diccionario")
Otra forma de iterar un diccionario, es accediendo a las claves y valores de forma simultánea, con una
variable para la clave y otra para el valor de cada par. Para ello, se requiere que se itere sobre la función
items() en el diccionario.
Normalmente, se utilizan las variables k para las claves (key) y v para los valores (value)
Desafío: Iteración de claves y valor
Tenemos un listado de países y la cantidad de usuarios por cada país en la siguiente tabla:
México 70
Chile 50
Argentina 55
Requerimientos
usuarios_por_pais = {
"México": 65,
"Chile": 50,
"Argentina": 55,
}
México
Chile
Argentina
México
Desafío: Transformación
Dada la información de ventas de 3 meses:
Mes Ventas
Octubre 65000
Noviembre 68000
Diciembre 72000
Requerimientos
ventas_mensuales = {
"Octubre": 65000,
"Noviembre": 68000,
"Diciembre": 72000,
}
print(ventas_mensuales)
ventas_mensuales = {
"Octubre": 65000,
"Noviembre": 68000,
"Diciembre": 72000,
}
nuevas_ventas_mensuales = {}
for mes, venta in ventas_mensuales.items():
nuevas_ventas_mensuales[mes] = venta * 0.8
print(nuevas_ventas_mensuales)
print(ventas_mensuales)
{'Octubre': 52000.0, 'Noviembre': 54400.0, 'Diciembre': 57600.0}
{'Octubre': 65000, 'Noviembre': 68000, 'Diciembre': 72000}
Desafío: Filtrado
Dados los siguientes datos, crear un método que devuelva otro diccionario pero filtrando todos aquellos
pares con un valor inferior a 70000.
Mes Ventas
Octubre 65000
Noviembre 68000
Diciembre 72000
ventas_mensuales = {
"Octubre": 65000,
"Noviembre": 68000,
"Diciembre": 72000,
}
def filtrar_valores_altos(diccionario):
diccionario_filtrado = {}
for clave, valor in [Link]():
if valor > 70000:
diccionario_filtrado[clave] = valor
return diccionario_filtrado
print(filtrar_valores_altos(ventas_mensuales))
{'Diciembre': 72000}
Desafío: Integración
Se tiene la siguiente lista de productos:
Se solicita:
Si el producto tiene un valor menor a 120.000, se le debe aplicar un 10% de descuento (en el
diccionario original).
Capítulo 3: Operaciones típicas en diccionarios
Objetivos
Eliminar un elemento dentro de un diccionario
Unir dos diccionarios en uno solo
Invertir un diccionario
Transformar las claves del diccionario en una lista
Transformar los valores del diccionario en una lista
Introducción
En este capítulo aprenderemos varias funcionalidades de los diccionarios que facilitarán su uso. Todos los
métodos que aprenderemos los podemos consultar en la documentación.
del diccionario["celular"]
print(diccionario)
eliminado = [Link]("tablet")
print(eliminado)
print(diccionario)
120000
{'notebook': 489990, 'cargador': 12400}
Unir diccionarios
Una operación muy común es unir dos diccionarios, lo que se puede lograr a través de la siguiente
expresión:
Invertir diccionario
A veces, resulta útil invertir la relación de un diccionario para poder acceder a la llave asociada a un valor en
específico. Esto se puede lograr construyendo el diccionario nuevamente y almacenando el valor en el lugar
de la llave y viceversa. Para esto podemos usar una variación de lists comprehension y hacerlo en una línea:
colors = {
"red": "#cc0000",
"green": "#00cc00",
"blue": "#0000cc",
}
colors_inv = {v: k for k, v in [Link]()}
colors_inv["#cc0000"] # red
'red'
colors = {
"red": "#cc0000",
"green": "#00cc00",
"blue": "#0000cc",
}
[Link]()
Así como hay un método para las llaves, hay un método que permite obtener todos los valores de un
diccionario, el método values :
colors = {
"red": "#cc0000",
"green": "#00cc00",
"blue": "#0000cc",
}
[Link]()
Desafío: Búsqueda de colores
Se tiene una base de datos de colores:
{
"aliceblue": "#f0f8ff",
"antiquewhite": "#faebd7",
"aqua": "#00ffff",
"aquamarine": "#7fffd4",
"azure": "#f0ffff",
"darkorchid": "#9932cc",
"darkred": "#8b0000",
"darksalmon": "#e9967a",
"navajowhite": "#ffdead",
"navy": "#000080",
"orchid": "#da70d6",
"palegoldenrod": "#eee8aa",
"peachpuff": "#ffdab9",
"peru": "#cd853f",
"pink": "#ffc0cb",
"purple": "#800080",
"rebeccapurple": "#663399",
"red": "#ff0000",
"saddlebrown": "#8b4513",
"seashell": "#fff5ee",
"sienna": "#a0522d",
"silver": "#c0c0c0",
"skyblue": "#87ceeb",
"slateblue": "#6a5acd",
"teal": "#008080",
"thistle": "#d8bfd8",
"tomato": "#ff6347",
"turquoise": "#40e0d0",
"violet": "#ee82ee",
"wheat": "#f5deb3",
"white": "#ffffff",
"whitesmoke": "#f5f5f5",
"yellow": "#ffff00",
"yellowgreen": "#9acd32",
}
Uso:
$ busqueda_colores.py #6a5acd
slateblue
Soluciones
Para este ejercicio, hay dos soluciones posibles; Una es iterar el diccionario hasta encontrar la clave e
imprimirla. Y la otra es invertir el diccionario y acceder al nombre del color utilizando el nuevo diccionario
colors = {
"aliceblue": "#f0f8ff",
"antiquewhite": "#faebd7",
"aqua": "#00ffff",
"aquamarine": "#7fffd4",
"azure": "#f0ffff",
"darkorchid": "#9932cc",
"darkred": "#8b0000",
"darksalmon": "#e9967a",
"navajowhite": "#ffdead",
"navy": "#000080",
"orchid": "#da70d6",
"palegoldenrod": "#eee8aa",
"peachpuff": "#ffdab9",
"peru": "#cd853f",
"pink": "#ffc0cb",
"purple": "#800080",
"rebeccapurple": "#663399",
"red": "#ff0000",
"saddlebrown": "#8b4513",
"seashell": "#fff5ee",
"sienna": "#a0522d",
"silver": "#c0c0c0",
"skyblue": "#87ceeb",
"slateblue": "#6a5acd",
"teal": "#008080",
"thistle": "#d8bfd8",
"tomato": "#ff6347",
"turquoise": "#40e0d0",
"violet": "#ee82ee",
"wheat": "#f5deb3",
"white": "#ffffff",
"whitesmoke": "#f5f5f5",
"yellow": "#ffff00",
"yellowgreen": "#9acd32",
}
# Solucion iterando
search = "#6a5acd"
slateblue
Si bien esta solución muestra en pantalla el valor correcto, no maneja la situación de cuando no encuentra
el color. Podríamos estar tentandos a poner esto:
search = "#6a5acd"
for name, hexa in [Link]():
if hexa == search:
print(name)
else:
print("no-no")
El problema de este acercamiento es que vamos a mostrar muchas veces el texto de no encontrado y solo
debemos mostrarlo una vez.
Para evitar esto, ocuparemos una variable para guardar cuando encontremos el valor y preguntaremos por
ella al final. En la jerga, este tipo de variables se conoce como "flag", y se declaran fuera de un ciclo con valor
False , y cambian su valor a True dada una condición. De esta forma, se permite también evitar seguir
con el ciclo cuando ya se ha cumplido con la condición.
search = "#6a5acd"
found = False
for name, hexa in [Link]():
if hexa == search and found == False:
found = True
print(name)
if not found:
print("no-no")
slateblue
slateblue
Varias soluciones
¿Por qué se ven varias soluciones a un problema, si con una basta?
Esta pregunta es muy importante. Un programador no busca memorizar la respuesta a los problemas, de
hecho muy rara vez nos toca resolver exactamente el mismo problemas dos veces. Pero el acercamiento a
resolver un problema sí puede ser reutilizado en situaciones similares.
Lo importante es conocer diversas estrategias que nos permitan después enfrentar problemas nuevos.
En esta ocasión, aprendimos que invertir un diccionario puede ser mucho más fácil que iterarlo.
Desafío: Búsqueda de múltiples colores
Modificar el programa anterior para que el usuario pueda buscar múltiples colores.
Uso:
slateblue
turquoise
import sys
search1 = [Link][1]
search2 = [Link][2]
search3 = [Link][3]
if search1 in colors_inv:
print(colors_inv[search1])
else:
print("no-no")
if search2 in colors_inv:
print(colors_inv[search2])
else:
print("no-no")
if search3 in colors_inv:
print(colors_inv[search3])
else:
print("no-no")
Es una pésima solución porque si el usuario ingresa mas valores no funcionará. Otra forma de darse cuenta
de que es mal código es porque estamos repitiendo el mismo código varias veces.
# Solución buena
import sys
colors_inv = {v: k for k, v in [Link]()}
Capítulo 4: Listas y diccionarios
Objetivos
Convertir un diccionario en una lista
Convertir una lista en un diccionario
Transformar dos listas relacionadas en una única lista
Veamos un ejemplo
Supongamos que queremos almacenar alumnos y sus notas, perfectamente podríamos guardar la
información en dos listas, una con los nombres y otra con las notas.
De esta forma, si quisieramos consultar la nota de un alumno, podríamos recuperar la posición del alumno
en la lista de nombres, y luego consultar con ésta en la lista de las notas.
index = [Link]('Alumno1')
nota_alumno = notas[index]
Mientras que resolver el mismo problema con un diccionario puede ser mucho mas sencillo.
notas_por_alumno = {
"Alumno1": 10,
"Alumno2": 3,
"Alumno3": 8,
}
print(notas_por_alumno["Alumno1"])
A lo largo del programa, no siempre se tiene control sobre cuál es la estructura que se está trabajando. Por
ejemplo, puede ser que el resultado de una función sea un diccionario, pero se requiera una lista como
argumento para otra función.
Convertir estructuras
Como vimos, es importante saber cómo transformar una lista en un diccionario y viceversa, para resolver
distintos tipos de problemas.
Una tupla es una estructura de datos similar a una lista, con la diferencia de que sus datos no son mutables.
Se definen entre paréntesis redondos () .
Si se tiene información en 2 listas separadas, y se quiere juntar ambas en un diccionario, las opciones son:
notas_por_alumno = {}
for i in range(len(nombres)):
alumno = nombres[i]
nota = notas[i]
notas_por_alumno[alumno] = nota
print(notas_por_alumno)
Iterar el arreglo elemento a elemento también es posible, pero un poco más complejo.
notas_por_alumno = {}
for alumno in nombres:
i = [Link](alumno) # Obtenemos el indice
alumno = nombres[i]
nota = notas[i]
notas_por_alumno[alumno] = nota
print(notas_por_alumno)
Utilizando zip
print(notas_por_alumno)
Uso de group by
En el módulo itertools de Python, se tiene disponible la función groupby , la cual permite agrupar un
conjunto de elementos bajo cualquier criterio.
Esta función, al ser iterada, retornará llaves consecutivas y sus grupos asociados. Cada grupo se creará
según los datos que tengan igual valor. Es decir, cuando el valor iterado cambie, se creará un nuevo grupo.
Por ello, se requiere que los datos estén ordenados antes de poder agruparlos.
Por cada letra, se crea un grupo que tiene como clave la letra misma, y como valor una lista con la cantidad
de ocurrencias de la letra.
Supongamos que tenemos una lista de palabras, que queremos agrupar según su largo.
Vimos que como primer argumento de groupby ingresamos una estructura iterable, en el caso anterior,
un string , donde en cada iteración cada elemento corresponde a una letra. Pero también puede ser
sobre una lista, donde cada grupo será cada elemento de la lista.
Esto por un lado, ya nos permite agrupar en base a una lista de palabras. Por otro lado, groupby recibe un
segundo parámetro opcional, que corressponde cuál será la clave o key para la estructura retornada. Si no
se especifica este parámetro, toma por defecto el valor mismo de la estructura agrupada. En caso de
especificarse, debe corresponder a una función que se aplique al grupo y que retorne un valor.
Como se puede ver, el output no es el correcto. Esto sucede porque los elementos no están ordenados
según el criterio por el que los queremos agrupar. Por lo tanto, primero ordenaremos las palabras según su
largo y luego agruparemos.
# Primero ordenamos
[Link](key=lambda x: len(x))
# Luego agrupamos
{k: list(v) for k, v in groupby(words, key=len)}
{1: ['a', 'y'], 3: ['uno'], 4: ['hola', 'cada'], 5: ['todos']}
[1, 2, 6, 7, 2, 5, 8, 9, 1, 3, 6, 7]
Y queremos contar la cantidad de veces que aparece cada uno de los elementos.
Iterar y contar
Agrupar y contar
Iterar y contar
Para resolver el problema por iteración, cada vez que se encuentre un elemento nuevo en el ciclo, éste se
guardará en un diccionario con la cuenta en uno. Si se encuentra un elemento que ya está en el diccionario,
se incrementará su cuenta en 1.
lista = [1, 2, 6, 7, 2, 5, 8, 9, 1, 2, 9, 7]
diccionario = {}
for i in lista:
if i in diccionario:
diccionario[i] += 1
else:
diccionario[i] = 1
print(diccionario)
{1: 2, 2: 3, 6: 1, 7: 2, 5: 1, 8: 1, 9: 2}
Agrupar y contar
Otra alternativa es usar groupby , recordando ordenar primero los datos y luego agruparlos, para
finalmente contarlos midiendo el largo de la lista entregada por la función.
lista = [1, 2, 6, 7, 2, 5, 8, 9, 1, 2, 9, 7]
[Link]()
diccionario = {k: len(list(v)) for k, v in groupby(lista)}
print(diccionario)
{1: 2, 2: 3, 5: 1, 6: 1, 7: 2, 8: 1, 9: 2}
Capítulo 5: Introducción a APIs
Objetivos
Conocer el concepto de request y response
Conocer la importancia de las API REST para comunicar programas por internet
Utilizar Postman para realizar un request a una API
En términos burdos, una API REST es una página web para un programa, es decir, una página web fácil de
ser consultada desde cualquier programa. Esto es muy útil para integrar sistemas y comunicar distintas
aplicaciones.
Al programa que consulta se le denomina cliente, mientras que al programa que entrega la respuesta se le
suele llamar servidor.
Clima y temperatura
Cambio de monedas
Indicadores económicos
Servicios para subir archivos
Compra y venta de criptomonedas
Servicios de geolocalización, como Google Maps
Cualquier empresa puede construir una API y hacerla disponible a través de internet.
Un request (o pedido) es información que el cliente envía a una página web aunque, para ser más precisos,
desde ahora en adelante diremos URL (localización de un recurso). El response es la información que esa
URL devuelve al cliente.
En este capítulo aprenderemos cómo hacer una request, y cómo analizar una response.
Descargando Postman
Podemos descargar Postman desde la página oficial. [Link]
Instalaremos y abriremos la aplicación descargada, donde deberíamos ver un panel como el siguiente.
Primer request
Donde dice "Request URL" pondremos la siguiente URL: [Link] .
Luego, haremos click donde dice "Send" y obtendremos nuestra primera respuesta.
Luego de algunos milisegundos (o segundos en el peor de los casos) el servidor nos enviará una respuesta:
el texto que aparece en la parte inferior de la imagen.
La respuesta se parece mucho a cosas que hemos previamente: primero vemos la apertura de una lista y
luego varios diccionarios. La respuesta está en un formato llamado JSON.
Se debe tener en cuenta eso sí, que si bien uno ve que la respuesta está organizada en una estructura como
la de los diccionarios, en realidad corresponde a un solo string o cadena de texto (desde el inicio hasta el fin
de la respuesta). Lo que ocurre es que Postman, y algunas extensiones de navegadores, permiten visualizar
estos string con estructura JSON en una forma más "humana" y entendible.
JSON
JSON es acrónimo de JavaScript Object Notation. Es un formato para enviar información en texto plano,
fácilmente leíble por humanos y fácilmente analizable por lenguajes de programación. Hoy en día es uno de
los formato más utilizados para enviar información entre sistemas.
JSON a Python
En Python, transformar un string con un JSON a un diccionario es tan sencillo como:
import json
[Link](string)
Capítulo 6: Consumiendo una API desde Python
Objetivos
Utilizar Postman para obtener el código Python necesario para hacer un request
Consumir una API desde Python
Transformar la respuesta de JSON a una estructura utilizable directamente en Python
Conocer las implicaciones de SSL
Aprender a nunca enviar información sensible sin SSL
Entender la importancia de verificar el certificado
import requests
url = "[Link]
headers = {
'cache-control': "no-cache",
'Postman-Token': "2defb9f3-9b11-499b-be4f-82505a2f8e1a",
}
# Código de la respuesta
print(response)
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio
reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et
cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet
architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea
dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui
aperiam non debitis possimus qui neque nisi nulla"
},
{
"userId": 1,
"id": 3,
"title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
"body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut
ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et
labore et velit aut"
},
{
"userId": 1,
"id": 4,
"title": "eum et est occaecati",
"body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda
provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis
sunt voluptatem rerum illo velit"
},
{
"userId": 1,
"id": 5,
"title": "nesciunt quas odio",
"body": "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed
est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque"
},
{
"userId": 1,
"id": 6,
"title": "dolorem eum magni eos aperiam quia",
"body": "ut aspernatur corporis harum nihil quis provident sequi\nmollitia nobis
aliquid molestiae\nperspiciatis et ea nemo ab reprehenderit accusantium quas\nvoluptate
dolores velit et doloremque molestiae"
},
{
"userId": 1,
"id": 7,
"title": "magnam facilis autem",
"body": "dolore placeat quibusdam ea quo vitae\nmagni quis enim qui quis quo nemo
aut saepe\nquidem repellat excepturi ut quia\nsunt ut sequi eos ea sed quas"
},
{
"userId": 1,
"id": 8,
"title": "dolorem dolore est ipsam",
"body": "dignissimos aperiam dolorem qui eum\nfacilis quibusdam animi sint suscipit
qui sint possimus cum\nquaerat magni maiores excepturi\nipsam ut commodi dolor
voluptatum modi aut vitae"
},
{
"userId": 1,
"id": 9,
"title": "nesciunt iure omnis dolorem tempora et accusantium",
"body": "consectetur animi nesciunt iure dolore\nenim quia ad\nveniam autem ut quam
aut nobis\net est aut quod aut provident voluptas autem voluptas"
},
{
"userId": 1,
"id": 10,
"title": "optio molestias id quia eum",
"body": "quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero
nisi sit\nquos veniam quod sed accusamus veritatis error"
},
{
"userId": 2,
"id": 11,
"title": "et ea vero quia laudantium autem",
"body": "delectus reiciendis molestiae occaecati non minima eveniet qui
voluptatibus\naccusamus in eum beatae sit\nvel qui neque voluptates ut commodi qui
incidunt\nut animi commodi"
},
{
"userId": 2,
"id": 12,
"title": "in quibusdam tempore odit est dolorem",
"body": "itaque id aut magnam\npraesentium quia et ea odit et ea voluptas
et\nsapiente quia nihil amet occaecati quia id voluptatem\nincidunt ea est distinctio
odio"
},
{
"userId": 2,
"id": 13,
"title": "dolorum ut in voluptas mollitia et saepe quo animi",
"body": "aut dicta possimus sint mollitia voluptas commodi quo doloremque\niste
corrupti reiciendis voluptatem eius rerum\nsit cumque quod eligendi laborum
minima\nperferendis recusandae assumenda consectetur porro architecto ipsum ipsam"
},
{
"userId": 2,
"id": 14,
"title": "voluptatem eligendi optio",
"body": "fuga et accusamus dolorum perferendis illo voluptas\nnon doloremque neque
facere\nad qui dolorum molestiae beatae\nsed aut voluptas totam sit illum"
},
{
"userId": 2,
"id": 15,
"title": "eveniet quod temporibus",
"body": "reprehenderit quos placeat\nvelit minima officia dolores impedit
repudiandae molestiae nam\nvoluptas recusandae quis delectus\nofficiis harum fugiat
vitae"
},
{
"userId": 2,
"id": 16,
"title": "sint suscipit perspiciatis velit dolorum rerum ipsa laboriosam odio",
"body": "suscipit nam nisi quo aperiam aut\nasperiores eos fugit maiores
voluptatibus quia\nvoluptatem quis ullam qui in alias quia est\nconsequatur magni
mollitia accusamus ea nisi voluptate dicta"
},
{
"userId": 2,
"id": 17,
"title": "fugit voluptas sed molestias voluptatem provident",
"body": "eos voluptas et aut odit natus earum\naspernatur fuga molestiae
ullam\ndeserunt ratione qui eos\nqui nihil ratione nemo velit ut aut id quo"
},
{
"userId": 2,
"id": 18,
"title": "voluptate et itaque vero tempora molestiae",
"body": "eveniet quo quis\nlaborum totam consequatur non dolor\nut et est
repudiandae\nest voluptatem vel debitis et magnam"
},
{
"userId": 2,
"id": 19,
"title": "adipisci placeat illum aut reiciendis qui",
"body": "illum quis cupiditate provident sit magnam\nea sed aut omnis\nveniam
maiores ullam consequatur atque\nadipisci quo iste expedita sit quos voluptas"
},
{
"userId": 2,
"id": 20,
"title": "doloribus ad provident suscipit at",
"body": "qui consequuntur ducimus possimus quisquam amet similique\nsuscipit porro
ipsam amet\neos veritatis officiis exercitationem vel fugit aut necessitatibus
totam\nomnis rerum consequatur expedita quidem cumque explicabo"
},
{
"userId": 3,
"id": 21,
"title": "asperiores ea ipsam voluptatibus modi minima quia sint",
"body": "repellat aliquid praesentium dolorem quo\nsed totam minus non itaque\nnihil
labore molestiae sunt dolor eveniet hic recusandae veniam\ntempora et tenetur expedita
sunt"
},
{
"userId": 3,
"id": 22,
"title": "dolor sint quo a velit explicabo quia nam",
"body": "eos qui et ipsum ipsam suscipit aut\nsed omnis non odio\nexpedita earum
mollitia molestiae aut atque rem suscipit\nnam impedit esse"
},
{
"userId": 3,
"id": 23,
"title": "maxime id vitae nihil numquam",
"body": "veritatis unde neque eligendi\nquae quod architecto quo neque vitae\nest
illo sit tempora doloremque fugit quod\net et vel beatae sequi ullam sed tenetur
perspiciatis"
},
{
"userId": 3,
"id": 24,
"title": "autem hic labore sunt dolores incidunt",
"body": "enim et ex nulla\nomnis voluptas quia qui\nvoluptatem consequatur numquam
aliquam sunt\ntotam recusandae id dignissimos aut sed asperiores deserunt"
},
{
"userId": 3,
"id": 25,
"title": "rem alias distinctio quo quis",
"body": "ullam consequatur ut\nomnis quis sit vel consequuntur\nipsa eligendi ipsum
molestiae et omnis error nostrum\nmolestiae illo tempore quia et distinctio"
},
{
"userId": 3,
"id": 26,
"title": "est et quae odit qui non",
"body": "similique esse doloribus nihil accusamus\nomnis dolorem fuga consequuntur
reprehenderit fugit recusandae temporibus\nperspiciatis cum ut laudantium\nomnis aut
molestiae vel vero"
},
{
"userId": 3,
"id": 27,
"title": "quasi id et eos tenetur aut quo autem",
"body": "eum sed dolores ipsam sint possimus debitis occaecati\ndebitis qui qui
et\nut placeat enim earum aut odit facilis\nconsequatur suscipit necessitatibus rerum
sed inventore temporibus consequatur"
},
{
"userId": 3,
"id": 28,
"title": "delectus ullam et corporis nulla voluptas sequi",
"body": "non et quaerat ex quae ad maiores\nmaiores recusandae totam aut blanditiis
mollitia quas illo\nut voluptatibus voluptatem\nsimilique nostrum eum"
},
{
"userId": 3,
"id": 29,
"title": "iusto eius quod necessitatibus culpa ea",
"body": "odit magnam ut saepe sed non qui\ntempora atque nihil\naccusamus illum
doloribus illo dolor\neligendi repudiandae odit magni similique sed cum maiores"
},
{
"userId": 3,
"id": 30,
"title": "a quo magni similique perferendis",
"body": "alias dolor cumque\nimpedit blanditiis non eveniet odio maxime\nblanditiis
amet eius quis tempora quia autem rem\na provident perspiciatis quia"
},
{
"userId": 4,
"id": 31,
"title": "ullam ut quidem id aut vel consequuntur",
"body": "debitis eius sed quibusdam non quis consectetur vitae\nimpedit ut qui
consequatur sed aut in\nquidem sit nostrum et maiores adipisci atque\nquaerat voluptatem
adipisci repudiandae"
},
{
"userId": 4,
"id": 32,
"title": "doloremque illum aliquid sunt",
"body": "deserunt eos nobis asperiores et hic\nest debitis repellat molestiae
optio\nnihil ratione ut eos beatae quibusdam distinctio maiores\nearum voluptates et aut
adipisci ea maiores voluptas maxime"
},
{
"userId": 4,
"id": 33,
"title": "qui explicabo molestiae dolorem",
"body": "rerum ut et numquam laborum odit est sit\nid qui sint in\nquasi tenetur
tempore aperiam et quaerat qui in\nrerum officiis sequi cumque quod"
},
{
"userId": 4,
"id": 34,
"title": "magnam ut rerum iure",
"body": "ea velit perferendis earum ut voluptatem voluptate itaque iusto\ntotam
pariatur in\nnemo voluptatem voluptatem autem magni tempora minima in\nest distinctio
qui assumenda accusamus dignissimos officia nesciunt nobis"
},
{
"userId": 4,
"id": 35,
"title": "id nihil consequatur molestias animi provident",
"body": "nisi error delectus possimus ut eligendi vitae\nplaceat eos harum
cupiditate facilis reprehenderit voluptatem beatae\nmodi ducimus quo illum voluptas
eligendi\net nobis quia fugit"
},
{
"userId": 4,
"id": 36,
"title": "fuga nam accusamus voluptas reiciendis itaque",
"body": "ad mollitia et omnis minus architecto odit\nvoluptas doloremque maxime aut
non ipsa qui alias veniam\nblanditiis culpa aut quia nihil cumque facere et
occaecati\nqui aspernatur quia eaque ut aperiam inventore"
},
{
"userId": 4,
"id": 37,
"title": "provident vel ut sit ratione est",
"body": "debitis et eaque non officia sed nesciunt pariatur vel\nvoluptatem iste
vero et ea\nnumquam aut expedita ipsum nulla in\nvoluptates omnis consequatur aut enim
officiis in quam qui"
},
{
"userId": 4,
"id": 38,
"title": "explicabo et eos deleniti nostrum ab id repellendus",
"body": "animi esse sit aut sit nesciunt assumenda eum voluptas\nquia voluptatibus
provident quia necessitatibus ea\nrerum repudiandae quia voluptatem delectus fugit aut
id quia\nratione optio eos iusto veniam iure"
},
{
"userId": 4,
"id": 39,
"title": "eos dolorem iste accusantium est eaque quam",
"body": "corporis rerum ducimus vel eum accusantium\nmaxime aspernatur a porro
possimus iste omnis\nest in deleniti asperiores fuga aut\nvoluptas sapiente vel dolore
minus voluptatem incidunt ex"
},
{
"userId": 4,
"id": 40,
"title": "enim quo cumque",
"body": "ut voluptatum aliquid illo tenetur nemo sequi quo facilis\nipsum rem optio
mollitia quas\nvoluptatem eum voluptas qui\nunde omnis voluptatem iure quasi maxime
voluptas nam"
},
{
"userId": 5,
"id": 41,
"title": "non est facere",
"body": "molestias id nostrum\nexcepturi molestiae dolore omnis repellendus quaerat
saepe\nconsectetur iste quaerat tenetur asperiores accusamus ex ut\nnam quidem est
ducimus sunt debitis saepe"
},
{
"userId": 5,
"id": 42,
"title": "commodi ullam sint et excepturi error explicabo praesentium voluptas",
"body": "odio fugit voluptatum ducimus earum autem est incidunt voluptatem\nodit
reiciendis aliquam sunt sequi nulla dolorem\nnon facere repellendus voluptates
quia\nratione harum vitae ut"
},
{
"userId": 5,
"id": 43,
"title": "eligendi iste nostrum consequuntur adipisci praesentium sit beatae
perferendis",
"body": "similique fugit est\nillum et dolorum harum et voluptate eaque
quidem\nexercitationem quos nam commodi possimus cum odio nihil nulla\ndolorum
exercitationem magnam ex et a et distinctio debitis"
},
{
"userId": 5,
"id": 44,
"title": "optio dolor molestias sit",
"body": "temporibus est consectetur dolore\net libero debitis vel velit laboriosam
quia\nipsum quibusdam qui itaque fuga rem aut\nea et iure quam sed maxime ut distinctio
quae"
},
{
"userId": 5,
"id": 45,
"title": "ut numquam possimus omnis eius suscipit laudantium iure",
"body": "est natus reiciendis nihil possimus aut provident\nex et dolor\nrepellat
pariatur est\nnobis rerum repellendus dolorem autem"
},
{
"userId": 5,
"id": 46,
"title": "aut quo modi neque nostrum ducimus",
"body": "voluptatem quisquam iste\nvoluptatibus natus officiis facilis dolorem\nquis
quas ipsam\nvel et voluptatum in aliquid"
},
{
"userId": 5,
"id": 47,
"title": "quibusdam cumque rem aut deserunt",
"body": "voluptatem assumenda ut qui ut cupiditate aut impedit veniam\noccaecati
nemo illum voluptatem laudantium\nmolestiae beatae rerum ea iure soluta
nostrum\neligendi et voluptate"
},
{
"userId": 5,
"id": 48,
"title": "ut voluptatem illum ea doloribus itaque eos",
"body": "voluptates quo voluptatem facilis iure occaecati\nvel assumenda rerum
officia et\nillum perspiciatis ab deleniti\nlaudantium repellat ad ut et autem
reprehenderit"
},
{
"userId": 5,
"id": 49,
"title": "laborum non sunt aut ut assumenda perspiciatis voluptas",
"body": "inventore ab sint\nnatus fugit id nulla sequi architecto nihil quaerat\neos
tenetur in in eum veritatis non\nquibusdam officiis aspernatur cumque aut commodi aut"
},
{
"userId": 5,
"id": 50,
"title": "repellendus qui recusandae incidunt voluptates tenetur qui omnis
exercitationem",
"body": "error suscipit maxime adipisci consequuntur recusandae\nvoluptas eligendi
et est et voluptates\nquia distinctio ab amet quaerat molestiae et vitae\nadipisci
impedit sequi nesciunt quis consectetur"
},
{
"userId": 6,
"id": 51,
"title": "soluta aliquam aperiam consequatur illo quis voluptas",
"body": "sunt dolores aut doloribus\ndolore doloribus voluptates tempora
et\ndoloremque et quo\ncum asperiores sit consectetur dolorem"
},
{
"userId": 6,
"id": 52,
"title": "qui enim et consequuntur quia animi quis voluptate quibusdam",
"body": "iusto est quibusdam fuga quas quaerat molestias\na enim ut sit accusamus
enim\ntemporibus iusto accusantium provident architecto\nsoluta esse reprehenderit qui
laborum"
},
{
"userId": 6,
"id": 53,
"title": "ut quo aut ducimus alias",
"body": "minima harum praesentium eum rerum illo dolore\nquasi exercitationem rerum
nam\nporro quis neque quo\nconsequatur minus dolor quidem veritatis sunt non explicabo
similique"
},
{
"userId": 6,
"id": 54,
"title": "sit asperiores ipsam eveniet odio non quia",
"body": "totam corporis dignissimos\nvitae dolorem ut occaecati accusamus\nex velit
deserunt\net exercitationem vero incidunt corrupti mollitia"
},
{
"userId": 6,
"id": 55,
"title": "sit vel voluptatem et non libero",
"body": "debitis excepturi ea perferendis harum libero optio\neos accusamus cum fuga
ut sapiente repudiandae\net ut incidunt omnis molestiae\nnihil ut eum odit"
},
{
"userId": 6,
"id": 56,
"title": "qui et at rerum necessitatibus",
"body": "aut est omnis dolores\nneque rerum quod ea rerum velit pariatur beatae
excepturi\net provident voluptas corrupti\ncorporis harum reprehenderit dolores
eligendi"
},
{
"userId": 6,
"id": 57,
"title": "sed ab est est",
"body": "at pariatur consequuntur earum quidem\nquo est laudantium soluta
voluptatem\nqui ullam et est\net cum voluptas voluptatum repellat est"
},
{
"userId": 6,
"id": 58,
"title": "voluptatum itaque dolores nisi et quasi",
"body": "veniam voluptatum quae adipisci id\net id quia eos ad et dolorem\naliquam
quo nisi sunt eos impedit error\nad similique veniam"
},
{
"userId": 6,
"id": 59,
"title": "qui commodi dolor at maiores et quis id accusantium",
"body": "perspiciatis et quam ea autem temporibus non voluptatibus qui\nbeatae a
earum officia nesciunt dolores suscipit voluptas et\nanimi doloribus cum rerum quas et
magni\net hic ut ut commodi expedita sunt"
},
{
"userId": 6,
"id": 60,
"title": "consequatur placeat omnis quisquam quia reprehenderit fugit veritatis
facere",
"body": "asperiores sunt ab assumenda cumque modi velit\nqui esse omnis\nvoluptate
et fuga perferendis voluptas\nillo ratione amet aut et omnis"
},
{
"userId": 7,
"id": 61,
"title": "voluptatem doloribus consectetur est ut ducimus",
"body": "ab nemo optio odio\ndelectus tenetur corporis similique nobis repellendus
rerum omnis facilis\nvero blanditiis debitis in nesciunt doloribus dicta dolores\nmagnam
minus velit"
},
{
"userId": 7,
"id": 62,
"title": "beatae enim quia vel",
"body": "enim aspernatur illo distinctio quae praesentium\nbeatae alias amet
delectus qui voluptate distinctio\nodit sint accusantium autem omnis\nquo molestiae
omnis ea eveniet optio"
},
{
"userId": 7,
"id": 63,
"title": "voluptas blanditiis repellendus animi ducimus error sapiente et suscipit",
"body": "enim adipisci aspernatur nemo\nnumquam omnis facere dolorem dolor ex quis
temporibus incidunt\nab delectus culpa quo reprehenderit blanditiis
asperiores\naccusantium ut quam in voluptatibus voluptas ipsam dicta"
},
{
"userId": 7,
"id": 64,
"title": "et fugit quas eum in in aperiam quod",
"body": "id velit blanditiis\neum ea voluptatem\nmolestiae sint occaecati est eos
perspiciatis\nincidunt a error provident eaque aut aut qui"
},
{
"userId": 7,
"id": 65,
"title": "consequatur id enim sunt et et",
"body": "voluptatibus ex esse\nsint explicabo est aliquid cumque adipisci fuga
repellat labore\nmolestiae corrupti ex saepe at asperiores et perferendis\nnatus id esse
incidunt pariatur"
},
{
"userId": 7,
"id": 66,
"title": "repudiandae ea animi iusto",
"body": "officia veritatis tenetur vero qui itaque\nsint non ratione\nsed et ut
asperiores iusto eos molestiae nostrum\nveritatis quibusdam et nemo iusto saepe"
},
{
"userId": 7,
"id": 67,
"title": "aliquid eos sed fuga est maxime repellendus",
"body": "reprehenderit id nostrum\nvoluptas doloremque pariatur sint et accusantium
quia quod aspernatur\net fugiat amet\nnon sapiente et consequatur necessitatibus
molestiae"
},
{
"userId": 7,
"id": 68,
"title": "odio quis facere architecto reiciendis optio",
"body": "magnam molestiae perferendis quisquam\nqui cum reiciendis\nquaerat animi
amet hic inventore\nea quia deleniti quidem saepe porro velit"
},
{
"userId": 7,
"id": 69,
"title": "fugiat quod pariatur odit minima",
"body": "officiis error culpa consequatur modi asperiores et\ndolorum assumenda
voluptas et vel qui aut vel rerum\nvoluptatum quisquam perspiciatis quia rerum
consequatur totam quas\nsequi commodi repudiandae asperiores et saepe a"
},
{
"userId": 7,
"id": 70,
"title": "voluptatem laborum magni",
"body": "sunt repellendus quae\nest asperiores aut deleniti esse accusamus
repellendus quia aut\nquia dolorem unde\neum tempora esse dolore"
},
{
"userId": 8,
"id": 71,
"title": "et iusto veniam et illum aut fuga",
"body": "occaecati a doloribus\niste saepe consectetur placeat eum voluptate dolorem
et\nqui quo quia voluptas\nrerum ut id enim velit est perferendis"
},
{
"userId": 8,
"id": 72,
"title": "sint hic doloribus consequatur eos non id",
"body": "quam occaecati qui deleniti consectetur\nconsequatur aut facere quas
exercitationem aliquam hic voluptas\nneque id sunt ut aut accusamus\nsunt consectetur
expedita inventore velit"
},
{
"userId": 8,
"id": 73,
"title": "consequuntur deleniti eos quia temporibus ab aliquid at",
"body": "voluptatem cumque tenetur consequatur expedita ipsum nemo quia
explicabo\naut eum minima consequatur\ntempore cumque quae est et\net in consequuntur
voluptatem voluptates aut"
},
{
"userId": 8,
"id": 74,
"title": "enim unde ratione doloribus quas enim ut sit sapiente",
"body": "odit qui et et necessitatibus sint veniam\nmollitia amet doloremque
molestiae commodi similique magnam et quam\nblanditiis est itaque\nquo et tenetur
ratione occaecati molestiae tempora"
},
{
"userId": 8,
"id": 75,
"title": "dignissimos eum dolor ut enim et delectus in",
"body": "commodi non non omnis et voluptas sit\nautem aut nobis magnam et sapiente
voluptatem\net laborum repellat qui delectus facilis temporibus\nrerum amet et nemo
voluptate expedita adipisci error dolorem"
},
{
"userId": 8,
"id": 76,
"title": "doloremque officiis ad et non perferendis",
"body": "ut animi facere\ntotam iusto tempore\nmolestiae eum aut et dolorem
aperiam\nquaerat recusandae totam odio"
},
{
"userId": 8,
"id": 77,
"title": "necessitatibus quasi exercitationem odio",
"body": "modi ut in nulla repudiandae dolorum nostrum eos\naut consequatur omnis\nut
incidunt est omnis iste et quam\nvoluptates sapiente aliquam asperiores nobis amet
corrupti repudiandae provident"
},
{
"userId": 8,
"id": 78,
"title": "quam voluptatibus rerum veritatis",
"body": "nobis facilis odit tempore cupiditate quia\nassumenda doloribus rerum qui
ea\nillum et qui totam\naut veniam repellendus"
},
{
"userId": 8,
"id": 79,
"title": "pariatur consequatur quia magnam autem omnis non amet",
"body": "libero accusantium et et facere incidunt sit dolorem\nnon excepturi qui
quia sed laudantium\nquisquam molestiae ducimus est\nofficiis esse molestiae iste et
quos"
},
{
"userId": 8,
"id": 80,
"title": "labore in ex et explicabo corporis aut quas",
"body": "ex quod dolorem ea eum iure qui provident amet\nquia qui facere excepturi
et repudiandae\nasperiores molestias provident\nminus incidunt vero fugit rerum sint
sunt excepturi provident"
},
{
"userId": 9,
"id": 81,
"title": "tempora rem veritatis voluptas quo dolores vero",
"body": "facere qui nesciunt est voluptatum voluptatem nisi\nsequi eligendi
necessitatibus ea at rerum itaque\nharum non ratione velit laboriosam quis
consequuntur\nex officiis minima doloremque voluptas ut aut"
},
{
"userId": 9,
"id": 82,
"title": "laudantium voluptate suscipit sunt enim enim",
"body": "ut libero sit aut totam inventore sunt\nporro sint qui sunt
molestiae\nconsequatur cupiditate qui iste ducimus adipisci\ndolor enim assumenda soluta
laboriosam amet iste delectus hic"
},
{
"userId": 9,
"id": 83,
"title": "odit et voluptates doloribus alias odio et",
"body": "est molestiae facilis quis tempora numquam nihil qui\nvoluptate sapiente
consequatur est qui\nnecessitatibus autem aut ipsa aperiam modi dolore
numquam\nreprehenderit eius rem quibusdam"
},
{
"userId": 9,
"id": 84,
"title": "optio ipsam molestias necessitatibus occaecati facilis veritatis dolores
aut",
"body": "sint molestiae magni a et quos\neaque et quasi\nut rerum debitis similique
veniam\nrecusandae dignissimos dolor incidunt consequatur odio"
},
{
"userId": 9,
"id": 85,
"title": "dolore veritatis porro provident adipisci blanditiis et sunt",
"body": "similique sed nisi voluptas iusto omnis\nmollitia et quo\nassumenda
suscipit officia magnam sint sed tempora\nenim provident pariatur praesentium atque
animi amet ratione"
},
{
"userId": 9,
"id": 86,
"title": "placeat quia et porro iste",
"body": "quasi excepturi consequatur iste autem temporibus sed molestiae beatae\net
quaerat et esse ut\nvoluptatem occaecati et vel explicabo autem\nasperiores pariatur
deserunt optio"
},
{
"userId": 9,
"id": 87,
"title": "nostrum quis quasi placeat",
"body": "eos et molestiae\nnesciunt ut a\ndolores perspiciatis repellendus repellat
aliquid\nmagnam sint rem ipsum est"
},
{
"userId": 9,
"id": 88,
"title": "sapiente omnis fugit eos",
"body": "consequatur omnis est praesentium\nducimus non iste\nneque hic
deserunt\nvoluptatibus veniam cum et rerum sed"
},
{
"userId": 9,
"id": 89,
"title": "sint soluta et vel magnam aut ut sed qui",
"body": "repellat aut aperiam totam temporibus autem et\narchitecto magnam
ut\nconsequatur qui cupiditate rerum quia soluta dignissimos nihil iure\ntempore quas
est"
},
{
"userId": 9,
"id": 90,
"title": "ad iusto omnis odit dolor voluptatibus",
"body": "minus omnis soluta quia\nqui sed adipisci voluptates illum ipsam
voluptatem\neligendi officia ut in\neos soluta similique molestias praesentium
blanditiis"
},
{
"userId": 10,
"id": 91,
"title": "aut amet sed",
"body": "libero voluptate eveniet aperiam sed\nsunt placeat suscipit
molestias\nsimilique fugit nam natus\nexpedita consequatur consequatur dolores quia eos
et placeat"
},
{
"userId": 10,
"id": 92,
"title": "ratione ex tenetur perferendis",
"body": "aut et excepturi dicta laudantium sint rerum nihil\nlaudantium et at\na
neque minima officia et similique libero et\ncommodi voluptate qui"
},
{
"userId": 10,
"id": 93,
"title": "beatae soluta recusandae",
"body": "dolorem quibusdam ducimus consequuntur dicta aut quo laboriosam\nvoluptatem
quis enim recusandae ut sed sunt\nnostrum est odit totam\nsit error sed sunt eveniet
provident qui nulla"
},
{
"userId": 10,
"id": 94,
"title": "qui qui voluptates illo iste minima",
"body": "aspernatur expedita soluta quo ab ut similique\nexpedita dolores amet\nsed
temporibus distinctio magnam saepe deleniti\nomnis facilis nam ipsum natus sint
similique omnis"
},
{
"userId": 10,
"id": 95,
"title": "id minus libero illum nam ad officiis",
"body": "earum voluptatem facere provident blanditiis velit laboriosam\npariatur
accusamus odio saepe\ncumque dolor qui a dicta ab doloribus consequatur omnis\ncorporis
cupiditate eaque assumenda ad nesciunt"
},
{
"userId": 10,
"id": 96,
"title": "quaerat velit veniam amet cupiditate aut numquam ut sequi",
"body": "in non odio excepturi sint eum\nlabore voluptates vitae quia qui
et\ninventore itaque rerum\nveniam non exercitationem delectus aut"
},
{
"userId": 10,
"id": 97,
"title": "quas fugiat ut perspiciatis vero provident",
"body": "eum non blanditiis soluta porro quibusdam voluptas\nvel voluptatem qui
placeat dolores qui velit aut\nvel inventore aut cumque culpa explicabo aliquid
at\nperspiciatis est et voluptatem dignissimos dolor itaque sit nam"
},
{
"userId": 10,
"id": 98,
"title": "laboriosam dolor voluptates",
"body": "doloremque ex facilis sit sint culpa\nsoluta assumenda eligendi non ut
eius\nsequi ducimus vel quasi\nveritatis est dolores"
},
{
"userId": 10,
"id": 99,
"title": "temporibus sit alias delectus eligendi possimus magni",
"body": "quo deleniti praesentium dicta non quod\naut est molestias\nmolestias et
officia quis nihil\nitaque dolorem quia"
},
{
"userId": 10,
"id": 100,
"title": "at nam consequatur ea labore ea harum",
"body": "cupiditate quo est a modi nesciunt soluta\nipsa voluptas error itaque dicta
in\nautem qui minus magnam et distinctio eum\naccusamus ratione error aut"
}
]
<Response [200]>
Analizando la respuesta
El métoodo .request devuelve un objeto que contiene dos elementos claves (entre otros): el código de la
respuesta y el cuerpo body.
El código de la respuesta
En caso de haber obtenido exitosamente la respuesta, el código será 200 (OK). Existen varios códigos, pero
no es necesario saberlos de memoria, ya que podemos encontrarlos de forma muy rápida en internet.
1xx: Información
2xx: Solicitudes exitosas
3xx: Redireccionamiento
4xx: Error del cliente (no hizo la request correctamente)
5xx: Error del servidor (no puede dar una respuesta)
200: Ok
401: Unauthorized
403: Forbidden
404: Not Found
500: Server error
El contenido de la respuesta
La otra parte de la respuesta es el cuerpo, o body, el cual contiene la información que nos interesa. Esta
información viene como un string, lo que hace muy complicado extraer información, por ejemplo, si solo
queremos saber un detalle my específico de la respuesta, o seleccionar elementos específicos de ellas.
"[\n {\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"sunt aut facere repellat
provident occaecati excepturi optio reprehenderit\",\n \"body\": \"quia et
suscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut
ut quas totam\\nnostrum rerum est autem sunt rem eveniet architecto\"\n },\n {\n
\"userId\": 1,\n \"id\": 2,\n \"title\": \"qui est esse\",\n \"body\": \"est
rerum tempore vitae\\nsequi sint nihil reprehenderit dolor beatae ea dolores
neque\\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\\nqui
aperiam non debitis possimus qui neque nisi nulla\"\n },\n {\n \"userId\": 1,\n
\"id\": 3,\n \"title\": \"ea molestias quasi exercitationem repellat qui ipsa sit
aut\",\n \"body\": \"et iusto sed quo iure\\nvoluptatem occaecati omnis eligendi aut
ad\\nvoluptatem doloribus vel accusantium quis pariatur\\nmolestiae porro eius odio et
labore et velit aut\"\n },\n {\n \"userId\": 1,\n \"id\": 4,\n \"title\":
\"eum et est occaecati\",\n \"body\": \"ullam et saepe reiciendis voluptatem
adipisci\\nsit amet autem assumenda provident rerum culpa\\nquis hic commodi nesciunt
rem tenetur doloremque ipsam iure\\nquis sunt voluptatem rerum illo velit\"\n },\n {\n
\"userId\": 1,\n \"id\": 5,\n \"title\": \"nesciunt quas odio\",\n
Sin embargo, el contenido dentro de este string tiene una estructura JSON, lo que hace muy fácil
transformar los datos en un diccionario o una lista. A esto se le denomina parsing: transformar un input (ya
sea un archivo o datos introducidos por el usuario, o la respuesta de una API) en datos que pueden ser
fácilmente manipulados.
import json
results = [Link]([Link])
print(type(results)) # Veremos que el resultado es una lista
print(results[0]) # Mostramos el primer elemento
<class 'list'>
{'userId': 1, 'id': 1, 'title': 'sunt aut facere repellat provident occaecati excepturi
optio reprehenderit', 'body': 'quia et suscipit\nsuscipit recusandae consequuntur
expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt
rem eveniet architecto'}
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio
reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et
cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet
architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea
dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui
aperiam non debitis possimus qui neque nisi nulla"
}, ...
Accediendo a un solo elemento de la respuesta
Dentro del primer elemento, lo que tenemos es un diccionario y podemos accederlo como aprendimos.
print(results[0]["userId"])
print(results[0]["title"])
1
sunt aut facere repellat provident occaecati excepturi optio reprehenderit
import json
import requests
def request(requested_url):
headers = {
"cache-control": "no-cache",
"Postman-Token": "2defb9f3-9b11-499b-be4f-82505a2f8e1a",
}
response = [Link]("GET", requested_url, headers=headers)
return [Link]([Link])
request('[Link]
[{'userId': 1,
'id': 1,
'title': 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
'body': 'quia et suscipit\nsuscipit recusandae consequuntur expedita et
cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet
architecto'},
{'userId': 1,
'id': 2,
'title': 'qui est esse',
'body': 'est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea
dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui
aperiam non debitis possimus qui neque nisi nulla'},
{'userId': 1,
'id': 3,
'title': 'ea molestias quasi exercitationem repellat qui ipsa sit aut',
'body': 'et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem
doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit
aut'},
{'userId': 1,
'id': 4,
'title': 'eum et est occaecati',
'body': 'ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda
provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis
sunt voluptatem rerum illo velit'},
{'userId': 1,
'id': 5,
'title': 'nesciunt quas odio',
'body': 'repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed
est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque'},
{'userId': 1,
'id': 6,
'title': 'dolorem eum magni eos aperiam quia',
'body': 'ut aspernatur corporis harum nihil quis provident sequi\nmollitia nobis
aliquid molestiae\nperspiciatis et ea nemo ab reprehenderit accusantium quas\nvoluptate
dolores velit et doloremque molestiae'},
{'userId': 1,
'id': 7,
'title': 'magnam facilis autem',
'body': 'dolore placeat quibusdam ea quo vitae\nmagni quis enim qui quis quo nemo aut
saepe\nquidem repellat excepturi ut quia\nsunt ut sequi eos ea sed quas'},
{'userId': 1,
'id': 8,
'title': 'dolorem dolore est ipsam',
'body': 'dignissimos aperiam dolorem qui eum\nfacilis quibusdam animi sint suscipit
qui sint possimus cum\nquaerat magni maiores excepturi\nipsam ut commodi dolor
voluptatum modi aut vitae'},
{'userId': 1,
'id': 9,
'title': 'nesciunt iure omnis dolorem tempora et accusantium',
'body': 'consectetur animi nesciunt iure dolore\nenim quia ad\nveniam autem ut quam
aut nobis\net est aut quod aut provident voluptas autem voluptas'},
{'userId': 1,
'id': 10,
'title': 'optio molestias id quia eum',
'body': 'quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero
nisi sit\nquos veniam quod sed accusamus veritatis error'},
{'userId': 2,
'id': 11,
'title': 'et ea vero quia laudantium autem',
'body': 'delectus reiciendis molestiae occaecati non minima eveniet qui
voluptatibus\naccusamus in eum beatae sit\nvel qui neque voluptates ut commodi qui
incidunt\nut animi commodi'},
{'userId': 2,
'id': 12,
'title': 'in quibusdam tempore odit est dolorem',
'body': 'itaque id aut magnam\npraesentium quia et ea odit et ea voluptas et\nsapiente
quia nihil amet occaecati quia id voluptatem\nincidunt ea est distinctio odio'},
{'userId': 2,
'id': 13,
'title': 'dolorum ut in voluptas mollitia et saepe quo animi',
'body': 'aut dicta possimus sint mollitia voluptas commodi quo doloremque\niste
corrupti reiciendis voluptatem eius rerum\nsit cumque quod eligendi laborum
minima\nperferendis recusandae assumenda consectetur porro architecto ipsum ipsam'},
{'userId': 2,
'id': 14,
'title': 'voluptatem eligendi optio',
'body': 'fuga et accusamus dolorum perferendis illo voluptas\nnon doloremque neque
facere\nad qui dolorum molestiae beatae\nsed aut voluptas totam sit illum'},
{'userId': 2,
'id': 15,
'title': 'eveniet quod temporibus',
'body': 'reprehenderit quos placeat\nvelit minima officia dolores impedit repudiandae
molestiae nam\nvoluptas recusandae quis delectus\nofficiis harum fugiat vitae'},
{'userId': 2,
'id': 16,
'title': 'sint suscipit perspiciatis velit dolorum rerum ipsa laboriosam odio',
'body': 'suscipit nam nisi quo aperiam aut\nasperiores eos fugit maiores voluptatibus
quia\nvoluptatem quis ullam qui in alias quia est\nconsequatur magni mollitia accusamus
ea nisi voluptate dicta'},
{'userId': 2,
'id': 17,
'title': 'fugit voluptas sed molestias voluptatem provident',
'body': 'eos voluptas et aut odit natus earum\naspernatur fuga molestiae
ullam\ndeserunt ratione qui eos\nqui nihil ratione nemo velit ut aut id quo'},
{'userId': 2,
'id': 18,
'title': 'voluptate et itaque vero tempora molestiae',
'body': 'eveniet quo quis\nlaborum totam consequatur non dolor\nut et est
repudiandae\nest voluptatem vel debitis et magnam'},
{'userId': 2,
'id': 19,
'title': 'adipisci placeat illum aut reiciendis qui',
'body': 'illum quis cupiditate provident sit magnam\nea sed aut omnis\nveniam maiores
ullam consequatur atque\nadipisci quo iste expedita sit quos voluptas'},
{'userId': 2,
'id': 20,
'title': 'doloribus ad provident suscipit at',
'body': 'qui consequuntur ducimus possimus quisquam amet similique\nsuscipit porro
ipsam amet\neos veritatis officiis exercitationem vel fugit aut necessitatibus
totam\nomnis rerum consequatur expedita quidem cumque explicabo'},
{'userId': 3,
'id': 21,
'title': 'asperiores ea ipsam voluptatibus modi minima quia sint',
'body': 'repellat aliquid praesentium dolorem quo\nsed totam minus non itaque\nnihil
labore molestiae sunt dolor eveniet hic recusandae veniam\ntempora et tenetur expedita
sunt'},
{'userId': 3,
'id': 22,
'title': 'dolor sint quo a velit explicabo quia nam',
'body': 'eos qui et ipsum ipsam suscipit aut\nsed omnis non odio\nexpedita earum
mollitia molestiae aut atque rem suscipit\nnam impedit esse'},
{'userId': 3,
'id': 23,
'title': 'maxime id vitae nihil numquam',
'body': 'veritatis unde neque eligendi\nquae quod architecto quo neque vitae\nest illo
sit tempora doloremque fugit quod\net et vel beatae sequi ullam sed tenetur
perspiciatis'},
{'userId': 3,
'id': 24,
'title': 'autem hic labore sunt dolores incidunt',
'body': 'enim et ex nulla\nomnis voluptas quia qui\nvoluptatem consequatur numquam
aliquam sunt\ntotam recusandae id dignissimos aut sed asperiores deserunt'},
{'userId': 3,
'id': 25,
'title': 'rem alias distinctio quo quis',
'body': 'ullam consequatur ut\nomnis quis sit vel consequuntur\nipsa eligendi ipsum
molestiae et omnis error nostrum\nmolestiae illo tempore quia et distinctio'},
{'userId': 3,
'id': 26,
'title': 'est et quae odit qui non',
'body': 'similique esse doloribus nihil accusamus\nomnis dolorem fuga consequuntur
reprehenderit fugit recusandae temporibus\nperspiciatis cum ut laudantium\nomnis aut
molestiae vel vero'},
{'userId': 3,
'id': 27,
'title': 'quasi id et eos tenetur aut quo autem',
'body': 'eum sed dolores ipsam sint possimus debitis occaecati\ndebitis qui qui et\nut
placeat enim earum aut odit facilis\nconsequatur suscipit necessitatibus rerum sed
inventore temporibus consequatur'},
{'userId': 3,
'id': 28,
'title': 'delectus ullam et corporis nulla voluptas sequi',
'body': 'non et quaerat ex quae ad maiores\nmaiores recusandae totam aut blanditiis
mollitia quas illo\nut voluptatibus voluptatem\nsimilique nostrum eum'},
{'userId': 3,
'id': 29,
'title': 'iusto eius quod necessitatibus culpa ea',
'body': 'odit magnam ut saepe sed non qui\ntempora atque nihil\naccusamus illum
doloribus illo dolor\neligendi repudiandae odit magni similique sed cum maiores'},
{'userId': 3,
'id': 30,
'title': 'a quo magni similique perferendis',
'body': 'alias dolor cumque\nimpedit blanditiis non eveniet odio maxime\nblanditiis
amet eius quis tempora quia autem rem\na provident perspiciatis quia'},
{'userId': 4,
'id': 31,
'title': 'ullam ut quidem id aut vel consequuntur',
'body': 'debitis eius sed quibusdam non quis consectetur vitae\nimpedit ut qui
consequatur sed aut in\nquidem sit nostrum et maiores adipisci atque\nquaerat voluptatem
adipisci repudiandae'},
{'userId': 4,
'id': 32,
'title': 'doloremque illum aliquid sunt',
'body': 'deserunt eos nobis asperiores et hic\nest debitis repellat molestiae
optio\nnihil ratione ut eos beatae quibusdam distinctio maiores\nearum voluptates et aut
adipisci ea maiores voluptas maxime'},
{'userId': 4,
'id': 33,
'title': 'qui explicabo molestiae dolorem',
'body': 'rerum ut et numquam laborum odit est sit\nid qui sint in\nquasi tenetur
tempore aperiam et quaerat qui in\nrerum officiis sequi cumque quod'},
{'userId': 4,
'id': 34,
'title': 'magnam ut rerum iure',
'body': 'ea velit perferendis earum ut voluptatem voluptate itaque iusto\ntotam
pariatur in\nnemo voluptatem voluptatem autem magni tempora minima in\nest distinctio
qui assumenda accusamus dignissimos officia nesciunt nobis'},
{'userId': 4,
'id': 35,
'title': 'id nihil consequatur molestias animi provident',
'body': 'nisi error delectus possimus ut eligendi vitae\nplaceat eos harum cupiditate
facilis reprehenderit voluptatem beatae\nmodi ducimus quo illum voluptas eligendi\net
nobis quia fugit'},
{'userId': 4,
'id': 36,
'title': 'fuga nam accusamus voluptas reiciendis itaque',
'body': 'ad mollitia et omnis minus architecto odit\nvoluptas doloremque maxime aut
non ipsa qui alias veniam\nblanditiis culpa aut quia nihil cumque facere et
occaecati\nqui aspernatur quia eaque ut aperiam inventore'},
{'userId': 4,
'id': 37,
'title': 'provident vel ut sit ratione est',
'body': 'debitis et eaque non officia sed nesciunt pariatur vel\nvoluptatem iste vero
et ea\nnumquam aut expedita ipsum nulla in\nvoluptates omnis consequatur aut enim
officiis in quam qui'},
{'userId': 4,
'id': 38,
'title': 'explicabo et eos deleniti nostrum ab id repellendus',
'body': 'animi esse sit aut sit nesciunt assumenda eum voluptas\nquia voluptatibus
provident quia necessitatibus ea\nrerum repudiandae quia voluptatem delectus fugit aut
id quia\nratione optio eos iusto veniam iure'},
{'userId': 4,
'id': 39,
'title': 'eos dolorem iste accusantium est eaque quam',
'body': 'corporis rerum ducimus vel eum accusantium\nmaxime aspernatur a porro
possimus iste omnis\nest in deleniti asperiores fuga aut\nvoluptas sapiente vel dolore
minus voluptatem incidunt ex'},
{'userId': 4,
'id': 40,
'title': 'enim quo cumque',
'body': 'ut voluptatum aliquid illo tenetur nemo sequi quo facilis\nipsum rem optio
mollitia quas\nvoluptatem eum voluptas qui\nunde omnis voluptatem iure quasi maxime
voluptas nam'},
{'userId': 5,
'id': 41,
'title': 'non est facere',
'body': 'molestias id nostrum\nexcepturi molestiae dolore omnis repellendus quaerat
saepe\nconsectetur iste quaerat tenetur asperiores accusamus ex ut\nnam quidem est
ducimus sunt debitis saepe'},
{'userId': 5,
'id': 42,
'title': 'commodi ullam sint et excepturi error explicabo praesentium voluptas',
'body': 'odio fugit voluptatum ducimus earum autem est incidunt voluptatem\nodit
reiciendis aliquam sunt sequi nulla dolorem\nnon facere repellendus voluptates
quia\nratione harum vitae ut'},
{'userId': 5,
'id': 43,
'title': 'eligendi iste nostrum consequuntur adipisci praesentium sit beatae
perferendis',
'body': 'similique fugit est\nillum et dolorum harum et voluptate eaque
quidem\nexercitationem quos nam commodi possimus cum odio nihil nulla\ndolorum
exercitationem magnam ex et a et distinctio debitis'},
{'userId': 5,
'id': 44,
'title': 'optio dolor molestias sit',
'body': 'temporibus est consectetur dolore\net libero debitis vel velit laboriosam
quia\nipsum quibusdam qui itaque fuga rem aut\nea et iure quam sed maxime ut distinctio
quae'},
{'userId': 5,
'id': 45,
'title': 'ut numquam possimus omnis eius suscipit laudantium iure',
'body': 'est natus reiciendis nihil possimus aut provident\nex et dolor\nrepellat
pariatur est\nnobis rerum repellendus dolorem autem'},
{'userId': 5,
'id': 46,
'title': 'aut quo modi neque nostrum ducimus',
'body': 'voluptatem quisquam iste\nvoluptatibus natus officiis facilis dolorem\nquis
quas ipsam\nvel et voluptatum in aliquid'},
{'userId': 5,
'id': 47,
'title': 'quibusdam cumque rem aut deserunt',
'body': 'voluptatem assumenda ut qui ut cupiditate aut impedit veniam\noccaecati nemo
illum voluptatem laudantium\nmolestiae beatae rerum ea iure soluta nostrum\neligendi et
voluptate'},
{'userId': 5,
'id': 48,
'title': 'ut voluptatem illum ea doloribus itaque eos',
'body': 'voluptates quo voluptatem facilis iure occaecati\nvel assumenda rerum officia
et\nillum perspiciatis ab deleniti\nlaudantium repellat ad ut et autem reprehenderit'},
{'userId': 5,
'id': 49,
'title': 'laborum non sunt aut ut assumenda perspiciatis voluptas',
'body': 'inventore ab sint\nnatus fugit id nulla sequi architecto nihil quaerat\neos
tenetur in in eum veritatis non\nquibusdam officiis aspernatur cumque aut commodi aut'},
{'userId': 5,
'id': 50,
'title': 'repellendus qui recusandae incidunt voluptates tenetur qui omnis
exercitationem',
'body': 'error suscipit maxime adipisci consequuntur recusandae\nvoluptas eligendi et
est et voluptates\nquia distinctio ab amet quaerat molestiae et vitae\nadipisci impedit
sequi nesciunt quis consectetur'},
{'userId': 6,
'id': 51,
'title': 'soluta aliquam aperiam consequatur illo quis voluptas',
'body': 'sunt dolores aut doloribus\ndolore doloribus voluptates tempora
et\ndoloremque et quo\ncum asperiores sit consectetur dolorem'},
{'userId': 6,
'id': 52,
'title': 'qui enim et consequuntur quia animi quis voluptate quibusdam',
'body': 'iusto est quibusdam fuga quas quaerat molestias\na enim ut sit accusamus
enim\ntemporibus iusto accusantium provident architecto\nsoluta esse reprehenderit qui
laborum'},
{'userId': 6,
'id': 53,
'title': 'ut quo aut ducimus alias',
'body': 'minima harum praesentium eum rerum illo dolore\nquasi exercitationem rerum
nam\nporro quis neque quo\nconsequatur minus dolor quidem veritatis sunt non explicabo
similique'},
{'userId': 6,
'id': 54,
'title': 'sit asperiores ipsam eveniet odio non quia',
'body': 'totam corporis dignissimos\nvitae dolorem ut occaecati accusamus\nex velit
deserunt\net exercitationem vero incidunt corrupti mollitia'},
{'userId': 6,
'id': 55,
'title': 'sit vel voluptatem et non libero',
'body': 'debitis excepturi ea perferendis harum libero optio\neos accusamus cum fuga
ut sapiente repudiandae\net ut incidunt omnis molestiae\nnihil ut eum odit'},
{'userId': 6,
'id': 56,
'title': 'qui et at rerum necessitatibus',
'body': 'aut est omnis dolores\nneque rerum quod ea rerum velit pariatur beatae
excepturi\net provident voluptas corrupti\ncorporis harum reprehenderit dolores
eligendi'},
{'userId': 6,
'id': 57,
'title': 'sed ab est est',
'body': 'at pariatur consequuntur earum quidem\nquo est laudantium soluta
voluptatem\nqui ullam et est\net cum voluptas voluptatum repellat est'},
{'userId': 6,
'id': 58,
'title': 'voluptatum itaque dolores nisi et quasi',
'body': 'veniam voluptatum quae adipisci id\net id quia eos ad et dolorem\naliquam quo
nisi sunt eos impedit error\nad similique veniam'},
{'userId': 6,
'id': 59,
'title': 'qui commodi dolor at maiores et quis id accusantium',
'body': 'perspiciatis et quam ea autem temporibus non voluptatibus qui\nbeatae a earum
officia nesciunt dolores suscipit voluptas et\nanimi doloribus cum rerum quas et
magni\net hic ut ut commodi expedita sunt'},
{'userId': 6,
'id': 60,
'title': 'consequatur placeat omnis quisquam quia reprehenderit fugit veritatis
facere',
'body': 'asperiores sunt ab assumenda cumque modi velit\nqui esse omnis\nvoluptate et
fuga perferendis voluptas\nillo ratione amet aut et omnis'},
{'userId': 7,
'id': 61,
'title': 'voluptatem doloribus consectetur est ut ducimus',
'body': 'ab nemo optio odio\ndelectus tenetur corporis similique nobis repellendus
rerum omnis facilis\nvero blanditiis debitis in nesciunt doloribus dicta dolores\nmagnam
minus velit'},
{'userId': 7,
'id': 62,
'title': 'beatae enim quia vel',
'body': 'enim aspernatur illo distinctio quae praesentium\nbeatae alias amet delectus
qui voluptate distinctio\nodit sint accusantium autem omnis\nquo molestiae omnis ea
eveniet optio'},
{'userId': 7,
'id': 63,
'title': 'voluptas blanditiis repellendus animi ducimus error sapiente et suscipit',
'body': 'enim adipisci aspernatur nemo\nnumquam omnis facere dolorem dolor ex quis
temporibus incidunt\nab delectus culpa quo reprehenderit blanditiis
asperiores\naccusantium ut quam in voluptatibus voluptas ipsam dicta'},
{'userId': 7,
'id': 64,
'title': 'et fugit quas eum in in aperiam quod',
'body': 'id velit blanditiis\neum ea voluptatem\nmolestiae sint occaecati est eos
perspiciatis\nincidunt a error provident eaque aut aut qui'},
{'userId': 7,
'id': 65,
'title': 'consequatur id enim sunt et et',
'body': 'voluptatibus ex esse\nsint explicabo est aliquid cumque adipisci fuga
repellat labore\nmolestiae corrupti ex saepe at asperiores et perferendis\nnatus id esse
incidunt pariatur'},
{'userId': 7,
'id': 66,
'title': 'repudiandae ea animi iusto',
'body': 'officia veritatis tenetur vero qui itaque\nsint non ratione\nsed et ut
asperiores iusto eos molestiae nostrum\nveritatis quibusdam et nemo iusto saepe'},
{'userId': 7,
'id': 67,
'title': 'aliquid eos sed fuga est maxime repellendus',
'body': 'reprehenderit id nostrum\nvoluptas doloremque pariatur sint et accusantium
quia quod aspernatur\net fugiat amet\nnon sapiente et consequatur necessitatibus
molestiae'},
{'userId': 7,
'id': 68,
'title': 'odio quis facere architecto reiciendis optio',
'body': 'magnam molestiae perferendis quisquam\nqui cum reiciendis\nquaerat animi amet
hic inventore\nea quia deleniti quidem saepe porro velit'},
{'userId': 7,
'id': 69,
'title': 'fugiat quod pariatur odit minima',
'body': 'officiis error culpa consequatur modi asperiores et\ndolorum assumenda
voluptas et vel qui aut vel rerum\nvoluptatum quisquam perspiciatis quia rerum
consequatur totam quas\nsequi commodi repudiandae asperiores et saepe a'},
{'userId': 7,
'id': 70,
'title': 'voluptatem laborum magni',
'body': 'sunt repellendus quae\nest asperiores aut deleniti esse accusamus repellendus
quia aut\nquia dolorem unde\neum tempora esse dolore'},
{'userId': 8,
'id': 71,
'title': 'et iusto veniam et illum aut fuga',
'body': 'occaecati a doloribus\niste saepe consectetur placeat eum voluptate dolorem
et\nqui quo quia voluptas\nrerum ut id enim velit est perferendis'},
{'userId': 8,
'id': 72,
'title': 'sint hic doloribus consequatur eos non id',
'body': 'quam occaecati qui deleniti consectetur\nconsequatur aut facere quas
exercitationem aliquam hic voluptas\nneque id sunt ut aut accusamus\nsunt consectetur
expedita inventore velit'},
{'userId': 8,
'id': 73,
'title': 'consequuntur deleniti eos quia temporibus ab aliquid at',
'body': 'voluptatem cumque tenetur consequatur expedita ipsum nemo quia explicabo\naut
eum minima consequatur\ntempore cumque quae est et\net in consequuntur voluptatem
voluptates aut'},
{'userId': 8,
'id': 74,
'title': 'enim unde ratione doloribus quas enim ut sit sapiente',
'body': 'odit qui et et necessitatibus sint veniam\nmollitia amet doloremque molestiae
commodi similique magnam et quam\nblanditiis est itaque\nquo et tenetur ratione
occaecati molestiae tempora'},
{'userId': 8,
'id': 75,
'title': 'dignissimos eum dolor ut enim et delectus in',
'body': 'commodi non non omnis et voluptas sit\nautem aut nobis magnam et sapiente
voluptatem\net laborum repellat qui delectus facilis temporibus\nrerum amet et nemo
voluptate expedita adipisci error dolorem'},
{'userId': 8,
'id': 76,
'title': 'doloremque officiis ad et non perferendis',
'body': 'ut animi facere\ntotam iusto tempore\nmolestiae eum aut et dolorem
aperiam\nquaerat recusandae totam odio'},
{'userId': 8,
'id': 77,
'title': 'necessitatibus quasi exercitationem odio',
'body': 'modi ut in nulla repudiandae dolorum nostrum eos\naut consequatur omnis\nut
incidunt est omnis iste et quam\nvoluptates sapiente aliquam asperiores nobis amet
corrupti repudiandae provident'},
{'userId': 8,
'id': 78,
'title': 'quam voluptatibus rerum veritatis',
'body': 'nobis facilis odit tempore cupiditate quia\nassumenda doloribus rerum qui
ea\nillum et qui totam\naut veniam repellendus'},
{'userId': 8,
'id': 79,
'title': 'pariatur consequatur quia magnam autem omnis non amet',
'body': 'libero accusantium et et facere incidunt sit dolorem\nnon excepturi qui quia
sed laudantium\nquisquam molestiae ducimus est\nofficiis esse molestiae iste et quos'},
{'userId': 8,
'id': 80,
'title': 'labore in ex et explicabo corporis aut quas',
'body': 'ex quod dolorem ea eum iure qui provident amet\nquia qui facere excepturi et
repudiandae\nasperiores molestias provident\nminus incidunt vero fugit rerum sint sunt
excepturi provident'},
{'userId': 9,
'id': 81,
'title': 'tempora rem veritatis voluptas quo dolores vero',
'body': 'facere qui nesciunt est voluptatum voluptatem nisi\nsequi eligendi
necessitatibus ea at rerum itaque\nharum non ratione velit laboriosam quis
consequuntur\nex officiis minima doloremque voluptas ut aut'},
{'userId': 9,
'id': 82,
'title': 'laudantium voluptate suscipit sunt enim enim',
'body': 'ut libero sit aut totam inventore sunt\nporro sint qui sunt
molestiae\nconsequatur cupiditate qui iste ducimus adipisci\ndolor enim assumenda soluta
laboriosam amet iste delectus hic'},
{'userId': 9,
'id': 83,
'title': 'odit et voluptates doloribus alias odio et',
'body': 'est molestiae facilis quis tempora numquam nihil qui\nvoluptate sapiente
consequatur est qui\nnecessitatibus autem aut ipsa aperiam modi dolore
numquam\nreprehenderit eius rem quibusdam'},
{'userId': 9,
'id': 84,
'title': 'optio ipsam molestias necessitatibus occaecati facilis veritatis dolores
aut',
'body': 'sint molestiae magni a et quos\neaque et quasi\nut rerum debitis similique
veniam\nrecusandae dignissimos dolor incidunt consequatur odio'},
{'userId': 9,
'id': 85,
'title': 'dolore veritatis porro provident adipisci blanditiis et sunt',
'body': 'similique sed nisi voluptas iusto omnis\nmollitia et quo\nassumenda suscipit
officia magnam sint sed tempora\nenim provident pariatur praesentium atque animi amet
ratione'},
{'userId': 9,
'id': 86,
'title': 'placeat quia et porro iste',
'body': 'quasi excepturi consequatur iste autem temporibus sed molestiae beatae\net
quaerat et esse ut\nvoluptatem occaecati et vel explicabo autem\nasperiores pariatur
deserunt optio'},
{'userId': 9,
'id': 87,
'title': 'nostrum quis quasi placeat',
'body': 'eos et molestiae\nnesciunt ut a\ndolores perspiciatis repellendus repellat
aliquid\nmagnam sint rem ipsum est'},
{'userId': 9,
'id': 88,
'title': 'sapiente omnis fugit eos',
'body': 'consequatur omnis est praesentium\nducimus non iste\nneque hic
deserunt\nvoluptatibus veniam cum et rerum sed'},
{'userId': 9,
'id': 89,
'title': 'sint soluta et vel magnam aut ut sed qui',
'body': 'repellat aut aperiam totam temporibus autem et\narchitecto magnam
ut\nconsequatur qui cupiditate rerum quia soluta dignissimos nihil iure\ntempore quas
est'},
{'userId': 9,
'id': 90,
'title': 'ad iusto omnis odit dolor voluptatibus',
'body': 'minus omnis soluta quia\nqui sed adipisci voluptates illum ipsam
voluptatem\neligendi officia ut in\neos soluta similique molestias praesentium
blanditiis'},
{'userId': 10,
'id': 91,
'title': 'aut amet sed',
'body': 'libero voluptate eveniet aperiam sed\nsunt placeat suscipit
molestias\nsimilique fugit nam natus\nexpedita consequatur consequatur dolores quia eos
et placeat'},
{'userId': 10,
'id': 92,
'title': 'ratione ex tenetur perferendis',
'body': 'aut et excepturi dicta laudantium sint rerum nihil\nlaudantium et at\na neque
minima officia et similique libero et\ncommodi voluptate qui'},
{'userId': 10,
'id': 93,
'title': 'beatae soluta recusandae',
'body': 'dolorem quibusdam ducimus consequuntur dicta aut quo laboriosam\nvoluptatem
quis enim recusandae ut sed sunt\nnostrum est odit totam\nsit error sed sunt eveniet
provident qui nulla'},
{'userId': 10,
'id': 94,
'title': 'qui qui voluptates illo iste minima',
'body': 'aspernatur expedita soluta quo ab ut similique\nexpedita dolores amet\nsed
temporibus distinctio magnam saepe deleniti\nomnis facilis nam ipsum natus sint
similique omnis'},
{'userId': 10,
'id': 95,
'title': 'id minus libero illum nam ad officiis',
'body': 'earum voluptatem facere provident blanditiis velit laboriosam\npariatur
accusamus odio saepe\ncumque dolor qui a dicta ab doloribus consequatur omnis\ncorporis
cupiditate eaque assumenda ad nesciunt'},
{'userId': 10,
'id': 96,
'title': 'quaerat velit veniam amet cupiditate aut numquam ut sequi',
'body': 'in non odio excepturi sint eum\nlabore voluptates vitae quia qui
et\ninventore itaque rerum\nveniam non exercitationem delectus aut'},
{'userId': 10,
'id': 97,
'title': 'quas fugiat ut perspiciatis vero provident',
'body': 'eum non blanditiis soluta porro quibusdam voluptas\nvel voluptatem qui
placeat dolores qui velit aut\nvel inventore aut cumque culpa explicabo aliquid
at\nperspiciatis est et voluptatem dignissimos dolor itaque sit nam'},
{'userId': 10,
'id': 98,
'title': 'laboriosam dolor voluptates',
'body': 'doloremque ex facilis sit sint culpa\nsoluta assumenda eligendi non ut
eius\nsequi ducimus vel quasi\nveritatis est dolores'},
{'userId': 10,
'id': 99,
'title': 'temporibus sit alias delectus eligendi possimus magni',
'body': 'quo deleniti praesentium dicta non quod\naut est molestias\nmolestias et
officia quis nihil\nitaque dolorem quia'},
{'userId': 10,
'id': 100,
'title': 'at nam consequatur ea labore ea harum',
'body': 'cupiditate quo est a modi nesciunt soluta\nipsa voluptas error itaque dicta
in\nautem qui minus magnam et distinctio eum\naccusamus ratione error aut'}]
Tener este código como método nos permite realizar requests a otras direcciones con una sola línea de
código.
Objetivos
Entender la estructura tras una API REST
Leer la documentación de una API REST
Realizar requests a una API REST
Introducción
Las API REST son un estándar sobre cómo crear APIs, en base a recursos y acciones. Cada acción se realiza
sobre un recurso en específico, y para esto tiene una ruta asignada.
Para saber cuáles recursos y rutas tenemos disponibles debemos leer la documentación de la API.
Leyendo la documentación
La documentación en cada página es distinta, pero particularmente lo que se necesita de cada una es saber
qué recursos se tiene disponibles y cuáles son las rutas a esos recursos.
Los recursos
¿Qué son los recursos?
Los recursos son elementos que se puede obtener y mostrar, y además, en algunos casos, crear nuevos,
actualizarlos y borrarlos.
Por ejemplo, en esta API tenemos los recursos "posts", "comentarios", "álbumes", "fotos", "listas de tareas
(todos)" y "usuarios". Además hay relaciones entre estos recursos.
Para ver qué acciones se puede hacer en específico sobre estos recursos, se necesita conocer las rutas (o
direcciones).
Las rutas
Las palabras que aparecen antes de cada ruta se conocen como métodos HTTP o verbos, y se debe usar el
verbo especificado para cada ruta.
Request = URL + HTTP method
Se vio anteriormente que las rutas de una API tienen un HTTP method, también conocido como verbo,
asociado.
Un request depende tanto de la dirección como del verbo. En el request anterior no lo mencionamos pero sí
utilizamos uno: utilizamos el verbo GET.
Por ahora seguiremos ocupando el verbo GET, pero haremos un request a otro recurso. Obtendremos las
fotos.
[{'albumId': 1,
'id': 1,
'title': 'accusamus beatae ad facilis cum similique qui sunt',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 2,
'title': 'reprehenderit est deserunt velit ipsam',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 3,
'title': 'officia porro iure quia iusto qui ipsa ut modi',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 4,
'title': 'culpa odio esse rerum omnis laboriosam voluptate repudiandae',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 5,
'title': 'natus nisi omnis corporis facere molestiae rerum in',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 6,
'title': 'accusamus ea aliquid et amet sequi nemo',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 7,
'title': 'officia delectus consequatur vero aut veniam explicabo molestias',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 8,
'title': 'aut porro officiis laborum odit ea laudantium corporis',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 9,
'title': 'qui eius qui autem sed',
'url': '[Link]
'thumbnailUrl': '[Link]
{'albumId': 1,
'id': 10,
'title': 'beatae et provident et ut vel',
'url': '[Link]
'thumbnailUrl': '[Link]
Analizando la respuesta
La estructura de la respuesta es la misma: una lista que contiene diccionarios donde cada uno representa
una foto. El proceso de obtener resultados también es el mismo; iteramos la lista, y de cada diccionario
obtenemos la información que necesitamos.
Como ejercicio de integración, vamos a obtener todas las direcciones de las fotos y generar una página web
con una galería.
Desafío: Construir una página web a partir de las fotos
Primero idearemos el algoritmo. El secreto para resolver problemas es descomponerlos en partes que ya
sabemos hacer.
# Solución
data = request("[Link]
html = ""
for photo in data:
html += "<img src=\"{}\">\n".format(photo["url"])
Objetivos
Utilizar los verbos POST, PUT y DELETE
Conocer el concepto de negociación de contenido
Utilizar headers para negociar contenido
Utilizar el body de un request para enviar contenido
Crear un nuevo objeto uitlizando el método POST
Introducción
Las APIs no solo permiten obtener información, sino que también permiten subir (crear), actualizar y borrar
información. En una API REST, estos pedidos suceden bajo otros verbos diferentes al de GET.
Creando un recurso
En una API REST hay un estandar definido, que es el método Post.
Esta parte de la documentación no dice mucho, pero hay un link a ejemplos. Al seguir el link:
El ejemplo de la documentación está en JavaScript, pero de todas formas podemos leerlo poniendo
atención en algunos elementos específicos.
Creando un recurso desde Postman
Para subir un artículo nuevo necesitamos seleccionar el verbo POST, e ingresar la URL de la documentación.
Negociación de contenido
Además, necesitaremos agregar el header Content-type: application/json . Esto es necesario porque
algunas APIs pueden recibir distintos tipos de contenido.
Negociar el contenido permite que, en un mismo endpoint, se puedan resolver pedidos de distintos clientes
en distintos formatos. Los tipos de contenido que puede manejar una API se especifican en la
documentación, en este caso, nosotros lo obtuvimos del ejemplo.
Agregando el contenido
Dentro de la API y del ejemplo, vimos que un artículo se compone de un título title, de un cuerpo body y de
un dueño userId
Como primera prueba, subiremos un artículo con título, para lo que iremos al tab de body, seleccionaremos
la opción raw y a la derecha marcaremos la opción JSON (application/json)
Aquí es muy importante indicar que se debe utilizar doble comilla alrededor de un string en un JSON para
contenerlo correctamente.
Observando el resultado
En la sección inferior, bajo el tag body, encontraremos el resultado obtenido de la API indicando que se creó
el artículo con id 101 y título "hola".
{
"title": "Post 101",
"body": "Este es nuestro primer post",
"userId": 1
}
{
"title": "Post 101",
"body": "Este es nuestro primer post",
"userId": 1,
"id": 101
}
import requests
url = "[Link]
{
"title": "Post 101",
"body": "Este es nuestro primer post",
"userId": 1,
"id": 101
}
Actualizando un recurso
Los métodos para actualizar un recurso en una API REST son PUT o PATCH. Si bien existe una diferencia
entre estos, la mayoría de las API no hace distinción.
Existen muchas APIs que para actualizar un recurso además aceptan el verbo POST. E incluso, algunas solo
aceptan POST, y no PUT.
Lo otro que tenemos que saber además del verbo es el endpoint (o dirección). Para esto veremos de nuevo
la documentación.
En este caso, los identificadores van desde 1 hasta 100, por lo tanto, si queremos cambiar el artículo con id
20 tendríamos que hacer un request con método put a
[Link]
Además, dentro del body de la request debemos que agregar los nuevos valores para el artículo.
Actualizando un artículo desde Python
Para estudiar cómo podemos modificar el artículo utilizando Python, lo que haremos es copiar el código
generado por Postman y veremos que la idea es exactamente la misma.
import requests
url = "[Link]
print([Link])
Borrar un recurso
Para borrar un artículo seguiremos la misma idea. Veremos de la documentación que el método es DELETE
y que la dirección es posts/id .
import requests
url = "[Link]
payload = ""
headers = {
'Content-Type': "application/json",
'cache-control': "no-cache",
'Postman-Token': "fc3777ed-499a-4a9b-8250-43c1b1c8b6c3"
}
print([Link])
Resumen del capítulo:
En este capítulo aprendimos:
Una API REST es un estandar para ver, crear, actualizar y borrar recursos.
Para ver recursos utilizaremos el verbo (o http method) GET
Para agregar un recurso nuevo utilizaremos el verbo POST
Para actualizar un recurso utilizaremos PUT o PATCH
Para borrar un recurso utilizaremos DELETE
[Link]
Se pide obtener los precios y fechas del último periodo, y a partir de estos, obtener una lista de todas las
fechas donde el valor ha sido menor a 5000 USD.
Solución
Primero dividiremos el problema en 2 grandes partes.
import json
import requests
def request(requested_url):
headers = {
"cache-control": "no-cache",
"Postman-Token": "2defb9f3-9b11-499b-be4f-82505a2f8e1a",
}
response = [Link]("GET", requested_url, headers=headers)
return [Link]([Link])
prices = request("[Link]
El segundo paso consiste en obtener la lista con las fechas, para lo que hay distintas posibilidades. La
primera pregunta que deberíamos hacernos es si podemos utilizar una sola línea para seleccionar
elementos en base a un valor.
# Solución 1
['2018-11-19',
'2018-11-20',
'2018-11-21',
'2018-11-22',
'2018-11-23',
'2018-11-24',
'2018-11-25',
'2018-11-26',
'2018-11-27',
'2018-11-28',
'2018-11-29',
'2018-11-30',
'2018-12-01',
'2018-12-02',
'2018-12-03',
'2018-12-04',
'2018-12-05',
'2018-12-06',
'2018-12-07',
'2018-12-08',
'2018-12-09',
'2018-12-10',
'2018-12-11']
Sin embargo hay muchas otras formas de resolver el problema, por ejemplo pudimos haberlo hecho
utilizando un for y guardando en un nuevo diccionario todos los elementos que cumplan el criterio.
# Solución 2
selected_data = []
for date, value in [Link]():
if value < 5000:
selected_data.append(date)
selected_data
['2018-11-19',
'2018-11-20',
'2018-11-21',
'2018-11-22',
'2018-11-23',
'2018-11-24',
'2018-11-25',
'2018-11-26',
'2018-11-27',
'2018-11-28',
'2018-11-29',
'2018-11-30',
'2018-12-01',
'2018-12-02',
'2018-12-03',
'2018-12-04',
'2018-12-05',
'2018-12-06',
'2018-12-07',
'2018-12-08',
'2018-12-09',
'2018-12-10',
'2018-12-11']
Otra opción, bastante distinta, sería obtener una lista con únicamente los precios, filtrarla por los valores
bajo 5000 y luego utilizar un diccionario invertido para buscarlos.
# Solución 3
['2018-11-19',
'2018-11-20',
'2018-11-21',
'2018-11-22',
'2018-11-23',
'2018-11-24',
'2018-11-25',
'2018-11-26',
'2018-11-27',
'2018-11-28',
'2018-11-29',
'2018-11-30',
'2018-12-01',
'2018-12-02',
'2018-12-03',
'2018-12-04',
'2018-12-05',
'2018-12-06',
'2018-12-07',
'2018-12-08',
'2018-12-09',
'2018-12-10',
'2018-12-11']
Existen muchas soluciones a un problema siempre deberíamos preferir las mas sencillas.
Capítulo 9: SSL
Objetivos
Conocer las implicaciones de SSL.
Conocer la importancia de no enviar información sensible sin SSL.
Entender la importancia de verificar el certificado.
Introducción
SSL es un acrónimo de Secure Sockets Layer. Es una capa de seguridad que establece encriptación entre el
navegador y el servidor, y evita que la información que enviamos o recibimos sea leída por un tercero.
Esto sucede ya sea conectándonos a una página web por el navegador o una API.
Supongamos por un momento que la comunicación es entre dos personas, Alice y Bob. Para cifrar el
mensaje, Alice tiene una clave y para descifrarlo tiene otra. Previo a comunicarse, Alice se junta con Bob y le
traspasa la clave para descifrar.
Esto permite que Alice cifre su mensaje con su clave, le envía el mensaje a Bob, y Bob la descifra con la clave
que la pasó previamente Alice. Esto tiene dos ventajas; Primero, el mensaje pasa cifrado por lo que nadie
mas puede leerlo a menos que tenga la clave para descifrar. Pero además, la llave para descifrar solo sirve
para descifrar mensajes de Alice, por lo que sabremos que el mensaje viene realmente de Alice y no de otra
persona.
La clave que firma el mensaje, pero jamás se comparte, recibe el nombre de clave privada, mientras que la
clave que se comparte recibe el nombre de clave pública.
Ventajas de SSL
El sistema de juego entonces tiene dos ventajas.
Si nos conectamos con el navegador y hacemos click en el candado de la conexión segura podemos ver el
certificado.
El cliente ocupa la clave pública que viene en el certificado para cifrar un mensaje y se la devuelve al
servidor. Si el servidor puede descifrar el nuevo mensaje significa que el servidor tiene la clave privada
correcta.
Dentro del proceso, cliente y servidor crearon una clave secreta especial utilizando los números que se
enviaron durante el handshake. Durante el resto del proceso, se ocupa un sistema de cifrado simétrico
utilizando esta única clave que nunca fue transmitida pero que ambos servidores tienen.
Conectandose a SSL
Postman identifica automáticamente si un request ocupa HTTPS y genera el código para conectarnos. La
librería requests , por defecto, tiene la verificación de certificados SSL habilitada, por lo que si no puede
verificar un certificado durante un request, ocurrirá un SSLError .
Hombre en el medio
Hombre en el medio (Man in the middle) es una estrategia de hacking que consiste en hacer de puente
(Proxy) entre el cliente y el servidor.
El atacante se sitúa en el punto medio, captura la clave pública que envía el servidor y le envía una nueva
clave pública al cliente. El cliente cree que se está conectando con el servidor directamente pero no es así y
toda la comunicación queda comprometida.
Este ataque es muy fácil de lograr, pero solo si el certificado no es validado (o auto firmado). Al momento de
conectarse, los certificados se revisan contra agentes certificadores. Un certificado validado (nombre de
sitio + clave pública) complica la situación al atacante puesto que este difícilmente tendrá la clave privada
asociada al certificado.
Capítulo 10: API con autenticación
Objetivos
Obtener el id y la clave para autenticarse a una API
Conectarse a una API que requiere autenticación
Utilizar la API del diccionario de oxford
Estudiar otros tipos de autenticación
Autenticación
Muchas APIs requieren de autenticación para poder acceder a sus servicios.
Para autenticarse con una API, nuestro primer paso consiste en conseguir una clave para conectarse. Las
mismas APIs disponen de servicio de registro y al completarlo entregan un id.
En algunos casos se utilizan dos claves, un app_id y un app_key, en otros casos un key y un secret.
Independiente de cuantas claves el sistema siempre es similar.
import json
import requests
def request(requested_url):
headers = {
"app_id": "e51457d3",
"app_key": "6cf09f1d0edbefd2381f937f396150a3",
}
response = [Link]("GET", requested_url, headers=headers)
return [Link]([Link])
word = "test"
request("[Link]
La pregunta importante es qué información es la que queremos. Por ahora nos conformaremos con la
definición definitions, así que iremos del final hasta el principio.
result = request("[Link]
result['results'][0]['lexicalEntries'][0]['entries'][0]['senses'][0]['definitions']
No siempre es tan complicado, muchas veces los datos están con uno o dos niveles de profundidad, pero es
un muy buen caso de estudio.
También existen otros modelos más complejos como el de Facebook y el de Twitter que al día de hoy
ocupan OAuth2.
De todas formas, lo importante siempre es leer con calma la documentación y encontrar las pistas
necesarias para lograr la conexión. En el peor de los casos, siempre existe la opción de comunicarse con los
desarrolladores de la API para pedir ayuda o buscar otra API que logre el mismo propósito.
¿Cómo podemos manejar los tokens?
Con args
Hay varias estrategias. Podemos utilizarar una muy simple que consiste en dejar los datos sensibles fuera
del programa y entregarle los datos como parámetros (utilizando los args ) al cargar el programa.
Esta opción consiste en utilizar variables que se definen en el terminal y las podemos llamar desde nuestro
programa.
Veamos un ejemplo básico (para Linux y OSX). En el terminal escribiremos export a=5 . Luego entraremos
a Python e importamos [Link] ( from os import environ ). Escribimos environ["a"] y
observaremos el valor 5.
Siguiendo con Linux y OSX, este valor solo quedará en la sesión, es decir, al abrir un terminal nuevo, no lo
tendremos. Para hacerlo persistente podemos escribir esta línea en el archivo .bashrc o .bash_profile .
Este archivo que se encuentra en la carpeta de usuario. Lo podemos abrir con un editor de texto y en la
última línea agregar nuestra variable.
export API_1_SECRET_KEY=23123u2139183
Finalmente, después de guardar, para recargar los cambios realizados dentro del archivo ocuparemos la
siguiente línea:
source ~/.bash_profile
Cierre
A lo largo de este módulo aprendimos las bases de la programación, que consiste en la solución de
problemas.
Palabas finales
Aprender a programar es un largo camino y requiere de mucha práctica. Hemos dado los primeros pasos a
lo largo de estas cuatro unidades, donde estudiamos desde conceptos muy simples hasta protocolos de
seguridad informática actuales. Sin embargo, todavía nos queda mucho por recorrer. Este es solo el punto
de partida de la programación y existen muchas ramas interesantes donde podemos profundizar. Algunas
interesantes para tenerlas en el radar.
Estructuras de datos
Complejidad algorítmica
Almacenamiento y recuperación de información
Bases de datos
QA y Construcción de pruebas automatizadas
Arquitectura de software
Ciencia de datos
Inteligencia artificial
Los campos son muy diversos y aunque están parcialmente entrelazados cada uno es un mundo de
profunidad y la vida es muy corta para ser experto en todo.