Receiving 'BadRequestKeyError' when attempting to GET data from endpoint url - python

I was trying to implement an API using Python, and flask to help myself learn and practice REST.
The idea was to receive a HTTP POST with data that looks like as such:
{"startDate":"2015-07-01","endDate":2015-07-08","within":{"value":9000,"units":miles}} and send some of the data to a NASA API(endpoint).
I was able to create a POST method , and I am able to receive the data (both in POSTMAN and in the browser). Here is the relevant code :
#neows.route('/UserInput',methods=['GET','POST'])
def UserInput():
startDate = request.args.get('startDate')
endDate = request.args.get('endDate')
#print (type(startDate))
#print (type(endDate))
getAsteroids(startDate,endDate)
return jsonify(request.args)
But when I extract some data from the POST above to send to a NASA API (GET), I am receiving this error:
werkzeug.exceptions.BadRequestKeyError
Here is the url I am trying to hit : (https://api.nasa.gov/neo/rest/v1/feed?start_date=START_DATE&end_date=END_DATE&api_key=API_KEY)
I am able to hit the url both on POSTMAN and browser, outside of my code.
The relevant piece of code with the error is posted below and the line that seems to be throwing the error is in Italics (marked with *).
def getAsteroids(startDate,endDate):
API_KEY='xxx'
print (startDate)
print (endDate)
*result=request.args["https://api.nasa.gov/neo/rest/v1/feed?
start_date="+startDate+"&end_date="+endDate+"&api_key="+API_KEY+""]*
I would really appreciate if some one could help me understand and resolve this issue.

If you want to do a request against the NASA's API you can use requests module. (Or any other module to send HTTP requests)
import requests
# ...
def getAsteroids(startDate, endDate):
API_KEY='xxx'
payload = {'start_date': startDate, 'end_date': endDate, 'api_key': API_KEY}
result = requests.get('https://api.nasa.gov/neo/rest/v1/feed', params=payload)
request.args is something different used to get the parameters of the incoming request.

Related

Issue with getting the response data using Locust

Im trying to see if I'm able to get the response data as I'm trying to learn how to use regex on Locust. I'm trying to reproduce my test script from JMeter using Locust.
This is the part of the code that I'm having problem with.
import time,csv,json
from locust import HttpUser, task,between,tag
class ResponseGet(HttpUser):
response_data= ""
wait_time= between (1,1.5)
host= "https://portal.com"
username= "NA"
password= "NA"
#task
def portal(self):
print("Portal Task")
response = self.client.post('/login', json={'username':'user','password':'123'})
print(response)
self.response_data = json.loads(response.text)
print(response_data)
I've tried this suggestion and I somehow can't make it work.
My idea is get response data > use regex to extract string > pass the string for the next task to use
For example:
Get login response data > use regex to extract token > use the token for the next task.
Is there any better way to do this?
The way you're doing it should work, but Locust's HttpUser's client is based on Requests so if you want to access the response data as a JSON you should be able to do that with just self.response_data = response.json(). But that will only work if the response body is valid JSON. Your code will also fail if the response body is not JSON.
If your problem is in parsing the response text as JSON, it's likely that the response just isn't JSON, possibly because you're getting an error or something. You could print the response body before your attempt to load it as JSON. But your current print(response) won't do that because it will just be printing the Response object returned by Requests. You'd need to print(response.text()) instead.
As far as whether a regex would be the right solution for getting at the token returned in the response, that will depend on how exactly the response is formatted.

How do I properly format data in a Python POST request to Streamlabs API?

I'm trying to connect our application to Streamlabs' API so we can post donation alerts. To do that, I need to get an access token for the user whose channel we want to alert on. It's a normal OAuth2 thing. We hit the /authorize endpoint and get a code back, which we're then supposed to able to use to get an access token from the /token endpoint (https://dev.streamlabs.com/v1.0/reference#token-1).
But when we send the POST request for the token, we get an error saying the request is missing the "grant_type" parameter.
We're using the normal requests library. I've tried changing the format of the request to requests.post. I've tried altering the data by wrapping it in urlencode and json.dumps. Still no luck.
streamlabs_client_id = config('STREAMLABS_CLIENT_ID')
streamlabs_client_secret = config('STREAMLABS_CLIENT_SECRET')
streamlabs_redirect_uri = config('STREAMLABS_REDIRECT_URI')
grant_type = 'authorization_code'
querydict = {
"grant_type":"authorization_code",
"client_id":streamlabs_client_id,
"client_secret":streamlabs_client_secret,
"redirect_uri":streamlabs_redirect_uri,
"code":code
}
url = "https://streamlabs.com/api/v1.0/token"
streamlabs_response = requests.request("POST", url, data=querydict)
This is the json I get back every time:
{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \"grant_type\" parameter."}
Any ideas what I'm doing wrong with the data?

Send Key value form data using post request in Python

I am able to make Post request using postMan and I get correct data but when I send the same using python ,I get a different output .
As you can see below using postMan when I make a request I can see the desired output .
But when I do the same using my below python code ,it doesn't give me the desired output and overall just gives me the a HTML text with fields filled up ,seems it makes a Get request ,not sure If am sending my form incorrectly
def checkDate(self):
values ={'numberItems':1,
'mode':'DriveTest',
'officeId':592,
'requestedTask':'DT',
'firstName':'xxx',
'lastName':'xxx',
'dlNumber':'xxx',
'birthMonth':05,
'birthDay':31,
'birthYear':123,
'resetCheckFields':'true'}
r = requests.post('https://www.dmv.ca.gov/wasapp/foa/findDriveTest.do',params=values)
tet=r.text
print(tet)
The actual page is https://www.dmv.ca.gov/wasapp/foa/findDriveTest.do ,so here what I am trying to do is create a script which will run every 4 hours to notify me that a early date is now available .
To make a POST request you should pass your values like this:
r = request.post('https://www.dmv.ca.gov/wasapp/foa/findDriveTest.do',data=values)
The reason that your previous code didn't make a POST request is that you were trying to pass your values as URL parameters which is used when making a GET request
Try using this :
import json
r = requests.post('https://www.dmv.ca.gov/wasapp/foa/findDriveTest.do',params=json.dumps(values), headers = {"content-type": "application/json"})
tet=r.text
print(tet)

Streamlabs API 405 response code

I'm trying to use Streamlabs API. Streamlabs API uses Oauth2 for creating apps. So first I send whoever's using my app to an authorization link containing my app's client id and the scopes I want to use.
(Something like this: streamlabs.com/api/v1.0/authorize?client_id=CLIENT-ID-HERE&redirect_uri=REDIRECT-URI&response_type=code&scope=SOME+SCOPES+HERE)
Once I've done that I receive a code at the redirect uri specified. I then use that code to get the access token for permanent access to the connected user's account. I then receive the access token from a POST request that works perfectly... Now I run into the problem. When getting the temporary code before the access token I specified the scopes: "donations.read +donations.create+alerts.write+alerts.create".
When authorizing, the app asks for permission to the different scopes. The scope in focus is "alerts.write" so that I can send test alerts using POST requests. But this doesn't work for some reason. To send a test alert I have to send a POST request to this url: "https://streamlabs.com/api/alerts/send_test_alert"
I've tried doing that in two different ways.
1:
import requests
url = "https://streamlabs.com/api/alerts/send_test_alert"
data = {
"access_token":"UserAccessTokenHere",
"type":"donation"
}
response = requests.post(url=url, data=data)
print(response.text)
2:
import requests
url = "https://streamlabs.com/api/alerts/send_test_alert?access_token=UserAccessTokenHere&type=donation"
response = requests.post(url=url)
print(response.text)
If I do print(response) it prints "Response [405]".
But if I do print(response.text) I get a long HTML document for this page: Error response page
Any ideas what's going wrong with my Python requests? send_test_alert documentation here: Link
I've contacted support and looks like you've made the same error as me.
You're not actually sending a request to the right URL.
You are a sending a request to: "https://streamlabs.com/api/alerts/send_test_alert"
You should be using the URL: "https://streamlabs.com/api/v1.0/alerts/send_test_alert"

Python 2 Zoho Post Error?

I am trying to add a lead to a Zoho CRM module with Python. I keep getting:
< response>< error>< code>4600< /code>< message>Unable to process your request. Please verify if the name and value is appropriate for the "xmlData" parameter.< /message>< /error>< /response>
from the server. I have no idea if I am posting correctly or if it is a problem with our Xml Data. I am using urllib and urllib2 to format the post request.
The post request looks like this.
url = ("https://crm.zoho.com/crm/private/xml/Leads/insertRecords?authtoken="
""+str(self.authToken)+"&scope=crmapi")
params = {"xmlData":self.xml}
data = urllib.urlencode(params)
request = urllib2.Request(url = url, data =data)
request.add_header("Content-Type",'application/xml')
response = urllib2.urlopen(request)
You cannot combine HTTP GET query parameters (ones in URL) and HTTP POST parameters.
This is limitation on the HTTP protocol level, not in Python or Zoho.
Most likely you are doing it wrong. Revisit Zoho documentation how it should be done.
Here is another old library doing Zoho + CRM, written in Python. You might want to check it for inspiration: https://github.com/miohtama/mfabrik.zoho

Categories