This question already has answers here:
Return JSON response from Flask view
(15 answers)
Closed 6 years ago.
Back again here with a flask question. I am a beginner and learn some awesome things from reddit (how to legit code).
Here is my code that I have grabbed certain information from an API that I am now trying to host locally through flask.
from flask import Flask, render_template
import httplib
import json
app = Flask(__name__)
#app.route('/')
def index():
connection = httplib.HTTPConnection('api.football-data.org')
headers = {'X-Auth-Token': 'this is my api token here', 'X-Response-Control': 'minified'}
connection.request('GET', '/v1/competitions/426/leagueTable', None, headers)
response = json.loads(connection.getresponse().read().decode())
return response
if __name__ == '__main__':
app.run()
When I run 127.0.0.1:5000 I get:
Internal Server Error
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.
Here is what my server is telling me!
MacBooks-MBP:Football macbookpro13$ python Footy_Web.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[2016-12-20 13:58:17,493] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/Library/Python/2.7/site-packages/flask/app.py", line 1642, in full_dispatch_request
response = self.make_response(rv)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1746, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 847, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 57, in _run_wsgi_app
return _run_wsgi_app(*args)
File "/Library/Python/2.7/site-packages/werkzeug/test.py", line 871, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'dict' object is not callable
127.0.0.1 - - [20/Dec/2016 13:58:17] "GET / HTTP/1.1" 500 -
I should mention this code works outside of the flask framework!
You need to return a valid HTTP response. To do so, you can use jsonify like below:
return jsonify(response)
Do not forget to import jsonify like this:
from flask import jsonify
jsonify() returns a flask.Response() object.
You can also use json.dumps(), but in this case you need to add a http status code and a Content-Type header to return a valid HTTP response:
return json.dumps(response), 200, {'content-type': 'application/json'}
Related
I am using waitress on IIS with Flask.
I have a route that sets a session as follows
#gp_clinicals_bp.route("/setting", methods=["POST","GET"])
def gp_clinicals():
session["gp_clinicals_meds_repeat"] = "123456"
return session["gp_clinicals_meds_repeat"]
This returns, unsurprisingly:
123456
I have another route as follows:
#gp_clinicals_bp.route("/testing", methods=["POST","GET"])
def gp_clinicals_test():
return session["gp_clinicals_meds_repeat"]
Now, I get nothing back and the following in the error log
2022-08-02 20:03:51,126 - ERROR - app.py - log_exception - 1455 - Exception on /gp-clinicals/medication-repeat [GET]
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\flask\app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python310\lib\site-packages\flask\app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python310\lib\site-packages\flask\app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python310\lib\site-packages\flask\app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "E:\Apps\dev\digital\gp_clinicals\gp_clinicals.py", line 158, in gp_clinicals_medication_repeat
return str(session["gp_clinicals_meds_repeat"])
KeyError: 'gp_clinicals_meds_repeat'
2022-08-02 20:03:51,128 - ERROR - __init__.py - handle_error_500 - 92 - 500 Internal Server Error: 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.
I'm the only one on the server. Below is a snippet from my initilisation file:
"""Initialize Flask app."""
import logging
import os
from logging.handlers import RotatingFileHandler
from flask import Flask, render_template, flash,request
from flask_session import Session
from flask_assets import Environment
from config import Config
if Config.FLASK_ENV == "development" and Config.DD_SERVICE:
patch_all()
sess = Session()
def init_app():
"""Create Flask application."""
app = Flask(__name__, instance_relative_config=False)
app.config["CACHE_TYPE"] = "null"
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config["SESSION_TYPE"] = "filesystem"
app.config.from_object("config.Config")
assets = Environment()
assets.init_app(app)
sess.init_app(app)
What's going wrong? In the flask_session folder I am seeing files being created
Any advice? I tried using single apostophes instead of quotes but no go there either
The site in IIS is running through a reverse proxy in IIS - could that be doing it?
I have been really stumped on this, been out of this game of web dev/python for a bit. I had a previously working Azure app service running this website, we did a minor HTML spelling change and re deployed. I am assuming some dependency got updated and now its broken. I don't know if this is a packaging version issue or if I have a missing import for my flask app.
I am getting a NameError: name 'Markup' is not defined error when trying to load a static html page. My app starts up just fine but I can't load the actual web pages.
Full Traceback
Traceback (most recent call last):
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 2095, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 2080, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask_cors\extension.py", line 165, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask_cors\extension.py", line 165, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\St**\PycharmProjects\**Site-portfolio\application.py", line 32, in index
return render_template("//index.html")
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\templating.py", line 147, in render_template
ctx.app.update_template_context(context)
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask\app.py", line 756, in update_template_context
context.update(func())
File "C:\Users\St**\PythonProjects\**Site-Portfolio\lib\site-packages\flask_recaptcha.py", line 59, in get_code
return dict(recaptcha=Markup(self.get_code()))
NameError: name 'Markup' is not defined
127.0.0.1 - - [08/Apr/2022 17:02:51] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 304 -
127.0.0.1 - - [08/Apr/2022 17:02:51] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 304 -
127.0.0.1 - - [08/Apr/2022 17:02:51] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 304 -
Process finished with exit code 0
Here is my code:
from flask import Flask, request, render_template, flash
from flask_mail import Mail, Message
from flask_cors import CORS, cross_origin
from flask_recaptcha import ReCaptcha
import requests
import json
import os
app = Flask(__name__, static_folder='static', static_url_path='')
recaptcha = ReCaptcha(app=app)
app.config['RECAPTCHA_ENABLED'] = True
app.config['RECAPTCHA_PUBLIC_KEY'] = '***********************'
app.config['RECAPTCHA_PRIVATE_KEY'] = '****************************'
#app.route('/', methods=['GET'])
def index():
return render_template("//index.html")
#app.route('/contact-us', methods=['GET'])
#app.route('/contact', methods=['GET', 'POST'])
def contact():
if request.method == 'POST':
r = requests.post('https://www.google.com/recaptcha/api/siteverify',
data={'secret': '***********',
'response': request.form['g-recaptcha-response']})
google_response = json.loads(r.text)
if google_response['success']:
contact_form = {'name': request.form['name'],
'email': request.form['email'],
'message': request.form['message']}
msg = Message(subject='Contact from website',
sender=contact_form['email'],
recipients=['*************'],
body=contact_form['message'])
mail.send(msg)
flash('Success, we will respond within at least 24 hours.')
return render_template('contact.html')
else:
flash('failed to submit, please retry or contact us at ************')
return render_template('contact.html')
return render_template('contact.html')
if __name__ == '__main__':
app.run()
My requirements.txt for package version
Flask>=1.0.2
jinja2>=2.11.3
Flask-Mail>=0.9.1
Flask-Cors>=3.0.9
Flask-Admin>=1.5.2
Flask-ReCaptcha>=0.4.2
Flask-SQLAlchemy>=2.3.2
Flask-WTF>=0.14.2
SQLAlchemy>=1.3.0
requests>=2.20.0
Flask-Login>=0.4.1
Werkzeug>=0.15.3
Flask-ReCaptcha is a very old project. The last update of Flask-ReCaptcha is on 2016. You'd better not use it.
Back to the error log itself, Flask-ReCaptcha has code like from jinja2 import Markup. But, since jinja2==3.1.0, Markup's position has changed. Try pip install jinja2==3.0.0`.
You will probably meet other problems as Flask-ReCaptcha is really old.
Go to Python installation folder
Go to Lib > site-packages
Open flask_recaptcha.py
You'll see something like this:
try:
from flask import request
from jinja2 import Markup
import requests
except ImportError as ex:
print("Missing dependencies")
Change it to:
try:
from flask import request
from markupsafe import Markup
import requests
except ImportError as ex:
print("Missing dependencies")
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.
I have a middleware in my Flask app that is used to authenticate a JSON Web Token coming in the header of the request and is checking to verify it, below is my middleware class:
class AuthMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
path = environ.get('PATH_INFO')
if path != '/authenticate' or path != '/token':
token = environ.get('HTTP_X_ACCESS_TOKEN')
verfied_token = verify_token(token)
if verfied_token is False:
abort(401)
elif verfied_token is True:
# payload = get_token_payload(token)
# check_permissions(payload)
pass
return self.app(environ, start_response)
verify_token() is a function that will return True or False, and if it returns False, I want it to abort with an error 401. However, it aborts with an error 500:
127.0.0.1 - - [25/Mar/2015 11:37:25] "POST /role HTTP/1.1" 500 -
Error on request:
Traceback (most recent call last):
File "/ENV/lib/python2.7/site-packages/werkzeug/serving.py", line 180, in run_wsgi
execute(self.server.app)
File "/ENV/lib/python2.7/site-packages/werkzeug/serving.py", line 168, in execute
application_iter = app(environ, start_response)
File "/ENV/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/middleware.py", line 24, in __call__
return self.app(environ, start_response)
File "/ENV/lib/python2.7/site-packages/werkzeug/exceptions.py", line 605, in __call__
raise self.mapping[code](*args, **kwargs)
BadRequest: 400: Bad Request
In my views, I abort a 401 like it should, but here it seems to be a problem. What should I do?
The middleware you've shown runs some other code and then calls the wrapped Flask application. However, abort raises exceptions that Flask handles, but aren't handled by WSGI directly. Since you're not in the Flask application yet, it can't handle the exception.
A much easier way would be to do this check inside the Flask app. Create a before_request handler that does basically the same thing as the middleware, except you can use flask.request rather than needing to parse the path and headers yourself.
from flask import request, abort
#app.before_request
def check_auth_token():
if request.path in ('/authenticate', '/token'):
return
token = request.headers.get('X-ACCESS-TOKEN')
if not verify_token(token):
abort(401)
check_permissions(get_token_payload(token))
If you do want to use WSGI middleware for this, you need to create the response yourself. Conveniently, Werkzeug's exceptions behave like WSGI applications, so it's straightforward to use them.
from werkzeug.exceptions import Unauthorized
# in place of abort(401) in the middleware
return Unauthorized()(environ, start_response)
You can also use abort still by catching the exceptions it raises (which, again, are WSGI applications).
from werkzeug.exceptions import abort, HTTPException
# werkzeug.exceptions.abort is the same as flask.abort
try:
abort(401)
except HTTPException as e:
return e(environ, start_response)
I am trying to use the Python requests module to issue Http GET commands to access some REST based APIs. The urls are working fine on a RESTClient but when I use the same url in python, I get a connection error.
The code I am trying to execute is:
payload={"mac":new_mac,"token":token}
userloginurl="http://192.168.1.40:9119/uid"
r=requests.get(userloginurl,params=payload)
print(r.url)
If I test this url using RESTClient, I get a 200 OK status code in the response header along with some more fields.
But this is not working with python requests. The traceback of the error is shown below:
Traceback (most recent call last):
File "getAPids.py", line 34, in <module>
r=requests.get(userloginurl,params=payload)
File "C:\Users\garvitab\python\lib\site-packages\requests\api.py", line 65, in
get
return request('get', url, **kwargs)
File "C:\Users\garvitab\python\lib\site-packages\requests\api.py", line 49, in
request
response = session.request(method=method, url=url, **kwargs)
File "C:\Users\garvitab\python\lib\site-packages\requests\sessions.py", line 4
61, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\garvitab\python\lib\site-packages\requests\sessions.py", line 5
73, in send
r = adapter.send(request, **kwargs)
File "C:\Users\garvitab\python\lib\site-packages\requests\adapters.py", line 4
15, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("''",
))
I looked up for the cause of the problem. Possibly, the response received is not formatted correctly. Is there a way to handle this problem?
Thanks in advance.
The problem was with the url. This connection was meant to be established over https and I was using http in the python script. Hence the issue.
Have you actually checked, what gets send over the wire? I suppose you might have to convert your dictionary to a JSON string by yourself, or use the json= keyword instead of payload=. See http://docs.python-requests.org/en/latest/user/quickstart/#custom-headers for details. This may do the trick:
import json
payload = json.dumps({"mac":new_mac,"token":token})
userloginurl = "http://192.168.1.40:9119/uid"
r = requests.get(userloginurl, data=payload)
print(r.url)
I was getting the same error and spent hours on it. I found that you cannot call the flask server in a client using "Localhost". It has to be "127.0.0.1"
#server
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run(debug=True)
Now the client causing the error:
#client
import requests
x = requests.get('http://localhost:5000') # change it to 127.0.0.1
print(x.text)