I'm developing a python web application on Heroku and I'm facing a problem with the locale settings.
My aim ist to format a python datetime object as a string like this
import datetime
now = datetime.datetime.now()
print now.strftime('%a %d %B %Y') # output: Sat 14 July 2012
but in different languages.
On my local machine I use therefore:
import locale
locale.setlocale(locale.LC_ALL, '')
or locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') for specific languages.
On my local machine this works and I get the date in the right language but on Heroku it fails and all I get is a locale.Error: unsupported locale settings.
Am I doing something wrong or is it permitted to change locale setting in a python app on Heroku?
Thanks.
You can see available locales by running:
$ heroku run "locale -a"
Running `locale -a` attached to terminal... up, run.5061
aa_DJ.utf8
aa_ER
aa_ER#saaho
aa_ET
af_ZA.utf8
am_ET
an_ES.utf8
ar_AE.utf8
ar_BH.utf8
ar_DZ.utf8
ar_EG.utf8
ar_IN
ar_IQ.utf8
ar_JO.utf8
ar_KW.utf8
ar_LB.utf8
ar_LY.utf8
ar_MA.utf8
ar_OM.utf8
ar_QA.utf8
ar_SA.utf8
ar_SD.utf8
ar_SY.utf8
ar_TN.utf8
ar_YE.utf8
as_IN
ast_ES.utf8
az_AZ
be_BY#latin
be_BY.utf8
ber_DZ
ber_MA
bg_BG.utf8
bn_BD
bn_IN
bo_CN
bo_IN
br_FR.utf8
bs_BA.utf8
C
ca_AD.utf8
ca_ES.utf8
ca_ES.utf8#valencia
ca_FR.utf8
ca_IT.utf8
crh_UA
csb_PL
cs_CZ.utf8
cy_GB.utf8
da_DK.utf8
de_AT.utf8
de_BE.utf8
de_CH.utf8
de_DE.utf8
de_LI.utf8
de_LU.utf8
dv_MV
dz_BT
el_CY.utf8
el_GR.utf8
en_AG
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IN
en_NG
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZW.utf8
eo_US.utf8
eo.utf8
es_AR.utf8
es_BO.utf8
es_CL.utf8
es_CO.utf8
es_CR.utf8
es_DO.utf8
es_EC.utf8
es_ES.utf8
es_GT.utf8
es_HN.utf8
es_MX.utf8
es_NI.utf8
es_PA.utf8
es_PE.utf8
es_PR.utf8
es_PY.utf8
es_SV.utf8
es_US.utf8
es_UY.utf8
es_VE.utf8
et_EE.utf8
eu_ES.utf8
eu_FR.utf8
fa_IR
fi_FI.utf8
fil_PH
fo_FO.utf8
fr_BE.utf8
fr_CA.utf8
fr_CH.utf8
fr_FR.utf8
fr_LU.utf8
fur_IT
fy_DE
fy_NL
ga_IE.utf8
gd_GB.utf8
gl_ES.utf8
gu_IN
ha_NG
he_IL.utf8
hi_IN
hne_IN
hr_HR.utf8
hsb_DE.utf8
ht_HT
hu_HU.utf8
hy_AM
ia
id_ID.utf8
ig_NG
is_IS.utf8
it_CH.utf8
it_IT.utf8
iu_CA
ja_JP.utf8
ka_GE.utf8
kk_KZ.utf8
km_KH
kn_IN
ko_KR.utf8
ks_IN
ks_IN#devanagari
ku_TR.utf8
kw_GB.utf8
ky_KG
la_AU.utf8
lg_UG.utf8
li_BE
li_NL
lo_LA
lt_LT.utf8
lv_LV.utf8
mai_IN
mg_MG.utf8
mi_NZ.utf8
mk_MK.utf8
ml_IN
mn_MN
mr_IN
ms_MY.utf8
mt_MT.utf8
nan_TW#latin
nb_NO.utf8
nds_DE
nds_NL
ne_NP
nl_AW
nl_BE.utf8
nl_NL.utf8
nn_NO.utf8
nr_ZA
nso_ZA
oc_FR.utf8
om_ET
om_KE.utf8
or_IN
pa_IN
pap_AN
pa_PK
pl_PL.utf8
POSIX
pt_BR.utf8
pt_PT.utf8
ro_RO.utf8
ru_RU.utf8
ru_UA.utf8
rw_RW
sa_IN
sc_IT
sd_IN
sd_IN#devanagari
se_NO
shs_CA
si_LK
sk_SK.utf8
sl_SI.utf8
so_DJ.utf8
so_ET
so_KE.utf8
so_SO.utf8
sq_AL.utf8
sr_ME
sr_RS
sr_RS#latin
ss_ZA
st_ZA.utf8
sv_FI.utf8
sv_SE.utf8
ta_IN
te_IN
tg_TJ.utf8
th_TH.utf8
ti_ER
ti_ET
tk_TM
tlh_GB.utf8
tl_PH.utf8
tn_ZA
tr_CY.utf8
tr_TR.utf8
ts_ZA
tt_RU
tt_RU#iqtelif
ug_CN
uk_UA.utf8
ur_PK
uz_UZ#cyrillic
uz_UZ.utf8
ve_ZA
vi_VN
wa_BE.utf8
wo_SN
xh_ZA.utf8
yi_US.utf8
yo_NG
zh_CN.utf8
zh_HK.utf8
zh_SG.utf8
zh_TW.utf8
zu_ZA.utf8
To fix your issue try
locale.setlocale(locale.LC_ALL, 'de_DE.utf8')
or
heroku config:add LANG=de_DE.utf8
Only English locales are installed on the Heroku environment by default. So far there seems to be no way to install additional locales. Your best bet will be to implement your own formatting functions for the languages you support.
This is an older question, but I thought it worth mentioning here that Heroku added support for installing additional locales in September 2018.
To do this, commit a .locales file containing the locales you'd like to set up:
de_DE
fr_FR
Then add the locale buildpack:
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-locale
For more information, check the buildpack's GitHub repository.
Related
I have a Django webapp, and I'd like to check if it's running on the Heroku stack (for conditional enabling of debugging, etc.) Is there any simple way to do this? An environment variable, perhaps?
I know I can probably also do it the other way around - that is, have it detect if it's running on a developer machine, but that just doesn't "sound right".
An ENV var seems to the most obvious way of doing this. Either look for an ENV var that you know exists, or set your own:
on_heroku = False
if 'YOUR_ENV_VAR' in os.environ:
on_heroku = True
more at: http://devcenter.heroku.com/articles/config-vars
Similar to what Neil suggested, I would do the following:
debug = True
if 'SOME_ENV_VAR' in os.environ:
debug = False
I've seen some people use if 'PORT' in os.environ: But the unfortunate thing is that the PORT variable is present when you run foreman start locally, so there is no way to distinguish between local testing with foreman and deployment on Heroku.
I'd also recommend using one of the env vars that:
Heroku has out of the box (rather than setting and checking for your own)
is unlikely to be found in your local environment
At the date of posting, Heroku has the following environ variables:
['PATH', 'PS1', 'COLUMNS', 'TERM', 'PORT', 'LINES', 'LANG', 'SHLVL', 'LIBRARY_PATH', 'PWD', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'DYNO', 'PYTHONHASHSEED', 'PYTHONUNBUFFERED', 'PYTHONHOME', 'HOME', '_']
I generally go with if 'DYNO' in os.environ:, because it seems to be the most Heroku specific (who else would use the term dyno, right?).
And I also prefer to format it like an if-else statement because it's more explicit:
if 'DYNO' in os.environ:
debug = False
else:
debug = True
First set the environment variable ON_HEROKU on heroku:
$ heroku config:set ON_HEROKU=1
Then in settings.py
import os
# define if on heroku environment
ON_HEROKU = 'ON_HEROKU' in os.environ
Read more about it here: https://devcenter.heroku.com/articles/config-vars
My solution:
$ heroku config:set HEROKU=1
These environment variables are persistent – they will remain in place across deploys and app restarts – so unless you need to change values, you only need to set them once.
Then you can test its presence in your app.:
>>> 'HEROKU' in os.environ
True
The most reliable way would be to set an environment variable as above.
If that's not possible, there are a few signs you can look for in the filesystem, but they may not be / are not foolproof
Heroku instances all have the path /app - the files and scripts that are running will be under this too, so you can check for the presence of the directory and/or that the scripts are being run from under it.
There is an empty directory /etc/heroku
/etc/hosts may have some heroku related domains added
~ $ cat /etc/hosts
<snip>.dyno.rt.heroku.com
Any of these can and may change at any moment.
Your milage may vary
DATABASE_URL environment variable
in_heroku = False
if 'DATABASE_URL' in os.environ:
in_heroku = True
I think you need to enable the database for your app with:
heroku addons:create heroku-postgresql:hobby-dev
but it is free and likely what you are going to do anyways.
Heroku makes this environment variable available when running its apps, in particular for usage as:
import dj_database_url
if in_heroku:
DATABASES = {'default': dj_database_url.config()}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
Not foolproof as that variable might be defined locally, but convenient for simple cases.
heroku run env
might also show other possible variables like:
DYNO_RAM
WEB_CONCURRENCY
but I'm not sure if those are documented like DATABASE_URL.
Short version: check that the time zone is UTC/GMT:
if not 'ORIGINAL_TIMEZONE' in os.environ:
f = os.popen('date +%Z')
tz = f.read().upper()
os.environ['ORIGINAL_TIMEZONE']=tz
tz = os.environ['ORIGINAL_TIMEZONE']
if tz != '' and (not 'utc' in tz.lower()) and (not 'gmt' in tz.lower()):
print 'Definitely not running on Heroku (or in production in general)'
else:
print 'Assume that we are running on Heroku (or in production in general)'
This is more conservative than if tz=='UTC\n': if in doubt, assume that we are in production. Note that we are saving the timezone to an environment variable because settings.py may be executed more than once. In fact, the development server executes it twice, and the second time the system timezone is already 'UTC' (or whatever is in settings.TIMEZONE).
Long version:
making absolutely sure that we never run on Heroku with DEBUG=True, and that we never run the development server on Heroku even with DEBUG=False. From settings.py:
RUNNING_DEV_SERVER = (len(sys.argv) > 1) and (sys.argv[1] == 'runserver')
DEBUG = RUNNING_DEV_SERVER
TEMPLATE_DEBUG = DEBUG
# Detect the timezone
if not 'ORIGINAL_TIMEZONE' in os.environ:
f = os.popen('date +%Z')
tz = f.read().upper()
os.environ['ORIGINAL_TIMEZONE']=tz
print ('DEBUG: %d, RUNNING_DEV_SERVER: %d, system timezone: %s ' % (DEBUG, RUNNING_DEV_SERVER, tz))
if not (DEBUG or RUNNING_DEV_SERVER):
SECRET_KEY = os.environ['SECRET_KEY']
else:
print 'Running in DEBUG MODE! Hope this is not in production!'
SECRET_KEY = 'DEBUG_INSECURE_SECRET_KEY_ae$kh(7b%$+a fcw_bdnzl#)$t88x7h2-p%eg_ei5m=w&2p-)1+'
# But what if we are idiots and are still somehow running with DEBUG=True in production?!
# 1. Make sure SECRET_KEY is not set
assert not SECRET_KEY in os.environ
# 2. Make sure the timezone is not UTC or GMT (indicating production)
tz = os.environ['ORIGINAL_TIMEZONE']
assert tz != '' and (not 'UTC' in tz) and (not 'GMT' in tz)
# 3. Look for environment variables suggesting we are in PROD
for key in os.environ:
for red_flag in ['heroku', 'amazon', 'aws', 'prod', 'gondor']:
assert not red_flag in key.lower()
assert not red_flag in os.environ[key].lower()
If you really want to run the development server on Heroku, I suggest you add an environment variable specifying the date when you can do that. Then only proceed if this date is today. This way you'll have to change this variable before you begin development work, but if you forget to unset it, next day you will still be protected against accidentally running it in production. Of course, if you want to be super-conservative, you can also specify, say, a 1-hour window when exceptions apply.
Lastly, if you decided to adopt the approach suggested above, while you are at it, also install django-security, add djangosecurity to INSTALLED_APPS, and add to the end of your settings.py:
if not (DEBUG or RUNNING_DEV_SERVER):
### Security
SECURE_SSL_REDIRECT = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 86400000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_BROWSER_XSS_FILTER = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True # May have problems with Ajax
CSRF_COOKIE_SECURE = True
Every time I run any python script (.py) in my Cygwin (bash) shell, I get a huge list of profling: ... :Skip. I don't think it's Cygwin-related, but something with my Python setup, which is installed from the official Cygwin repos & builds.
Python itself is functioning correctly but these messages clutter my output.
How can I fix/remove them?
[admin#Zbook ~/Desktop]λ python3.8 --version
Python 3.8.2
profiling:/usr/local/src/Python-3.8.2/Programs/python.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/getbuildinfo.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/acceler.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/grammar1.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/listnode.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/node.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/parser.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/token.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/myreadline.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/parsetok.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Parser/tokenizer.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/abstract.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/accu.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/boolobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/bytes_methods.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/bytearrayobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/bytesobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/call.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/capsule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/cellobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/classobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/codeobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/complexobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/descrobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/enumobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/exceptions.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/genobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/fileobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/floatobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/frameobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/funcobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/interpreteridobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/iterobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/listobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/longobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/dictobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/odictobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/memoryobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/methodobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/moduleobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/namespaceobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/object.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/obmalloc.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/picklebufobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/rangeobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/setobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/sliceobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/structseq.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/tupleobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/typeobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/unicodeobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/unicodectype.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Objects/weakrefobject.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/_warnings.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/Python-ast.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/asdl.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/ast.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/ast_opt.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/ast_unparse.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/bltinmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/ceval.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/codecs.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/compile.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/context.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/errors.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/frozenmain.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/future.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/getargs.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/getcompiler.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/getcopyright.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/getplatform.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/getversion.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/hamt.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/import.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/importdl.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/initconfig.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/marshal.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/modsupport.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/mysnprintf.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/mystrtoul.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pathconfig.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/peephole.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/preconfig.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pyarena.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pyfpe.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pyhash.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pylifecycle.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pymath.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pystate.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pythonrun.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pytime.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/bootstrap_hash.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/structmember.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/symtable.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/sysmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/thread.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/traceback.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/getopt.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pystrcmp.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pystrtod.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/pystrhex.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/dtoa.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/formatter_unicode.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/fileutils.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Python/dynload_shlib.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/getpath.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/main.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/gcmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/posixmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/errnomodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/pwdmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_sre.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_codecsmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_weakref.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_functoolsmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_operator.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_collectionsmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_abc.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/itertoolsmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/atexitmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/signalmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_stat.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/timemodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_threadmodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_localemodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_iomodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/iobase.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/fileio.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/bytesio.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/bufferedio.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/textio.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/stringio.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/faulthandler.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/_tracemalloc.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/hashtable.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/symtablemodule.gcda:Skip
profiling:/usr/local/src/Python-3.8.2/Modules/xxsubtype.gcda:Skip
#matzeri is right! Turns out I had an old & partial Python 3.8 installation which I compiled from source long ago and totally forgot about it!
Cited messages in the output are because of the --enable-optimizations and maybe the --disable-profiling compilation flags.
I used this bash script from Stack Exchange to clear this old compiled-from-source Python!
EDIT: I just realized, that when i'm not trying to print to console that variable, it works. Why?
I run into an issue related to displaying string label with utf chars. I set locale env in uwsgi ini file like this:
env =LC_ALL=en_US.UTF-8
env =LANG=en_US.UTF-8
and in wsgi.py:
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
When I run app code:
print (locale.getlocale(), locale.getpreferredencoding())
print locale.getdefaultlocale()
print "option_value", option_value
label = force_text(option_label)
print 'label', label #THIS FAILS
the output is:
(('en_US', 'UTF-8'), 'UTF-8')
('en_US', 'UTF-8')
option_value d
ERROR <stack trace>
print 'label', label
UnicodeEncodeError: 'ascii' codec can't encode character u'\u015b' in position 5: ordinal not in range(128)
The problem is not present when I run app via runserver in production environment.
Django 1.6.5 Python 2.7.6 Ubuntu 14.04 uWSGI 2.0.5.1
I just found answer here: http://chase-seibert.github.io/blog/2014/01/12/python-unicode-console-output.html
Realized that the console is responsible for that error, so exporting additional env variable in uwsgi config file solves the issue: env = PYTHONIOENCODING=UTF-8
for all in django when you want use unicode , like in forms and etc .. you must set a u in leading of your unicode that you want to be saved ! do this any where that your unicode have been saved !
in this case i think it is (option_label)
How do i get a basic web2py server up and running on
PythonAnywhere?
[update - 29/05] We now have a big button on the web tab that will do all this stuff for you. Just click where it says Web2Py, fill in your admin password, and you're good to go.
Here's the old stuff for historical interest...
I'm a PythonAnywhere developer. We're not massive web2py experts (yet?) but I've managed to get web2py up and running like this:
First download and unpack web2py:
wget http://www.web2py.com/examples/static/web2py_src.zip
unzip web2py_src.zip
Go to the PythonAnywhere "Web" panel and edit your wsgi.py. Add these lines:
import os
import sys
path = '/home/my_username/web2py'
if path not in sys.path:
sys.path.append(path)
from wsgihandler import application
replacing my_username with your username.
You will also need to comment out the last two lines in wsgi.py, where we have the default hello world web.py application...
# comment out these two lines if you want to use another framework
#app = web.application(urls, globals())
#application = app.wsgifunc()
Thanks to Juan Martinez for his instructions on this part, which you can view here:
http://web2py.pythonanywhere.com/
then open a Bash console, and cd into the main web2py folder, then run
python web2py.py --port=80
enter admin password
press ctrl-c
(this will generate the parameters_80.py config file)
then go to your Web panel on PythonAnywhere, click reload web app,
and things should work!
You can also simply run this bash script:
http://pastebin.com/zcA5A89k
admin will be disabled because of no HTTPS unless you bypass it as in the previous post. It will create a security vulnerability.
Pastebin was down, I retrieved this from the cache.
cd ~
wget -O web2py_srz.zip http://web2py.com/examples/static/web2py_src.zip
unzip web2py_src.zip
echo "
PATH = '/home/"`whoami`"/web2py'
import os
import sys
sys.stdout = sys.stderr
os.chdir(PATH)
if not './' in sys.path[:1]: sys.path.insert(0,'./')
from gluon.main import wsgibase as application
" > /var/www/wsgi.py
cd web2py
python -c "from gluon.main import save_password; save_password(raw_input('admin password: '),433)"
I have recently summarized my experience with deployment of Web2Py on PythonAnywhere here
Hope it helps
NeoToren
I'll try to add something new to the discussion. The EASIEST way I've found is to go here when you aren't logged in. This makes it so you don't have to mess around with the terminal:
https://www.pythonanywhere.com/try-web2py
Come up with a domain name, then you'll get redirected to a page showing your login information and created dashboard for that domain. From there just create an account so your app isn't erased after 24 hours. When you sign up, your app has a 3 month expiry date (if you're not paying). I believe this is a new policy. Then simply go to https://appname.pythonanywhere.com/admin and then enter the password you were given and then upload your Web2Py file into the dashboard and then visit the page.
I'm not sure how to upload a Web2Py app on PythonAnywhere for an existing account, but that's the easiest method I've found.
I have a small Python web application using the Cherrypy framework. I am by no means an expert in web servers.
I got Cherrypy working with Apache using mod_python on our Ubuntu server. This time, however, I have to use Windows 2003 and IIS 6.0 to host my site.
The site runs perfectly as a stand alone server - I am just so lost when it comes to getting IIS running. I have spent the past day Googling and blindly trying any and everything to get this running.
I have all the various tools installed that websites have told me to (Python 2.6, CherrpyPy 3, ISAPI-WSGI, PyWin32) and have read all the documentation I can. This blog was the most helpful:
http://whatschrisdoing.com/blog/2008/07/10/turbogears-isapi-wsgi-iis/
But I am still lost as to what I need to run my site. I can't find any thorough examples or how-to's to even start with. I hope someone here can help!
Cheers.
I run CherryPy behind my IIS sites. There are several tricks to get it to work.
When running as the IIS Worker Process identity, you won't have the same permissions as you do when you run the site from your user process. Things will break. In particular, anything that wants to write to the file system will probably not work without some tweaking.
If you're using setuptools, you probably want to install your components with the -Z option (unzips all eggs).
Use win32traceutil to track down problems. Be sure that in your hook script that you're importing win32traceutil. Then, when you're attempting to access the web site, if anything goes wrong, make sure it gets printed to standard out, it'll get logged to the trace utility. Use 'python -m win32traceutil' to see the output from the trace.
It's important to understand the basic process to get an ISAPI application running. I suggest first getting a hello-world WSGI application running under ISAPI_WSGI. Here's an early version of a hook script I used to validate that I was getting CherryPy to work with my web server.
#!python
"""
Things to remember:
easy_install munges permissions on zip eggs.
anything that's installed in a user folder (i.e. setup develop) will probably not work.
There may still exist an issue with static files.
"""
import sys
import os
import isapi_wsgi
# change this to '/myapp' to have the site installed to only a virtual
# directory of the site.
site_root = '/'
if hasattr(sys, "isapidllhandle"):
import win32traceutil
appdir = os.path.dirname(__file__)
egg_cache = os.path.join(appdir, 'egg-tmp')
if not os.path.exists(egg_cache):
os.makedirs(egg_cache)
os.environ['PYTHON_EGG_CACHE'] = egg_cache
os.chdir(appdir)
import cherrypy
import traceback
class Root(object):
#cherrypy.expose
def index(self):
return 'Hai Werld'
def setup_application():
print "starting cherrypy application server"
#app_root = os.path.dirname(__file__)
#sys.path.append(app_root)
app = cherrypy.tree.mount(Root(), site_root)
print "successfully set up the application"
return app
def __ExtensionFactory__():
"The entry point for when the ISAPIDLL is triggered"
try:
# import the wsgi app creator
app = setup_application()
return isapi_wsgi.ISAPISimpleHandler(app)
except:
import traceback
traceback.print_exc()
f = open(os.path.join(appdir, 'critical error.txt'), 'w')
traceback.print_exc(file=f)
f.close()
def install_virtual_dir():
import isapi.install
params = isapi.install.ISAPIParameters()
# Setup the virtual directories - this is a list of directories our
# extension uses - in this case only 1.
# Each extension has a "script map" - this is the mapping of ISAPI
# extensions.
sm = [
isapi.install.ScriptMapParams(Extension="*", Flags=0)
]
vd = isapi.install.VirtualDirParameters(
Server="CherryPy Web Server",
Name=site_root,
Description = "CherryPy Application",
ScriptMaps = sm,
ScriptMapUpdate = "end",
)
params.VirtualDirs = [vd]
isapi.install.HandleCommandLine(params)
if __name__=='__main__':
# If run from the command-line, install ourselves.
install_virtual_dir()
This script does several things. It (a) acts as the installer, installing itself into IIS [install_virtual_dir], (b) contains the entry point when IIS loads the DLL [__ExtensionFactory__], and (c) it creates the CherryPy WSGI instance consumed by the ISAPI handler [setup_application].
If you place this in your \inetpub\cherrypy directory and run it, it will attempt to install itself to the root of your IIS web site named "CherryPy Web Server".
You're also welcome to take a look at my production web site code, which has refactored all of this into different modules.
OK, I got it working. Thanks to Jason and all his help. I needed to call
cherrypy.config.update({
'tools.sessions.on': True
})
return cherrypy.tree.mount(Root(), '/', config=path_to_config)
I had this in the config file under [/] but for some reason it did not like that. Now I can get my web app up and running - then I think I will try and work out why it needs that config update and doesn't like the config file I have...