how to solve this "Expecting value: line 1 column 1 (char 0)"? - python

Request Method: PATCH
There is a Query String Parameter section

Your code cannot be run to reproduce your error. Check what you get as a response here:
r = requests.patch(url, headers=self._construct_header(),data=body)
response = getattr(r,'_content').decode("utf-8")
response_json = json.loads(response)
If you pass invalid json to json.loads(), then an error occurs with a similar message.
import json
response = b'test data'.decode("utf-8")
print(response)
response_json = json.loads(response)
print(response_json)
Output:
test data
Traceback (most recent call last):
...
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
EDIT:
In your case, to avoid an error, you need to add an if-else block. After receiving the response, you need to check what exactly you received.
r = requests.patch(url, headers=self._construct_header(),data=body)
# if necessary, check content type
print(r.headers['Content-Type'])
response = getattr(r,'_content').decode("utf-8")
if r.status_code == requests.codes.ok:
# make sure you get the string "success"
# if necessary, do something with the string
return response
else:
# if necessary, check what error you have: client or server errors, etc.
# or throw an exception to indicate that something went wrong
# if necessary, make sure you get the error in json format
# you may also get an error if the json is not valid
# since your api returns json formatted error message:
response_dict = json.loads(response)
return response_dict
In these cases, your function returns the string "success" or dict with a description of the error.
Usage:
data = {
'correct_prediction': 'funny',
'is_accurate': 'False',
'newLabel': 'funny',
}
response = aiservice.update_prediction(data)
if isinstance(response, str):
print('New Prediction Status: ', response)
else:
# provide error information
# you can extract error description from dict

Related

NoneType stopping the script with nested functions

I am trying to achieve the following:
Run a script that will upon error call another script.
Get the output of that data and insert it into the existing script to update the token value
Then display the "data"
If the value of x is not invalid it will just display the "data"
Here is the error I get when the value is not invalid. I do understand why I am getting this error but I'm having an issue handling the script and making it go to the next step
if x not in err_data: TypeError: argument of type 'NoneType' is not iterable
url = 'https://somedomain.com/blah/etc'
headers = {
'Content-Type': 'application/json',
'Authorization': apikey
}
def check_token():
x = 'invalid_token'
response = requests.get(url, headers=headers)
data = response.json()
err_data = data.get('error')
#When I get a response "None" I get the above mentioned error and script stops
if x in err_data:
refresh_token.ref_token()
#If that value of x is present run this script that I imported
else:
check_data()
#If the value of x is "None" run this script
def check_data():
response = requests.get(url, headers=headers)
data = response.json()
pp(data)
if __name__ == "__main__":
check_token()
check_data()
refresh_token.ref_token()
Thank you

invalid type: string "test#example.com", expected a sequence at line 1 column 30

I am trying to create a script to check if an email address is a disposable one or not using Python and Json but each time I run it am getting this error:
invalid type: string test#example.com, expected a sequence at line 1 column 30
I have no clue as to what next.
Here is the code:
import requests
surl = "https://ecxxxxxs.herokuapp.com"
payload = {"to_emails":"test#example.com"}
response = requests.post(surl, data=payload)
print(response.text)
Thanks in anticipation
Sorted it out, here is the code that worked for me.
import requests
surl = "https://echxxxxxs.herokuapp.com"
payload = {
"to_emails": ["test#example.com"]
}
response = requests.post(surl, json=payload)
print(response.text)

Instancemethod object is not iterable (AirPi) (Python)

