I always get a Type Error when I run the following python code (abc.py) as follows:
./abc.py activatelink alphabeta
Type Error: ['alphabeta']
My code:
#!/usr/bin/python
import urllib2
from urllib2 import URLError
from urllib2 import HTTPError
import requests
import urllib
import json
import time
import os
import sys
import hashlib
def activate_user(link):
print invoke_rest('GET', link)
def invoke_rest(request_type, rest_url, payload, headers):
try:
api_url = rest_url
if request_type == 'GET':
r = requests.get(api_url)
to_ret = {'code':r.status_code, 'reply':r.text}
return to_ret
elif request_type == 'POST':
r = requests.post(api_url, data=payload, headers=headers)
to_ret = {'code':r.status_code, 'reply':r.text}
return to_ret
else:
return "Invalid request type ", request_type
except Exception, e:
return "Exception:", e, " in getting the API call"
def help():
print ('Usage: %s { activate | help }', os.path.basename(sys.argv[0])
if __name__ == '__main__':
actions = {'activatelink': activate_user, 'help': help}
try:
action = str(sys.argv[1])
except IndexError:
print "IndexError: ", sys.argv[1]
action = 'help'
args = sys.argv[2:]
try:
actions[action](*args)
except (KeyError):
print "Key Error:", args
help()
except (TypeError):
print "Type Error:", args
help()
Am I doing anything wrong? I added some other functions other than activatelink, which work fine, can anyone point out whats wrong in here?
Your invoke_rest() function takes four arguments:
def invoke_rest(request_type, rest_url, payload, headers):
but you pass in just the two:
print invoke_rest('GET', link)
That raises a TypeError exception:
>>> def invoke_rest(request_type, rest_url, payload, headers):
... pass
...
>>> invoke_rest('GET', 'alphabeta')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: invoke_rest() takes exactly 4 arguments (2 given)
Perhaps you wanted those two extra arguments (payload and headers) to be optional. If so, make them keyword arguments and set their default value to None:
def invoke_rest(request_type, rest_url, payload=None, headers=None):
which is fine by the requests library.
Related
I want to check if the json file is empty. Where in the code do i check that properly?
This is my code:
import os
import sys
import traceback
import json
import requests
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
try:
API_ENDPOINT = os.getenv('OVERPASS_API_ENDPOINT', 'http://overpass.osm.ch/api/interpreter')
query = "".join(sys.stdin.readlines())
r = requests.get(API_ENDPOINT, params={'data': query})
print(json.dumps(r.json(), sort_keys=True, indent=2))
except Exception as e:
print("Error: %s" % e, file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
sys.exit(1)
Thanks for your help.
Simple comparison with empty dict should do:
r.json() == {}
or
r.json() == dict()
or
len(r.json()) == 0
Edit: Seems like you may not be receiving a JSON in your response at all, to check that, you add this conditional:
if r.headers.get('content-type') == 'application/json':
if r.json() == {}:
# rest of your code
I'm trying to test my function that returns dictionary. I'm getting error AttributeError: 'dict' object has no attribute 'content_type'. How can I test if the response is a dictionary or not?
def response_get(url):
try:
response = requests.get(url)
except requests.exceptions.RequestException as e:
raise SystemExit(e)
data = response.json()
return data
def test_response_get(self):
response = response_get('https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49')
self.assertEqual(response.content_type, 'application/dict')
You are already returning a dict and there is no content_type on a dictionary.
Instead you can use isinstance and assertTrue.
import requests
import unittest
def response_get(url):
try:
response = requests.get(url)
except requests.exceptions.RequestException as e:
raise SystemExit(e)
data = response.json()
return data
class SimpleTest(unittest.TestCase):
def test_response_get(self):
response = response_get('https://ghibliapi.herokuapp.com/films/58611129-2dbc-4a81-a72f-77ddfc1b1b49')
self.assertTrue(isinstance(response, dict))
if __name__ == '__main__':
unittest.main()
Output:
.
----------------------------------------------------------------------
Ran 1 test in 0.966s
OK
i need a script to make it like a cpanel checker, with more than 1 url and the url is stored in a txt file.
usage : python script.py list.txt
format in file list.txt : https://demo.cpanel.net:2083|democom|DemoCoA5620
this is my code but it doesn't work, can someone help me?
Thanks.
import requests, sys
from multiprocessing.dummy import Pool as ThreadPool
try:
with open(sys.argv[1], 'r') as f:
list_data = [line.strip() for line in f if line.strip()]
except IOError:
pass
def cpanel(url):
try:
data = {'user':'democom', 'pass':'DemoCoA5620'}
r = requests.post(url, data=data)
if r.status_code==200:
print "login success"
else:
print "login failed"
except:
pass
def chekers(url):
try:
cpanel(url)
except:
pass
def Main():
try:
start = timer()
pp = ThreadPool(25)
pr = pp.map(chekers, list_data)
print('Time: ' + str(timer() - start) + ' seconds')
except:
pass
if __name__ == '__main__':
Main()
I fixed your code in a way that it will return an actual array containing a boolean array indicating the success of the cpanel function.
from __future__ import print_function
import requests
from multiprocessing.pool import ThreadPool
try:
list_data = ["https://demo.cpanel.net:2083|democom|DemoCoA5620",
"https://demo.cpanel.net:2083|UserDoesNotExist|WRONGPASSWORD",
]
except IOError:
pass
def cpanel(url):
try:
# try to split that url to get username / password
try:
url, username, password = url.split('|')
except Exception as e:
print("Url {} seems to have wrong format. Concrete error: {}".format(url, e))
return False
# build the correct url
url += '/login/?login_only=1'
# build post parameters
params = {'user': username,
'pass': password}
# make request
r = requests.post(url, params)
if r.status_code==200:
print("login for user {} success".format(username))
return True
else:
print("login for user {} failed due to Status Code {} and message \"{}\"".format(username, r.status_code, r.reason))
return False
except Exception as e:
print("Error occured for url {} ".format(e))
return False
def chekers(url):
return cpanel(url)
def Main():
try:
# start = timer()
pp = ThreadPool(1)
pr = pp.map(chekers, list_data)
print(pr)
# print('Time: ' + str(timer() - start) + ' seconds')
except:
pass
if __name__ == '__main__':
Main()
Output:
login for user democom success
login for user UserDoesNotExist failed due to Status Code 401 and message "Access Denied"
[True, False]
Be aware that I replaced your file read operation by some fixed urls.
Since you use request.post I guess you actually want to POST something to that urls. Your code does not do that. If you just want to send a request, use the requests.get method.
See the official documentation for the requests packet: https://2.python-requests.org/en/master/user/quickstart/#make-a-request for more details.
Also note that
"but it doesn't work"
is NOT a question.
After running successfully i suddenly see below error for python script. Not much experienced in python. The script fetch's information over API. Python 2.7.12
/usr/local/lib/python2.7/dist-packages/requests/__init__.py:83: RequestsDependencyWarning: Old version of cryptography ([1, 2, 3]) may cause slowdown.
warnings.warn(warning, RequestsDependencyWarning)
Traceback (most recent call last):
File "fetch-drives-ncpa.py", line 31, in <module>
data = r.json()
NameError: name 'r' is not defined
Below is the script.
# importing the requests library
import requests
import json
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# defining a params dict for the parameters to be sent to the API
PARAMS = {'token':'dddsxsdsdsd','units':'l'}
openfiledrives = open("device_drivelist.txt", 'w')
openfiledrives.truncate(0)
openfile = open('device_list.txt')
for devicename in openfile.readlines():
devicename = devicename.strip()
# api-endpoint
URL = "https://"+devicename+":5666/api/"
try:
r = requests.get(url = URL, params = PARAMS, verify=False,timeout=30)
r.raise_for_status()
except requests.exceptions.HTTPError as errh:
print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
print ("Timeout Error:",errt)
except requests.exceptions.RequestException as err:
print ("OOps: Something Else",err)
# extracting data in json format
data = r.json()
Machine = data['root']['system']['node']
# print the keys and values
for i in data['root']['disk']['logical']:
Drive = data['root']['disk']['logical'][i]['device_name']
FreeSpace = data['root']['disk']['logical'][i]['free']
TotalSpace = data['root']['disk']['logical'][i]['total_size']
FSType=data['root']['disk']['logical'][i]['opts']
#print Machine.lower(),Drive[0],FreeSpace[0],TotalSpace[0]
#openfiledrives.write('{0}\t{1}\t{2:.0f}\t{3:.0f}\n'.format(Machine.lower(),Drive[0],FreeSpace[0],TotalSpace[0]))
if FSType != 'ro,cdrom':
openfiledrives.write('{0}\t{1}\t{2:.0f}\n'.format(Machine.lower(),Drive[0],FreeSpace[0]))
openfile.close()
openfiledrives.close()
If requests.get raises an exception, no value is ever assigned to r. But you still try to call r.json() following that exception.
I have an error handling module that I'm using in my main script to make requests to an API. I want to return "response" and "data" to use in the main script. It works up until trying to print "response". Apologies for inconsistencies, I am obviously still learning. And I won't learn without making a few mistakes first. I appreciate constructive criticism.
my_module
import requests
import json
def errorHandler(url):
try:
response = requests.get(url, timeout=5)
status = response.status_code
data = response.json()
except requests.exceptions.Timeout:
print "Timeout error.\n"
except requests.exceptions.ConnectionError:
print "Connection error.\n"
except ValueError:
print "ValueError: No JSON object could be decoded.\n"
else:
if response.status_code == 200:
print "Status: 200 OK \n"
elif response.status_code == 400:
print "Status: " + str(status) + " error. Bad request."
print "Correlation ID: " + str(data['correlationId']) + "\n"
else:
print "Status: " + str(status) + " error.\n"
return response
return data
my_script
errorHandler("https://api.weather.gov/alerts/active")
print "Content type is " + response.headers['content-type'] +".\n" #expect geo+json
# I need the data from the module to do this, but not for each get request
nwsId = data['features'][0]['properties']['id']
error
Traceback (most recent call last):
File "my_script.py", line 20, in <module>
print errorHandler.response
AttributeError: 'function' object has no attribute 'response'
If you want to return multiple values, you return them as a tuple in a single statement:
return response, data
Then in the caller, you assign them to variables with a tuple assignment:
response, data = errorHandler("https://api.weather.gov/alerts/active")
print "Content type is " + response.headers['content-type'] +".\n"
nwsId = data['features'][0]['properties']['id']
However, your function will not work correctly if any of the exceptions occur. If there's an exception, it won't set the variables response or data, so when it tries to return them it will get an error.