KeyError in Weather API Response - python

I was making a python program which tells about weather but facing the following error
Please tell how to correct it?
CODE
import requests
import json
api = "<MY_API_KEY>"
BASE_URL = "https://api.openweathermap.org/data/2.5/weather?"
print("for which city?")
CITY = input("city?: ")
URL = BASE_URL + "q=" + CITY + "&appid=" + api
response = requests.get(URL)
if __name__ == "__main__":
data = response.json()
main = data['main']
temperature = main['temp']
humidity = main['humidity']
pressure = main['pressure']
report = data['weather']
print(f"{CITY:-^30}")
print(f"Temperature: {temperature}")
print(f"Humidity: {humidity}")
print(f"Pressure: {pressure}")
print(f"Weather Report: {report[0]['description']}")
TERMINAL
PS C:\Users\mamta\Documents\PythonPanti\JARVISprj> c:; cd 'c:\Users\mamta\Documents\PythonPanti\JARVISprj'; & 'C:\Users\mamta\AppData\Local\Programs\Python\Python39\python.exe' 'c:\Users\mamta\.vscode\extensions\ms-python.python-2021.5.842923320\pythonFiles\lib\python\debugpy\launcher'
'53873' '--' 'c:\Users\mamta\Documents\PythonPanti\JARVISprj\exp.py'
for which city?
city?: Delhi
Traceback (most recent call last):
File "c:\Users\mamta\Documents\PythonPanti\JARVISprj\exp.py", line 13, in <module>
main = data['main']
KeyError: 'main'

Your code is perfectly fine only problem here I see is when you enter any garbage value. You need to do error handling.

Related

BeautifulSoup4 and Requests Module 'IndexError: list index out of range'

I'm new to web scraping with python and am having a problem with the weather web scraping script I wrote. Here is the whole code 'weather.py':
#! python3
import bs4, requests
weatherSite = requests.get('https://weather.com/en-CA/weather/today/l/eef019cb4dca2160f08eb9714e30f28e05e624bbae351ccb6a855dbc7f14f017')
weatherSoup = bs4.BeautifulSoup(weatherSite.text, 'html.parser')
weatherLoc = weatherSoup.select('.CurrentConditions--location--kyTeL')
weatherTime = weatherSoup.select('.CurrentConditions--timestamp--23dfw')
weatherTemp = weatherSoup.select('.CurrentConditions--tempValue--3a50n')
weatherCondition = weatherSoup.select('.CurrentConditions--phraseValue--2Z18W')
weatherDet = weatherSoup.select('.CurrentConditions--precipValue--3nxCj > span:nth-child(1)')
location = weatherLoc[0].text
time = weatherTime[0].text
temp = weatherTemp[0].text
condition = weatherCondition[0].text
det = weatherDet[0].text
print(location)
print(time)
print(temp + 'C')
print(condition)
print(det)
It basically parses the weather information from 'The Weather Channel' and prints it out. This code was working fine yesterday when I wrote it. But, I tried today and it is giving me the following error:
Traceback (most recent call last):
File "C:\Users\username\filesAndStuff\weather.py", line 16, in <module>
location = weatherLoc[0].text
IndexError: list index out of range
Replace:
weatherLoc = weatherSoup.select('.CurrentConditions--location--kyTeL')
# print(weatherLoc)
# []
By:
weatherLoc = weatherSoup.select('h1[class*="CurrentConditions--location--"]')
# print(weatherLoc)
# [<h1 class="CurrentConditions--location--2_osB">Hamilton, Ontario Weather</h1>]
As you can see, your suffix kYTeL is not the same for me 2_osB. You need a partial match on class attribute (class*=) (note the *)

turn my for loop into a function in python

