Django returning JSON for AJAX requests

In your you can have a page that return JSON data for AJAX request like this:

from django.http import JsonResponse

def ajax(request):
    data = {}
    data['something'] = 'useful'
    return JsonResponse(data)

This would work fine if you fill the data your self, but if you are getting the data from a model try the following:

from django.core import serializers
def tasks_json(request):
    tasks = Task.objects.all()
    data = serializers.serialize("json", tasks)
    return HttpResponse(data, content_type='application/json')

If you have non trivial application, I would recommend using Django Rest Framework or similar frameworks for better support for REST beyond simple JSON response.

Setting Up Python and Supervisor on CentOS

CentOS default repository is very limited, and even if you install EPEL you will get old packages, in my case I needed to install Supervisor to manage my Django application, after trying to do it manually and through EPEL I ended up with the following setup.

Install Needed Package

sudo yum install python-setuptools
sudo easy_install pip
sudo pip install supervisor

Setup Supervisor

We’ve already installed “Supervisor” globally, but we need to create its configuration, luckily it comes with default config:

echo_supervisord_conf > supervisord.conf
sudo cp supervisord.conf /etc/supervisord.conf
sudo mkdir /etc/supervisord.d/
sudo vi /etc/supervisord.conf
files = /etc/supervisord.d/*.conf

Next we need to set “Supervisor” to run automatically every time you restart your machine, we need to create /etc/rc.d/init.d/supervisord with the following content:

sudo vi /etc/rc.d/init.d/supervisord
# /etc/rc.d/init.d/supervisord
# Supervisor is a client/server system that
# allows its users to monitor and control a
# number of processes on UNIX-like operating
# systems.
# chkconfig: - 64 36
# description: Supervisor Server
# processname: supervisord

# Source init functions
. /etc/rc.d/init.d/functions



       echo -n $"Starting $prog: "
       daemon $prog_bin --pidfile $PIDFILE
       [ -f $PIDFILE ] && success $"$prog startup" || failure $"$prog startup"

       echo -n $"Shutting down $prog: "
       [ -f $PIDFILE ] && killproc $prog || success $"$prog shutdown"

case "$1" in



       status $prog


   echo "Usage: $0 {start|stop|restart|status}"


Then make sure CentOS knows about it:

sudo chmod +x /etc/rc.d/init.d/supervisord
sudo chkconfig --add supervisord
sudo chkconfig supervisord on
sudo service supervisord start

Sample Supervisor App

Here is a sample of Django App to be controlled and monitored by Supervisor, just put it:

sudo vi /etc/supervisord.d/my_django_cms.conf
command=/home/rayed/.virtualenvs/dev/bin/gunicorn apps.wsgi:application -b --workers 8 --max-requests 1000
# UNIX Socket version (better with Nginx)
#command=/home/rayed/.virtualenvs/dev/bin/gunicorn apps.wsgi:application -b unix:/tmp/my_django_cms.sock --workers 8  --max-requests 1000

After that:

 sudo supervisorctl add my_django_cms
 sudo supervisorctl start my_django_cms

Setting Apache to Proxy to Gunicorn

To add virtual host to Apache that forward dynamic content to Gunicorn:

sudo vi /etc/httpd/conf.d/my_django_cms.conf
NameVirtualHost *:80
<VirtualHost *:80>
    DocumentRoot /var/www/my_django_cms/www
    RewriteEngine on
    ProxyPreserveHost On
    RewriteCond $1 !^/(favicon\.ico|robots\.txt|media|static)/
    RewriteRule ^(.*) http://localhost:8000$1 [P]
    <Proxy *>
            Order deny,allow
            Allow from all
            Allow from localhost

If you have SELinux enabled you might need to apply the following command:

setsebool -P httpd_can_network_connect 1

If you have issues accessing your statics files from Apache it might be SELinux also:

restorecon -Rv /var/www/my_django_cms/

Django Multiple Settings with Single File

Instead of having multiple settings files one for production and one for development and so on, I prefer to use an “if” statement with environment variable:

ENV = os.environ.get('DJANGO_ENV', '')
print "==== Active Env: [%s]  ====" % (ENV)    
if ENV == "dev":
    # DEBUG
    DEBUG = True
    DEBUG = False

Then from your “.bashrc” file:

export DJANGO_ENV=dev

Django “render” vs “render_to_response”

Summary: Always use render and not render_to_response

In Django you have more than one way to return a response, but many times I get confused between render and render_to_response, render_to_response seems shorter, so why not use it!

To explain let’s assume simple posts page:

def article_list(request, template_name='article/list.html'):
    posts = Post.objects.all()
    # DON'T USE
    return render_to_response(template_name, {'posts': posts})

In this example you will be able to access “posts” in your template, but unfortunately you will not have access to other important variables from other Middlewares, most importantly: user, csrf_token, and messages. To make “render_to_response” pass all these parameters you must send a “context_instance” like this:

return render_to_response(template_name, {'posts': posts}, context_instance=RequestContext(request))

Not so short after all, compare to “render” version:

return render(request, template_name, {'posts': posts})

In fact “render” is always shorter than “render_to_response”, even without the “context_instance”:

return render(request, template_name, {'posts': posts})
... vs ...
return render_to_response(template_name, {'posts': posts})

Install Python Image Library (PIL) on OSX

PIL or Python Imaging Library is a library that allows you to manipulate images in Python programming language, trying to install “PIL” using “pip” tool won’t work perfectly so here is how to proper installation.

Install Brew

Brew is a package management system that simplifies the installation of software on Mac OS X, you can install it easily with the following command:

ruby -e "$(curl -fsSL"

Install Pil

Actually we will install ”pillow” a fork of ”pil”:

brew install samueljohn/python/pillow

Configure your Python Path

To make PIL available to Python we add its path to PYTHONPATH variable:

vi ~/.bash_profile

Check it

To test if you have PIL installed:

python -c "import PIL.Image"

You shouldn’t get any errors.

My New Project: AgentX Implementation in Python

Update: I changed the module name to ”pyagentx”, thank you Daniel for the suggestion.

During this Eid vacation I spent many hours working on AgentX implementation in Python.

You can find the project in GitHub:

What is AgentX?

AgentX is protocol to extend SNMP agents, defined in RFC 2741.

But what is SNMP? let’s say you have a Linux machine you want to monitor, you will use Simple Network Management Protocol or SNMP for short, you install an SNMP agent on the machine like Net-SNMP, and from your management station you connect to the SNMP agent and ask it for the data you want report on, for example the current state of network link.

What happen if you install new software, like PostgreSQL DB, and your SNMP agent doesn’t support it, how can you monitor it! The good news SNMP agents (e.g. Net-SNMP) can be extend with multiple options, the bad news most options are very hard.

One of the most flexible options is AgentX protocol, you will need to build an application that run AgentX protocol (AgentX SubAgent), upon startup it will contact the SNMP agent (AgentX master) and register a part of the MIB tree that your app will handle, the SNMP agent (AgentX master) will forward all queries to your app which will return the result back to the master which will forward it to the management station (Cacti, NMS).

Net-SNMP already have an API to build AgentX Sub Agent, and there are Python module that utilise it, but unfortunately it doesn’t look active, and as far as I know Net-SNMP API it self isn’t the easiest thing to work with.

This is why I started working with Pure Python implementation for AgentX protocol, it is already in a working condition and tested with Net-SNMP agent, I’ve some more issues to resolve before I can use it in production.

So please if you are interested in the field give my module a try, and let me know how can improve it, and also suggest better name.

Python auto complete in OSX

If you run Python shell in OSX you notice the auto completion functionality isn’t working, this is caused by Apple decision not to ship GNU readline and instead they use libedit (BSD license), to fix the problem I used the following snippet:

import readline
import rlcompleter
if 'libedit' in readline.__doc__:
    readline.parse_and_bind("bind ^I rl_complete")
    readline.parse_and_bind("tab: complete")