I'm writing a function in Python Flask to deal with the oauth2 call backs of multiple api's.
The function as it stands is:
#app.route('/external_api/<api>/oauth2callback', methods=['POST', 'GET'])
def gdrive_oauth2callback(api):
toReturn = external_api.APIs[api]['lib'].oauth2callback(os.path.join(APP_OAUTH, str(api + '_id.json')))
userSession = UserSession()
userSession.addUserAuth(api)
return toReturn
However this causes a build error:
raise BuildError(endpoint, values, method)
BuildError: ('gdrive_oauth2callback', {}, None)
I'm confused as to why this is happening, as when i replace the api variable with the string 'gdrive' no error is created and it works perfectly. I'm calling the function in the same manner on both occasions (example.com/external_api/gdrive/oauth2callback), I'm wondering if Flask is unable to deal with both a POST request and a GET request at the same time, and if anyone else has had the same issue?
The full error log is below:
ERROR:app:Exception on /external_api/gdrive/connect [GET]
Traceback (most recent call last):
File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/app/app/views.py", line 43, in gdrive_connect
toReturn = external_api.APIs[api]['lib'].makeConnection()
File "/app/app/external_api/gdrive/api.py", line 14, in makeConnection
return flask.redirect(flask.url_for('gdrive_oauth2callback'))
File "/app/.heroku/python/lib/python2.7/site-packages/flask/helpers.py", line 312, in url_for
return appctx.app.handle_url_build_error(error, endpoint, values)
File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1641, in handle_url_build_error
reraise(exc_type, exc_value, tb)
File "/app/.heroku/python/lib/python2.7/site-packages/flask/helpers.py", line 305, in url_for
force_external=external)
File "/app/.heroku/python/lib/python2.7/site-packages/werkzeug/routing.py", line 1616, in build
raise BuildError(endpoint, values, method)
BuildError: ('gdrive_oauth2callback', {}, None) - at=info method=GET path
If anyone could give me any pointers on this that would be great! Thanks!
I think that flask must not be failing, if you take a look to this example, it works perfectly, http://flask.pocoo.org/snippets/62/.
I tried:
from flask import Flask
app = Flask(__name__)
#app.route("/<name>",methods=['POST', 'GET'])
def hello(name):
return "Hello World!"+name
if __name__ == "__main__":
app.run()
and it works fine on post and get requests. I know that isnt enougth but it shows what the problem probably isn’t.
Related
I have been developing a little forum site with a basic login system. My Flask app functions as it should when logging in, however whenever I use 'return redirect(url_for("index"))' I seem to get an exception problem in my Flask which stops the app. The error it produces is:
ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "MY DIRECTORY\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "MY DIRECTORY\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "MY DIRECTORY\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "MY DIRECTORY\_compat.py", line 39, in reraise
raise value
File "MY DIRECTORY\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "MY DIRECTORY\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "MY FLASK APP FILE\app.py", line 16, in index
cursor = mydb.cursor()
File "MY FLASK APP FILE\lib\site-packages\mysql\connector\connection.py", line 1022, in cursor
self.handle_unread_result()
File "MY FLASK APP FILE\lib\site-packages\mysql\connector\connection.py", line 1286, in handle_unread_result
raise errors.InternalError("Unread result found")
mysql.connector.errors.InternalError: Unread result found
How can I prevent this from happening, I assume I need to do something with a GET but I am not sure.
It seems as if you are using mysql connector. To fix this,change the properties of the cursor object.
cursor = <connection-name>.cursor(buffered=True)
This must solve your issue.
For educational purposes, we're building a very simple Flask app. While it runs smoothly locally, it no longer does when I copy the code to my virtual private server.
The route is defined as follows:
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route("/", methods=["GET", "POST"])
def sign_up():
...
This is the function that uses autocomplete:
with connection.cursor() as cursor:
sql = f"SELECT * FROM movies WHERE title"
query = cursor.execute(sql)
data = cursor.fetchall()
# from flask import jsonify
results = [data[i]['title'] for i in range(len(data))]
return render_template("autocomplete.html", results=results)
autocomplete.html is located in the templates folder, which sits next to the Python program file.
And the web service is started like this:
if __name__ == '__main__':
app.run(host='0.0.0.0')
I can start the web service successfully, but when I connect using the URL, it returns a 500 error, and the server console shows:
[2020-05-28 16:19:47,099] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "/root/miniconda3/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/root/miniconda3/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/miniconda3/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/root/miniconda3/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/root/miniconda3/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/root/miniconda3/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "app.py", line 94, in sign_up
return render_template("autocomplete.html", results=results)
File "/root/miniconda3/lib/python3.7/site-packages/flask/templating.py", line 140, in render_template
ctx.app,
File "/root/miniconda3/lib/python3.7/site-packages/flask/templating.py", line 120, in _render
rv = template.render(context)
File "/root/miniconda3/lib/python3.7/site-packages/jinja2/environment.py", line 1090, in render
self.environment.handle_exception()
File "/root/miniconda3/lib/python3.7/site-packages/jinja2/environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "/root/miniconda3/lib/python3.7/site-packages/jinja2/_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "/root/recommender/app-flask/templates/autocomplete.html", line 10, in top-level template code
$.getJSON("{{url_for('autocomplete')}}",{
File "/root/miniconda3/lib/python3.7/site-packages/flask/helpers.py", line 370, in url_for
return appctx.app.handle_url_build_error(error, endpoint, values)
File "/root/miniconda3/lib/python3.7/site-packages/flask/app.py", line 2216, in handle_url_build_error
reraise(exc_type, exc_value, tb)
File "/root/miniconda3/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/root/miniconda3/lib/python3.7/site-packages/flask/helpers.py", line 358, in url_for
endpoint, values, method=method, force_external=external
File "/root/miniconda3/lib/python3.7/site-packages/werkzeug/routing.py", line 2179, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.BuildError: Could not build url for endpoint 'autocomplete'. Did you mean 'static' instead?
I assume this is because of a change in the URL, but I don't know how to solve this.
Can anyone help?
$.getJSON("{{url_for('autocomplete')}}",{
=> your code wrong at this line, read more about url_for in flask.
It's need to render route like: <blueprint_name>.<function_name> If use app as route use can skip blueprint_name => Ex: .sign_up
sample
In my new job we are using the Flask framework (I'm newbie in the Flask). Every view is the child of MethodView. The code looks like this:
from flask import render_template
from flask.views import MethodView
class HelloWorldPage(MethodView):
def get(self):
return render_template('helloworld.html')
def configure_routing(app):
app.add_url_rule('/<lang>/helloworld', view_func=HelloWorldPage.as_view('helloworld'))
Of course, configure_routing(app) from helloworld.py is called in appropriate place. Now, my question is if it's possible to get <lang> from route? When I write get(self, lang) it throws an exception TypeError: get() takes exactly 2 arguments (1 given), when I create a method called helloworld(lang), it throws me that method get is not implemented and so on. Thank you very much. Bye
Edit:
traceback to get(self, lang)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1994, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 149, in dispatch_request
return meth(*args, **kwargs)
TypeError: get() takes exactly 2 arguments (1 given)
I tried the same
from flask import Flask, render_template
from flask.views import MethodView
app = Flask(__name__)
class HelloWorldPage(MethodView):
def get(self, lang):
return render_template('HelloWorld.html', language=lang)
app.add_url_rule('/<lang>/helloworld', view_func=HelloWorldPage.as_view('helloworld'))
if __name__ == '__main__':
app.run()
response below
comment from flask.views
METHODVIEW :
Like a regular class-based view but that dispatches requests to
particular methods. For instance if you implement a method called
:meth:get it means it will respond to 'GET' requests and
the :meth:dispatch_request implementation will automatically
forward your request to that. Also :attr:options is set for you
automatically::
Did you restrart the service after changing get(self) to get(self, lang) ?
if you did then please check the application init file where you import HelloWorldPage view and make sure
app = Flask(__name__)
## IMPORT YOUR APP VIEWS
## THEN CONFIGURE THE ROUTINGS
def configure_routing(app):
app.add_url_rule('/<lang>/helloworld', view_func=HelloWorldPage.as_view('helloworld'))
When a user goes on my flask app with a URL that has more than 3 sub paths, like "domain.com/var1/var2/var3/var4", it throws the error below:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1478, in full_dispatch_request
response = self.make_response(rv)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1574, in make_response
rv = self.response_class(rv, headers=headers, status=status)
File "/usr/local/lib/python2.7/site-packages/werkzeug/wrappers.py", line 758, in __init__
self.status = status
File "/usr/local/lib/python2.7/site-packages/werkzeug/wrappers.py", line 862, in _set_status
self._status = to_native(value)
File "/usr/local/lib/python2.7/site-packages/werkzeug/_compat.py", line 111, in to_native
return x.encode(charset, errors)
AttributeError: 'NotFound' object has no attribute 'encode'
It works fine for url's that have less than or equal to 3 subpaths like "domain.com/var1/var2/var3", but I have routes for url's with 1, 2, and 3 subpaths.
How can I get my app to go to the 404 Page Not Found method instead of throwing this error?
Thank you!
edit..
Here's a pastebin of the route methods I'm using. http://pastebin.com/kjYsqk9n
Sorry I can't provide an example of this problem, it's really weird and I don't know how to reproduce it myself. My other flask apps work fine, this one doesn't. If anyone needs clarification, please let me know... thanks for all your help!
Found out why it was returning that error. It turns out I was passing in the error object instead of "404" at the end of this line:
return render_template("error.html", usa=usa, canada=canada, breadcrumbs=breadcrumbs, error_code=e), 404
Thanks!
I'm building a website using Flask in which I also use Websockets using Flask-socketIO, but there's one thing I don't understand.
I built a chat-functionality. When one user sends a message I use websockets to send that message to the server, after which I emit the message to the other user from within that same call:
#socketio.on('newPM', namespace='/test')
#login_required_with_global
def io_newMessage(theJson):
emit('message', {'message': theJson['message']}, room=str(theJson['toUserId']))
But let's say that I want to emit a message to a user when a file was saved. This means that I need to emit a message from within the view in which the file is POSTed. So according to the flask_socketio docs I can add a namespace in the emit. So I wrote this:
#app.route('/doc', methods=['POST'])
#login_required
def postDoc():
saveDocument(request.files['file'], g.user.id)
emit('my response', {'data': 'A NEW FILE WAS POSTED'}, room=current_user.id, namespace='/test')
return jsonify({'id': str(doc.id)})
But seeing the stacktrace below there still is a problem with the namespace; werkzeug has an AttributeError: 'Request' object has no attribute 'namespace'.
Does anybody know what I'm doing wrong here? Or is this a bug in flask_socketio? All tips are welcome!
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 758, in decorated_view
return func(*args, **kwargs)
File "/home/vg/app/views.py", line 768, in emitNotificationCount
emit('menuInit', emitJson, room=current_user.id, namespace='/test')
File "/usr/local/lib/python2.7/dist-packages/flask_socketio/__init__.py", line 444, in emit
return request.namespace.emit(event, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
AttributeError: 'Request' object has no attribute 'namespace'
Quoting from Miguel Grinberg's response on an open issue page on the Flask-SocketIO GitHub:
When you want to emit from a regular route you have to use
socketio.emit(), only socket handlers have the socketio context
necessary to call the plain emit().
So as an example:
from flask_socketio import SocketIO
app = Flask(__name__)
app.config.from_object('config')
socketio = SocketIO(app)
#app.route('/doc', methods=['POST'])
def postDoc():
saveDocument(request.files['file'], g.user.id)
socketio.emit('my response', {'data': 'A NEW FILE WAS POSTED'}, room=current_user.id)
return jsonify({'id': str(doc.id)})