I am trying to make a website that allows a user to create their own "to-watch" list and also can randomly select a title from the created list, showing the movie's plot, genre, and IMDb rating using an API. I've encountered a "NoneType' object is not subscriptable" error message when trying to run this function and am not sure how to overcome it. Here are the relevant parts of my code:
application.py
import os
from cs50 import SQL
from flask import Flask, flash, jsonify, redirect, render_template, request, session
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
from werkzeug.security import check_password_hash, generate_password_hash
from helpers import apology, login_required, imdb
app = Flask(__name__)
app.config["TEMPLATES_AUTO_RELOAD"] = True
#app.after_request
def after_request(response):
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Expires"] = 0
response.headers["Pragma"] = "no-cache"
return response
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
db = SQL("sqlite:///project.db")
#app.route("/select", methods=["GET", "POST"])
#login_required
def select():
if request.method == "POST":
"""Randomly pick a movie to watch"""
therearemovies = db.execute("SELECT uniqueid FROM movies WHERE id=:id", id=session["user_id"])
if therearemovies:
chosen = db.execute("SELECT * FROM movies WHERE id=:id ORDER BY RANDOM() LIMIT 1", id=session["user_id"])
for uniqueindex in chosen:
suggestion = uniqueindex["title"]
**info = imdb(suggestion)
plot = info["plot"]
genre = info["genre"]
rating = info["rating"]**
return render_template("select.html", suggestion=suggestion, plot=plot, genre=genre, rating=rating)
else:
return apology("You don't have any movies in your list")
else:
return render_template("/")
helper.py:
import os
import requests
import urllib.parse
def imdb(title):
try:
response=requests.get(f"http://www.omdbapi.com/?t={urllib.parse.quote_plus(title)}&apikey=12345678")
response.raise_for_status()
except requests.RequestException:
return None
try:
data = response.json()
return
{
"plot": data["plot"],
"genre": data["genre"],
"rating": data["imdbRating"]
}
except (KeyError, TypeError, ValueError):
return None
Error Message:
File "/home/ubuntu/finalproject/helpers.py", line 32, in decorated_function
return f(*args, **kwargs)
File "/home/ubuntu/finalproject/application.py", line 126, in select
plot = info["plot"]
TypeError: 'NoneType' object is not subscriptable
Related
I am testing/attempting to learn flask, and flast_restful. This issue I get is:
code 400, message Bad request syntax ('name=testitem')
main.py:
from flask import Flask,request
from flask_restful import Api, Resource, reqparse
app = Flask(__name__)
api = Api(app)
product_put_args = reqparse.RequestParser()
product_put_args.add_argument("name", type = str, help = "Name of the product")
product_put_args.add_argument("quantity", type = int, help = "Quantity of the item")
products = {}
class Product(Resource):
def get(self, barcode):
return products[barcode]
def put(self, barcode):
args = product_put_args.parse_args()
return {barcode: args}
api.add_resource(Product, "/product/<int:barcode>")
if(__name__) == "__main__":
app.run(debug = True)
and my
test.py
import requests
base = "http://127.0.0.1:5000/"
response = requests.put(base + "product/1", {"name": "testitem"})
print(response.json())
I have attempted to reform mat and change around both files to figure out what is sending the issue, I feel like it is something simple, but if you can help me, I bet this will help me and many others that are trying to start creating a rest API.
You need to add the location information to the RequestParser by default it tries to parse values from flask.Request.values, and flask.Request.json, but in your case, the values need to be parsed from a flask.request.form. Below code fixes your error
from flask import Flask,request
from flask_restful import Api, Resource, reqparse
app = Flask(__name__)
api = Api(app)
product_put_args = reqparse.RequestParser()
product_put_args.add_argument("name", type = str, help = "Name of the product", location='form')
product_put_args.add_argument("quantity", type = int, help = "Quantity of the item", location='form')
products = {}
class Product(Resource):
def get(self, barcode):
return products[barcode]
def put(self, barcode):
args = product_put_args.parse_args()
products[barcode] = args['name']
return {barcode: args}
api.add_resource(Product, "/product/<int:barcode>")
if(__name__) == "__main__":
app.run(debug = True)
I am doing an app and I am using the Blueprints structure. My code is running okay, but I got this error while trying to implment flask-caching into one function.
The error returned is:
AttributeError: 'Blueprint' object has no attribute 'cache'
Does anybody has a light of solution in here to make the cache happens to this function?
Here is a piece of my code:
from flask import render_template, redirect, request, Blueprint
from cache import store_weather, number_of_views, cached_weather, cache
import json, requests
bp = Blueprint('bp', __name__, url_prefix="/weather")
main = Blueprint('main', __name__)
api_key = "42fbb2fcc79717f7601238775a679328"
#main.route('/')
def hello():
views = 5
max_views = number_of_views()
return render_template('index.html', cached_weather=cached_weather, max_views=max_views, views=views)
#bp.route('/', methods=['GET'])
def weather():
clean_list_cache()
if request.args.get('max').isdigit():
views = int(request.args.get('max'))
else:
views = 5
try:
city_name = request.args.get('city')
if city_name not in cached_weather:
uri = 'http://api.openweathermap.org/data/2.5/weather?q={city}&appid={key}'.format(city=city_name,key=api_key)
# On that point, we bring the data from the Open Weather API
rUrl = requests.get(uri)
# The temperature of the Open Weather API is in Kelvin, so, we have to subtract 273.15 to transform
# it into Celsius degrees
temperature = str(round((json.loads(rUrl.content)['main'])['temp']-273.15))+" °C"
name = json.loads(rUrl.content)['name']
description = json.loads(rUrl.content)['weather'][0]['description']
city_data = { "temp":temperature, "name":name, "desc":description }
store_weather(city_data)
max_views = number_of_views(views)
return render_template('weather.html', cached_weather = cached_weather, error_rec_city = False, max_views=max_views, views=views)
except KeyError:
max_views = number_of_views(views)
return render_template('weather.html', cached_weather=cached_weather, error_rec_city = True, max_views=max_views, views=views)
#bp.cache.cached(timeout=30, key_prefix='list_cache')
def clean_list_cache():
cached_weather.clear()
The error occurs, as you are trying to call cache on your blueprint: #bp.cache.cached. An example from the docs how to use cache is:
#app.route("/")
#cache.cached(timeout=50)
def index():
return render_template('index.html')
So you have to squeeze the cache decorator between your app decorator and the function
I am new to python and flask, trying to import a function from route_user.py file which is present in folder named Users_service into a route_jd.py file which is present in folder named JD_service and both the folder Users_service and JD_service is present inside a folder named blue.
route_users.py file
from flask import jsonify,request,Blueprint,make_response
from flask_pymongo import PyMongo
from blue import app
from werkzeug.security import generate_password_hash,check_password_hash
import uuid
import jwt
import datetime
from functools import wraps
app.config['SECRET_KEY'] = 'itshouldbehidden'
app.config['MONGO_URI'] = "mongodb://localhost:27017/mydata"
mongo = PyMongo(app)
mod = Blueprint('Users_Service',__name__)
def token_required(f):
#wraps(f)
def decorated(*args,**kwargs):
token = None
if 'x-access-token' in request.headers:
token = request.headers['x-access-token']
if not token:
return jsonify({'message':'token is missing!'}),401
try:
data = jwt.decode(token, app.config['SECRET_KEY'])
print(data)
jd = mongo.db.hashed_User
current_user = jd.find_one({'public_id':data['public_id']})
print(current_user)
except:
return jsonify({'message':'Token is invalid'}),401
return f(current_user,*args,**kwargs)
return decorated
#mod.route('/add',methods=['POST'])
#token_required
def create_user(current_user):
if not current_user['admin']:
return jsonify({'message':'cannot perform that function'})
jd = mongo.db.hashed_User
data = request.get_json()
try:
hashed_password = generate_password_hash(data['password'],method='sha256')
jd.insert({"public_id":str(uuid.uuid4()),"name":data['name'],"password":hashed_password,"admin":False})
output = 'new user created!'
except:
output = 'please fill all the fields and try again'
return jsonify({'message':output})
#mod.route('/all',methods=['GET'])
#token_required
def get_all_users(current_user):
if not current_user['admin']:
return jsonify({'message':'cannot perform that function'})
jd = mongo.db.hashed_User
output = []
for q in jd.find():
output1={'User Name': q['name'],'Password':q['password'],'Public ID':q['public_id'],'Admin':q['admin']}
output.append(output1)
return jsonify({'Users':output})
#mod.route('/<public_id>',methods=['GET'])
#token_required
def get_one_user(current_user,public_id):
if not current_user['admin']:
return jsonify({'message':'cannot perform that function'})
jd = mongo.db.hashed_User
user = jd.find_one({'public_id':public_id})
if not user:
return jsonify({'message':'No such User exists'})
user_data={'User Name': user['name'],'Password':user['password'],'Public ID':user['public_id'],'Admin':user['admin']}
return jsonify({'Users':user_data})
#mod.route('/admin_promote/<public_id>',methods=['PUT'])
#token_required
def Promote_to_admin(current_user,public_id):
if not current_user['admin']:
return jsonify({'message':'cannot perform that function'})
jd = mongo.db.hashed_User
user = jd.find_one({'public_id':public_id})
if not user:
return jsonify({'message':'No such User exists'})
whereto = { "public_id":public_id}
newvalues={"$set":{'admin':True}}
jd.update_one(whereto,newvalues)
return jsonify({'message':'promoted to admin successfully'})
#mod.route('/delete/<public_id>',methods=['DELETE'])
#token_required
def delete_user(current_user,public_id):
if not current_user['admin']:
return jsonify({'message':'cannot perform that function'})
jd = mongo.db.hashed_User
user = jd.find_one({'public_id':public_id})
if not user:
return jsonify({'message':'No such User exists'})
jd = mongo.db.hashed_User
jd.delete_one({'public_id':public_id})
return jsonify({'message':'Deleted successfully'})
#mod.route('/auth/login',methods=['GET'])
def login():
auth=request.authorization
print(auth)
if not auth or not auth.username or not auth.password:
return make_response('Could not very',401,{'WWW-Authenticate':'Basic realm="Login required!"'})
jd = mongo.db.hashed_User
user = jd.find_one({'name':auth.username})
if not user:
return make_response('Could not very',401,{'WWW-Authenticate':'Basic realm="Login required!"'})
if check_password_hash(user['password'],auth.password):
token = jwt.encode({'public_id' : user['public_id'],'exp':datetime.datetime.utcnow() + datetime.timedelta(minutes=30)},app.config['SECRET_KEY'])
return jsonify({'token' : token.decode('UTF-8')})
return make_response('Could not very',401,{'WWW-Authenticate':'Basic realm="Login required!"'})
route_jd.py file
from flask import jsonify,request,Blueprint
from flask_pymongo import PyMongo
from blue import app
from blue.Users_Service import token_required # getting an error here
app.config['MONGO_URI'] = "mongodb://localhost:27017/mydata"
mongo = PyMongo(app)
mod = Blueprint('JD_Service',__name__)
#mod.route('/',methods=['GET'])
#token_required
def get_all_jds():
if not current_user['admin']:
return jsonify({'message':'cannot perform that function'})
jd = mongo.db.User11
output = []
.
.
.
.some more codes below
the error i m getting is
Traceback (most recent call last):
File "run.py", line 1, in <module>
from blue import app
File "D:\flask_resource\blue\__init__.py", line 5, in <module>
from blue.JD_Service.route_jd import mod
File "D:\flask_resource\blue\JD_Service\route_jd.py", line 4, in <module>
from blue.Users_Service import token_required
ImportError: cannot import name 'token_required'
as i m new to python and flask please help me out how to get rid of this error ?and what m i doing wrong?
Thanks in advance!
You forgot to put file name while importing in route_jd.py file:
from blue.Users_Service.route_users import token_required
Two ways:
Define Users_Service as a module, that is create a file __init__.py in folder Users_Service
Within __init__.py create import import * from blue.Users_Service.route_users
In route_jd.py: from blue.Users_Service import token_required
That is you are trying to import from module blue.Users_Service which in your case is not a module, but just a folder
Other way is to import directly:
from blue.Users_Service.route_users import token_required
I'm trying to test the example of ToDo in Flask-Restplus site, but it keeps on getting me 404...
Basically I have 3 files:
app.py
import sys
import os
import platform
import datetime
import logging
from logging import Formatter
from logging.handlers import RotatingFileHandler
from jinja2 import Environment, PackageLoader
from flask import Flask, url_for, render_template, abort, request, Blueprint
from flask.ext.restplus import Api, Resource, fields
from werkzeug.contrib.fixers import ProxyFix
api_v1 = Blueprint('api', __name__, url_prefix='/api/1')
ns = api.namespace('todos', description='TODO operations')
TODOS = {
'todo1': {'task': 'build an API'},
'todo2': {'task': '?????'},
'todo3': {'task': 'profit!'},
}
todo = api.model('Todo', {
'task': fields.String(required=True, description='The task details')
})
listed_todo = api.model('ListedTodo', {
'id': fields.String(required=True, description='The todo ID'),
'todo': fields.Nested(todo, description='The Todo')
})
def abort_if_todo_doesnt_exist(todo_id):
if todo_id not in TODOS:
api.abort(404, "Todo {} doesn't exist".format(todo_id))
parser = api.parser()
parser.add_argument('task', type=str, required=True, help='The task details', location='form')
#ns.route('/<string:todo_id>')
#api.doc(responses={404: 'Todo not found'}, params={'todo_id': 'The Todo ID'})
class Todo(Resource):
'''Show a single todo item and lets you delete them'''
#api.doc(description='todo_id should be in {0}'.format(', '.join(TODOS.keys())))
#api.marshal_with(todo)
def get(self, todo_id):
'''Fetch a given resource'''
abort_if_todo_doesnt_exist(todo_id)
return TODOS[todo_id]
#api.doc(responses={204: 'Todo deleted'})
def delete(self, todo_id):
'''Delete a given resource'''
abort_if_todo_doesnt_exist(todo_id)
del TODOS[todo_id]
return '', 204
#api.doc(parser=parser)
#api.marshal_with(todo)
def put(self, todo_id):
'''Update a given resource'''
args = parser.parse_args()
task = {'task': args['task']}
TODOS[todo_id] = task
return task
#ns.route('/')
class TodoList(Resource):
'''Shows a list of all todos, and lets you POST to add new tasks'''
#api.marshal_list_with(listed_todo)
def get(self):
'''List all todos'''
return [{'id': id, 'todo': todo} for id, todo in TODOS.items()]
#api.doc(parser=parser)
#api.marshal_with(todo, code=201)
def post(self):
'''Create a todo'''
args = parser.parse_args()
todo_id = 'todo%d' % (len(TODOS) + 1)
TODOS[todo_id] = {'task': args['task']}
return TODOS[todo_id], 201
app = Flask(__name__)
app.secret_key = "secretkey"
app.config.from_pyfile('settings.py')
if os.path.exists(os.path.join(app.root_path, 'local_settings.py')):
app.config.from_pyfile('local_settings.py')
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://%s#%s/%s' % (
app.config['DB_USER'], app.config['DB_HOST'], app.config['DB_NAME'])
main.py
import sys
from flask import Blueprint
from portal.app import app
from portal import libs
if __name__ == '__main__':
if len(sys.argv) == 2:
port = int(sys.argv[1])
else:
port = 5000
host = app.config.get('HOST', '127.0.0.1')
from portal.app import api_v1
app.register_blueprint(api_v1)
import os
app.root_path = os.getcwd()
print "Running in", app.root_path, " with DEBUG=", app.config.get('DEBUG', False)
app.run(host,
port,
app.config.get('DEBUG', False),
use_reloader=True
)
tests.py
class ApiTests(helpers.ViewBase):
############################
#### setup and teardown ####
############################
def setUp(self):
super(ApiTests, self).setUp()
app.config['TESTING'] = True
app.config['WTF_CSRF_ENABLED'] = False
app.config['DEBUG'] = False
self.assertEquals(app.debug, False)
# executed after to each test
def tearDown(self):
pass
###############
#### tests ####
###############
def test_can_obtain_todos(self):
response = self.client.get('/api/1/todos')
self.assertEqual(response.status_code, 200)
If I run the app I can access http://localhost:5000/api/1/todos without problems, but if I run the tests, I keep to getting 404 routing exception
Traceback (most recent call last):
File "/home/internetmosquito/python_envs/portal/local/lib/python2.7/site-packages/flask/app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "/home/internetmosquito/python_envs/portal/local/lib/python2.7/site-packages/flask/app.py", line 1617, in dispatch_request
self.raise_routing_exception(req)
File "/home/internetmosquito/python_envs/portal/local/lib/python2.7/site-packages/flask/app.py", line 1600, in raise_routing_exception
raise request.routing_exception
NotFound: 404: Not Found
> /home/internetmosquito/git/wizbots/portal/src/portal/test/test_api.py(47)test_can_obtain_todos()
Any idea what I'm missing here? thanks!
Just for the record, test was failing because I wasn't properly initializing the blueprint again in the test file...this is done in main.py to avoid circular dependencies issues I was having.
So simply re-creating the blueprint and assigning it to app in setUp in the test file does the trick, but this is not efficient and should be avoided, guess I should check why the circular dependencies is happening and do everythng in the app.py file instead...
Hello Stackoveflow members
I am making a Google Plus user authentication using Oauth and at the same time I need to fetch user profile, pics and drive information as well. The best way to do this is to use Oauth. So I am using flask_googlelogin.
I am trying to use the example.py of this library but What I found that the API works well and my Application pages comes up with information and Cancel and Accept button. But when I push accept button, I get the flask error
TypeError: 'instancemethod' object has no attribute 'getitem'
Now please have a look at the example.py code and flask_googlelogin.py code
here
import json
from flask import Flask, url_for, redirect, session
from flask_login import (UserMixin, login_required, login_user, logout_user,
current_user)
from flask_googlelogin import GoogleLogin
users = {}
app = Flask(__name__)
app.config.update(
SECRET_KEY='<secret_key>',
GOOGLE_LOGIN_CLIENT_ID='<client_id>',
GOOGLE_LOGIN_CLIENT_SECRET='<client_secret>',
GOOGLE_LOGIN_REDIRECT_URI='<redirection_url>')
googlelogin = GoogleLogin(app)
class User(UserMixin):
def __init__(self, userinfo):
self.id = userinfo['id']
self.name = userinfo['name']
self.picture = userinfo.get('picture')
#googlelogin.user_loader
def get_user(userid):
return users.get(userid)
#app.route('/')
def index():
return """
<p><a href="%s">Login</p>
<p><a href="%s">Login with extra params</p>
<p><a href="%s">Login with extra scope</p>
""" % (
googlelogin.login_url(approval_prompt='force'),
googlelogin.login_url(approval_prompt='force',
params=dict(extra='large-fries')),
googlelogin.login_url(
approval_prompt='force',
scopes=['https://www.googleapis.com/auth/drive'],
access_type='offline',
),
)
#app.route('/profile')
#login_required
def profile():
return """
<p>Hello, %s</p>
<p><img src="%s" width="100" height="100"></p>
<p>Token: %r</p>
<p>Extra: %r</p>
<p>Logout</p>
""" % (current_user.name, current_user.picture, session.get('token'),
session.get('extra'))
#app.route('/oauth2callback')
#googlelogin.oauth2callback
def login(token, userinfo, **params):
user = users[userinfo['id']] = User(userinfo)
login_user(user)
session['token'] = json.dumps(token)
session['extra'] = params.get('extra')
return redirect(params.get('next', url_for('.profile')))
#app.route('/logout')
def logout():
logout_user()
session.clear()
return """
<p>Logged out</p>
<p>Return to /</p>
"""
app.run(debug=True)
and flask_googlelogin.py code here
"""
Flask-GoogleLogin
"""
from base64 import (urlsafe_b64encode as b64encode,
urlsafe_b64decode as b64decode)
from urllib import urlencode
from urlparse import parse_qsl
from functools import wraps
from flask import request, redirect, abort, current_app, url_for
from flask_login import LoginManager, make_secure_token
import requests
GOOGLE_OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth'
GOOGLE_OAUTH2_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'
GOOGLE_OAUTH2_USERINFO_URL = 'https://www.googleapis.com/oauth2/v1/userinfo'
USERINFO_PROFILE_SCOPE = 'https://www.googleapis.com/auth/userinfo.profile'
class GoogleLogin(object):
"""
Main extension class
"""
def __init__(self, app=None, login_manager=None):
if login_manager:
self.login_manager = login_manager
else:
self.login_manager = LoginManager()
if app:
self._app = app
self.init_app(app)
def init_app(self, app, add_context_processor=True, login_manager=None):
"""
Initialize with app configuration. Existing
`flask_login.LoginManager` instance can be passed.
"""
if login_manager:
self.login_manager = login_manager
else:
self.login_manager = LoginManager()
# Check if login manager has been init
if not hasattr(app, 'login_manager'):
self.login_manager.init_app(
app,
add_context_processor=add_context_processor)
# Clear flashed messages since we redirect to auth immediately
self.login_manager.login_message = None
self.login_manager.needs_refresh_message = None
# Set default unauthorized callback
self.login_manager.unauthorized_handler(self.unauthorized_callback)
#property
def app(self):
return getattr(self, '_app', current_app)
#property
def scopes(self):
return self.app.config.get('GOOGLE_LOGIN_SCOPES', '')
#property
def client_id(self):
return self.app.config['GOOGLE_LOGIN_CLIENT_ID']
#property
def client_secret(self):
return self.app.config['GOOGLE_LOGIN_CLIENT_SECRET']
#property
def redirect_uri(self):
return self.app.config.get('GOOGLE_LOGIN_REDIRECT_URI')
#property
def redirect_scheme(self):
return self.app.config.get('GOOGLE_LOGIN_REDIRECT_SCHEME', 'http')
def sign_params(self, params):
return b64encode(urlencode(dict(sig=make_secure_token(**params),
**params)))
def parse_state(self, state):
return dict(parse_qsl(b64decode(str(state))))
def login_url(self, params=None, **kwargs):
"""
Return login url with params encoded in state
Available Google auth server params:
response_type: code, token
prompt: none, select_account, consent
approval_prompt: force, auto
access_type: online, offline
scopes: string (separated with commas) or list
redirect_uri: string
login_hint: string
"""
kwargs.setdefault('response_type', 'code')
kwargs.setdefault('access_type', 'online')
if 'prompt' not in kwargs:
kwargs.setdefault('approval_prompt', 'auto')
scopes = kwargs.pop('scopes', self.scopes.split(','))
if USERINFO_PROFILE_SCOPE not in scopes:
scopes.append(USERINFO_PROFILE_SCOPE)
redirect_uri = kwargs.pop('redirect_uri', self.redirect_uri)
state = self.sign_params(params or {})
return GOOGLE_OAUTH2_AUTH_URL + '?' + urlencode(
dict(client_id=self.client_id,
scope=' '.join(scopes),
redirect_uri=redirect_uri,
state=state,
**kwargs))
def unauthorized_callback(self):
"""
Redirect to login url with next param set as request.url
"""
return redirect(self.login_url(params=dict(next=request.url)))
def exchange_code(self, code, redirect_uri):
"""
Exchanges code for token/s
"""
token = requests.post(GOOGLE_OAUTH2_TOKEN_URL, data=dict(
code=code,
redirect_uri=redirect_uri,
grant_type='authorization_code',
client_id=self.client_id,
client_secret=self.client_secret,
)).json
if not token: # or token.get('error'):
abort(400)
return token
def get_userinfo(self, access_token):
userinfo = requests.get(GOOGLE_OAUTH2_USERINFO_URL, params=dict(
access_token=access_token,
)).json
if not userinfo: # or userinfo.get('error'):
abort(400)
return userinfo
def get_access_token(self, refresh_token):
"""
Use a refresh token to obtain a new access token
"""
token = requests.post(GOOGLE_OAUTH2_TOKEN_URL, data=dict(
refresh_token=refresh_token,
grant_type='refresh_token',
client_id=self.client_id,
client_secret=self.client_secret,
)).json
if not token: # or token.get('error'):
return
return token
def oauth2callback(self, view_func):
"""
Decorator for OAuth2 callback. Calls `GoogleLogin.login` then
passes results to `view_func`.
"""
#wraps(view_func)
def decorated(*args, **kwargs):
params = {}
# Check sig
if 'state' in request.args:
params.update(**self.parse_state(request.args.get('state')))
if params.pop('sig', None) != make_secure_token(**params):
return self.login_manager.unauthorized()
code = request.args.get('code')
# Web server flow
if code:
token = self.exchange_code(
code,
url_for(
request.endpoint,
_external=True,
_scheme=self.redirect_scheme,
),
)
#received = get_access_token(token['access_token'])
userinfo = self.get_userinfo(token['access_token'])
params.update(token=token, userinfo=userinfo)
# Browser flow
else:
if params:
params.update(dict(request.args.items()))
else:
return '''
<script>
window.onload = function() {
location.href = '?' + window.location.hash.substr(1);
};
</script>
'''
return view_func(**params)
return decorated
def user_loader(self, func):
"""
Shortcut for `login_manager`'s `flask_login.LoginManager.user_loader`
"""
self.login_manager.user_loader(func)
Please Note down there may be some disturbed code in def oauth2callback and the condition if code the line is
userinfo = self.get_userinfo(token['access_token'])
Here token['access_token'] produces the error names "TypeError: 'instancemethod' object has no attribute 'getitem'"
Please let me know how can I fix it
Looks like a bug or api change.
In exchange_code
token = requests.post(GOOGLE_OAUTH2_TOKEN_URL, data=dict(
code=code,
redirect_uri=redirect_uri,
grant_type='authorization_code',
client_id=self.client_id,
client_secret=self.client_secret,
)).json
token is now the json function. In newer versions of flask_googlelogin this is json().