How to prevent Flask (python) from emitting html?
Question:
It appears that Flask assumes that the server is returning html to the client (browser).
Here’s a simple example;
import json
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
msg = ['Hello, world!']
return json.dumps(msg) + 'n'
This code works as expected and returns the desired json;
$ curl -s http://localhost:5000/
["Hello, world!"]
But if I introduce an error;
import json
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
msg = ['Hello, world!']
return json.dumps(XXmsg) + 'n'
Then Flask emits the error wrapped in several pages worth of html, starting like;
$ curl -s http://localhost:5000/
<!DOCTYPE html>
<html>
<head>
<title>NameError: name 'XXmsg' is not defined
// Werkzeug Debugger</title>
<link rel="stylesheet" href="?__debugger__=yes&cmd=resource&f=style.css">
<link rel="shortcut icon"
href="?__debugger__=yes&cmd=resource&f=console.png">
<script src="?__debugger__=yes&cmd=resource&f=debugger.js"></script>
<script>
var CONSOLE_MODE = false,
EVALEX = true,
EVALEX_TRUSTED = false,
SECRET = "Mq5TSy6QE4OuOHUfvk8b";
</script>
</head>
<body style="background-color: #fff">
<div class="debugger">
Emitting html makes sense if you’re creating a page load app. But I’m creating an api that only returns json.
Is there anyway to prevent Flask from emitting html at all?
Thanks
Mike
Answers:
Have a look at the section Returning API Errors as JSON of the Flask docs.
Basically, you have to replace the default error handler with a function that returns the error as json. A very basic example:
@app.errorhandler(HTTPException)
def handle_exception(exception):
response = exception.get_response()
response.content_type = "application/json"
response.data = json.dumps({"code": exception.code})
return response
The accepted response gives a good hint for handling HTTPException
but it won’t work for all exceptions unless you create a handler for the mother of all exceptions:Exception
. And you might not want to do this for security reasons, if you have some custom defined exceptions with sensible data it’ll get handled by this handler.
I suspect the true reason you have those lengthy html responses is because you started your flask app with the --debug
option.
It appears that Flask assumes that the server is returning html to the client (browser).
Here’s a simple example;
import json
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
msg = ['Hello, world!']
return json.dumps(msg) + 'n'
This code works as expected and returns the desired json;
$ curl -s http://localhost:5000/
["Hello, world!"]
But if I introduce an error;
import json
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
msg = ['Hello, world!']
return json.dumps(XXmsg) + 'n'
Then Flask emits the error wrapped in several pages worth of html, starting like;
$ curl -s http://localhost:5000/
<!DOCTYPE html>
<html>
<head>
<title>NameError: name 'XXmsg' is not defined
// Werkzeug Debugger</title>
<link rel="stylesheet" href="?__debugger__=yes&cmd=resource&f=style.css">
<link rel="shortcut icon"
href="?__debugger__=yes&cmd=resource&f=console.png">
<script src="?__debugger__=yes&cmd=resource&f=debugger.js"></script>
<script>
var CONSOLE_MODE = false,
EVALEX = true,
EVALEX_TRUSTED = false,
SECRET = "Mq5TSy6QE4OuOHUfvk8b";
</script>
</head>
<body style="background-color: #fff">
<div class="debugger">
Emitting html makes sense if you’re creating a page load app. But I’m creating an api that only returns json.
Is there anyway to prevent Flask from emitting html at all?
Thanks
Mike
Have a look at the section Returning API Errors as JSON of the Flask docs.
Basically, you have to replace the default error handler with a function that returns the error as json. A very basic example:
@app.errorhandler(HTTPException)
def handle_exception(exception):
response = exception.get_response()
response.content_type = "application/json"
response.data = json.dumps({"code": exception.code})
return response
The accepted response gives a good hint for handling HTTPException
but it won’t work for all exceptions unless you create a handler for the mother of all exceptions:Exception
. And you might not want to do this for security reasons, if you have some custom defined exceptions with sensible data it’ll get handled by this handler.
I suspect the true reason you have those lengthy html responses is because you started your flask app with the --debug
option.