Python 3 Flask Rest Api: "request.get_json()" gives TypeError: 'NoneType' object is not subscriptable - flask-sqlalchemy

I am creating a route in python flask which will server as rest api to register a user.
when I try to get json data passed through postman in POST method, I get error TypeError: 'NoneType' object is not subscriptable
my request from postman:
http://127.0.0.1:5000/register
raw input: {"username":"alok","password":"1234"}
my route and function:
#app.route('/register', methods=['GET', 'POST'])
def signup_user():
data = request.get_json()
return data['username']
As per my knowledge above function should return : "alok"
but i get error: TypeError: 'NoneType' object is not subscriptable
Any help will be appreciated

I spending few hours over internet I got answer from flask official website
I had not set mimetype while making request.
If the mimetype does not indicate JSON (application/json, see is_json()), this returns None.
request.get_json() is used to Parse data as JSON.
actual syntax is get_json(force=False, silent=False, cache=True)
Parameters
force – Ignore the mimetype and always try to parse JSON.
silent – Silence parsing errors and return None instead.
cache – Store the parsed JSON to return for subsequent calls.
So finally I have changed my code to
#app.route('/register', methods=['GET', 'POST'])
def signup_user():
data = request.get_json(force=True)
return data['username']
It is resolved.

Add Content-Type : application/json to the header of your Post API request .

Related

How to solve HTTPError: 400 Client Error: Bad Request for URL inRobot Frame work

