I am using requests
to call to Aruba's NBAPI for mobility master. Their documentation is scarce with Python examples. The API requires an initial auth to get a UID which needs to be referenced in each GET request. I cannot get the login to work within Python.
I'm using a GET request which may be part of the issue but it's my understanding of the curl
example provided by Aruba the default GET
method is being used. Please note I'm also not verifying the SSL cert as my end goal is zero touch provisioning.
Here is the curl command they offer to auth
curl --insecure -c "aruba-cookie-jar" -d "username=username&password=password" https://<url-here>:4343/v1/api/login
command output:
{"_global_result": {"status":"0", "status_str": "You've logged in successfully.", "UIDARUBA":"<key output here>"}}
I tried to convert this into python using 'requests' as shown below
import requests
session = requests.Session()
session.verify = False
r = session.get('https://<url-here>:4343/v1/api/login', auth=('username', 'password'))
I get the below when checking response (ipython)
In [6]: r.status_code
Out[6]: 401
In [7]: print(r.text)
{"_global_result": {"status":"1", "status_str": "Unauthorized request, authentication failed"}}
What am I doing wrong with this request? When using the POST method in Python results in the same output. I am thinking the auth
method being used in my Python example is not correct.
You are not making the same request. The -d
switch for curl
sends POST data, not an authorization header. From the curl
documentation:
-d, --data <data>
(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded.
You are using a GET request, not POST. Send the username and password in the data
argument, you can use a dictionary here to have requests
handle encoding it to a application/x-www-form-urlencoded
formatted request body:
session = requests.Session()
session.verify = False
login_info = {'username': 'username', 'password': 'password'}
r = session.post('https://<url-here>:4343/v1/api/login', data=login_info)
In general, API documentation that uses curl
command-line examples count on a minimal familiarity with that tool, it is always worth reading the curl
manpage to understand what the switches do, as well as have a minimal understanding of HTTP headers and the likes.
When in doubt, use both curl
and requests
to send your request to the httpbin.org test site, and compare the results. Here, using the /anything
endpoint with curl
gives:
$ curl --insecure -c "aruba-cookie-jar" -d "username=username&password=password" https://httpbin.org/anything
{
"args": {},
"data": "",
"files": {},
"form": {
"password": "password",
"username": "username"
},
"headers": {
"Accept": "*/*",
"Content-Length": "35",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "curl/7.54.0"
},
"json": null,
"method": "POST",
"origin": "...",
"url": "https://httpbin.org/anything"
}
while your request
code outputs:
>>> import requests
>>> session.verify = False
>>> r = session.get('https://httpbin.org/anything', auth=('username', 'password'))
/.../lib/python3.8/site-packages/urllib3/connectionpool.py:842: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
warnings.warn((
>>> print(r.text)
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.21.0"
},
"json": null,
"method": "GET",
"origin": "...",
"url": "https://httpbin.org/anything"
}
which should hopefully make it clearer what the differences where here.