I would like to know how can I turn my for loop into a function.
I wrote a code which asks the user to input an address, then the code iterate through preset addresses and return me the closest address to the input one.
I would like to make it a function so I can call it in my GUI.
Here is my code:
import urllib.request
import json
# Google Maps directions API endpoint
endpoint = 'https://maps.googleapis.com/maps/api/directions/json?'
api_key = 'MY API KEY'
# donner l'adresse en code postal
origin = input("Inserer l'adresse du fabricant : ").replace(' ', '+')
destinations = ['H7N 5H9', 'H4N 1P9', 'K4A 0G2']
distances = []
# Parcourt la liste des adresses et calcule chacune de leurs distances
def proximity():
for i in range(len(destinations)):
currentDestination = destinations[i].replace(' ', '+')
nav_request = 'origin={}&destination={}&key={}'.format(origin, currentDestination, api_key)
request = endpoint + nav_request
response = urllib.request.urlopen(request).read()
directions = json.loads(response)
distance = directions["routes"][0]["legs"][0]["distance"]["text"]
distances.append(distance)
closestDistance = min(distances)
return closestDistance
print("the distance is: " + proximity())
print("closest address is : " + destinations[distances.index(proximity())])
EDIT :
i'm not getting the error below anymore though
I'm getting this error:
Traceback (most recent call last):
File "/Users/cn/PycharmProjects/Calendrier/venv/proximity.py", line 25, in <module>
print("the distance is: " + closestDistance)
NameError: name 'closestDistance' is not defined
What I want, is to be able to call this function in my other module.
The code works perfectly with the for loop, I just want to be able to transform it into a function.

Python code in Zapier (invalid syntax (usercode.py, line 42))

This code is pre-made in a Zapier forum to pull failed responses from another piece of software called iAuditor. When I plug in the code and update the API token and webhook URL this error pops up:
Traceback (most recent call last):
SyntaxError: invalid syntax (usercode.py, line 42)
Here is the code:
[code]
import json
import requests
auth_header = {'Authorization': 'a4fca847d3f203bd7306ef5d1857ba67a2b3d66aa455e06fac0ad0be87b9d226'}
webhook_url = 'https://hooks.zapier.com/hooks/catch/3950922/efka9n/'
api_url = 'https://api.safetyculture.io/audits/'
audit_id = input['audit_id']
audit_doc = requests.get(api_url + audit_id, headers=auth_header).json()
failed_items = []
audit_author = audit_doc['audit_data']['authorship']['author']
conducted_on = audit_doc['audit_data']['date_completed']
conducted_on = conducted_on[:conducted_on.index('T')]
audit_title = audit_doc['template_data']['metadata']['name']
for item in audit_doc['items']:
if item.get('responses') and item['responses'].get('failed') == True:
label = item.get('label')
if label is None:
label = 'no_label'
responses = item['responses']
response_label = responses['selected'][0]['label']
notes = responses.get('text')
if notes is None:
notes = ''
failed_items.append({'label': label,
'response_label': response_label,
'conducted_on': conducted_on,
'notes': notes,
'author': audit_author
})
for item in failed_items:
r = requests.post(webhook_url, data = item)
return response.json()
[/code]
This looks like an error from the platform. It looks like Zapier uses a script called usercode.py to bootstrap launching your script and the error seems to be coming from that part.

python error : 'module' object is not callable "math.ceil"

