I am using flask, here giving example, what I want to do. I copied code from flask portal.
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
Running the app
(py35) root#localhost:tmp root$ flask run
* Serving Flask app "hello"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Send request
root#localhost:~ root$ curl http://localhost:5000/
Hello, World!
I modify my function and change it to raise error.
#app.route('/')
def hello_world():
print(xyz)
return 'Hello, World!'
When i try to send request, it failed
[2017-11-06 10:22:13,625] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "/py35/lib/python3.5/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/py35/lib/python3.5/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/py35/lib/python3.5/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/nile2691/sbdev/StorageCenterUI/.tox/py35/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/py35/lib/python3.5/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "py35/lib/python3.5/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/private/tmp/hello.py", line 6, in hello_world
print(xyz)
NameError: name 'xyz' is not defined
I have can add try...except in my code, but in real code, its in many place, and I dont want to handle this general exception everywhere.
Is there any way like
try:
process_flask_request()
except Exception as ex:
# Log detail exception
logger.exception(ex)
return "Custome error message for all general exception"
With this changes, instead of getting general error like below
curl http://localhost:5000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
I want to return proper output, with custom error message.
You can include error handlers like this, e.g. for displaying the internal server error in your example more nicely:
import traceback
(...some code...)
#app.errorhandler(500)
def internal_error(e):
"""
handle internal errors nicely
"""
tb = traceback.format_exc()
return render_template('error.html',
error=e.message,
traceback=tb), 500
In your template you can then output the short error message, and (maybe depending on user rights if you have user management) the detailed stacktrace.
As mentioned in the comments on your question, you should read the documentation to get the full picture.
Related
I am trying to use my Flask server to receive webhooks in a POST from a Zap, but I'm getting a 500 Internal Server Error when I test.
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
TypeError: receive_webhook() missing 1 required positional argument: 'request'
Here is my handler for the webhook:
#app.route("/webhook", methods=['POST'])
def receive_webhook(request):
print(request.json)
return request.json
Here's a screenshot of my Zap I am trying to send the POST from
Thanks for any assistance.
It seems like Zapier is calling my handler with no argument. Shouldn’t it be passing the payload as that request argument or am I misunderstanding something here?
Edit: Also, if it's relevant, I'm using Nginx and Gunicorn for hosting. On an Ubuntu Linode.
I figured out the problem. I was using the Flask request module incorrectly. This code made it work -
#app.route("/webhook", methods=['POST'])
def receive_webhook():
print(request.data)
return request.data
I'm making a Flask webapp and I'm using Flask-Socketio. For various reasons, I have a need to also use the websocket-client package. Everything is working as intended, except that when I tried running the app on a different computer on a different network, I get the following error:
"""
Traceback (most recent call last):
File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "[Path to venv]\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "[Path to venv]\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "[Path to app]\app\views.py", line 7, in index
sio.connect("http://localhost:80/", transports=['websocket', 'polling'])
File "[Path to venv]\venv\lib\site-packages\socketio\client.py", line 262, in connect
engineio_path=socketio_path)
File "[Path to venv]\venv\lib\site-packages\engineio\client.py", line 170, in connect
url, headers, engineio_path)
File "[Path to venv]\venv\lib\site-packages\engineio\client.py", line 346, in _connect_websocket
cookie=cookies)
File "[Path to venv]\venv\lib\site-packages\websocket\_core.py", line 514, in create_connection
websock.connect(url, **options)
File "[Path to venv]\venv\lib\site-packages\websocket\_core.py", line 223, in connect
options.pop('socket', None))
File "[Path to venv]\venv\lib\site-packages\websocket\_http.py", line 120, in connect
sock = _open_socket(addrinfo_list, options.sockopt, options.timeout)
File "[Path to venv]\venv\lib\site-packages\websocket\_http.py", line 189, in _open_socket
raise error
File "[Path to venv]\venv\lib\site-packages\websocket\_http.py", line 172, in _open_socket
sock.connect(address)
OSError: [WinError 10057] A request to send or receive data was disallowed because
the socket is not connected and (when sending on a datagram socket using a sendto call)
no address was supplied
"""
I've boiled down my code as much as possible to the following, which still works on my computer, but gives the same error on the other:
|start.py
|app
|__init__.py
|views.py
|templates
|index.html
# __init__.py
from flask import Flask
from flask_socketio import SocketIO
from gevent import monkey
monkey.patch_all()
APP = Flask(__name__)
SOCKETIO = SocketIO(APP, engineio_logger=True, logger=True)
from . import views
# views.py
from app import APP
from socketio import Client
from flask import render_template
#APP.route('/', methods=['GET', 'POST'])
def index():
sio = Client()
sio.connect("http://localhost:80", transports=['websocket', 'polling']) # Error being caused here
return render_template('index.html')
# start.py
from app import APP, SOCKETIO
if __name__ == "__main__":
SOCKETIO.run(APP, debug=True, port=80, host='0.0.0.0')
index.html is just a basic 'Hello World' html page.
What kind of stuff might give me this error on one computer/network an not another, especially just running it on localhost:80? I really don't know what to try here.
EDIT: Added traceback data to error
EDIT 2: In my actual code, the websocket.Client is being run inside a Celery task. I didn't include it here because the error is reproduceable without going into that much complexity.
The problem is when you try to run -(Flask-webapp, websocket-client)- both of them simultaneously, only one of them will be running.
Update:
Here are some things to be noted:
If you changing machine, make sure system-softwares are already up-to-date.
Check your system is not behind firewall but when you're running Flask webapp and websocket-client on the same machine then there is not need of this step.
Try to restart your machine after update your OS.
Use multiprocessing instead of Threads as they won't work here because the famous Python-Global-Interpreter or GIL. According to which Only one thread can be in a state of execution at any point in time.
The impact of the GIL isn’t visible to developers who execute
single-threaded programs, but it can be a - Performance-bottleneck - in
CPU-bound and multi-threaded code.
Then Check: How to run flask on Port:80. For development purposes Port:5000 is mostly recommended.
In order to perform "Error Handling" visit the flask-socketio documentation, there is nice tips to to deal with exceptions.
You can go as follow:
#socketio.on_error_default # handles all namespaces without an explicit error handler
def default_error_handler(e):
pass
And finally, to handle socket.timeout, you may also use this following code to handle the final error: socket timed out:
try:
socketio.run(app,...
except socket.error as socketerror:
print("Error: ", socketerror)
It would be an better approach to use postman.For learning and testing purpose, try to use POSTMAN which is a quick and easy platform for sending REST, SOAP, and GraphQL requests directly within Postman. Visit reference: getting-started-postman.
Here is an example program:
import multiprocessing
# Assume for flask-app
def start_flask_app:
app.run()
# Assume for websocket-client-app
# Assume basic events you will handle in your client e.g. on_message, on_error, on_close
def start_ws:
ws = websocket.WebSocketApp(WS_URI, on_message= on_message,
on_error = on_error,
on_close = on_close)
ws.on_open = on_open
ws.run_forever()
# use of sub-processes instead of threads.
p_flask = multiprocessing.Process(target=start_flask_app)
p_ws = multiprocessing.Process(target=start_ws)
p_ws.start()
p_flask.start()
p_ws.join()
p_flask.join()
I have my flask-restful app.py which contains all of my main functions. I have created a server.py file as instructed from here: https://auth0.com/docs/quickstart/backend/python
In my app.py file from server i import AuthError and requires_auth. I have then put #requires_auth in front of my functions.
When I have a valid jwt, it works perfectly. When the jwt is not valid it fails. Failing is good, because the requests shouldn't work. But the response i get from my api is "Internal Server Error" rather than the detailed response in the raise AuthError section in the server.py file.
I get 2 errors:
Traceback (most recent call last):
File "C:\Users\ME\code\server.py", line 88, in decorated
issuer="https://"+AUTH0_DOMAIN+"/"
File "C:\Users\ME\lib\site-packages\jose\jwt.py", line 150, in decode
options=defaults)
File "C:\Users\ME\lib\site-packages\jose\jwt.py", line 457, in _validate_claims
_validate_exp(claims, leeway=leeway)
File "C:\Users\ME\lib\site-packages\jose\jwt.py", line 299, in _validate_exp
raise ExpiredSignatureError('Signature has expired.')
jose.exceptions.ExpiredSignatureError: Signature has expired.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\ME\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\ME\lib\site-packages\flask\app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\ME\lib\site-packages\flask_restful\__init__.py", line 480, in wrapper
resp = resource(*args, **kwargs)
File "C:\Users\ME\lib\site-packages\flask\views.py", line 88, in view
return self.dispatch_request(*args, **kwargs)
File "C:\Users\ME\lib\site-packages\flask_restful\__init__.py", line 595, in dispatch_request
resp = meth(*args, **kwargs)
File "C:\Users\ME\code\server.py", line 92, in decorated
"description": "token is expired"}, 401)
server.AuthError: ({'code': 'token_expired', 'description': 'token is expired'}, 401)
How do i get the AuthError as the response to the call, rather than just my Internal Server Error?
Thanks!
There is an issue with this specific tutorial in Auth0, it instructs you to include the error handler in auth.py:
#app.errorhandler(AuthError)
def handle_auth_error(ex):
response = jsonify(ex.error)
response.status_code = ex.status_code
return response
Instead, you have to include this handler in your app.py, where you actually use #requires_auth.
Notice that to do so, you need to add relevant imports:
from auth import AuthError
from flask import jsonify
Notice: To be able to import from auth.py you need to add an empty file __init__.py in the same directory.
Try setting app.config[“PROPAGATE_EXCEPTIONS”] = True
Uou could maybe use an errorhandler to explicitly catch those errors and return some explicit json based on them.
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!
I'm aware that once I have everything up and running on a production server, nginx or apache are supposed to be serving static assets instead of Flask. In the interest of getting started quickly though, I'm running into an issue with Flask and requests to files in subdirectories of static.
A request for /static/test.css returns correctly, but a request for /static/test/test.css returns a 500 and throws this exception:
Traceback (most recent call last):
File "/home/tim/shadowcraft-ui-python/venv/lib/python3.5/site-packages/flask/app.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/tim/shadowcraft-ui-python/venv/lib/python3.5/site-packages/flask/app.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/tim/shadowcraft-ui-python/venv/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/home/tim/shadowcraft-ui-python/venv/lib/python3.5/site-packages/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/home/tim/shadowcraft-ui-python/venv/lib/python3.5/site-packages/flask/app.py", line 1642, in full_dispatch_request
response = self.make_response(rv)
File "/home/tim/shadowcraft-ui-python/venv/lib/python3.5/site-packages/flask/app.py", line 1731, in make_response
raise ValueError('View function did not return a response')
ValueError: View function did not return a response
A bit of searching on that error returns mostly simple cases where someone forgot a return in a request handler, but nothing for when making direct requests for assets. It also does the same thing if trying to use url_for in a template to request the file from the subdirectory.
This ended up being an error in my code. I have a route handler that takes three parts as arguments, and since that handler isn't implemented yet, it caused Flask to throw the exception above. I ended up implementing the solution from Does Flask support regular expressions in its URL routing? for that handler since I know the first part is always one of a few different values, and the static handler can run as normal.