Unable to retrieve the api token using requests library python - python

I'm trying to use requests API to login into Zabbix API, but unable to do due to the below issue.
I want to achieve the login by pyzabbix module, but I want to use API user authentication token.
Without password and username in the code (any suggestion would help me).
Error:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Code:
import requests
from pprint import pprint
import json
url = 'http://127.0.0.1/zabbix'
########################################
# user.login
########################################
payload = {
"jsonrpc" : "2.0",
"method" : "user.login",
"params": {
'user': 'Admin',
'password':'Zabbix',
},
"auth" : None,
"id" : 0,
}
headers = {
'content-type': 'application/json',
}
res = requests.post(url, data=json.dumps(payload), headers=headers)
print(res)
res = res.json()
print('user.login response: ',res['result'])

If you want to call the Zabbix API you have to use the correct endpoint, which is api_jsonrpc.php.
So, for instance you can use:
url = 'http://127.0.0.1/api_jsonrpc.php'
However your code does not account for errors (ie: if Admin/Zabbix is wrong, your script will return a key error, because the error response does not contain a result.
A better choice is to use a library such as py-zabbix

Related

Getting different responses from postman vs. python API call

I'm trying get the same data from an API call in Postman using Python.
The call is relatively simple. It uses Basic Authorization that only requires the API key being passes as the username, and a dynamic component: csv_key variable that is passed from earlier codes.
I was able to successfully made the request (status code 200), but the response from Python is different from the one in Postman. It's missing all key-value pairs except the firs two: id and description.
I'm getting this response from postman:
response from postman
{
"id": "63c9c0927885bf003ecd3a1b",
"description": "Streaming analytics",
"download_url": "https://storage.googleapis.com/***-static/***.csv?GoogleAccessId=888211540537-r3m40kms2upicdr07e5rl2q67feg9loh%40developer.gserviceaccount.com&Expires=4070908800&Signature=WvuuKdddCFKjSNpst5n8yKFNR5qtC1m1o1mQZFWLHmKomJtc7npa6PbwfRoTj9FhIIqbta98VPOYKMGW89XaqXtITh15V%2Bf9opAD3BnuLjTzWC6X24RC5kMCZATXpp9DWi1Our061%2FdKlpUozi1ir7b8AwBWWf%2Bs8u5J6VoelvtEyiZIO4l%2FQdeJ26GqDLRgWElEMAlBE3TJo7m3UuE8gOQPsYBCwBSfLI1bTIytNOHZMUlWuVtMQxEHzUOujAp%2Fgqn1Q8TGGzy5GoeEmzw%2FD80xs%2BALjhT%2BxdiN9riG6%2BEcObrhPoudxl32jUhVH0EmGJwjgiJFQpz%2FLfKr86LrCQ%3D%3D",
"error": "Cannot read property 'email' of undefined",
"completed_at": "2023-01-19T22:13:39.219Z"
}
But I'm only getting the first two key-value pairs using a Python script of the same API call:
response from Python
csv key: 63c9c0927885bf003ecd3a1b
api url: https://api.eventive.org/temporary_exports/63c9c0927885bf003ecd3a1b
<Response [200]>
response:[{'id': '63c9c0927885bf003ecd3a1b', 'description': 'Streaming analytics'}]
Process finished with exit code 0
My code for the Python script is:
import requests
import json
url_for_key = 'https://api.***.org/reports/streams?event_bucket=63279b48d8f8f1009209694f&start=1674111600000&end=1674198000000&tz=America%2FDenver'
api_key = '*************************'
header = {'content-type': 'application/json'}
r1 = requests.get(url=url_for_key, auth=(api_key, ''))
csv_obj = [r1.json()]
csv_key = csv_obj[0]['temporary_export']
#print(csv_obj)
print(f'csv key: {csv_key}')
url_for_link = 'https://api.***.org/temporary_exports/{}'.format(csv_key)
print(f'api url: {url_for_link}')
r2 = requests.get(url=url_for_link, headers=header, auth=(api_key, ''))
print(r2)
print(f'response:{[r2.json()]}')
csv_key is the same as id. Could anyone help me understand what's going on?
Many thanks,

Why twitter api request get Expecting value: line 1 column 1 (char 0)?

I got the below error when using a Twitter API request to change PFP:
'Expecting value: line 1 column 1 (char 0)'
And this for the Code
picture = [f for f in os.listdir("pfp/") if isfile(join("pfp/", f))]
random_picture = random.choice(picture)
with open(f'pfp/{random_picture}', "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
cookies = {
'auth_token': x
}
headers = {'Content-Type': 'multipart/form-data'}
params = f"image=data:image/png;base64,{(encoded_string.decode('utf-8'))}"
response = requests.post('https://api.twitter.com/1.1/account/update_profile_image.json',
cookies=cookies, params=params, headers=headers, proxies=proxies)
is the my code wrong ?
Any help is appreciated.
Thing which you need to provide:
method: POST
url: https://api.twitter.com/1.1/account/update_profile_image.json
parameter as encoded url-safe Base64 (so for example + should be changed to %20) for example: iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAABwgAAAcIAHND5ueAAAAJklEQVQImWMQibsx73%20NSNyNGyIiDBAWhGSAs%20b9r2G4ISIC5wMAg%20IY55xszl4AAAAASUVORK5CYII%3D
header to authorise user: auth_token: 1610678221XXX-ab5sYYYYY
headers to authorise application (for OAuth 1.0 HMAC-SHA1)
Authorization headers - RFC 5849: The OAuth 1.0 Protocol
How to build it, check here:
https://www.rfc-editor.org/rfc/rfc5849#section-3.5.1
or here:
https://stackoverflow.com/a/67668940/5529263
For python you can use Requests-OAuthlib library
Example of code:
import requests
image = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAABwgAAAcIAHND5ueAAAAJklEQVQImWMQibsx73%20NSNyNGyIiDBAWhGSAs%20b9r2G4ISIC5wMAg%20IY55xszl4AAAAASUVORK5CYII%3D"
url = "https://api.twitter.com/1.1/account/update_profile_image.json?image=" + image
headers = {
'auth_token': '12341234512345234512345-abcedfghijklm',
'Authorization': 'OAuth '
'oauth_consumer_key="ABCD1234ABCD1234ABCD1234",'
'oauth_signature_method="HMAC-SHA1",'
'oauth_timestamp="1234567890",'
'oauth_nonce="MNOPRST0987MN",'
'oauth_version="1.0",'
'oauth_signature="ABCDEFGHIJ1234ABCDEFGHIJ"',
}
response = requests.request("POST", url, headers=headers, data={})
print(response.text)
After sending correct request you can receive response with code 403
{
"errors": [
{
"message": "You currently have Essential access which includes access to Twitter API v2 endpoints only. If you need access to this endpoint, you’ll need to apply for Elevated access via the Developer Portal. You can learn more here: https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-leve",
"code": 453
}
]
}
so it means you need to apply for Elevated access, here you have more information:
https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-level

Allcoin signed POST request fails

The API i am using requires an MD5 encryption to work on POST requests. I am trying the make an 'userBalance' request to the API using the documentation https://www.allcoin.ca/api_market/market But every time it gives me back {'code': 1, 'msg': '签名校验失败'} (which means signature check failed). The API only asks for 2 parameteres, the api_key and sign. I carefully follow the guidance of the documentation, but the API still rejects the POST. Any suggestions why it fails the signature check? Am i missing something?
import hashlib
import keys
import requests
KEY = keys.allcoin["key"]
API_SECRET = keys.allcoin["secret"]
msg = "api_key='{}&secret_key={}".format(KEY, API_SECRET)
signature = hashlib.md5(msg.encode("utf-8")).hexdigest()
parameters = {
"api_key": KEY,
"sign": signature.upper(),
}
params = "&".join("{}={}".format(a, b) for a, b in parameters.items())
url = "http://www.allcoin.ca/Api_User/userBalance"
r = requests.post(
headers={
"Content-Type": "application/x-www-form-urlencoded",
'user-agent': 'my-app/0.0.1'
},
url=url,
params=parameters
)
print(r.json())
I think you want to change params=parameters to params=params in your requests.post().

Trying to interact with an API

I'm in the process of moving learning how to interact with APIs in my programming training. The following script is used on the sandbox environment for a software I'm trying to interact with.
For some reason, I cannot login to the API to run the second function. Does anyone see the issue?
# import requests library
import requests
#import json library
import json
controller='apicontroller#test.com'
def getToken():
# put the ip address or dns of your apic-em controller in this url
url = "https://" + controller + "/api/aaaLogin.json"
json_object = {
"aaaUser" : {
"attributes" : {
"name" : "******",
"pwd" : "*******"
}
}
}
#Content type must be included in the header
header = {"content-type": "application/json"}
#Performs a POST on the specified url to get the service ticket
response= requests.post(url,data=json.dumps(json_object), headers=header, verify=False)
#convert response to json format
r_json=response.json()
#parse the json to get the service ticket
token = r_json["response"]["token"]
return token
def pushtenant():
# URL for network device REST API call to get list of existing devices on the network.
url = "https://" + controller + "/api/api/mo/uni"
#Content type must be included in the header as well as the ticket
headers = {"content-type": "application/json", "X-Auth-Token":Token}
json_tenant = [{
"fvTenant" : {
"attributes" : {
"name" : "ExampleCorp"
}
}
}]
# this statement performs a GET on the specified network-device url
response = requests.post(url, json.dumps(json_tenant), headers=headers,verify=False)
# json.dumps serializes the json into a string and allows us to
# print the response in a 'pretty' format with indentation etc.
print ("Response = ")
print (json.dumps(response.json(), indent=4, separators=(',', ': ')))
enter code here
#convert data to json format.
r_json=response.json()
theToken=getToken()
pushtenant(theToken)

Connect R to an API, pass it username and password

I have been trying to retrieve data from an API using R, but haven't succeeded yet. I tried doing it in R using the httr package and the GET function, but I get the following error when I enter the URL:
Error: 'new_handle' is not an exported object from 'namespace:curl'
What it comes down to is that I want to connect to data and that I have to pass some arguments like password and username.
I do have some Python code from a colleague that works (I have anonymized the URLs that are specific to our company), what I want is to connect to the data in a similar way in R:
------------- Equivalent Python code: --------------
import urllib
import datetime as dt
import dateutil
import json
headers = {u'content-type': u'application/x-www-form-urlencoded; charset=UTF-8'}
values = {"grant_type": "password",
"username": "XXXXXXXXX",
"password": "XXXXXXXXX",
"client_id": "PS"}
ko = urllib.request.Request("XXXXXX",
urllib.parse.urlencode(values).encode("utf-8"),
headers)
token = urllib.request.urlopen(ko).read()
epic = token.decode()
token_key = epic.split(",")[0].split(":")[1].replace('"', "")
lines_to_write = list()
lines_to_write.append("Identifier;Year;Period;Park Energy Availability [%]")
start_day = dt.datetime(2015, 1, 1)
data_day = start_day
headers = {u'content-type': u'application/json', u'Authorization': 'Bearer ' + token_key}
values = {'scope': {}, 'period': {'Begin': str(data_day).replace(" ", "T"), 'End': str(data_day + dateutil.relativedelta.relativedelta(months=1)).replace(" ", "T")}}
hest = urllib.request.Request("XXXXXXXXX", json.dumps(values).encode(), headers)
data = urllib.request.urlopen(hest)
vild_hest = data.read()
Any help would be greatly appreciated,
Best regards,
Tristan
The R code for API you presented will not work since it is just simply fractions of what is needed. Below you find the structure that R needs for working towards a REST API. The username and password will be passed to API server through the body of the POST (either as stated below or it could also be added as a list in the body).
You will also have to provide a key (in below case "API-KEY"). Note that you are sending a POST to initiate the authentication with the API server. Most API server will send you back 1 or 2 keys that you will use in later communication with the API server.
It is correct that all http interaction will take help of the package httr.
GET will be used in later stage in the communication between your API client and API server but not during the first authentication phase.
POST (
url = "xxx",
add_headers(
"API-KEY" = "xxx",
"VERSION" = "2",
"Content-Type" = "application/json; charset=UTF-8",
"Accept" = "application/json; charset=UTF-8"),
body = "{identifier: xxx, password: xxx}"
)

Categories

Resources