This question already has answers here:
demystify Flask app.secret_key
(2 answers)
Closed 7 years ago.
I'm developing an app in python that uses YT API. I decided to move it to the web and i'm using Flask. I took the auth example from Google guides. For testing purposes i'm trying to create a playlist after authentication. It looks like this:
#app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.redirect(flask.url_for('oauth2callback'))
credentials = client.OAuth2Credentials.from_json(flask.session['credentials'])
if credentials.access_token_expired:
return flask.redirect(flask.url_for('oauth2callback'))
else:
http_auth = credentials.authorize(httplib2.Http())
yt_service = discovery.build('youtube', 'v3', http_auth)
playlists_insert_response = yt_service.playlists().insert(
part="snippet,status",
body=dict(
snippet=dict(
title="Test Playlist",
description="A private playlist created with the YouTube API v3"
),
status=dict(
privacyStatus="private"
)
)
).execute()
return playlists_insert_response["id"]
#app.route('/oauth2callback')
def oauth2callback():
flow = client.flow_from_clientsecrets('youtube/client_secret.json',scope='https://www.googleapis.com/auth/youtube',redirect_uri=flask.url_for('oauth2callback', _external=True))
if 'code' not in flask.request.args:
auth_uri = flow.step1_get_authorize_url()
return flask.redirect(auth_uri)
else:
auth_code = flask.request.args.get('code')
credentials = flow.step2_exchange(auth_code)
flask.session['credentials'] = credentials.to_json()
return flask.redirect(flask.url_for('index'))
So in browser I authenticate, accept app's permisions and then I see 500 internal error with ouath2callback URI and code parameter. In the error log I see this:
2015-09-07 10:23:08,319 :Successfully retrieved access token
2015-09-07 10:23:08,330 :Exception on /oauth2callback [GET]
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/Kraxi/youtube/playlist.py", line 63, in oauth2callback
flask.session['credentials'] = credentials.to_json()
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 339, in __setitem__
self._get_current_object()[key] = value
File "/usr/local/lib/python2.7/dist-packages/flask/sessions.py", line 57, in _fail
raise RuntimeError('the session is unavailable because no secret '
RuntimeError: the session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
I tihnk it might be something wrong with Flask session - maybe seassion type?
Using Flask 0.10
Any ideas, please?
In order to use sessions you need to set a SECRET_KEY.
Extracted from the docs:
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
Related
I am trying to send e-mails from a GAE application using this code:
from google.appengine.api.mail import send_mail
send_mail(
"sender#nowhere.com",
["user#example.com"],
"Subject",
"Body",
)
I have configured usage of the apis in app.yaml with:
app_engine_apis: true
And deploy to App Engine is done with gcloud beta app deploy.
However, I get this error:
Traceback (most recent call last):
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app response = self.full_dispatch_request()
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request rv = self.handle_user_exception(e)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request rv = self.dispatch_request()
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/srv/infrastructure/view_modifiers.py", line 12, in view_method response_val = f(*args, **kwargs)
File "/srv/views/orders.py", line 25, in create_order vm.create_order()
File "/srv/viewmodels/orders/order_viewmodel.py", line 74, in create_order self._send_order_email()
File "/srv/viewmodels/orders/order_viewmodel.py", line 54, in _send_order_email send_mail(
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/mail.py", line 401, in send_mail message.send(make_sync_call=make_sync_call)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/mail.py", line 1209, in send make_sync_call('mail', self._API_CALL, message, response)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 96, in MakeSyncCall return stubmap.MakeSyncCall(service, call, request, response)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 348, in MakeSyncCall assert stub, 'No api proxy found for service "%s"' % service AssertionError: No api proxy found for service "mail"
This seems to suggest that even for the default behavior of the mail service, some kind of proxy needs to be configured. However, I cannot find any information about the setup of this proxy.
And, my initial understanding was that setting up a proxy is only needed for unit-testing or local development.
Here is an example that works with fastapi. (answer to anton's comment)
from google.appengine.api import mail
from fastapi.middleware.wsgi import WSGIMiddleware
from google.appengine.api import wrap_wsgi_app
from flask import Flask
app = create_app() # this is just app = FastAPI() and somes middleware but but no relevance here
app_flask = Flask(__name__)
app_flask.wsgi_app = wrap_wsgi_app(app_flask.wsgi_app, use_deferred=True)
def send_approved_mail(sender_address):
# [START send_message]
message = mail.EmailMessage(
sender=sender_address,
subject="Your account has been approved")
message.to = "test#gmail.com"
message.body = """Dear Albert:
Your example.com account has been approved. You can now visit
http://www.example.com/ and sign in using your Google Account to
access new features.
Please let us know if you have any questions.
The example.com Team
"""
message.send()
#app_flask.route("/send_email", methods=['GET'])
def send_email():
send_approved_mail("registred_email#domain.com")
return "message sent"
app.mount("/v1", WSGIMiddleware(app_flask))
here app.yaml
runtime: python39
entrypoint: gunicorn -k uvicorn.workers.UvicornWorker app.main:app
instance_class: F1
app_engine_apis: true
inbound_services:
- mail
- mail_bounce
You will not see flask route on swagger.
and for some reason, i could not sent email with app engine's default service account. I had to register my email ( with same domain) here : https://console.cloud.google.com/appengine/settings/emailsenders?project=your_project
I just tested this and it worked for me (i.e. I received the email I supplied for recipient_email_address in the code below). Note that sender must be a value specified under Email Senders in App Engine settings page
requirements.txt file
Flask
appengine-python-standard>=1.0.0
app.yaml file
runtime: python39
app_engine_apis: true
handlers:
- url: /static
static_dir: static/
- url: /.*
script: auto
main.py
from flask import Flask
from google.appengine.api import wrap_wsgi_app
from google.appengine.api.mail import send_mail
app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
#app.route("/")
def sendMail():
send_mail(sender= <authorized_email_sender>,
to= <recipient_email_address>,
subject="Testing Python3 sending mails",
body="""Dear Albert:
Your example.com account has been approved. You can now visit
http://www.example.com/ and sign in using your Google Account to
access new features.
Please let us know if you have any questions.
The example.com Team
""")
return "Mail was sent"
I am trying to test Restful API with Flask and MySQL database with Raspberry Pi. Found a interesting article Tutorial My Full Code is below,
from flask import Flask, request, jsonify, make_response
from flask_sqlalchemy import SQLAlchemy
from marshmallow import fields
from marshmallow_sqlalchemy import SQLAlchemySchema
import json
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root#localhost:3306/todo'
db = SQLAlchemy(app)
# Model
class Todo(db.Model):
__tablename__ = "todos"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(20))
todo_description = db.Column(db.String(100))
def create(self):
db.session.add(self)
db.session.commit()
return self
def __init__(self, title, todo_description):
self.title = title
self.todo_description = todo_description
def __repr__(self):
return f"{self.id}"
db.create_all()
class TodoSchema(SQLAlchemySchema):
class Meta(SQLAlchemySchema.Meta):
model = Todo
sqla_session = db.session
id = fields.Number(dump_only=True)
title = fields.String(required=True)
todo_description = fields.String(required=True)
#app.route('/api/v1/todo', methods=['POST'])
def create_todo():
data = request.get_json()
print(data)
todo_schema = TodoSchema()
todo = todo_schema.load(data)
result = todo_schema.dump(todo.create())
return make_response(jsonify({"todo": result}), 200)
# return 'This works',200
#app.route('/api/v1/todo', methods=['GET'])
def index():
get_todos = Todo.query.all()
todo_schema = TodoSchema(many=True)
todos = todo_schema.dump(get_todos)
return make_response(jsonify({"todos": todos}))
#app.route('/api/v1/todo/<id>', methods=['GET'])
def get_todo_by_id(id):
get_todo = Todo.query.get(id)
todo_schema = TodoSchema()
todo = todo_schema.dump(get_todo)
return make_response(jsonify({"todo": todo}))
But when I send Rest POST request through Postman I am getting following error,
Error:
(venv) root#raspberrypi:~/password_db_test1# flask run -h 0.0.0.0
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
/root/password_db_test1/venv/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py:873: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://192.168.8.182:5000/ (Press CTRL+C to quit)
{'title': 'test title', 'todo_description': 'test'}
[2021-09-19 07:58:10,883] ERROR in app: Exception on /api/v1/todo [POST]
Traceback (most recent call last):
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/root/password_db_test1/app.py", line 48, in create_todo
result = todo_schema.dump(todo.create())
AttributeError: 'dict' object has no attribute 'create'
192.168.8.228 - - [19/Sep/2021 07:58:10] "POST /api/v1/todo HTTP/1.1" 500 -
I have done playing with the code and change the below
From:
result = todo_schema.dump(todo.create())
To:
result = todo_schema.dump(todo.create())
Since method is Todo
After that I am getting,
Error:
{'title': 'test title', 'todo_description': 'test'}
[2021-09-19 08:02:29,147] ERROR in app: Exception on /api/v1/todo [POST]
Traceback (most recent call last):
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "/root/password_db_test1/venv/lib/python3.7/site-packages/flask/app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/root/password_db_test1/app.py", line 48, in create_todo
result = todo_schema.dump(Todo.create())
TypeError: create() missing 1 required positional argument: 'self'
192.168.8.228 - - [19/Sep/2021 08:02:29] "POST /api/v1/todo HTTP/1.1" 500 -
I changed some codes due to testing and changes in marshmallow_sqlalchemy import ModelSchema to SQLAlchemySchema as per the ModelSchema_Change
My Sample JSON POST Request from Postman is below
{
"title": "test title",
"todo_description": "test"
}
Please help me to sort this issue, I am doing a project to encrypted user date in mariaDB for a project using Raspberry Pi which will be this be a sample.
I am trying to use YouTube data API for searching videos in Python. I have read full tutorial and I am able to authorize and authenticate the user from the local machine, But when I deployed the same code in the server I am getting bellow listed errors in logs. and browser displays 'Internal server error'
[ N 2019-02-01 04:12:09.9860 4335/Tq age/Cor/CoreMain.cpp:1117 ]: Checking whether to disconnect long-running connections for process 20744, application /home/pricemon/YT_VDO_search_1 (production)
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 262, in parse_authorization_code_response
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/clients/web_application.py", line 203, in parse_request_uri_response
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/requests_oauthlib/oauth2_session.py", line 208, in fetch_token
App 20744 output: File "/home/pricemon/YT_VDO_search_1/one.py", line 88, in oauth2callback
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
I am trying the coed from This guide from Google
I have replaced the redirected URL path in the Google API console.
Bellow is my code.
def oauth2callback():
# Specify the state when creating the flow in the callback so that it can
# verified in the authorization server response.
state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
# Use the authorization server's response to fetch the OAuth 2.0 tokens.
authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)
# Store credentials in the session.
# ACTION ITEM: In a production app, you likely want to save these
# credentials in a persistent database instead.
credentials = flow.credentials
flask.session['credentials'] = credentials_to_dict(credentials)
return flask.redirect(flask.url_for('test_api_request'))
I am getting error when I fetch token using command flow.fetch_token
I am trying to access MeisterTask's API with Python and Flask, and no matter what I do, I seem to always get a 302 code in return from the API, although I can get an access token (or so I think). Here is the code I have so far (I tried reducing it, this is the smallest snippet I could get that replicates the error):
from flask import Flask, redirect, url_for, session, request, jsonify
from flask_oauthlib.client import OAuth
app = Flask(__name__)
app.debug = True
app.secret_key = "development"
oauth = OAuth(app)
meistertask = oauth.remote_app(
'meistertask',
consumer_key= "XXXXXX",
consumer_secret= "XXXXXX",
request_token_params={"scope" : "meistertask"},
base_url='https://www.meistertask.com/api',
request_token_url=None,
access_token_method='GET',
access_token_url='https://www.mindmeister.com/login/oauth2/token',
authorize_url='https://www.mindmeister.com/oauth2/authorize'
)
#app.route('/')
def index():
if 'meistertask_token' in session:
me = meistertask.get('user')
return jsonify(me.data)
return redirect(url_for('login'))
#app.route('/login')
def login():
return meistertask.authorize(callback=url_for('authorized', _external=True))
#app.route('/logout')
def logout():
session.pop('meistertask_token', None)
return redirect(url_for('index'))
#app.route('/login/authorized')
def authorized():
resp = meistertask.authorized_response()
print(resp.get('code'))
if resp is None or resp.get('code') is None:
return 'Access denied: reason=%s error=%s resp=%s' % (
request.args['error'],
request.args['error_description'],
resp
)
session['meistertask_token'] = (resp['code'], '')
return "Hello"
#meistertask.tokengetter
def get_meistertask_oauth_token():
return session.get('meistertask_token')
if __name__ == "__main__":
app.run()
And here is the traceback:
flask_oauthlib.client.OAuthException: Invalid response from meistertask
Traceback (most recent call last):
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2309, in __call__ return self.wsgi_app(environ, start_response)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2295, in wsgi_app response = self.handle_exception(e)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 35, in reraise raise value
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2292, in wsgi_app response = self.full_dispatch_request()
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 35, in reraise raise value
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request rv = self.dispatch_request()
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1799, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args)
File "~\Documents\MeisterTaskServer\hello.py", line 49, in authorized resp = meistertask.authorized_response()
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_oauthlib\client.py", line 707, in authorized_response data = self.handle_oauth2_response(args)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_oauthlib\client.py", line 692, in handle_oauth2_response
Things I have tried
Tried to modify the method to get the access token from GET to POST. The API clearly states that I should use GET, yet every other example I have seen on flask_oauthlib's GitHub uses POST (the examples are 3 years old, but some still work, namely the GitHub one). Either give the same result.
Tried doing it barebones, without any library. The resulting code was thrice as long and also had more problems.
Used Django instead of Flask. Never even managed to get the hello world example going, it was too much work, and also I have discovered the library flask_oauthlib.
Things worth mentioning
I derived this code from this here GitHub example
There is also code there I omitted in order to keep the snippet short, that establishes that the server should use SSL (as per the request from the API that the redirect_uri should use HTTPS)
The app manages to redirect me over at MeisterTask and asks for my permission. Once I grant it, it redirects to "https://127.0.0.1:5000/login/authorized?code=some_token" where I get the traceback. If I look with Chrome's debugging tools to the requests made and what I receive, I see that I get an 302 from the API, but I also get an access token.
I run Windows 10 with Python 3.7.0
So what's the deal? What's the next step here? I've run out of things to try. Thank you for taking the time to solve this!
This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Closed 6 years ago.
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
}
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)