Using the PythonAnywhere API: an (open source) helper script to create a Django webapp with a virtualenv

With the beta launch of our API, we want to start making it possible for people to do more scripted things with PythonAnywhere.

Our starter for 10 was this: our web-based UI has some helpers for creating new web apps for common web frameworks (Django, Flask, web2py, etc), but they pin you to the system-installed version of those packages. Using a virtualenv would give the user more flexibility, but currently that means using the more complicated “manual config” option.

The API means it’s now possible to build a single command-line tool that you can run from a PythonAnywhere console to create, from scratch, a new Django project, with a virtualenv, all in one go.

The command-line tool in a Bash console

The script is called and it’s available by default in any PythonAnywhere Bash console. Here’s its command-line help:

$ -h
Create a new Django webapp with a virtualenv.  Defaults to
your free domain, the latest version of Django and Python 3.6

Usage: [--domain=<domain> --django=<django-version> --python=<python-version>] [--nuke]
  --domain=<domain>         Domain name, eg   [default:]
  --django=<django-version> Django version, eg "1.8.4"  [default: latest]
  --python=<python-version> Python version, eg "2.7"    [default: 3.6]
  --nuke                    *Irrevocably* delete any existing web app config on this domain. Irrevocably.

Seeing it in action

If we launch the script and accept the defaults, we can watch it automatically going through all the steps you’d normally have to go through manually to create a new web app on PythonAnywhere:

screenshot of helper script building virtualenv etc
  • Creating a virtualenv
  • Installing Django into it
  • Creating a folder for your django site and running startproject
  • Creating a web app configuration on the PythonAnywhere Web tab
  • Editing your WSGI file to import your django app (and setting DJANGO_SETTINGS_MODULE correctly)
  • Creating a static files mapping on the web tab so that /static/ and /media/ urls work
  • updating to match those, and to set ALLOWED_HOSTS
  • runs collectstatic to get your CSS up and running
  • reloads your webapp to make it all live
screenshot of helper script building virtualenv etc

Lovely progress reports! 1

Once it’s run, you can see your web app is immediately live.

screenshot of django it worked page

And your code is ready to go in a folder predictably named after the site’s domain name:

17:08 ~ $ tree -L 3
├── mysite
│   ├──
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   └── urls.cpython-36.pyc
│   ├──
│   ├──
│   └──
└── static
    └── admin
        ├── css
        ├── fonts
        ├── img
        └── js

Plans for the future – it’s open source!

The helper script is online here: Issues, pull requests and suggestions are gratefully accepted.

The audacious vision of the future would be a script called something like which takes the URL to a GitHub repo, and:

  • pulls down the repo
  • detects a requirements.txt and automatically creates a virtualenv for it
  • detects common web frameworks like Django, Flask, etc
  • automatically creates a PythonAnywhere WSGI config for them
  • automatically creates a web app configuration as well

It’s ambitious but it shouldn’t be too hard to get working. We’d love to get you, the user, involved in shaping the way such a tool might work though.

(and of course, there’s nothing preventing you from just writing your own script to do these things, and to hell with our own corporate versions! Feel free to let us know if you do that. Or keep it as your own little secret).

  1. That’s right, forget cowsay, on PythonAnywhere we have snakesay* ↩︎

comments powered by Disqus