Flask-restless create model with unicode field - python

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.

Related

#jwt_required decorator not working on flask endpoint

I have a Flask Blueprint endpoint, defined as:
from flask_jwt import JWT, jwt_required, current_identity
my_api = Blueprint('MyApi', __name__)
#my_api.route("/MyApi", methods=['GET'])
#jwt_required()
def get_my_api():
return make_response()
I have JWT configuration done in main API configuration file (other than the file that has the endpoint defined above):
app = Flask(__name__)
app.register_blueprint(my_api)
jwt = JWTManager(app)
So even though I am able to generate access_token and refresh_token but upon hitting the decorator jwt_required, I get this exception:
File "/home/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/home/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/home/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/lib/python3.6/site-packages/flask_jwt/__init__.py", line 177, in decorator
_jwt_required(realm or current_app.config['JWT_DEFAULT_REALM'])
File "/home/lib/python3.6/site-packages/flask_jwt/__init__.py", line 152, in _jwt_required
token = _jwt.request_callback()
File "/home/lib/python3.6/site-packages/werkzeug/local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
File "/home/lib/python3.6/site-packages/werkzeug/local.py", line 307, in _get_current_object
return self.__local()
File "/home/lib/python3.6/site-packages/flask_jwt/__init__.py", line 28, in <lambda>
_jwt = LocalProxy(lambda: current_app.extensions['jwt'])
KeyError: 'jwt'
Am I doing something wrong? Thanks.
It looks like you are mixing two different extensions. from flask_jwt import JWT, jwt_required, current_identity is the flask-jwt extension, and the jwt = JWTManager(app) is flask-jwt-extended extension. Flask-jwt has been abandoned for a long time now, so I would recommend using flask-jwt-extended in your codebase: https://flask-jwt-extended.readthedocs.io/en/stable/basic_usage.html

Python Flask routing - how to get parameter from MethodView class

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'))

KeyError: u'FLASK_AUTH_REALM'

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()

<Response [200]> is not JSON serializable

following the document conversion API example trying to use Flask to convert msword document to text, but it does not work.
Here is the code
import os, json, requests
from flask import Flask, jsonify
from watson_developer_cloud import DocumentConversionV1
app = Flask(__name__) #create flask instance
#app.route('/')
def Welcome():
v = json.loads(os.getenv('VCAP_SERVICES'))
svcName = 'document_conversion'
svc = v[svcName][0]['credentials']
url = svc['url']
user = svc['username']
password = svc['password']
document_conversion = DocumentConversionV1(username=user, password=password,version='2015-12-15')
# Example of retrieving html or plain text
with open('./doc.docx', 'rb') as document:
config = {'conversion_target': DocumentConversionV1.NORMALIZED_TEXT}
print(json.dumps(document_conversion.convert_document(document=document, config=config),indent=2))
if __name__ == "__main__":
port = os.getenv('VCAP_APP_PORT', '5000')
app.run(host='0.0.0.0', port=int(port),debug=True)
Here is the runtime log
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/vcap/app/.heroku/python/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/vcap/app/welcome.py", line 39, in Welcome
password = svc['password']
document_conversion = DocumentConversionV1(username=user, password=password,version='2015-12-15')
# Example of retrieving html or plain text
with open('./doc.docx', 'rb') as document:
config = {'conversion_target': DocumentConversionV1.NORMALIZED_TEXT}
print(json.dumps(document_conversion.convert_document(document=document, config=config),indent=2))
if __name__ == "__main__":
port = os.getenv('VCAP_APP_PORT', '5000')
File "/home/vcap/app/.heroku/python/lib/python3.5/json/__init__.py", line 237, in dumps
**kw).encode(obj)
File "/home/vcap/app/.heroku/python/lib/python3.5/json/encoder.py", line 201, in encode
chunks = list(chunks)
File "/home/vcap/app/.heroku/python/lib/python3.5/json/encoder.py", line 436, in _iterencode
o = _default(o)
File "/home/vcap/app/.heroku/python/lib/python3.5/json/encoder.py", line 180, in default
raise TypeError(repr(o) + " is not JSON serializable")
The documentation appears to be out of date. The object returned is a Response object, as seen in the Requests library. In my experience, you can just use .text to get a string representing the JSON. I should say, you might have to use the .json representation to get something you can call .dumps() on.

Flask: token-based authorization

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)

Categories

Resources