I got ERROR:Exception during output: 'instancemethod' object is not iterable when debugging this AirPi code from https://github.com/haydnw/AirPi/blob/master/outputs/ubidots.py
This suppose to upload my sensor data to the Ubidots server.
*I'd put my correct token and variable ID inside the configuration file for this AirPi.
requiredSpecificParams = ["token"]
optionalSpecificParams = ["showcost",
"ID-BMP085-temp",
"ID-BMP085-pres",
"ID-DHT22-hum",
"ID-DHT22-temp",
"ID-LDR",
"ID-TGS2600",
"ID-MiCS-2710",
"ID-MiCS-5525",
"ID-Microphone",
"ID-Raingauge"
]
def __init__(self, config):
super(Ubidots, self).__init__(config)
self.token = self.params["token"]
if "showcost" in self.params:
self.showcost = self.params["showcost"]
else:
self.showcost = False
self.ubivariables = {}
for key, value in self.params.iteritems():
if key[:3] == "ID-":
if value:
self.ubivariables[key[3:]] = value
def output_data(self, datapoints, dummy):
"""Output data.
Output data in the format stipulated by the plugin. Calibration
is carried out first if required.
Because this particular plugin (ubidots) does not show time, the
third argument (normally called 'sampletime') is called 'dummy'
to facilitate compliance with pylint.
Args:
self: self.
datapoints: A dict containing the data to be output.
dummy: datetime representing the time the sample was taken.
Returns:
boolean True if data successfully output to Ubidots; False if
not
"""
if self.params["calibration"]:
datapoints = self.cal.calibrate(datapoints)
payload = []
for point in datapoints:
for ubivariablename, ubivariableid in self.ubivariables.iteritems():
if point["sensor"] == ubivariablename:
if point["value"] is not None:
thisvalue = {}
thisvalue["variable"] = ubivariableid
thisvalue["value"] = point["value"]
payload.append(thisvalue)
break
headers = {'Accept': 'application/json; indent=4', 'Content-Type': 'application/json', 'X-Auth-Token': self.token}
url = "http://things.ubidots.com/api/v1.6/collections/values"
req = None
cost = 0
try:
req = requests.post(url, data=json.dumps(payload), headers=headers)
except Exception, e:
print("ERROR: Failed to contact the Ubidots service.")
print("ERROR: " + str(e))
return False
for response in req.json:
if response["status_code"] is not 201:
print("ERROR: Ubidots responded with an error for one of the values.")
return False
else:
cost += 1
if self.showcost:
print("Ubidots upload cost " + str(cost) + " dots.")
return True
for response in req.json:
According to the documentation, json is a method and must be called, so this should be:
for response in req.json():
In the future it is helpful to include just as much of your code as is necessary to reproduce the problem, and to include the complete error message with traceback.

assert JSON response

i have an python API call, and the server response is coming to me as JSON output.
How can I assert that the "status" from this output is 0 for example:
def test_case_connection():
req = requests.get_simple(url=Server.MY_SERVER, params=my_vars)
assert req["status"]="0"
is what i've tried.
The response is looking like:
{"status" : 0, ......}
error i got is:
TypeError: 'Response' object has no attribute '__getitem__'
If you simply need to check that the request was successful, using request.status_code will do the trick:
def test_case_connection():
req = requests.get_simple(url=Server.MY_SERVER, params=my_vars)
assert req.status_code == 200
If you want instead to check for the presence of a specific key-value pair in the response, you need to convert your response payload from json to a dict:
import json
def test_case_connection():
req = requests.get_simple(url=Server.MY_SERVER, params=my_vars)
data = json.loads(req.content)
assert data["status"] == "0"
If you are using the Requests library you can avoid converting json manually by using its builtin json decoder.
It should be assert req['status'] == 0, i. e. comparison (==) instead of assignment (=) and 0 as integer not "0" as string (not entirely sure about the latter).
status code in assertion:
response.ok #it is True if response status code is 200.
In context with pytest it would be like that:
#pytest.mark.parametrize("fixture_name", [(path, json)], indirect=True)
def test_the_response_status_code_first(fixture_name):
assert fixture_name.ok, "The message for the case if the status code != 200."
# the same with checking status code directly:
assert fixture_name.status_code == 200, "Some text for failure. Optional."

Writing to csv error handling