I know there are many similar kinds of questions available but none of them worked.
Can someone tell me if there is any kind of syntax error for the Testcase below
Create Token
Create Session testsession ${baseUrl} verify=true
${body}= create dictionary clientId=unittest.cc.client clientSecret=RyDQ$xxxxxRtv
${header}= create dictionary Content-Type=application/json
${resp}= POST On Session testsession ${reqUri} json=${body} headers=${header} params=${ApiKeyParameter}
${source data}= Evaluate json.loads("""${resp.content}""") json
${token}= Set Variable ${source data['accessToken']}
#No errors Uptill this much - Bearer token creation was successful after that getting error while using it
${header}= create dictionary Authorization=${tpre} ${token} Content-Type=application/json cookies=ss-id=KF84fFy4txxxxxxxxx76i; ss-pid=StDTDxxxxxxxxxxxxn7r
${body}= get file API/data.txt
log to console ${header}
${resp}= post on session testsession /orders json=${body} headers=${header}
log to console ${resp.status_code}
The problem is every time I run the test I am getting a 400 error. Below is the Python code provided by POSTMAN and the screenshots of the headers used. Now I am not sure of how to get the HOST header in my python or maybe robot framework.
Please let me know if any additional details are needed. I am not sure of headers in the URL formation while get or post request is done
Is there any way to find that out?
import requests
import JSON
url = "https://domain:10001/orders?format=json"
payload = json.dumps({ Can ignore this part
})
headers = {
'Authorization': 'Bearer xxx',
'Content-Type': 'application/json',
'Cookie': 'ss-id=xxx; ss-pid=xxx'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
If you all ever come across this kind of issue don't forget to check the body of the JSON / XML you are sending.
Mine resolved as I was saving the dump JSON in a text file so while reading from the file my code was adding some extra spaces in front so I was getting a 400 error.
For further information try logging the Response Content it must show you the error message.

Invalid request body error when sending json string as data to an external api using CL_HTTP_CLIENT

We are facing an issue while sending json data to an external api using CL_HTTP_CLIENT.
The JSON data is produced using '/ui2/cl_json=>serialize( data = ls_body compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case )' .
when sending this JSON as data the the external api returns status 400 with response as
{ "errorCode": "INVALID_REQUEST_BODY", "message": "The request body is missing or improperly formatted. Unexpected character encountered while parsing value: \u001f. Path '', line 0, position 0." } .
we also stringyfied this JSON Data in backend as it might be due to parsing error but it didnt work.
The same stringyfied data tried to send through browser console using ajax and it did worked without any issue.
could any any one tell us how to handle this json object and send this to external api using CL_HTTP_CLIENT.
Note : JSON STRING is deeply nested .
Thanks in advance..
You can use request catcher service for getting SAP output.
Then check your output has valid json.
Check external api with rest tool like postman or SoapUI. Every developer not track guidliness may be external api has limitations.
The issue was with the unicodes in the string.
these were not accepted by the external api so removed from the string and sent to api and it did worked.
Thanks for You suggestion.

POST item JSON to API using Scrapy

I am trying to HTTP POST an item to an API using Scrapy. In my pipeline I have:
Request( url, method='POST',
body=json.dumps(item),
headers={'Content-Type':'application/json'} )
This does not work. The error is:
{ some JSON } is not JSON serializable
Any idea on what I am doing wrong?
As stated in paul trmbrth's comment, instead of
body=json.dumps(item)
use
body=json.dumps(dict(item))
So your code would become:
Request( url, method='POST',
body=json.dumps(dict(item)),
headers={'Content-Type':'application/json'} )
I have used JsonRequest from from scrapy.http as follows:
JsonRequest(
url=<url>,
method='POST',
# Replace with your item or dict(item)
data=item
)
Behind it calls json.dumps on the dictionary you pass to the data parameter so you first might want to make sure that your item that you're trying to send is json serializable.

Porting Cryptsy authenticatedAPI to Python 3

I am trying to port a class I use to connect to Cryptsy's authenticated API to Python 3.3. I have managed to solve the data type issues, and am getting something that is at least getting a request from the website, but it is rejecting my authentication, this is the code, API keys are not included, for obvious reasons...:
req['method'] = method
req['nonce'] = int(time.time())
post_data = urllib.parse.urlencode(req)
sign = hmac.new(self.Secret, str.encode(post_data), hashlib.sha512).hexdigest()
headers = {
'Sign': sign,
'Key': self.APIKey
}
print('headers: ',headers)
print('post data: ',post_data)
b=urllib.parse.urlencode(headers)
print(b)
test=post_data + '&'+ b
print('test: ',test)
data=test.encode()
print('data: ',data)
ret = urllib.request.urlopen(urllib.request.Request('https://www.cryptsy.com/api', data))
q=ret.read()
w=q.decode()
e=json.loads(w)
return self.post_process(e)
And this is the response from the server:
{'error': 'Unable to Authorize Request - Check Your Post Data', 'success': '0'}
Thanks.
The original script had the DATA and HEADERS components for the Request, but was somehow formatted in a way that confused Python 3 into thinking the HEADERS part was a TIMEOUT argument, and throwing an error about it needing to be an INT. This sent me on a wild goose chase of trying to concatenate the DATA and HEADERS.

Calling a webservice using google closures jsonp and sending json as parameter

I want to call a webservice using google closures, via jsonp since i am performing a cross domain webservice.
And i am calling it in the following manner
var url = "http://myurl/";
var jsonp = new goog.net.Jsonp(url);
jsonp.send(
{"name":"jessi","action":"initaction","gameId":"123"},
callback, callbackfailed);
But in this method the url is converted as a normal get method string as the follows
http://myurl/?name=jessi&action=initaction&gameId=123
But i need to send this url as a json object in the following manner
"name":"pari123","action":"initaction","gameId":"slotreel3"
How can i do this, i searched google and i couldnt find proper documentation regarding ?this.
The function goog.net.Jsonp.addPayloadToUri_ that is used to encode the object says:
#param {!Object} payload A map of value name pairs to be encoded.
A value may be specified as an array, in which case a query parameter
will be created for each value, e.g.:
{"foo": [1,2]} will encode to "foo=1&foo=2".
This is exactly what is happening. So, why not initialize your url with the query? e.g.
var url = "http://myurl.php?" + goog.json.serialize({"name":"jessi","action":"initaction","gameId":"123"});
var jsonp = new goog.net.Jsonp(url);
jsonp.send()
Untested but maybe this works.
Regards,
Rene