'NoneType' object is not subscriptable
You need to explicitly set the content-type
to application/json
for request.json
to work properly in flask. If the header isn't set, request.json
would return None.
But the recommended to get json data in flask from a post request is to use request.get_json()
I'll also urge you to test your api with the nifty requests module before using your ios
application.
>>> import requests
>>> requests.post(url, json={'name': 'hello world'})
It already sets the appropriate headers required to make a json
request
If it works with the requests
module, then you can be sure that it's going to work with your ios application. you just need to make sure you're setting the correct content-type
.
You can forcefully tell flask to ignore the content-type
header with
request.get_json(force=True)
Lucas Padden
Updated on July 05, 2022Comments
-
Lucas Padden almost 2 years
I am creating an ios app that uses a server written in flask + python, and when I make a connection to the server to register a user I keep getting a 'NoneType' object is not subscriptable error in my server.py file. Basically my question is what is causing this error and how am I able to fix this. Also if anyone can point me in the right direction of different or easier ways to do this I would appreciate it thanks!
Here is the server.py file:
import bcrypt from flask import Flask, request, make_response,jsonify from flask_restful import Resource, Api from pymongo import MongoClient from json import JSONEncoder from bson.objectid import ObjectId from functools import wraps app = Flask(__name__) mongo = MongoClient('localhost', 27017) app.db = mongo.eventure_db app.bcrypt_rounds = 12 api = Api(app) # Authentication code. def check_auth(username, password): # check_auth should access the database and check if the username + password are correct. # create a collection to hold the users. user_collection = app.db.users user = user_collection.find_one({'username': username}) if user is None: return False else: # check if hash generated matches stored hash encodedPassword = password.encode('utf-8') if bcrypt.hashpw(encodedPassword, user['password']) == user['password']: return True else: return False # User resource class User(Resource): def post(self): if (request.json['username'] == None or request.json['password'] == None): return ({'error': 'Request requires username and password'}, 400, None) user_collection = app.db.users user = user_collection.find_one({'username': request.json['username']}) if user is not None: return ({'error': 'Username already in use'}, 400, None) else: encodedPassword = request.json['password'].encode('utf-8') hashed = bcrypt.hashpw( encodedPassword, bcrypt.gensalt(app.bcrypt_rounds)) request.json['password'] = hashed user_collection.insert_one(request.json) @requires_auth def get(self): return (None, 200, None) api.add_resource(User, '/eventure/api/v1.1/user/') # Must define a custom JSON Serializer for flask_restful # this is because ObjectId is not a string, and therefore, # Flask's default serializer cannot serialize it. @api.representation('application/json') def output_json(data, code, headers=None): resp = make_response(JSONEncoder().encode(data), code) resp.headers.extend(headers or {}) return resp if __name__ == '__main__': app.config['TRAP_BAD_REQUEST_ERRORS'] = True app.run(host='localhost', port=8789, debug=True)
And this is my register function in swift:
@IBAction func register(_ sender: AnyObject) { let url = URL(string: "http://localhost:8789/eventure/api/v1.1/user/") var request = URLRequest(url: url!) request.httpMethod = "POST" request.setValue(generateBasicAuthHeader(username: username.text!, password: password.text!), forHTTPHeaderField: "Authorization") let session = URLSession.shared let task = session.dataTask(with: request) { data, response, error in if let response = response, let data = data { print(String(data: data, encoding: String.Encoding.utf8)) } } task.resume() self.username.text = "" self.password.text = "" }
traceback:
[28/Oct/2016 19:22:33] "POST /eventure/api/v1.1/user/ HTTP/1.1" 500 - Traceback (most recent call last): File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__ return self.wsgi_app(environ, start_response) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app response = self.make_response(self.handle_exception(e)) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 270, in error_router return original_handler(e) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception reraise(exc_type, exc_value, tb) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/_compat.py", line 32, in reraise raise value.with_traceback(tb) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 270, in error_router return original_handler(e) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/_compat.py", line 32, in reraise raise value.with_traceback(tb) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 471, in wrapper resp = resource(*args, **kwargs) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/views.py", line 84, in view return self.dispatch_request(*args, **kwargs) File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 581, in dispatch_request resp = meth(*args, **kwargs) File "/Users/Dynee/eventure-backend-api/server.py", line 128, in post if (request.json['username'] == None TypeError: 'NoneType' object is not subscriptable
Also here is the generateBasicAuthHeader function:
func generateBasicAuthHeader(username: String, password: String) -> String { let loginString = String(format: "%@:%@", username, password) let loginData = loginString.data(using: String.Encoding.utf8)! let base64LoginString = loginData.base64EncodedString() let basicAuthHeader = "Basic \(base64LoginString)" return basicAuthHeader }