2016-10-28 13 views
0

フラスコ+ pythonで書かれたサーバーを使用するiosアプリケーションを作成しています。ユーザーを登録するためにサーバーに接続すると、 '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 ['username']は動作しません。 – Dynee

+0

'request.json'と' None.'と表示されます。 – furas

答えて

4

request.jsonがフラスコ内で正しく機能するためには、content-typeapplication/jsonに明示的に設定する必要があります。ヘッダーが設定されていない場合、request.jsonはNoneを返します。

しかし、ポスト要求からフラスコ内でJSONデータを取得することをお勧めしますが、私はまた、あなたのiosアプリケーションを使用する前に、気の利いたrequestsモジュールを使用して、APIをテストするためにあなたを促すだろうrequest.get_json()

を使用することです。

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

それはすでにそれがrequestsモジュールで動作する場合、あなたはあなたのiOSアプリケーションで動作するように起こっていることを確認することができますjson要求

を作るために必要な適切なヘッダを設定します。あなたはちょうどあなたが正しいcontent-typeを設定していることを確認する必要があります。あなたが強制的に

request.get_json(force=True)

+0

ああ、それは私の部分で間違いだった...私は実際には 'json'を意味した – danidee

関連する問題