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)})
Related
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'))
I impemented today https://pypi.python.org/pypi/flask-htpasswd/ on my site and I'm getting KeyError: u'FLASK_AUTH_REALM' error. What I did was putting app.config's before Class so it looks like here:
from .utils import now, dottedQuadToNum, get_blacklist
log = logging.getLogger(__name__)
compress = Compress()
import flask
from flask_htpasswd import HtPasswdAuth
app = flask.Flask(__name__)
app.config['FLASK_HTPASSWD_PATH'] = 'C:/.htpasswd'
app.config['FLASK_SECRET'] = 'Hey Hey Kids, secure me!'
htpasswd = HtPasswdAuth(app)
class Pogom(Flask):
def __init__(self, import_name, **kwargs):
And here's an error that I'm getting
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\flask\app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Python27\lib\site-packages\flask\app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "C:\Python27\lib\site-packages\flask\app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Python27\lib\site-packages\flask\app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python27\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python27\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Python27\lib\site-packages\flask_htpasswd.py", line 205, in decorated
return self.auth_failed()
File "C:\Python27\lib\site-packages\flask_htpasswd.py", line 159, in auth_failed
current_app.config['FLASK_AUTH_REALM']
KeyError: u'FLASK_AUTH_REALM'
You do not show the complete code. I guess you want to declare the Pogom class which derive from Flask class, then declare an instance from Pogom, and execute pogom.run.
According to the exception stack, I think missing FLASK_AUTH_REALM key in app.config.
Why the FLASK_AUTH_REALM missing?
First, the flask_htpasswd extension will set the default value for FLASK_AUTH_REALM in init_app function.
But you declare one new class, and may be instance one app from Pogom and app.run. the flask_htpasswd just initialize the old app which is the instance Flask, and the new app does not have proper FLASK_AUTH_REALM key in config.
So, I try to show some code like below:
from flask import Flask
from flask_htpasswd import HtPasswdAuth
class Pogom(Flask):
def __init__(self, import_name, **kwargs):
# missing some special code
super(Pogom, self).__init__(import_name, **kwargs)
htpasswd = HtPasswdAuth()
def create_app():
app = Pogom(__name__)
app.config['FLASK_HTPASSWD_PATH'] = 'C:/.htpasswd'
app.config['FLASK_SECRET'] = 'Hey Hey Kids, secure me!'
htpasswd.init_app(app)
return app
if __name__ == '__main__':
app = create_app()
# just for demonstration
#app.route('/')
#htpasswd.required
def index():
return "Hello"
app.run()
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'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.
I am building a basic app with Flask: it has a unique route that requests just a token authentication, i.e. if the token provided in the headers is correct, then the request is satisfied. To do so, I installed both Flask and Flask-Security. This is a snippet of my app:
from flask import Flask
from flask.ext.security import auth_token_required
from flask.ext.security import Security
app = Flask(__name__)
app.config['SECURITY_TOKEN_AUTHENTICATION_KEY'] = 'mytoken'
security = Security(app)
#app.route('/myurl')
#auth_token_required
def myrequest():
return 'OK'
if __name__ == '__main__':
app.run(debug=True)
I test it by running:
$ curl -H 'Authorization: Token token="mytoken"' localhost:5000/myurl
or even:
$ curl localhost:5000/myurl
However, I get the following error:
Traceback (most recent call last):
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask_security/decorators.py", line 113, in decorated
if _check_token():
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask_security/decorators.py", line 50, in _check_token
header_key = _security.token_authentication_header
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask_security/decorators.py", line 24, in <lambda>
_security = LocalProxy(lambda: current_app.extensions['security'])
KeyError: 'security'
Do you know where the error lies? Is it in the app or in some conflicts among the Flask libraries?
EDIT: added Security(app) initialization
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)