Hacking OpenWISP: Python and Django¶
In this page we aim to help users and contributors who want to work on the internal code of OpenWISP in the following ways:
- By explaining why OpenWISP uses Python and Django as its main technologies for the backend application
- By introducing some Python tools and Django extensions which are extremely useful during development and debugging.
Python is an interpreted high-level programming language for general-purpose programming which emphasizes productivity, fast prototyping and high readability.
It is very widely used these days, to the point where even famous organizations like Google, Mozilla and Dropbox make extensive use of it for their systems.
Here are the main reasons why OpenWISP is written in Python:
- it is widely used in the networking and configuration management world, famous libraries such as networkx, ansible, salt, paramiko and fabric are written in Python, this allows our users to work with a programming language which they are already familiar with
- finding developers who know Python is very easy and allows the community to grow and help to improve the OpenWISP software ecosystem over time
- Python allows great flexibility and extensibility, this in turns allows OpenWISP to be hackable and highly customizable, which is one of the goals of OpenWISP 2, the major rewrite of the project
Resources for learning Python:
The first version of OpenWISP was written in Ruby.
OpenWISP 2 was rewritten in Python because Ruby developers are more scarce and this caused the project to stagnate. The fact that Python is widely used in the networking world was also an important factor in the decision.
Django is a high-level Python Web framework which encourages rapid development and clean, pragmatic design.
In OpenWISP we chose Django mainly for these reasons:
- It has a rich ecosystem and pluggable apps which allow us to get a lot done very fast
- It has been battle tested over many years by a high amount of people and high profile companies
- Security vulnerabilities are usually privately disclosed to the developers and quickly fixed
- Being popular, it’s easy to find Python developers who have experience with Django and can get up to speed very fast in contributing to OpenWISP
- Django projects are easily customizable by editing a
settings.pyfile, this allows OpenWISP to design its modules so that these can be imported into larger, more complex and customized applications, allowing to create customized network management solutions; this makes OpenWISP similar to a framework: users can use the default installation but if they need a solution that is more tailored to their needs they can use it as a base to avoid re-developing a lot of code from scratch
Resources for learning Django:
PS: if you are wondering why the second tutorial mentions the word “Girls”, we suggest taking a look at djangogirls.org.
Why Django REST framework?¶
Django REST framework is a powerful and flexible toolkit for building Web APIs and it’s used and trusted by internationally recognised companies including Mozilla, Red Hat, Heroku, and Eventbrite.
Here are some reasons why OpenWISP uses Django REST framework:
- Simplicity, flexibility, quality, and test coverage of source code
- Powerful serialization engine compatible with both ORM and non-ORM data sources
- Clean, simple, views for Resources, using Django’s new class based views
- HTTP response handling, content type negotiation using HTTP Accept headers
- Publishing of metadata along with querysets
Resources for learning Django REST Framework:
Useful Development Tools¶
IPython and ipdb¶
IPython (Interactive Python) is a command shell for interactive computing in multiple programming languages, originally developed for the Python programming language, which offers introspection, rich media, shell syntax, tab completion, and history.
- A powerful interactive shell with syntax highlighting
- A browser-based notebook interface with support for code, text, mathematical expressions, inline plots and other media.
- Support for interactive data visualization and use of GUI toolkits.
- Flexible, embeddable interpreters to load into one’s own projects
- Tools for parallel computing
More details including installation and updates can be found on the official webite.
As for ipdb, it allows to use the
ipython shell when using the python debugger (known as
Try to drop this line in a Django project (or an OpenWISP module),
for example in a
import ipdb; ipdb.set_trace()
Now load the Django development server and have fun while learning how to do debug Python code!
Django Extensions is a
collection of extensions for the Django Framework. These include
management commands, additional database fields, admin extensions and
much more. We will focus on three of them for now, namely
Django Extensions can be installed with:
pip install django-extensions
shell_plus: Django shell with autoloading of the apps database models and subclasses of user-defined classes.
runserver_plus: typical runserver with Werkzeug debugger baked in.
show_urls: shows the registered URLs of a Django project.
Django Debug Toolbar¶
The Django Debug Toolbar is a configurable set of panels which display various debug information about the current HTTP request/response and, when clicked, display more details about the panel’s content.
It can be installed with:
pip install django-debug-toolbar
More information can be found in the django-debug-toolbar documentation.
Using these tools in OpenWISP¶
These tools can be added to an OpenWISP development environment and
significantly improve the efficiency and experience while developing.
Let’s do a walkthrough of how to use them in OpenWISP Controller as an example. In the
local_settings.example.py must be copied and
local_settings.py which we will use for customization.
This technique can be used in other OpenWISP development environments too.
cd tests/ cp local_settings_example.py local_settings.py
To start, the steps
for installing OpenWISP Controller must be followed. The command
pipenv install --dev then the commands
pipenv run ./manage.py migrate and
pipenv run ./manage.py createsuperuser must be run and
SPATIALITE_LIBRARY_PATH should be specified in the
To start the development server, run
python manage.py runserver_plus
which will provide more debugging information.
ipython can be used alongside
shell_plus by running the
./manage.py shell_plus --ipython in the terminal. This will
provide an interactive shell for running code in Python.
To debug the code,
ipdb can be used. Commands similar to
ipdb mymodule.py may be used to carry out that process. A
list of lines where errors have been found or lines which can be further
optimized will be returned.
django-debug-toolbar may be used to display information
about processes occuring on the website. To achieve that, some code needs
to be added to our current module, i.e
openwisp-controller. To begin,
'debug_toolbar.middleware.DebugToolbarMiddleware' need to be added
INSTALLED_APPS and to the
MIDDLEWARE settings respectively
and the line
INTERNAL_IPS = ('127.0.0.1') should be added too,
otherwise the django debug toolbar won’t be displayed. We also need to
django_extensions and add it to our
but this is already done in
settings.py. Here’s what
local_settings.py will roughly look like at the end:
from django.conf import settings settings.INSTALLED_APPS += [ 'debug_toolbar', #django_extensions # already enabled in openwisp-controller, you may need to # uncomment the previous line in other development environments ] # This setting is specific for openwisp-controller. # Other OpenWISP development environments might not need it. SPATIALITE_LIBRARY_PATH = 'mod_spatialite' settings.MIDDLEWARE += [ 'debug_toolbar.middleware.DebugToolbarMiddleware' ] INTERNAL_IPS = ('127.0.0.1')
To complete the process, the Debug Toolbar’s URL needs to be added
to the URLconf of
openwisp-controller as shown in this
tutorial but this is already present in the last lines of
if settings.DEBUG and 'debug_toolbar' in settings.INSTALLED_APPS: import debug_toolbar urlpatterns += [ url(r'^__debug__/', include(debug_toolbar.urls)) ]
When you open
http://127.0.0.1:8000 in the browser now and enter the
credentials we created earlier, you should see something like the
Now that you know some basics, you can experiment and try to use these tricks on some other OpenWISP module.