I'm writing a Django app, and it prints Unicode to stdout
. It works perfectly on the development server, but with Apache and modwsgi I get UnicodeEncodeError: 'ascii' codec can't encode characters ...
.
So, the stdout encoding is forced to ASCII. I've found a number of solutions, all of which seem like they should work according to documentation, but none work for me:
I tried setting the PYTHONIOENCODING
variable to utf-8
, using the SetEnv
directive.
I also tried setting LANG
, LC_ALL
, LC_CTYPE
to en_US.UTF-8
using SetEnv
and PassEnv
.
Since my Apache server is running under systemd
, I tried setting the variables using Environment=
directives in the service file.
Finally, I tried adding lang=en_US.UTF-8 locale=en_US.UTF-8
to the WSGIDaemonProcess
directive.
The variables are seen in the environment (reflected eg on Django error pages in debug mode), but the error still occurs.
Why don't these things work and what should I do? Overriding stdout
in the code that works fine outside Apache or encoding everything manually doesn't feel like the right approach.
The error occurs at a plain print
statement. Here's the entire view that raises the error:
def test(request):
import locale
print locale.getdefaultlocale()
print locale.getpreferredencoding()
s = u'привет'
print s
return s
Apache error log:
('en_US', 'UTF-8')
UTF-8
Internal Server Error: /app/testview/
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/web/my_site/my_app/views.py", line 964, in test
print s
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)
When I print sys.stdout
itself, I see that it's actually a mod_wsgi.Log
object. In the WSGI file, all I have for logging is:
logging.basicConfig(stream=sys.stderr)
Versions: Python 2.7.14, Apache 2.4.29, mod_wsgi 4.5.20 on Arch Linux
The first two will not do anything as SetEnv
only sets per request WSGI environ, not process variables.
Adding lang/locale on WSGIDaemonProcess should work in most cases provided you are actually running things in daemon mode. It will not work for embedded mode.
Have you verified you are actually running in daemon mode.
Here is a solution that changed HTTPD_LANG=${HTTPD_LANG-"en_US.utf8"}
$ cat -n /etc/init.d/httpd | grep HTTPD_LANG
34 HTTPD_LANG=${HTTPD_LANG-"en_US.utf8"}
59 LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
85 if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.