I am trying to wrote some code using flask let another server can post some data to it and then inside flask, when I receive the call from outside, I would like to make another post to another server.
Below is my code
from flask import Flask, jsonify, request
import json
import requests
app = Flask(__name__)
#app.route("/sendData.json", methods=['POST'])
def receiveImageData():
imageData = request.json
# save data to son file
with open(request.json['image_filename'].split('.')[0] + '.json', 'w+') as f:
json.dump(imageData, f, indent=4)
# post some data to this url
r = requests.post('http://example.com/example.json', son = {'image_filename':'test.jpg', 'image_url': "http://images.come"})
# return json data back for /sendData.json
return jsonify({"status": "success"})
The problem is the last line {'status':'success'} will not return for sendData.json.
How can I fix it or there should be another way to make this happen?
Below is error log from flask
127.0.0.1 - - [03/Aug/2017 14:38:37] "POST /sendData.json HTTP/1.1" 500 -
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/bloomer/Documents/python/api_server/api.py", line 21, in receiveImageData
r = requests.post('http://example.com/example.json', son = {'image_filename':'test.jpg', 'image_url': "http://images.come"})
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 112, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 490, in send
raise ConnectionError(err, request=request)
ConnectionError: ('Connection aborted.', BadStatusLine("''",))
instead of jsonify({"status": "success"}) Use :
return (Response(),200)
Try it out with return Response(), 200 at the end of receiveImageData().
EDIT:
I researched a bit. Actually it should work. Try something like:
return jsonify({"success": True}), 202
What are the error messages you get? And is it the same server / API, where you post your data and status: success?
Related
I have a strange problem when using flask + TikTok API that I can't figure out.
I have the following code:
from flask import Flask
from flask_restful import Resource, Api
from TikTokApi import TikTokApi
tikTokApi = TikTokApi()
app = Flask(__name__)
api = Api(app)
#app.errorhandler(404)
def page_not_found(e):
return {'status': 'fail'}, 404
class TikTokProfile(Resource):
def get(self):
profileResponse = tikTokApi.getUserObject('rosiethepygmygoat')
return {'user' : profileResponse}
class TikTokMedia(Resource):
def get(self):
data = tikTokApi.getUserObject('rosiethepygmygoat')
response = tikTokApi.userPage(data["id"],data["secUid"])
return response
api.add_resource(TikTokProfile, '/profile')
api.add_resource(TikTokMedia, '/media')
if __name__ == '__main__':
app.run(debug=True)
When I visit /profile I get the user object, but when I try to get his user page via the /media route I get the following error:
INFO:werkzeug:127.0.0.1 - - [08/Jan/2021 09:20:45] "GET /media HTTP/1.1" 500 -
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 272, in error_router
return original_handler(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 272, in error_router
return original_handler(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 468, in wrapper
resp = resource(*args, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\views.py", line 89, in view
return self.dispatch_request(*args, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 583, in dispatch_request
resp = meth(*args, **kwargs)
File "D:\server\norway_group\tokmatic-sass\python\start.py", line 22, in get
response = tikTokApi.userPage(data["id"],data["secUid"])
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\tiktok.py", line 562, in userPage
return self.getData(url=api_url, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\tiktok.py", line 159, in getData
verify_fp, did, signature = self.browser.sign_url(**kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\browser.py", line 164, in sign_url
page = self.create_page()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\browser.py", line 116, in create_page
context = self.browser.newContext(**iphone)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\playwright\sync_api.py", line 6710, in newContext
self._sync(
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\playwright\_sync_base.py", line 95, in _sync
self._dispatcher_fiber.switch()
greenlet.error: cannot switch to a different thread
I thought that there is an issue with the TikTokApi package but when I try the same code outside the flask resource:
data = tikTokApi.getUserObject('rosiethepygmygoat')
response = tikTokApi.userPage(data["id"],data["secUid"])
print(response)
I get the object I need.
So am I missing a specific configuration for flask or something else? Any insights will be much appreciated.
Run your flask application using this comands:
flask run --without-threads
I'm working on a Flask server where we have a route to validate a user's JWT token using the library flask-jwt-extended. This is what our route looks like:
from flask_jwt_extended import (
JWTManager, jwt_required, create_access_token, create_refresh_token, get_jwt_identity, jwt_refresh_token_required
)
#app.route('/api/users/validate', methods=['POST'])
def validate_user():
if not request.json:
abort(400)
data = request.get_json()
if ('id_token' not in data):
abort(400, "id_token must be a parameter in the JSON")
decoded_token = auth.verify_id_token(data['id_token'])
if ('uid' not in decoded_token):
return json.dumps({'verified': False}), 200
else:
user = mongo.db.users.find_one({'_id': decoded_token['uid']})
if user:
access_token = create_access_token(identity=user['_id'])
refresh_token = create_refresh_token(identity=user['_id'])
return json.dumps({'verified': True, 'access_token': access_token, 'refresh_token': refresh_token}), 200
else:
return json.dumps({'verified': False, 'message': 'unable to locate user'}), 401
For some reason, whenever I try to make a post request to this route, I get a TypeError: 'module' object is not callable error for the function create_access_token. Here's the stack trace:
127.0.0.1 - - [08/May/2019 12:24:17] "POST /api/users/validate HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/user/Documents/server/src/controllers/auth_controller.py", line 44, in validate_user
access_token = create_access_token(identity=user['_id')
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask_jwt_extended/utils.py", line 157, in create_access_token
return jwt_manager._create_access_token(identity, fresh, expires_delta, user_claims)
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask_jwt_extended/jwt_manager.py", line 476, in _create_access_token
json_encoder=config.json_encoder
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask_jwt_extended/tokens.py", line 77, in encode_access_token
json_encoder=json_encoder)
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/flask_jwt_extended/tokens.py", line 31, in _encode_jwt
json_encoder=json_encoder).decode('utf-8')
File "/Users/user/Documents/server/venv/lib/python3.6/site-packages/jwt/api_jwt.py", line 61, in encode
cls=json_encoder
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
TypeError: 'module' object is not callable
I've triple checked the flask-jwt-extended docs and create_acess_token is, in fact, a function and when printing create_acess_token it prints that it's a function. I've looked over almost all of the StackOverflow posts on this topic and none of them are helpful—most of them talk about user generated classes, but this is a function that I'm pulling from an external library.
Here is the definition of create_access_token in flask-jwt-extended:
def _create_access_token(self, identity, fresh=False, expires_delta=None, user_claims=None):
if expires_delta is None:
expires_delta = config.access_expires
if user_claims is None:
user_claims = self._user_claims_callback(identity)
access_token = encode_access_token(
identity=self._user_identity_callback(identity),
secret=self._encode_key_callback(identity),
algorithm=config.algorithm,
expires_delta=expires_delta,
fresh=fresh,
user_claims=user_claims,
csrf=config.csrf_protect,
identity_claim_key=config.identity_claim_key,
user_claims_key=config.user_claims_key,
json_encoder=config.json_encoder
)
return access_token
If it helps, the code is in Python 3.6.5 and it's in a virtual environment. Any help would be greatly appreciated!
My goal for this code is to send an email using Mailgun. I'm using calling it from Flask using the requests library:
contact.py
def index():
data = request.form.to_dict()
send_email(data)
return "Success!"
send_email()
def send_email(data: dict):
data = format_data(data)
return requests.post(
API_URL,
auth={ "api": API_KEY },
data=data,
)
I know it has something to do with the send_email() function but I'm currently stuck at how to solve it.
EDIT: Here's the full traceback:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3/dist-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3/dist-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3/dist-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3/dist-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python3/dist-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "contact.py", line 9, in index
send_email(data)
File "/home/david-hermes/Desktop/Projects/frontend/web/single-page-resume/send_email.py", line 44, in send_email
data=data,
File "/usr/lib/python3/dist-packages/requests/api.py", line 112, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/lib/python3/dist-packages/requests/api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 494, in request
prep = self.prepare_request(req)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 437, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/usr/lib/python3/dist-packages/requests/models.py", line 309, in prepare
self.prepare_auth(auth, url)
File "/usr/lib/python3/dist-packages/requests/models.py", line 540, in prepare_auth
r = auth(self)
TypeError: 'dict' object is not callable
127.0.0.1 - - [31/Jan/2019 21:01:28] "POST / HTTP/1.1" 500 -
You are using the api argument incorrectly. You want to pass in the username and password combination as a tuple:
auth=("api", API_KEY),
The Mailgun API indeed requires you to pass in the API key as a Basic Auth password, but to send a Basic Authentication header using the auth keyword argument you either pass in a HTTPBasicAuth() instance or a tuple:
Making requests with HTTP Basic Auth is very simple:
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
<Response [200]>
In fact, HTTP Basic Auth is so common that Requests provides a handy shorthand for using it:
>>> requests.get('https://api.github.com/user', auth=('user', 'pass'))
<Response [200]>
Providing the credentials in a tuple like this is exactly the same as the HTTPBasicAuth example above.
I'm getting the following when sending a very large POST to a Flask application.
Logs:
restful stderr | /usr/local/lib/python2.7/dist-packages/werkzeug/filesystem.py:63: BrokenFilesystemWarning: Detected a misconfigured UNIX filesystem: Will use UTF-8 as filesystem encoding instead of 'ANSI_X3.4-1968'
BrokenFilesystemWarning)
restful stderr | 172.19.0.5 - - [25/Apr/2017 00:05:40] "POST /ml/source/ HTTP/1.1" 500 -
restful stderr | Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
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 "/opt/fish/bizco/ml/restful.py", line 49, in index
job = q.enqueue_call(func=process_request, args=(postObject,), result_ttl=5000, timeout=36000)
File "/usr/local/lib/python2.7/dist-packages/rq/queue.py", line 216, in enqueue_call
job = self.enqueue_job(job, at_front=at_front)
File "/usr/local/lib/python2.7/dist-packages/rq/queue.py", line 282, in enqueue_job
pipe.execute()
File "/usr/local/lib/python2.7/dist-packages/redis/client.py", line 2641, in execute
return execute(conn, stack, raise_on_error)
File "/usr/local/lib/python2.7/dist-packages/redis/client.py", line 2495, in _execute_transaction
connection.send_packed_command(all_cmds)
File "/usr/local/lib/python2.7/dist-packages/redis/connection.py", line 556, in send_packed_command
(errno, errmsg))
ConnectionError: Error 104 while writing to socket. Connection reset by peer.
Route Code:
#app.route('/zebra/', methods=['GET', 'POST'])
def index():
print "/zebra/ called:")
if request.method == "POST":
state = True
if request.headers['Content-Type'] == 'application/x-msgpack':
print 'Found MsgPack'
postObject = msgpack.unpackb(request.data)
else:
print 'Content type not correct'
state = False
if state == True:
json = jsonify(...)
else:
# return an error
json = jsonify...)
return json
The POST object contains a MessagePack encoded payload, but it never enters my route handler. I see no log statement inside the handler block.
This only seems to happen when the payload is above 200MB. How do I get flask to store handle properly?
I have unittested all the methods from my flask-restful API module. Now I want to test get method by actually making the API call. I expect error 400 from this test.
My resource class
class Response(Resource):
#marshal_with(response_params_get_responses_on_job)
def get(self, filter_name=None):
try:
response = self.process_get_request(filter_name)
if not response['users']:
raise MyValidationError("No data found")
return response
except MyValidationError as err:
abort(404, message=err)
except ValueError as mistake:
abort(400, message=mistake)
My Unittest
# TODO - Failing!
#mock.patch('application.resources.response.Response.process_get_request', autospec=True)
def test_get_400(self, process_get_request_mock):
process_get_request_mock.side_effect = ValueError("some error")
app = Flask(__name__)
app.debug = True
api = Api(app, prefix='/api/v2')
api.add_resource(Response, '/user/responses', endpoint='job_responses')
api.init_app(app)
with app.test_client() as client:
resp = client.get('/api/v2/user/responses',
environ_base={'HTTP_USER_AGENT': 'Chrome'},
headers={'Content-type': 'application/json'})
self.assertEqual(resp.status_code, 400)
My test fails because the response I get is error 500
AssertionError: 500 != 400
Stacktrace
Failure
Traceback (most recent call last):
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/mock.py", line 1201, in patched
return func(*args, **keywargs)
File "/home/hussain/workspace/my-app/tests/unittests/test_Response.py", line 38, in test_get_400
headers={'Content-type': 'application/json'})
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/werkzeug/test.py", line 774, in get
return self.open(*args, **kw)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/testing.py", line 108, in open
follow_redirects=follow_redirects)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/werkzeug/test.py", line 742, in open
response = self.run_wsgi_app(environ, buffered=buffered)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/werkzeug/test.py", line 659, in run_wsgi_app
rv = run_wsgi_app(self.application, environ, buffered=buffered)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/werkzeug/test.py", line 867, in run_wsgi_app
app_rv = app(environ, start_response)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 267, in error_router
return self.handle_error(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 267, in error_router
return self.handle_error(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py", line 1363, in handle_user_exception
assert exc_value is e
AssertionError
By putting a debug point in get method, I see that the execution goes till abort(400, message=mistake).
Then what is going on? Why does my test fail?
For all the time I assumed the issue was with my unit test. I was wrong!
The issue was in my code. And as Michele said my test has found it.
The message kwarg in abort method is expected to be a string, and instead I was passing it the exception object. So I was getting an exception on the abort line.
So I corrected it
abort(400, message=mistake.message)
Alternatively I can also write
abort(400, message=str(mistake))
Now my test is passing.