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'))
Related
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 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'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)})
I've get UnicodeEncodeError, when I try to create model instance with unicode field using curl
Here's my code, I've put it in one file for simplicity:
import flask
import flask.ext.sqlalchemy
import flask.ext.restless
from flask import send_from_directory
from sqlalchemy import Column, UnicodeText
from sqlalchemy.ext.declarative import declarative_base
app = flask.Flask(__name__, static_url_path='')
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://scott:tiger#localhost:5432/db'
db = flask.ext.sqlalchemy.SQLAlchemy(app)
Base = declarative_base()
class Tag(Base):
__tablename__ = 'tags'
name = Column(UnicodeText, primary_key=True)
# debug only
#app.route('/')
def index():
return send_from_directory('templates', 'index.html')
if __name__ == '__main__':
manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
# Create API endpoints, which will be available at /api/<tablename> by
# default. Allowed HTTP methods can be specified as well.
manager.create_api(Tag, methods=['GET', 'POST', 'DELETE'])
# start the flask loop
app.run(host='0.0.0.0', debug=True)
When I try to create model, using curl:
curl -i -H "Content-Type: application/json;charset=utf-8" -X POST -d '{"name": "ащьф"}' http://127.0.0.1:5000/api/tags
I get following error:
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 "/usr/local/lib/python2.7/dist-packages/flask_restless/views.py", line 139, in decorator
return func(*args, **kw)
File "/usr/local/lib/python2.7/dist-packages/mimerender.py", line 227, in wrapper
result = target(*args, **kwargs)
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)
File "/usr/local/lib/python2.7/dist-packages/flask_restless/views.py", line 1230, in post
primary_key = str(result[primary_key_name(instance)])
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)
How can I avoid this issue? I think I need to create preprocessors, which will be encode data correctly, or is there more easier way to fix this problem?
This looks like a bug with Flask-Restless. I noticed you've already submitted an issue there. If you find the solution, open a pull request and update us on the answer.
I'm trying to make Flask work with CouchDB but still can't for obscure reasons.
I just started a minimal application so to nail down problems more easily, still to no avail.
Here's my app code:
import datetime
from couchdbkit import *
from flask import Flask
app = Flask(__name__)
class Post(Document):
title = StringProperty()
content = StringProperty()
server = Server()
db = server.get_or_create_db('test')
Post.set_db(db)
post = **Post.view('post/all')**
#app.route('/')
def index():
return post
if __name__ == '__main__':
app.run(debug=True)
And here's the debug output from Flask:
TypeError: __call__() takes exactly 1 argument (3 given)
And here the traceback:
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 1478, in full_dispatch_request
response = self.make_response(rv)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1577, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/wrappers.py", line 824, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/usr/local/lib/python2.7/dist-packages/werkzeug/test.py", line 854, in run_wsgi_app
app_iter = app(environ, start_response)
TypeError: __call__() takes exactly 1 argument (3 given)
if I run Post.view('post/all') outside of the route definition it works..
I've also tried to follow the official tutorial line by line, but I'm assuming it's outdated or the author assumes I've modules he didn't mention..?
Your view doesn't return a string, tuple or WSGI response.
Flask sees it is not a string or tuple, so it tries to treat it as a WSGI response, which means it'll get called with environ and start_response arguments.
Return an actual valid response from your index view instead of the post object. See the About Responses section of the Flask Quickstart.
You might want to use the Flask-CouchDB integration package.