[Python-es] [Consulta] Sobre keyerror

Alexis Roda alexis.roda.villalonga en gmail.com
Vie Jul 3 14:00:27 EDT 2020


Haz este cambio:

print(complete_url)  # <<< añade esta línea
response = requests.get(complete_url)


Copia/pega lo que sale por pantalla.


Missatge de lemarchand8679 <lemarchand8679 en gmail.com> del dia dv., 3 de
jul. 2020 a les 19:40:

> Hice como me habían comentado antes, lo de hacer print en x. Lo hice y da
> el erroe de 401 el cual hace referencia a la api_key. Lo revisé y parece
> estar correcta, está validada y todo. Probé generando otra y lo mismo;
> keyerror.
>
>
>
> Enviado desde mi smartphone Samsung Galaxy.
>
>
> -------- Mensaje original --------
> De: Alexis Roda <alexis.roda.villalonga en gmail.com>
> Fecha: 3/7/20 11:19 (GMT-03:00)
> A: La lista de python en castellano <python-es en python.org>
> Asunto: Re: [Python-es] [Consulta] Sobre keyerror
>
> Tiendo a dar demasiada información y perderme en detalles. La parte
> relevante de mi respuesta es cuando digo que el número 404 y la cadena
> "404" comparan como distintos. En Python, si comparas un número (un int) y
> una cadena (un str) el resultado es que siempre son distintos,
> independientemente de su valor. Esto implica que *la rama del else jamás
> se ejecuta*, no importa qué código de respuesta devuelve la API, siempre
> se ejecuta la rama del then. Esto es un problema cuando la respuesta es
> no-OK y no contiene la clave "main".
>
> Lo puedes confirmar fácilmente inspeccionando el valor de x. Si estoy en
> lo cierto verás algo como {"cod": 123, ...} no {"cod": "123",  ...}. La
> confirmación definitiva sería la documentación de la API, la especificación
> del formato de la respuesta.
>
> Con "la forma correcta" quería decir "la forma recomendada". requests
> ofrece mecanismos para hacer lo mismo de forma más sencilla y robusta. Ya
> que se importa se me hace extraño no aprovecharlos.
>
> También te recomiendo que revises la gestión de errores, parece frágil.
> Imagino que si el código de respuesta es distingo de 404 no significa
> necesariamente que la petición ha ido bien. Confirmalo con la documentación
> de la API.
>
>
> Saludos
>
> Missatge de Lemarchand Barker <lemarchand8679 en gmail.com> del dia dv., 3
> de jul. 2020 a les 13:36:
>
>> Buenas gracias a todos por sus aportes. Si, me llamo Verónica.
>> En respuesta a Alexis, puede ser una forma incorrecta de realizar la
>> consulta pero cuando hice copy-paste, al probar con distintas localidades
>> funcionó. Tengo que mirar la info para desarrolladores que tiene más
>> detenidamente, no es larga.
>> Yo al 404 lo entiendo como el de page not found, de ahí que el else te
>> diga que no encontró la ciudad. No encuentra la página con la información
>> de esa localidad.
>>
>>
>>
>> El vie., 3 de jul. de 2020 04:33, Alexis Roda <
>> alexis.roda.villalonga en gmail.com> escribió:
>>
>>> Si python dice "KeyError: main" al ejecutar y = x["main"] es que x no
>>> tiene la clave "main". Averigua el valor de x, tal vez te dé una pista del
>>> problema.
>>>
>>> En el otro mensaje, al cambiar "main" por "cod" el error era "int value
>>> is not subscriptable" (o algo parecido), eso nos dice que el valor asociado
>>> a la clave "cod" es un número (habría que confirmarlo con la documentación
>>> de la API) pero el programa lo trata como una cadena (en el if x["cod"]
>>> != "404"). El número 404 y la cadena "404" comparan como distintos. No
>>> sé si tiene que ver con el KeyError main pero es un error que habría que
>>> corregir. Relacionado con esto, no parece buena idea asumir que si el
>>> código es distinto de 404 la petición ha ido bien. Asumiendo que sean
>>> códigos HTTP yo haría algo como: si cod == 200 procesamiento ok sino si
>>> cod == 404 imprime "no encontrado" ... sino imprime "error desconocido".
>>>
>>> Me llama la atención que el script utilice el paquete requests para
>>> luego acabar construyendo la URL a mano. Por otro lado la URL que construye
>>> no parece muy correcta. Suponiendo que nombre_ciudad sea FOO:
>>>
>>> url = "http://api.openweathermap.org/data/2.5/weather?q=sp"
>>> complete_url = url + "appid=" + api_key + "&q=sp" + nombre_ciudad
>>>
>>>
>>> al final complete_url vale
>>> http://api.openweathermap.org/data/2.5/weather?q=spappid=API_KEY&q=spFOO.
>>> Creo que deberia ser algo mas parecido a
>>> http://api.openweathermap.org/data/2.5/weather?q=FOO&appid=API_KEY&lang=sp
>>> .
>>>
>>> Usando requests de forma correcta te quitas problemas:
>>>
>>> url = "http://api.openweathermap.org/data/2.5/weather
>>> <http://api.openweathermap.org/data/2.5/weather?q=sp>"
>>> response = requests.get(url, data={"q": nombre_ciudad, "lang": "sp",
>>> "appid": api_key})
>>>
>>>
>>> añadirá el ? y los & donde corresponda, codificará correctamente los
>>> valores y no quedarán valores "desparejados" ni claves duplicadas.
>>>
>>> Visto todo esto sigo pensando que el problema es una mala petición a la
>>> API que devuelve un código de error que no es gestionado correctamente.
>>>
>>> Respecto a que el problema se produzca cuando escribes el programa a
>>> mano y que funciona si copias/pegas. En caso que no sea un error evidente
>>> en la transcripción y que el valor de x no te dé ninguna pista, los IDE
>>> suelen incluir alguna herramienta para comparar archivos. Comparalos y
>>> encuentra que los hace diferentes y puede causar el problema.
>>>
>>> https://www.jetbrains.com/help/pycharm/comparing-files-and-folders.html
>>>
>>> Creo que es excesivo para este problema pero es otra herramienta que
>>> puede ser útil.
>>>
>>>
>>> Saludos
>>>
>>> Missatge de Lemarchand Barker <lemarchand8679 en gmail.com> del dia dv., 3
>>> de jul. 2020 a les 1:22:
>>>
>>>> Hola, el código de api key funciona, porque me registré y lo usé y
>>>> funcionó.
>>>> Lo de sp fue más que nada para probar, corresponde al Multilingual
>>>> support. Incluso cuando hice copy-paste del código sin usar el sp,
>>>> funcionaba perfecto. Lo saqué de acá:
>>>> https://openweathermap.org/current. Lo del multilingual está ya casi
>>>> al final de la página.
>>>> La url que uso es esta: api.openweathermap.org/data/2.5/weather? que
>>>> es la misma que figura en la página. Reitero, el problema me salta cada vez
>>>> que copio el código de forma manual, con copy-paste ningún problema.
>>>> Saludos
>>>>
>>>> El jue., 2 jul. 2020 a las 20:00, David Suárez vía Python-es (<
>>>> python-es en python.org>) escribió:
>>>>
>>>>> Vero,
>>>>>
>>>>> el problema que veo es que tienes la cadena "sp" de sobra tanto en la
>>>>> variable url como cuando generas complete_url y creo que no deberían ir
>>>>> allí, aunque no he podido checarlo por lo de la llave API.
>>>>>
>>>>> El jue., 2 de jul. de 2020 a la(s) 17:30, Lemarchand Barker (
>>>>> lemarchand8679 en gmail.com) escribió:
>>>>>
>>>>>> Hola, este es mi código:
>>>>>>
>>>>>> import requests
>>>>>> import json
>>>>>>
>>>>>> api_key = "API_KEY"
>>>>>>
>>>>>> url = "http://api.openweathermap.org/data/2.5/weather?q=sp"
>>>>>>
>>>>>> nombre_ciudad = input("Ingrese nombre de la ciudad: ")
>>>>>>
>>>>>> complete_url = url + "appid=" + api_key + "&q=sp" + nombre_ciudad
>>>>>>
>>>>>> response = requests.get(complete_url)
>>>>>>
>>>>>> x = response.json()
>>>>>>
>>>>>> if x["cod"] != "404":
>>>>>>
>>>>>>     y = x["main"]
>>>>>>
>>>>>>     temperatura_actual = y["temp"]
>>>>>>
>>>>>>     celsius = temperatura_actual - 273.15
>>>>>>
>>>>>>     presion_actual = y["pressure"]
>>>>>>
>>>>>>     humedad_actual = y["humidity"]
>>>>>>
>>>>>>     z = x["clima"]
>>>>>>
>>>>>>     descripcion = z[0]["descripcion"]
>>>>>>
>>>>>>     print(f"Temperatura: {celsius}°")
>>>>>>     print(f"Presión atmosférica: {presion_actual} hPa")
>>>>>>     print(f"Humedad: {humedad_actual} %")
>>>>>>     print(f"Descripción: {descripcion}")
>>>>>>
>>>>>> else:
>>>>>>     print("Ciudad no encontrada")
>>>>>>
>>>>>> La salida es la siguiente:
>>>>>>
>>>>>> /usr/bin/python3.8 /home/raiden/Programacion/weather/weather.py
>>>>>> Ingrese nombre de la ciudad: Rosario
>>>>>> Traceback (most recent call last):
>>>>>>   File "/home/raiden/Programacion/weather/weather.py", line 18, in
>>>>>> <module>
>>>>>>     y = x["main"]
>>>>>> KeyError: 'main'
>>>>>>
>>>>>> El código original es este:
>>>>>> Python-find-current-weather-of-any-city-using-openweathermap-api/
>>>>>> <https://www.geeksforgeeks.org/python-find-current-weather-of-any-city-using-openweathermap-api/>
>>>>>>
>>>>>> Saludos y gracias
>>>>>>
>>>>>>
>>>>>> El jue., 2 jul. 2020 a las 18:20, Gerardo Diez (<
>>>>>> gerardo.diez.garcia en gmail.com>) escribió:
>>>>>> >
>>>>>> > Hola,
>>>>>> >
>>>>>> > No soy precisamente un experto, pero yo normalmente voy poniendo
>>>>>> prints /liga por todos lados para que me vaya mostrando el contenido de las
>>>>>> cadenas.
>>>>>> >
>>>>>> > No recuerdo muy bien el funcionamiento de input pero puede ser que
>>>>>> el string que se esté incorporando lleve un salto de línea final ( \n)?
>>>>>> >
>>>>>> > Si es así mira la función strip
>>>>>> >
>>>>>> > Un saludo
>>>>>> >
>>>>>> > El jue., 2 jul. 2020 22:01, lemarchand8679 <
>>>>>> lemarchand8679 en gmail.com> escribió:
>>>>>> >>
>>>>>> >> Hola, había escrito para comentar que había solucionado el
>>>>>> inconveniente de KeyError, y es cierto en parte. Digo en parte porque si
>>>>>> escribo desde 0 para hacer algunas modificaciones, me tira ese error al
>>>>>> introducir una ciudad, y si hago un copy-paste del código funciona y la
>>>>>> verdad no se por qué, alguna idea? Gracias
>>>>>> >>
>>>>>> >>
>>>>>> >>
>>>>>> >> Enviado desde mi smartphone Samsung Galaxy.
>>>>>> >>
>>>>>> >> _______________________________________________
>>>>>> >> Python-es mailing list
>>>>>> >> Python-es en python.org
>>>>>> >> https://mail.python.org/mailman/listinfo/python-es
>>>>>> >
>>>>>> > _______________________________________________
>>>>>> > Python-es mailing list
>>>>>> > Python-es en python.org
>>>>>> > https://mail.python.org/mailman/listinfo/python-es
>>>>>> _______________________________________________
>>>>>> Python-es mailing list
>>>>>> Python-es en python.org
>>>>>> https://mail.python.org/mailman/listinfo/python-es
>>>>>>
>>>>> _______________________________________________
>>>>> Python-es mailing list
>>>>> Python-es en python.org
>>>>> https://mail.python.org/mailman/listinfo/python-es
>>>>>
>>>> _______________________________________________
>>>> Python-es mailing list
>>>> Python-es en python.org
>>>> https://mail.python.org/mailman/listinfo/python-es
>>>>
>>> _______________________________________________
>>> Python-es mailing list
>>> Python-es en python.org
>>> https://mail.python.org/mailman/listinfo/python-es
>>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20200703/d56dc767/attachment.html>


Más información sobre la lista de distribución Python-es