1

I need a way to distinguish development server in Django (run eg. by ./manage.py runserver 0.0.0.0:8000) from the one being run on Apache. In case of Apache I use WSGI daemon mode, but I would like to find some more reliable solution for detecting execution on Django's development server.

What I currently use is similar to:

wsgi_wrapper = request.META.get('wsgi.file_wrapper')
wsgi_wrapper_path = wsgi_wrapper.__module__ if wsgi_wrapper else None

which seemingly gives wsgi_wrapper_path storing:

  • "wsgiref.util" string when run on Django's built-in development server,
  • None when run on Apache / WSGI in daemon mode,

The problem here is I am not sure if I can rely on that check (eg. if the production/staging/development server or my localhost configuration changes). I was not able to find any documentation regarding that.

I need that check primarily because of one issue with Django's development server: it sets request's CONTENT_TYPE (request.META['CONTENT_TYPE']) to "text/plain" even if the HTTP request itself had no content type set (eg. it was a GET request).

Any ideas regarding Django's development server detection (or solving issue with incorrect request content type on it) will be appreciated. Thanks.

Ps. I am basically asking this question: How can I tell whether my Django application is running on development server or not? for Django 1.4, trying to determine the solution that will be reliable enough in case configuration changes.

Community
  • 1
  • 1
Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • @YujiTomita: My research has shown, that the results are different than in accepted answer to that question. Plus, I have updated my answer to include the link to that question. The accepted answer to the question you linked does not solve the issue (differs slightly from my results) and I need updated version of that answer, some link to the proper documentation or another solution I can use and have peace of mind. – Tadeck Jun 09 '12 at 16:48
  • well, how about `'runserver' in sys.argv`? then set a flag in settings? RUNSERVER = True. Since it's for development only, I would personally be happy with this one. – Yuji 'Tomita' Tomita Jun 09 '12 at 16:52
  • @YujiTomita: I haven't considered it, but since there is no other proposal, I will take it into consideration. The problem with it is that the development server may be run not only by `./manage.py runserver` or `python manage.py runserver`, it may be possibly executed from something else (I am using Fabric for various tasks and such scenario would be possible). I would be really happy with the cleaner, more reliable solution. But right now I have doubts there is any. – Tadeck Jun 10 '12 at 02:57
  • what do you mean - how would fabric be any different? Wouldn't it just call manage.py runserver, if anything? – Yuji 'Tomita' Tomita Jun 10 '12 at 05:17
  • @YujiTomita: I may not be clear enough about that. I just meant that you can possibly run development server not by invoking `./manage.py runserver`, but rather doing what the `./manage.py runserver` command does (maybe in modified way). In other words: 1) having `runserver` in `sys.argv` does not necessarily mean you are running Django's internal development server, 2) running Django's internal development server does not necessarily result in having `runserver` in `sys.argv`. I need something more reliable. Optionally I may do various things, but is there any way to distinguish dev server? – Tadeck Jun 10 '12 at 19:29

1 Answers1

3

As a principle - when using a Production and Dev servers, they should have different configs - it is most common that they will use different databases, different mail settings, etc. So the best place to tell the kind of the server is the configuration. I can point to two most-used approaches:

  • Config file

then in settings.py just add:

server = config.get("SERVER_TYPE", "DEV")

and have SERVER_TYPE only in the config file on PRODUCTION

  • Environment

Set SERVER_TYPE as environment variable when running the web server. I.e. for Supervisord, running the webserver:

environment=SERVER_TYPE=PROD

or for Apache:

SetEnv SERVER_TYPE PROD

This way you will be sure that as long as you don't mix the config files, you will always get the real server type, no matter how you start the server. At least that why config files are used for.

Tisho
  • 8,320
  • 6
  • 44
  • 52
  • Didn't you mean `os.environ` instead of `config.get`? – Tadeck Jun 11 '12 at 12:30
  • os.environ['SERVER_TYPE'] will work for the second approach. I mean using ConfigParser library to read from a config file. Or any other tool to read from a config file. – Tisho Jun 11 '12 at 12:35
  • I followed your advice with setting the environment on the production server. If there is no other way (maybe some environment setting already set by Apache), then I believe this is the cleanest approach to distinguish environment (settings would be the same for both cases, and development server can be invoked not only by using `./manage.py runserver` call). Thank you. – Tadeck Jun 14 '12 at 04:51
  • Just one note: `SetEnv` within Apache is not being passed to Django, if you are using `mod_wsgi`. So anyone trying to apply that approach should use first option or find a walkaround for this issue. – Tadeck Aug 03 '12 at 08:14