Ive the following function which is do POST request to provider , I need to add new param to post request to incress the timeout ( which is by default is 5 mints i want to incress it to 1 hour , i did changes but i keep getting errors
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib64/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/opt/lvptest/lvp_upload.py", line 226, in run
op = uploadMedia(mediaName, "PyUploader", env)
File "/opt/lvptest/lvp_upload.py", line 121, in uploadMedia
expires = math.ceil(time() + 3000) ["expires"]
TypeError: 'module' object is not callable
Here is my function
def uploadMedia(filepath, description, env):
global verbose
global config
orgId = config[env]["org_id"]
accessKey = config[env]["access_key"]
secret = config[env]["secret"]
expires = math.ceil(time() + 3000) ["expires"]
filename = os.path.basename(filepath)
baseUrl = "http://api.videoplatform.limelight.com/rest/organizations/%s/media" %(orgId)
signedUrl = lvp_auth_util.authenticate_request("POST", baseUrl, accessKey, secret, expires)
c = pycurl.Curl()
c.setopt(c.POST, 1)
c.setopt(c.HEADER, 0)
c.setopt(c.HTTPPOST, [('title', filename), ("description", description), (("media_file", (c.FORM_FILE, filepath)))])
if verbose:
c.setopt(c.VERBOSE, 1)
bodyOutput = StringIO()
headersOutput = StringIO()
c.setopt(c.WRITEFUNCTION, bodyOutput.write)
c.setopt(c.URL, signedUrl)
c.setopt(c.HEADERFUNCTION, headersOutput.write)
try:
c.perform()
c.close()
Any tips if im mistaken adding param "expires" ?
here is example how is my POST request looks like
POST /rest/organizations/9fafklsdf/media?access_key=sfdfsdfsdfsdfsdf89234 &expires=1400406364&signature=Mc9Qsd4sdgdfg0iEOFUaRC4iiAJBtP%2BMCot0sFKM8A$
Two errors:
You should do from time import time instead of just time. Because the time module has a time function inside it.
math.ceil returns a float and you are trying to use it as a dict after:
expires = math.ceil(time() + 3000) ["expires"]
This doesn't make sense. math.ceil(time() + 3000) will be equal to something like 1400406364 and you can't retrieve a data from it.
Removing the ["expires"] should solve the problem.
The time module is not callable, you need to call time method from it:
>>> import time
>>> import math
>>> math.ceil(time())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable
>>> math.ceil(time.time())
1400657920.0
Then you need to get rid of ["expires"] after it, since it will return a float number not a dictionary.
I don't know why you are using cURL here, with requests your code is a lot simpler:
import time
import math
import urllib
import requests
url = 'http://api.videoplatform.limelight.com/rest/organizations/{}/media'
filename = 'foo/bar/zoo.txt'
params = {}
params['access_key'] = 'dfdfdeef'
params['expires'] = math.ceil(time.time()+3000)
url = '{}?{}'.format(url.format(org_id), urllib.urlquote(params))
payload = {}
payload['title'] = os.path.basename(filename)
payload['description'] = 'description'
file_data = {'media_file': open(filename, 'rb')}
result = requests.post(url, data=payload, files=file_data)
result.raise_for_status() # This will raise an exception if
# there is a problem with the request

TypeError: cannot concatenate 'str' and 'builtin_function_or_method' objects in python

Please I am beginner in python coding.This is my code and am not able to resolve the error . Can some one suggest me what is the prob in code actually. thanks in advance.
import urllib2
username = '<YOUR USERNAME>'
password = '<YOUR PASSWORD>'
format = 'json' # json or xml
filename = 'archive.json' # filename of the archive
tweets = 164 # number of tweets
pages = (int(float(tweets)/float(80)))+1
auth = urllib2.HTTPPasswordMgrWithDefaultRealm()
auth.add_password(None, 'http://twitter.com/account/', username, password)
authHandler = urllib2.HTTPBasicAuthHandler(auth)
opener = urllib2.build_opener(authHandler)
urllib2.install_opener(opener)
i = 1
response = ''
print 'Downloading tweets. Note that this may take some time'
while i <= pages:
request = urllib2.Request('http://twitter.com/statuses/user_timeline/account.' \
+ format + '?page=' + str(i))
response = response + urllib2.urlopen(request).read()
i = i + 1
handle = open(filename,"w")
handle.write(response)
handle.close()
print 'Archived ' + str(tweets) + ' of ' + username + \
'\'s tweets to ' + filename
ERROR is like this below:
**Traceback (most recent call last):
File "<pyshell#14>", line 3, in <module>
+ format + '?page=' + str(i))
TypeError: cannot concatenate 'str' and 'builtin_function_or_method' objects**
format is a built-in function. The error you quote is exactly what you get if you try to use + with the built-in format and a string.
Your earlier assignment format = 'json' should have shadowed the built-in function. But your error trace indicates that you're running this from some sort of shell, and not actually executing the code as you have posted it. So without knowing what exactly is executing, my guess is your assignment to format isn't in effect, for whatever reason.

Categories

Resources