2016-10-28 60 views
0

我正在創建一個ios應用程序,該應用程序使用在flask + python中編寫的服務器,並且當我連接到服務器以註冊用戶時,我總是收到一個'NoneType'對象不是可下載的錯誤在我的server.py文件中。基本上我的問題是什麼導致這個錯誤,我怎麼能夠解決這個問題。此外,如果任何人都可以指出我正確的方向不同或更簡單的方法來做到這一點,我將不勝感激謝謝!'NoneType'對象不可訂閱

這裏是server.py文件:

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) 

而且這是我迅速寄存器功能:

@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 = "" 



} 

回溯:

[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 

而且這裏是generateBasicAuthHeader功能:

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 
} 
+0

顯示完整回溯忽略content-type頭。錯誤發生在哪裏?無論如何,它意味着你做了像'x [y]'和'x'這樣的'None'。 –

+0

所以我猜在我的情況下request.json ['用戶名']將無法正常工作,因爲request.json沒有任何價值? – Dynee

+0

print'request.json',你看到它是'None' – furas

回答

4

您需要明確地將content-type設置爲application/json,以使request.json在燒瓶中正常工作。如果標題未設置,request.json將返回無。

但建議得到從POST請求燒瓶JSON數據是使用ios應用程序之前使用request.get_json()

我還會勸你與漂亮requests模塊測試您的API。

>>> import requests 
>>> requests.post(url, json={'name': 'hello world'}) 

它已經設置做出json要求

如果與requests模塊工作所需要的相應的頭,那麼你可以肯定的是它將會與您的iOS應用程序的工作。你只需要確保你設置了正確的content-type

可以有力地告訴燒瓶

request.get_json(force=True)

+0

哦,那是我的錯誤......我其實是指'json' – danidee