Getting Response 200 instead of data from API call - python

I am new here so pardon me for mistakes or silly questions
I am trying to implement following via python
https://docs.paloaltonetworks.com/cortex/cortex-xdr/cortex-xdr-api/cortex-xdr-apis/xql-apis/get-xql-query-exported-data.html
Intsead of data, I am getting <Response 200>
How can I get the GZIP file via this API call. This is the first time I am trying anything like this and any help would be appreciated.
My code:
def get_stream_data():
temp_headers = {
"x-xdr-auth-id": str(4),
"Authorization": config['CORTEX_KEY'],
"Accept-Encoding": "gzip",
"Content-Type":"application/json",
}
stream_id = get_XQL_query()
data_temp = {"request_data":{"stream_id":stream_id,"is_gzip_compressed": True}}
response = requests.post(url="<fqdn>.paloaltonetworks.com/public_api/v1/xql/get_query_results_stream/",headers=temp_headers,json=data_temp)
#something here to parse the response, no idea what
return response

Requests library documentation says that you need:
return response.json() # Returns JSON, if properly encoded else raises error
# or
return response.content # Return raw bytes

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,

requests.post returns isSuccess:false even though Postman returns true

I am trying to post some information into an API based on their recommended format. When I use Postman( tool to test APIs), I see that the response has the isSuccess flag set to true. However, when I write the same code in Python using the requests library, I get the isSuccess flag as false
As mentioned about, I verified the headers and the json data object, both are the same yet the results defer
import requests
data = {"AccountNumber":"100007777",
"ActivityID":"78",
"ActivityDT":"2019-08-07 12:00:00",
"ActivityValue":"1"
}
url = "http://<IP>/<API_PATH>"
headers = {
"X-Tenant":"Default",
"Content-Type":"application/json"
}
response = requests.post(url,data=data, headers = headers)
print(response.content)
This code should successfully post the data and I should get a isSuccess:true in my response variable.
Can anyone help me figure out what might be wrong?
Can you try to change;
response = requests.post(url,data=data, headers = headers)
to;
response = requests.post(url,json=data, headers = headers)
or;
response = requests.post(url,body=data, headers = headers)

Python How to GET Image and then POST (via requests library)

I am using python to try and get an image from one API, and then post it to a separate API.
So far I have this code:
def create_item(token, user_id):
url = '<api_url_to_post_to>'
headers = {"Authorization": "Token {0}".format(token)}
image_url = '<some_random_image_url>'
image_obj = requests.get(image_url)
data = {
"image": image_obj.content
}
r = requests.post(url, headers=headers, files=data)
response = r.json()
print(response)
return response
The issue is that when I try to post it to the second API, I get a "File extension '' is not allowed." error. This is obviously a custom error message, but it signifies that there is something wrong with the file that I am posting.
Any suggestions on what I may be doing wrong?
Try specifying the file type, just image_obj.content is the raw binary image:
r = requests.post(
url,
headers=headers,
files={'image': ('my_image.jpg', image_obj.content, 'image/jpg')})
This should add the correct headers to the multipart boundary for the image.
If you don't know for sure the content type, you might actually get it from the headers of your previous response: image_obj.headers['Content-Type'] should be "image/jpg" but for a different image it might be "image/png".
It wants a file extension, I'd hazard a guess that image should be image.<SOME_FORMAT>.

How to call an API using Python Requests library

I can't figure out how to call this api correctly using python urllib or requests.
Let me give you the code I have now:
import requests
url = "http://api.cortical.io:80/rest/expressions/similar_terms?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = {"positions":[0,6,7,29]}
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.get(url, params=params, headers=headers)
# Print the content of the response
print(response.content)
I've even added in the rest of the parameters to the params variable:
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False,
"positions":[0,6,7,29]}
I get this message back:
An internal server error has been logged # Sun Apr 01 00:03:02 UTC
2018
So I'm not sure what I'm doing wrong. You can test out their api here, but even with testing I can't figure it out. If I go out to http://api.cortical.io/, click on the Expression tab, click on the POST /expressions/similar_terms option then paste {"positions":[0,6,7,29]} in the body textbox and hit the button, it'll give you a valid response, so nothing is wrong with their API.
I don't know what I'm doing wrong. can you help me?
The problem is that you're mixing query string parameters and post data in your params dictionary.
Instead, you should use the params parameter for your query string data, and the json parameter (since the content type is json) for your post body data.
When using the json parameter, the Content-Type header is set to 'application/json' by default. Also, when the response is json you can use the .json() method to get a dictionary.
An example,
import requests
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False
}
data = {"positions":[0,6,7,29]}
r = requests.post(url, params=params, json=data)
print(r.status_code)
print(r.json())
200
[{'term': 'headphones', 'df': 8.991197733061748e-05, 'score': 4.0, 'pos_types': ['NOUN'], 'fingerprint': {'positions': []}}]
So, I can't speak to why there's a server error in a third-party API, but I followed your suggestion to try using the API UI directly, and noticed you're using a totally different endpoint than the one you're trying to call in your code. In your code you GET from http://api.cortical.io:80/rest/expressions/similar_terms but in the UI you POST to http://api.cortical.io/rest/expressions/similar_terms/bulk. It's apples and oranges.
Calling the endpoint you mention in the UI call works for me, using the following variation on your code, which requires using requests.post, and as was also pointed out by t.m. adam, the json parameter for the payload, which also needs to be wrapped in a list:
import requests
url = "http://api.cortical.io/rest/expressions/similar_terms/bulk?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = [{"positions":[0,6,7,29]}]
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.post(url, json=params, headers=headers)
# Print the content of the response
print(response.content)
Gives:
b'[[{"term":"headphones","df":8.991197733061748E-5,"score":4.0,"pos_types":["NOUN"],"fingerprint":{"positions":[]}}]]'

How to structure a request to neutrinoapi using python 3? (convert urllib2 request to urllib)

Im new to server side code and interested in using the neutrinoapi (www.neutrinoapi.com) for filtering some bad words out of text. I have written the following code in Python 3 (im using bottle server):
url = 'https://neutrinoapi.com/bad-word-filter'
params = {
'user-id': 'testing',
'api-key': '205cmqorLBdyV2F9FX4z6NNq1Y3z8AkRTw8ImtGE2MtzxmhT',
'ip': '162.209.104.195'
}
json_data = json.dumps(params).encode('utf8')
response = urllib.request.urlopen(url, data = json_data)
result = json.loads(response.read())
This request is returning the following error:
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
The example on the website is at this link:
https://www.neutrinoapi.com/api/api-examples/python/
Examples provided are using python 2.7 and urllib2 which i understand is now built into urllib. Cant seem to get the request to work in Python 3. Any ideas on how to make a proper request?
The Python example doesn't use JSON for the parameters, only for the response. You'll need to URL encode those parameters instead; use the urllib.parse.urlencode() function for that, then encode the resulting string to bytes.
You also need to send the content parameter for a bad-word-filter request, not an IP address:
from urllib.parse import urlencode
url = 'https://neutrinoapi.com/bad-word-filter'
params = {
'user-id': 'testing',
'api-key': '<valid api key>',
'content': 'foo bar baz'
}
encoded_params = urlencode(params).encode('utf8')
response = urllib.request.urlopen(url, data = encoded_params)
result = json.loads(response.read())

Categories

Resources