Python has joined the growing ranks of officially-supported languages on Heroku’s polyglot platform, going into public beta as of today. Python is the most-requested language for Heroku, and it brings with it the top-notch Django web framework.
As a language, Python has much in common with Ruby, Heroku’s origin language. But the Python community has its own unique character. Python has a culture which finds an ideal balance between fast-moving innovation and diligent caution. It emphasizes readability, minimizes “magic,” treats documentation as a first-class concern, and has a traditon of well-tested, backward-compatible releases in both the core language and its ecosystem of libraries. It blends approachability for beginners with maintainability for large projects, which has enabled its presence in fields as diverse as scientific computing, video games, systems automation, and the web.
Let’s take it for a spin on Heroku.
Make a directory with three files:
import os from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello from Python!" if __name__ == "__main__": port = int(os.environ.get("PORT", 5000)) app.run(host='0.0.0.0', port=port)
web: python app.py
Commit to Git:
$ git init $ git add . $ git commit -m "init"
Create an app on the Cedar stack and deploy:
$ heroku create --stack cedar Creating young-fire-2556... done, stack is cedar http://young-fire-2556.herokuapp.com/ | email@example.com:young-fire-2556.git Git remote heroku added $ git push heroku master Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (5/5), 495 bytes, done. Total 5 (delta 0), reused 0 (delta 0) -----> Heroku receiving push -----> Python app detected -----> Preparing virtualenv version 1.6.1 New python executable in ./bin/python2.7 Also creating executable in ./bin/python Installing setuptools............done. Installing pip...............done. -----> Installing dependencies using pip version 1.0.1 Downloading/unpacking Flask==0.7.2 (from -r requirements.txt (line 1)) ... Successfully installed Flask Werkzeug Jinja2 Cleaning up... -----> Discovering process types Procfile declares types -> web -----> Compiled slug size is 3.5MB -----> Launching... done, v2 http://young-fire-2556.herokuapp.com deployed to Heroku To firstname.lastname@example.org:young-fire-2556.git * [new branch] master -> master
Then view your app on the web!
$ curl http://young-fire-2556.herokuapp.com/ Hello from Python!
Dev Center: Getting Started with Python on Heroku/Cedar
Created by Guido van Rossum in 1991, Python is one of the world’s most popular programming languages, and finds application in a broad range of uses.
Cutting-edge communities, like Node.js and Ruby, encourage fast-paced innovation (though sometimes at the cost of application breakage). Conservative communities, like Java, favor a more responsible and predictable approach (though sometimes at the expense of being behind the curve). Python has managed to gracefully navigate a middle path between these extremes, giving it a respected reputation even among non-Python programmers. The Python community is an island of calm in the stormy seas of the programming world.
Python is known for its clearly-stated values, outlined in PEP 20, The Zen of Python. “Explicit is better than implicit” is one example (and a counterpoint to “Convention over configuration” espoused by Rails). “There’s only one way to do it” is another (counterpointing “There’s more than one way to do it” from Perl). SeeCode Like a Pythonista: Idiomatic Python for more.
The Python Enhancement Proposal (PEP) brings a structured approach to extending the core language design over time. It captures much of the value of Internet standard bodies procedures (like Internet Society RFCs or W3C standards proposals) without being as heavy-weight or resistant to change. Again, Python finds a graceful middle path: neither changing unexpectedly at the whim of its lead developers, nor unable to adapt to a changing world due to too many approval committees.
Documentation is one of Python’s strongest areas, and especially notable because docs are often a second-class citizen in other programming languages. Read the Docs is an entire site dedicated to packaging and documentation, sponsored by the Python Software Foundation. And the Django book defined a whole new approach to web-based publishing of technical books, imitated by many since its release.
In some ways, Python was the birthplace of modern web frameworks, with Zope and Plone. Concepts like separation of business and display logic via view templating, ORMs for database interaction, and test-driven development were built into Zope half a decade before Rails was born. Zope never had the impact achieved by the later generation of frameworks, partially due to its excessive complexity and steep learning curve, and partially due to simply being ahead of its time. Nevertheless, modern web frameworks owe much to Zope’s pioneering work.
The legacy of Zope’s checkered history combined with the Python community’s slow recognition of the importance of the web could have been a major obstacle to the language’s ongoing relevance with modern developers, who increasingly wanted to build apps for the web. But in 2005, the Django framework emerged as a Pythonic answer to Rails. (Eventually, even Guido came around.)
Django discarded the legacy of past Python web implementations, creating an approachable framework designed for rapid application development. Django’s spirit is perhaps best summarized by its delightful slogan: “the web framework for perfectionists with deadlines.” Where Rails specializes on CRUD applications, Django is best known for its CMS capabilities. It has an emphasis on DRY (Don’t Repeat Yourself). The Django community prefers to create reusable components or contribute back to existing projects over single-use libraries, which helps push the greater Python community forward. While Django is a batteries-included framework, the loose coupling of components allows flexibility and choice.
Other frameworks have found traction as well. Flask, a Sinatra-like microframework, makes use of Python’s decorators for readability. Pyramid emerged from the earlier Pylons and TurboGears projects, and their documentation already offers excellent instructions for deploying to Heroku.
Perhaps most striking about Python is the breadth of different realms it has taken root in. A few examples:
We anticipate that Python will be one of the most-used languages on the Heroku platform, and are overjoyed to welcome our Python brothers and sisters into the fold.
Special thanks to all the members of the Python community that helped with alpha testing, feedback, and patches on Heroku’s Python support, including: David Cramer, Ben Bangert, Kenneth Love, Armin Ronacher, and Jesse Noller.
We’ll be sponsoring and speaking at PyCodeConf next week. Come chat with us about what you’d like to see out of Python on Heroku!
With these factors in mind, we have revised the release schedule: we are now aiming to produce a release candidate in the week of February 14, with a final release in the week of February 21.
Django 1.3 adds a framework that allows you to use a class as a view. This means you can compose a view out of a collection of methods that can be subclassed and overridden to provide common views of data without having to write too much code.
Analogs of all the old function-based generic views have been provided, along with a completely generic view base class that can be used as the basis for reusable applications that can be easily extended.
See the documentation on Class-based Generic Views for more details. There is also a document to help you convert your function-based generic views to class-based views.
Django 1.3 adds framework-level support for Python’s logging module. This means you can now easily configure and control logging as part of your Django project. A number of logging handlers and logging calls have been added to Django’s own code as well – most notably, the error emails sent on a HTTP 500 server error are now handled as a logging activity. See the documentation on Django’s logging interface for more details.
In previous versions of Django, it was common to place static assets in MEDIA_ROOT along with user-uploaded files, and serve them both at MEDIA_URL. Part of the purpose of introducing the staticfiles app is to make it easier to keep static files separate from user-uploaded files. For this reason, you will probably want to make your MEDIA_ROOT and MEDIA_URL different from your STATIC_ROOT and STATIC_URL. You will need to arrange for serving of files in MEDIA_ROOT yourself; staticfiles does not deal with user-uploaded media at all.
Python 2.7 introduced some major changes to the unittest library, adding some extremely useful features. To ensure that every Django project can benefit from these new features, Django ships with a copy of unittest2, a copy of the Python 2.7 unittest library, backported for Python 2.4 compatibility.
To access this library, Django provides the django.utils.unittest module alias. If you are using Python 2.7, or you have installed unittest2 locally, Django will map the alias to the installed version of the unittest library. Otherwise, Django will use it’s own bundled version of unittest2.
To use this alias, simply use:
from django.utils import unittest
wherever you would have historically used:
If you want to continue to use the base unittest libary, you can — you just won’t get any of the nice new unittest2 features.
with transaction.autocommit(): # ...
For more information, see Controlling transaction management in views.
ForeignKey and OneToOneField now accept an on_delete argument to customize behavior when the referenced object is deleted. Previously, deletes were always cascaded; available alternatives now include set null, set default, set to any value, protect, or do nothing.
For more information, see the on_delete documentation.
For translation strings with ambiguous meaning, you can now use the pgettext function to specify the context of the string.
And if you just want to add some information for translators, you can also add special translator comments in the source.
It can sometimes be beneficial to allow decorators or middleware to modify a response after it has been constructed by the view. For example, you may want to change the template that is used, or put additional data into the context.
However, you can’t (easily) modify the content of a basic HttpResponse after it has been constructed. To overcome this limitation, Django 1.3 adds a new TemplateResponse class. Unlike basic HttpResponse objects, TemplateResponse objects retain the details of the template and context that was provided by the view to compute the response. The final output of the response is not computed until it is needed, later in the response process.
For more details, see the documentation on the TemplateResponse class.
Django 1.3 sees the introduction of several improvements to the Django’s caching infrastructure.
Firstly, Django now supports multiple named caches. In the same way that Django 1.2 introduced support for multiple database connections, Django 1.3 allows you to use the new CACHES setting to define multiple named cache connections.
Lastly, support for pylibmc has been added to the memcached cache backend.
For more details, see the documentation on caching in Django.
If you provide a custom auth backend with supports_inactive_user set to True, an inactive user model will check the backend for permissions. This is useful for further centralizing the permission handling. See the authentication docs for more details.
Previously, the MEDIA_URL setting only required a trailing slash if it contained a suffix beyond the domain name.
A trailing slash is now required for MEDIA_URL and the new STATIC_URL setting as long as it is not blank. This ensures there is a consistent way to combine paths in templates.
Project settings which provide either of both settings without a trailing slash will now raise a PendingDeprecation warning.
In Django 1.4 this same condition will raise an ImproperlyConfigured exception.
Django 1.1 and 1.2 added lots of big ticket items to Django, like multiple-database support, model validation, and a session-based messages framework. However, this focus on big features came at the cost of lots of smaller features.
To compensate for this, the focus of the Django 1.3 development process has been on adding lots of smaller, long standing feature requests. These include:
Introduction to Django
Django for Beginners
At this stage, there is:
and much more coming…
You can learn more about the history and motivation for Pinax in an interview with James Tauber on This Week in Django as well as his talk on Pinax at DjangoCon 2008 and talk on Pinax at PyCon 2009.