Currently my process works as follows:
Builds and sends requests to API
Receives responses
Parses JSON responses
Writes parsed values to csv
I am receiving a JSON response from the Google Directions API. My code works fine 99% of the time, but fails if I don't receive a JSON array as expected. Since I write the responses in bulk to csv after this loop, if an error occurs, I loose all of the results.
The code as is follows:
import requests
import csv
import json
import urlparse
import hashlib
import base64
import hmac
import sys
import time
from pprint import pprint
url_raw = 'https://maps.googleapis.com/maps/api/directions/json'
Private_Key = ''
client = ''
decodedkey = base64.urlsafe_b64decode(Private_Key)
with open('./Origins.csv', 'rU') as csvfile:
reader = csv.DictReader(csvfile)
origincoords = ['{Y},{X}'.format(**row) for row in reader]
with open('./Destinations.csv', 'rU') as csvfile:
reader = csv.DictReader(csvfile)
destinationcoords = ['{Y},{X}'.format(**row) for row in reader]
results=[]
session = requests.session()
for origin, destination in zip(origincoords, destinationcoords):
params ={'origin': origin, 'destination': destination, 'client': client}
request = requests.Request('GET', url_raw, params=params).prepare()
parsed_url = urlparse.urlparse(request.url)
Signature = hmac.new(decodedkey, '{}?{}'.format(parsed_url.path, parsed_url.query), hashlib.sha1).digest()
request.prepare_url(request.url, {'signature': base64.urlsafe_b64encode(Signature)})
response = session.send(request)
directions = response.json()
time.sleep(0.0)
results.append(directions)
pprint(results)
output = open('duration_distance_results.csv', 'w+')
writer = csv.DictWriter(output, delimiter=',', fieldnames=['duration(s)', 'distance(m)'])
writer.writeheader()
for route in results:
for leg in route['routes'][0]['legs']:
params = {
"duration(s)": leg['duration']['value'],
"distance(m)": leg['distance']['value'],
}
print(params)
writer.writerow(params)
If I don't get a JSON response back in the array expected, I get a list index out of range error and through this loose what had already been done up to this point.
Ideally, I think it would be more robust if I wrote to csv within the loop, as each result is received, rather than doing that after all of the results have been received. Or, as I have attempted, use if statements -
I have attempted an if statement, where if a value exists, write the value, if it doesn't, write error. However, I get the following error "NameError: name 'leg' is not defined"
if leg in route['routes'][0]['legs'] == value:
for route in results:
for leg in route['routes'][0]['legs']:
params = {
"duration(s)": leg['duration']['value'],
"distance(m)": leg['distance']['value'],
}
print(params)
writer.writerow(params)
else:
for value in results:
error = {
"duration(s)": 'error',
"distance(m)": 'error',
}
print(error)
writer.writerow(error)
I attempted an if statement which looks at the status message returned from Google. However, this fails with the error "for error_message in results['results'][0]['error_message']:
TypeError: list indices must be integers, not str"
for error_message in results['results'][0]['error_message']:
params = { "error_message": error_message}
if error_message == value:
for route in results:
for leg in route['routes'][0]['legs']:
params = {
"duration(s)": leg['duration']['value'],
"distance(m)": leg['distance']['value'],
}
print(params)
writer.writerow(params)
else:
for value in results:
error = {
"duration(s)": 'error',
"distance(m)": 'error',
}
print(error)
writer.writerow(error)
pprint(results)
As is obvious, Im learning slowly here. Comments on the best way to handle errors would be much appreciated.
The first obvious thing to do would be to check the HTTP status code for the response object. It's not an explicit part of the Google API documentation but obviously something else than a 200 ("Found") HTTP status code means you have a problem and you cannot even expect to get anything useful in the response's body. HTTP response codes are documented in the HTTP RFC.
Then if you read the API's documentation (https://developers.google.com/maps/documentation/directions/), you'll find out that the returned json dict has a 'status' key, which values are documented too. So the next obvious thing to check this status code, and behave appropriately, ie:
for result in results:
if result["status"] == "OK":
for leg in result['routes'][0]['legs']:
params = {
"duration(s)": leg['duration']['value'],
"distance(m)": leg['distance']['value'],
}
print(params)
writer.writerow(params)
else:
# not OK, let's check if we have an explicit error message:
if "error_message" in result:
print result["error_message"]
# handle the error case...

Categories