click locale error in flask tutorial
I'm trying to follow the flask tutorial in Pythonista, but I'm having a problem at the database configuration step. My problem is that it uses click commands. First off, there doesn't seem to be a way to invoke these in Pythonista. I managed to solve that problem by running the relevant function in code, however:
app = create_app() db.init_db_command(app)
So that's fine. Unfortunately, when I run this code, I get this:
RuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment. Consult https://click.palletsprojects.com/en/7.x/python3 for mitigation steps.
Additional information: on this system no suitable UTF-8 locales were discovered. This most likely requires resolving by reconfiguring the locale system.
Checking out that link, it seems I that I need to do:
export LC_ALL=en_US.utf-8 export LANG=en_US.utf-8
Once again, I need a way to do this in code, so: (many browser tabs later...)
import os os.environ['LC_ALL'] = 'en_US.utf-8' os.environ['LANG'] = 'en_US.utf-8'
...and I get the same error. But it has some new stuff at the end!
Click discovered that you exported a UTF-8 locale but the locale system could not pick up from it because it does not exist. The exported locale is "en_US.utf-8" but it is not supported.
How do I know what locales are supported then?
Sigh... yes, once again, I can't do this. so:
import locale locale.locale_alias
which apparently does not quite map to locale -a but it's the best I can come up with. That gives me a gigantic list of stuff, which I picked through and tried every alias that looked like it might be English UTF-8. Nothing worked.
So... now I think, somehow, the needed locale is simply not installed (although that does seem odd!). However... installing a new locale seems like something Apple is not going to let me do. Which brings me to my actual question:
Can I install a locale using Pythonista? Is this possible? If so, how?
OR is there some other way to solve this problem?
OR if this is really impossible, how can I refactor the flask tutorial to not use click?
So it turns out those error messages are more like guidelines than actual rules, and you can turn them off with
from click import core core._verify_python3_env = lambda: None
(this seems totally hacky and might cause unexpected behavior down the line, but whatever, it's working so far)
So that works, but then I realized that the way I was trying to call my function was totally stupid and was never going to work. Thankfully stackoverflow saved me. Following the instructions at the link, I'm making progress, only now it's telling me I don't have FLASK_APP defined - but wait, I know this one:
import os os.environ['FLASK_APP'] = 'flaskr'
It works! Final code:
import os from click import core from flaskr import db # flaskr is the package containing the code from the tutorial def call_click_command(cmd, *args, **kwargs): # see stackoverflow link above for code # I also put this in a separate file but you do you os.environ['FLASK_APP'] = 'flaskr' core._verify_python3_env = lambda: None call_click_command(db.init_db_command)
(and to run the app, in case anyone needs it):
from flaskr import create_app app = create_app() app.run(use_reloader=False, debug=True)
mikael last edited by
@mikael ah, I see. Took me a bit to figure out how that would work in this case, but it seems you can do:
from click import core from flaskr import create_app from flaskr import db core._verify_python3_env = lambda: None app = create_app() with app.app_context(): db.init_db_command()
(note: that call_click_command function is totally unnecessary, even in the previous implementation! Not sure why I thought I needed it... guess troubleshooting just takes you down a lot of garden paths, haha)
Thanks for the tip about bottle! I'll definitely look into it.
mikael last edited by
@egehman, do you still need the click import and the lambda?
@mikael unfortunately yes, it seems you need it if the function has the @click.command decorator. Although in this case init_db_command is just a thin wrapper over another function init_db, so you can get around it by just calling init_db directly instead.
Also I think I was wrong that you don't need the environment variable, as well, because I just tried running that code again and it didn't work. I'm guessing I must have had the variable still hanging around from a previous run, so it looked like I didn't need it, but alas. Again though, in this particular case, you can get around it by using init_db and wrapping in the app context. If you're using the command directly though, wrapping with the app context does nothing; you need the environment variable. Hope that makes sense.