Django In The Real World

  • 9,239 views
Uploaded on

There’s plenty of material (documentation, blogs, books) out there that’ll help you write a site using Django… but then what? You’ve still got to test, deploy, monitor, and tune the site; failure at …

There’s plenty of material (documentation, blogs, books) out there that’ll help you write a site using Django… but then what? You’ve still got to test, deploy, monitor, and tune the site; failure at deployment time means all your beautiful code is for naught.

This tutorial examines how best to cope when the Real World intrudes on your carefully designed website.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
9,239
On Slideshare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
0
Comments
1
Likes
64

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • Oh hai. I’m Jacob Kaplan-Moss; here’s a few ways to get in touch with me.

    I wear quite a few hats. Today, I’m wearing two: I’m one of the lead developers of Django; I’m a partner at `Revolution Systems`__, a consulting business specializing in, well, the stuff I’m about to talk about.
  • Just a brief shameless plug: my day job is as a consultant working in and around these issues. I get to come talk about this stuff publicly because of this gig, so If you need info specific to your situation please consider giving us a call!
  • Credit where credit is due: I first gave this talk at PyCon 2009 with the help of `James Bennett`__, so much of my thinking and some of the content comes from James.

    __ http://b-list.org/
  • This is the main theme of this tutorial: you’ve written a Django site...
  • ... and you’ve barely started.

    Writing the app is the easy part; what comes next is seriously complicated.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • Here’s just one list (Leonard Lin’s) of what you might need to think about *after* writing your app; I could easily add another dozen more things to this list. Luckily, not every site needs *all* of this... but any site of any size will need to understand at last some of this stuff, and bigger deployments will need to worry about all of it.

    Obviously this is far too much to cover even in a long tutorial, so we’ll pick and choose; the point is that writing the app is usually the easy part. Today we’re talking about what comes next.
  • So here’s the bare minimum you’ll need to think about:

    * You need to test your sites. Without tests, you can’t move forward without downtime.
    * You need to write your code in a way that makes deployment possible — and easy.
    * You need to use deployment tools that automate the repetitive bits and keep you from shooting yourself in the foot.
    * You need a production environment that scales with your traffic.
    * You need to watch your sites in action so that you know what’s up.
    * When things go slow you need to fix it.
  • So here’s the bare minimum you’ll need to think about:

    * You need to test your sites. Without tests, you can’t move forward without downtime.
    * You need to write your code in a way that makes deployment possible — and easy.
    * You need to use deployment tools that automate the repetitive bits and keep you from shooting yourself in the foot.
    * You need a production environment that scales with your traffic.
    * You need to watch your sites in action so that you know what’s up.
    * When things go slow you need to fix it.
  • So here’s the bare minimum you’ll need to think about:

    * You need to test your sites. Without tests, you can’t move forward without downtime.
    * You need to write your code in a way that makes deployment possible — and easy.
    * You need to use deployment tools that automate the repetitive bits and keep you from shooting yourself in the foot.
    * You need a production environment that scales with your traffic.
    * You need to watch your sites in action so that you know what’s up.
    * When things go slow you need to fix it.
  • So here’s the bare minimum you’ll need to think about:

    * You need to test your sites. Without tests, you can’t move forward without downtime.
    * You need to write your code in a way that makes deployment possible — and easy.
    * You need to use deployment tools that automate the repetitive bits and keep you from shooting yourself in the foot.
    * You need a production environment that scales with your traffic.
    * You need to watch your sites in action so that you know what’s up.
    * When things go slow you need to fix it.
  • So here’s the bare minimum you’ll need to think about:

    * You need to test your sites. Without tests, you can’t move forward without downtime.
    * You need to write your code in a way that makes deployment possible — and easy.
    * You need to use deployment tools that automate the repetitive bits and keep you from shooting yourself in the foot.
    * You need a production environment that scales with your traffic.
    * You need to watch your sites in action so that you know what’s up.
    * When things go slow you need to fix it.
  • So here’s the bare minimum you’ll need to think about:

    * You need to test your sites. Without tests, you can’t move forward without downtime.
    * You need to write your code in a way that makes deployment possible — and easy.
    * You need to use deployment tools that automate the repetitive bits and keep you from shooting yourself in the foot.
    * You need a production environment that scales with your traffic.
    * You need to watch your sites in action so that you know what’s up.
    * When things go slow you need to fix it.
  • So now you’ve got a working app, but how do you *know* that it works? Sure, you could just run the site and click around, but that guarantees nothing. The difference between stable and unstable code is often the quality of the tests.

    The “fear” that Beck is talking about here is the fear of not knowing if your new site will run or not. Testing, while often boring, relives you of that fear.
  • `Test Driven Development`__ by Kent Beck is the bible of TDD. Beck requires that you only add new code to your project after an existing test fails. This means writing tests before writing any new code. It can be rewarding -- particularly if you’re pair programming so you can keep each other honest. Unfortunately, it’s also simply not practical for most developers.

    __ http://www.amazon.com/dp/0321146530/
  • This is the pragmatic approach to testing: write tests when you need them. If you need to chase down a bug, write a test to trigger the bug, then when the test passes you know the bug is licked.

    Yes, this leaves you with less than perfect coverage.
  • I’m speaking from experience here. Once you commit with even a *single* breaking test, finding the time to clean up is an uphill battle. Knowing the suite fails discourages you from even running the tests at all, and thus the quality continues to decline.
  • I tend to think of this as a continuum of testing; another way of thinking about this is a continuum between internal/external, or whitebox/blackbox.
  • I tend to think of this as a continuum of testing; another way of thinking about this is a continuum between internal/external, or whitebox/blackbox.
  • I tend to think of this as a continuum of testing; another way of thinking about this is a continuum between internal/external, or whitebox/blackbox.
  • I tend to think of this as a continuum of testing; another way of thinking about this is a continuum between internal/external, or whitebox/blackbox.
  • Testing web applications is *hard*. Anything with a persistent state -- i.e. a database -- and network communications -- HTTP -- is a real pain to test.

    Ruby on Rails really changed the game, though. When it shipped a set of tools that took most of the pain out of automating web tests, it galvenized developers to compete.

    Django’s since come out with our own spin on this set of tools. I’m only going to cover doctests in this intro tutorial, so a brief overview of the other tools is in order:

    * Unit tests: Django can run tests using Python’s standard `unittest` framework, which is based on Java’s JUnit. Perfect for more formal unit tests like you’d see in Java/C#.
    * Fixtures: fixtures are a way of loading preset data into the database for each test, thus letting you test against “real” data.
    * The test client: this lets you “fake” a request to your views and inspect the returned response, template, and context.
    * Email capture: the test suite will intercept sent email so you can test logic involving email.
  • Testing web applications is *hard*. Anything with a persistent state -- i.e. a database -- and network communications -- HTTP -- is a real pain to test.

    Ruby on Rails really changed the game, though. When it shipped a set of tools that took most of the pain out of automating web tests, it galvenized developers to compete.

    Django’s since come out with our own spin on this set of tools. I’m only going to cover doctests in this intro tutorial, so a brief overview of the other tools is in order:

    * Unit tests: Django can run tests using Python’s standard `unittest` framework, which is based on Java’s JUnit. Perfect for more formal unit tests like you’d see in Java/C#.
    * Fixtures: fixtures are a way of loading preset data into the database for each test, thus letting you test against “real” data.
    * The test client: this lets you “fake” a request to your views and inspect the returned response, template, and context.
    * Email capture: the test suite will intercept sent email so you can test logic involving email.
  • Testing web applications is *hard*. Anything with a persistent state -- i.e. a database -- and network communications -- HTTP -- is a real pain to test.

    Ruby on Rails really changed the game, though. When it shipped a set of tools that took most of the pain out of automating web tests, it galvenized developers to compete.

    Django’s since come out with our own spin on this set of tools. I’m only going to cover doctests in this intro tutorial, so a brief overview of the other tools is in order:

    * Unit tests: Django can run tests using Python’s standard `unittest` framework, which is based on Java’s JUnit. Perfect for more formal unit tests like you’d see in Java/C#.
    * Fixtures: fixtures are a way of loading preset data into the database for each test, thus letting you test against “real” data.
    * The test client: this lets you “fake” a request to your views and inspect the returned response, template, and context.
    * Email capture: the test suite will intercept sent email so you can test logic involving email.
  • Testing web applications is *hard*. Anything with a persistent state -- i.e. a database -- and network communications -- HTTP -- is a real pain to test.

    Ruby on Rails really changed the game, though. When it shipped a set of tools that took most of the pain out of automating web tests, it galvenized developers to compete.

    Django’s since come out with our own spin on this set of tools. I’m only going to cover doctests in this intro tutorial, so a brief overview of the other tools is in order:

    * Unit tests: Django can run tests using Python’s standard `unittest` framework, which is based on Java’s JUnit. Perfect for more formal unit tests like you’d see in Java/C#.
    * Fixtures: fixtures are a way of loading preset data into the database for each test, thus letting you test against “real” data.
    * The test client: this lets you “fake” a request to your views and inspect the returned response, template, and context.
    * Email capture: the test suite will intercept sent email so you can test logic involving email.
  • Testing web applications is *hard*. Anything with a persistent state -- i.e. a database -- and network communications -- HTTP -- is a real pain to test.

    Ruby on Rails really changed the game, though. When it shipped a set of tools that took most of the pain out of automating web tests, it galvenized developers to compete.

    Django’s since come out with our own spin on this set of tools. I’m only going to cover doctests in this intro tutorial, so a brief overview of the other tools is in order:

    * Unit tests: Django can run tests using Python’s standard `unittest` framework, which is based on Java’s JUnit. Perfect for more formal unit tests like you’d see in Java/C#.
    * Fixtures: fixtures are a way of loading preset data into the database for each test, thus letting you test against “real” data.
    * The test client: this lets you “fake” a request to your views and inspect the returned response, template, and context.
    * Email capture: the test suite will intercept sent email so you can test logic involving email.

Transcript

  • 1. Django in the Real World Jacob Kaplan-Moss OSCON 2009 http://jacobian.org/TN
  • 2. Jacob Kaplan-Moss http://jacobian.org / jacob@jacobian.org / @jacobian Lead Developer, Django Partner, Revolution Systems 2
  • 3. Shameless plug: http://revsys.com/ 3
  • 4. Hat tip: James Bennett (http://b-list.org) 4
  • 5. So you’ve written a Django site… 5
  • 6. … now what? 6
  • 7. http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 8. • API Metering http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 9. • API Metering • Backups & Snapshots http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 10. • API Metering • Backups & Snapshots • Counters http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 11. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 12. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 13. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 14. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 15. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 16. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 17. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 18. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 19. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 20. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 21. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 22. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 23. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 24. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 25. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 26. • API Metering • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 27. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 28. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 29. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 30. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 31. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 32. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 33. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 34. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 35. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 36. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 37. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Real-time messaging (XMPP) • Multiple Devs, Staging, Prod • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 38. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Real-time messaging (XMPP) • Multiple Devs, Staging, Prod • Search • Data model upgrades • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 39. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Real-time messaging (XMPP) • Multiple Devs, Staging, Prod • Search • Data model upgrades • Ranging • Rolling deployments • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 40. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Real-time messaging (XMPP) • Multiple Devs, Staging, Prod • Search • Data model upgrades • Ranging • Rolling deployments • Geo • Multiple versions (selective beta) • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 41. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Real-time messaging (XMPP) • Multiple Devs, Staging, Prod • Search • Data model upgrades • Ranging • Rolling deployments • Geo • Multiple versions (selective beta) • Sharding • Bucket Testing • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 42. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Real-time messaging (XMPP) • Multiple Devs, Staging, Prod • Search • Data model upgrades • Ranging • Rolling deployments • Geo • Multiple versions (selective beta) • Sharding • Bucket Testing • Smart Caching • Rollbacks • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 43. • API Metering • Distributed Log storage, analysis • Backups & Snapshots • Graphing • Counters • HTTP Caching • Cloud/Cluster Management Tools • Input/Output Filtering • Instrumentation/Monitoring • Memory Caching • Failover • Non-relational Key Stores • Node addition/removal and hashing • Rate Limiting • Auto-scaling for cloud resources • Relational Storage • CSRF/XSS Protection • Queues • Data Retention/Archival • Rate Limiting • Deployment Tools • Real-time messaging (XMPP) • Multiple Devs, Staging, Prod • Search • Data model upgrades • Ranging • Rolling deployments • Geo • Multiple versions (selective beta) • Sharding • Bucket Testing • Smart Caching • Rollbacks • Dirty-table management • CDN Management • Distributed File Storage http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites 7
  • 44. The bare minimum: 8
  • 45. The bare minimum: • Test. 8
  • 46. The bare minimum: • Test. • Structure for deployment. 8
  • 47. The bare minimum: • Test. • Structure for deployment. • Use deployment tools. 8
  • 48. The bare minimum: • Test. • Structure for deployment. • Use deployment tools. • Design a production environment. 8
  • 49. The bare minimum: • Test. • Structure for deployment. • Use deployment tools. • Design a production environment. • Monitor. 8
  • 50. The bare minimum: • Test. • Structure for deployment. • Use deployment tools. • Design a production environment. • Monitor. • Tune. 8
  • 51. Testing 9
  • 52. “ Tests are the Programmer’s stone, transmuting fear into ” boredom. — Kent Beck 10
  • 53. Hardcore TDD 11
  • 54. “ I don’t do test driven development. I do stupidity driven testing… I wait until I do something stupid, and ” then write tests to avoid doing it again. — Titus Brown 12
  • 55. Whatever happens, don’t let your test suite break thinking, “I’ll go back and fix this later.” 13
  • 56. Unit testing Functional/behavior testing Browser testing 14
  • 57. Unit testing unittest Functional/behavior testing Browser testing 14
  • 58. Unit testing unittest doctest Functional/behavior testing Browser testing 14
  • 59. Unit testing unittest doctest Functional/behavior testing django.test.Client, Twill Browser testing 14
  • 60. Unit testing unittest doctest Functional/behavior testing django.test.Client, Twill Browser testing Windmill, Selenium 14
  • 61. You need them all. 15
  • 62. Testing Django 16
  • 63. Testing Django • Unit tests (unittest) 16
  • 64. Testing Django • Unit tests (unittest) • Doctests (doctest) 16
  • 65. Testing Django • Unit tests (unittest) • Doctests (doctest) • Fixtures 16
  • 66. Testing Django • Unit tests (unittest) • Doctests (doctest) • Fixtures • Test client 16
  • 67. Testing Django • Unit tests (unittest) • Doctests (doctest) • Fixtures • Test client • Email capture 16
  • 68. Unit tests 17
  • 69. Unit tests • “Whitebox” testing 17
  • 70. Unit tests • “Whitebox” testing • Verify the small functional units of your app 17
  • 71. Unit tests • “Whitebox” testing • Verify the small functional units of your app • Very fine-grained 17
  • 72. Unit tests • “Whitebox” testing • Verify the small functional units of your app • Very fine-grained • Familier to most programmers (JUnit, NUnit, etc.) 17
  • 73. Unit tests • “Whitebox” testing • Verify the small functional units of your app • Very fine-grained • Familier to most programmers (JUnit, NUnit, etc.) • Provided in Python by unittest 17
  • 74. django.test.TestCase 18
  • 75. django.test.TestCase • Fixtures. 18
  • 76. django.test.TestCase • Fixtures. • Test client. 18
  • 77. django.test.TestCase • Fixtures. • Test client. • Email capture. 18
  • 78. django.test.TestCase • Fixtures. • Test client. • Email capture. • Database management. 18
  • 79. django.test.TestCase • Fixtures. • Test client. • Email capture. • Database management. • Slower than unittest.TestCase. 18
  • 80. class StoryAddViewTests(TestCase): fixtures = ['authtestdata', 'newsbudget_test_data'] urls = 'newsbudget.urls' def test_story_add_get(self): r = self.client.get('/budget/stories/add/') self.assertEqual(r.status_code, 200) … def test_story_add_post(self): data = { 'title': 'Hungry cat is hungry', 'date': '2009-01-01', } r = self.client.post('/budget/stories/add/', data) self.assertEqual(r.status_code, 302) … 19
  • 81. Doctests 20
  • 82. Doctests • Easy to write & read. 20
  • 83. Doctests • Easy to write & read. • Produces self-documenting code. 20
  • 84. Doctests • Easy to write & read. • Produces self-documenting code. • Great for cases that only use assertEquals. 20
  • 85. Doctests • Easy to write & read. • Produces self-documenting code. • Great for cases that only use assertEquals. • Somewhere between unit tests and functional tests. 20
  • 86. Doctests • Easy to write & read. • Produces self-documenting code. • Great for cases that only use assertEquals. • Somewhere between unit tests and functional tests. • Difficult to debug. 20
  • 87. Doctests • Easy to write & read. • Produces self-documenting code. • Great for cases that only use assertEquals. • Somewhere between unit tests and functional tests. • Difficult to debug. • Don’t always provide useful test failures. 20
  • 88. class Choices(object): """ Easy declarative "choices" tool:: >>> STATUSES = Choices("Live", "Draft") # Acts like a choices list: >>> list(STATUSES) [(1, 'Live'), (2, 'Draft')] # Easily convert from code to verbose: >>> STATUSES.verbose(1) 'Live' # ... and vice versa: >>> STATUSES.code("Draft") 2 """ … 21
  • 89. **************************************************** File "utils.py", line 150, in __main__.Choices Failed example: STATUSES.verbose(1) Expected: 'Live' Got: 'Draft' **************************************************** 22
  • 90. Functional tests 23
  • 91. Functional tests • a.k.a “Behavior Driven Development.” 23
  • 92. Functional tests • a.k.a “Behavior Driven Development.” • “Blackbox,” holistic testing. 23
  • 93. Functional tests • a.k.a “Behavior Driven Development.” • “Blackbox,” holistic testing. • All the hardcore TDD folks look down on functional tests. 23
  • 94. Functional tests • a.k.a “Behavior Driven Development.” • “Blackbox,” holistic testing. • All the hardcore TDD folks look down on functional tests. • But they keep your boss happy. 23
  • 95. Functional tests • a.k.a “Behavior Driven Development.” • “Blackbox,” holistic testing. • All the hardcore TDD folks look down on functional tests. • But they keep your boss happy. • Easy to find problems; harder to find the actual bug. 23
  • 96. Functional testing tools 24
  • 97. Functional testing tools • django.test.Client 24
  • 98. Functional testing tools • django.test.Client • webunit 24
  • 99. Functional testing tools • django.test.Client • webunit • Twill 24
  • 100. Functional testing tools • django.test.Client • webunit • Twill • ... 24
  • 101. django.test.Client 25
  • 102. django.test.Client • Test the whole request path without running a web server. 25
  • 103. django.test.Client • Test the whole request path without running a web server. • Responses provide extra information about templates and their contexts. 25
  • 104. class StoryAddViewTests(TestCase): fixtures = ['authtestdata', 'newsbudget_test_data'] urls = 'newsbudget.urls' def test_story_add_get(self): r = self.client.get('/budget/stories/add/') self.assertEqual(r.status_code, 200) … def test_story_add_post(self): data = { 'title': 'Hungry cat is hungry', 'date': '2009-01-01', } r = self.client.post('/budget/stories/add/', data) self.assertEqual(r.status_code, 302) … 26
  • 105. Web browser testing 27
  • 106. Web browser testing • The ultimate in functional testing for web applications. 27
  • 107. Web browser testing • The ultimate in functional testing for web applications. • Run test in a web browser. 27
  • 108. Web browser testing • The ultimate in functional testing for web applications. • Run test in a web browser. • Can verify JavaScript, AJAX; even CSS. 27
  • 109. Web browser testing • The ultimate in functional testing for web applications. • Run test in a web browser. • Can verify JavaScript, AJAX; even CSS. • Test your site across supported browsers. 27
  • 110. Browser testing tools 28
  • 111. Browser testing tools • Selenium 28
  • 112. Browser testing tools • Selenium • Windmill 28
  • 113. “Exotic” testing 29
  • 114. “Exotic” testing • Static source analysis. 29
  • 115. “Exotic” testing • Static source analysis. • Smoke testing (crawlers and spiders). 29
  • 116. “Exotic” testing • Static source analysis. • Smoke testing (crawlers and spiders). • Monkey testing. 29
  • 117. “Exotic” testing • Static source analysis. • Smoke testing (crawlers and spiders). • Monkey testing. • Load testing. 29
  • 118. “Exotic” testing • Static source analysis. • Smoke testing (crawlers and spiders). • Monkey testing. • Load testing. • ... 29
  • 119. 30
  • 120. Further resources 31
  • 121. Further resources • Windmill talk here at OSCON http://bit.ly/14tkrd 31
  • 122. Further resources • Windmill talk here at OSCON http://bit.ly/14tkrd • Django testing documentation http://bit.ly/django-testing 31
  • 123. Further resources • Windmill talk here at OSCON http://bit.ly/14tkrd • Django testing documentation http://bit.ly/django-testing • Python Testing Tools Taxonomy http://bit.ly/py-testing-tools 31
  • 124. Structuring applications for reuse 32
  • 125. Designing for reuse 33
  • 126. Designing for reuse • Do one thing, and do it well. 33
  • 127. Designing for reuse • Do one thing, and do it well. • Don’t be afraid of multiple apps. 33
  • 128. Designing for reuse • Do one thing, and do it well. • Don’t be afraid of multiple apps. • Write for flexibility. 33
  • 129. Designing for reuse • Do one thing, and do it well. • Don’t be afraid of multiple apps. • Write for flexibility. • Build to distribute. 33
  • 130. Designing for reuse • Do one thing, and do it well. • Don’t be afraid of multiple apps. • Write for flexibility. • Build to distribute. • Extend carefully. 33
  • 131. 1. Do one thing, and do it well. 34
  • 132. Application == encapsulation 35
  • 133. Focus 36
  • 134. Focus • Ask yourself: “What does this application do?” 36
  • 135. Focus • Ask yourself: “What does this application do?” • Answer should be one or two short sentences. 36
  • 136. Good focus 37
  • 137. Good focus • “Handle storage of users and authentication of their identities.” 37
  • 138. Good focus • “Handle storage of users and authentication of their identities.” • “Allow content to be tagged, del.icio.us style, with querying by tags.” 37
  • 139. Good focus • “Handle storage of users and authentication of their identities.” • “Allow content to be tagged, del.icio.us style, with querying by tags.” • “Handle entries in a weblog.” 37
  • 140. Bad focus 38
  • 141. Bad focus • “Handle entries in a weblog, and users who post them, and their authentication, and tagging and categorization, and some flat pages for static content, and...” 38
  • 142. Warning signs 39
  • 143. Warning signs • Lots of files. 39
  • 144. Warning signs • Lots of files. • Lots of modules. 39
  • 145. Warning signs • Lots of files. • Lots of modules. • Lots of models. 39
  • 146. Warning signs • Lots of files. • Lots of modules. • Lots of models. • Lots of code. 39
  • 147. Small is good 40
  • 148. Small is good • Many great Django apps are very small. 40
  • 149. Small is good • Many great Django apps are very small. • Even a lot of “simple” Django sites commonly have a dozen or more applications in INSTALLED_APPS. 40
  • 150. Small is good • Many great Django apps are very small. • Even a lot of “simple” Django sites commonly have a dozen or more applications in INSTALLED_APPS. • If you’ve got a complex site and a short application list, something’s probably wrong. 40
  • 151. Approach features skeptically 41
  • 152. Approach features skeptically • What does the application do? 41
  • 153. Approach features skeptically • What does the application do? • Does this feature have anything to do with that? 41
  • 154. Approach features skeptically • What does the application do? • Does this feature have anything to do with that? • No? Don’t add it. 41
  • 155. 2. Don’t be afraid of many apps. 42
  • 156. The monolith anti-pattern 43
  • 157. The monolith anti-pattern • The “application” is the whole site. 43
  • 158. The monolith anti-pattern • The “application” is the whole site. • Re-use? YAGNI. 43
  • 159. The monolith anti-pattern • The “application” is the whole site. • Re-use? YAGNI. • Plugins that hook into the “main” application. 43
  • 160. The monolith anti-pattern • The “application” is the whole site. • Re-use? YAGNI. • Plugins that hook into the “main” application. • Heavy use of middleware-like concepts. 43
  • 161. (I blame Rails) 44
  • 162. The Django mindset 45
  • 163. The Django mindset • Application: some bit of functionality. 45
  • 164. The Django mindset • Application: some bit of functionality. • Site: several applications. 45
  • 165. The Django mindset • Application: some bit of functionality. • Site: several applications. • Spin off new “apps” liberally. 45
  • 166. The Django mindset • Application: some bit of functionality. • Site: several applications. • Spin off new “apps” liberally. • Develop a suite of apps ready for when they’re needed. 45
  • 167. Django encourages this 46
  • 168. Django encourages this • INSTALLED_APPS 46
  • 169. Django encourages this • INSTALLED_APPS • Applications are just Python packages, not some Django-specific “app” or “plugin.” 46
  • 170. Django encourages this • INSTALLED_APPS • Applications are just Python packages, not some Django-specific “app” or “plugin.” • Abstractions like django.contrib.sites make you think about this as you develop. 46
  • 171. Spin off a new app? 47
  • 172. Spin off a new app? • Is this feature unrelated to the app’s focus? 47
  • 173. Spin off a new app? • Is this feature unrelated to the app’s focus? • Is it orthogonal to the rest of the app? 47
  • 174. Spin off a new app? • Is this feature unrelated to the app’s focus? • Is it orthogonal to the rest of the app? • Will I need similar functionality again? 47
  • 175. The ideal: 48
  • 176. I need a contact form 49
  • 177. urlpatterns = ('', … (r'^contact/', include('contact_form.urls')), … ) 50
  • 178. Done. (http://bitbucket.org/ubernostrum/django-contact-form/) 51
  • 179. But… what about… 52
  • 180. But… what about… • Site A wants a contact form that just collects a message. 52
  • 181. But… what about… • Site A wants a contact form that just collects a message. • Site B’s marketing department wants a bunch of info. 52
  • 182. But… what about… • Site A wants a contact form that just collects a message. • Site B’s marketing department wants a bunch of info. • Site C wants to use Akismet to filter automated spam. 52
  • 183. 53
  • 184. 53
  • 185. 3. Write for flexibility. 54
  • 186. Common sense 55
  • 187. Common sense • Sane defaults. 55
  • 188. Common sense • Sane defaults. • Easy overrides. 55
  • 189. Common sense • Sane defaults. • Easy overrides. • Don’t set anything in stone. 55
  • 190. Forms 56
  • 191. Forms • Supply a form class. 56
  • 192. Forms • Supply a form class. • Let users specify their own. 56
  • 193. Templates 57
  • 194. Templates • Specify a default template. 57
  • 195. Templates • Specify a default template. • Let users specify their own. 57
  • 196. Form processing 58
  • 197. Form processing • You want to redirect after successful submission. 58
  • 198. Form processing • You want to redirect after successful submission. • Supply a default URL. 58
  • 199. Form processing • You want to redirect after successful submission. • Supply a default URL. • (Preferably by using reverse resolution). 58
  • 200. Form processing • You want to redirect after successful submission. • Supply a default URL. • (Preferably by using reverse resolution). • Let users override the default. 58
  • 201. def edit_entry(request, entry_id): form = EntryForm(request.POST or None) if form.is_valid(): form.save() return redirect('entry_detail', entry_id) return render_to_response('entry/form.html', {…}) 59
  • 202. def edit_entry(request, entry_id, form_class=EntryForm, template_name='entry/form.html', post_save_redirect=None): form = form_class(request.POST or None) if form.is_valid(): form.save() if post_save_redirect: return redirect(post_save_redirect) else: return redirect('entry_detail', entry_id) return render_to_response([template_name, 'entry/form.html'], {…}) 60
  • 203. URLs 61
  • 204. URLs • Provide a URLConf with all views. 61
  • 205. URLs • Provide a URLConf with all views. • Use named URL patterns. 61
  • 206. URLs • Provide a URLConf with all views. • Use named URL patterns. • Use reverse lookups (by name). 61
  • 207. 4. Build to distribute (even private code). 62
  • 208. What the tutorial teaches myproject/ settings.py urls.py myapp/ models.py mysecondapp/ views.py … 63
  • 209. from myproject.myapp.models import … from myproject. myapp.models import … … myproject.settings myproject.urls 64
  • 210. Project coupling kills re-use 65
  • 211. Projects in real life. 66
  • 212. Projects in real life. • A settings module. 66
  • 213. Projects in real life. • A settings module. • A root URLConf. 66
  • 214. Projects in real life. • A settings module. • A root URLConf. • Maybe a manage.py (but…) 66
  • 215. Projects in real life. • A settings module. • A root URLConf. • Maybe a manage.py (but…) • And that’s it. 66
  • 216. Advantages 67
  • 217. Advantages • No assumptions about where things live. 67
  • 218. Advantages • No assumptions about where things live. • No PYTHONPATH magic. 67
  • 219. Advantages • No assumptions about where things live. • No PYTHONPATH magic. • Reminds you that “projects” are just a Python module. 67
  • 220. You don’t even need a project 68
  • 221. ljworld.com: 69
  • 222. ljworld.com: • worldonline.settings.ljworld 69
  • 223. ljworld.com: • worldonline.settings.ljworld • worldonline.urls.ljworld 69
  • 224. ljworld.com: • worldonline.settings.ljworld • worldonline.urls.ljworld • And a whole bunch of apps. 69
  • 225. Where apps really live 70
  • 226. Where apps really live • Single module directly on Python path (registration, tagging, etc.). 70
  • 227. Where apps really live • Single module directly on Python path (registration, tagging, etc.). • Related modules under a top-level package (ellington.events, ellington.podcasts, etc.) 70
  • 228. Where apps really live • Single module directly on Python path (registration, tagging, etc.). • Related modules under a top-level package (ellington.events, ellington.podcasts, etc.) • No projects (ellington.settings doesn’t exist). 70
  • 229. Want to distribute? 71
  • 230. Want to distribute? • Build a package with distutils/setuptools. 71
  • 231. Want to distribute? • Build a package with distutils/setuptools. • Put it on PyPI (or a private package server). 71
  • 232. Want to distribute? • Build a package with distutils/setuptools. • Put it on PyPI (or a private package server). • Now it works with easy_install, pip, buildout, … 71
  • 233. General best practices 72
  • 234. General best practices • Establish dependancy rules. 72
  • 235. General best practices • Establish dependancy rules. • Establish a minimum Python version (suggestion: Python 2.5). 72
  • 236. General best practices • Establish dependancy rules. • Establish a minimum Python version (suggestion: Python 2.5). • Establish a minimum Django version (suggestion: Django 1.0). 72
  • 237. General best practices • Establish dependancy rules. • Establish a minimum Python version (suggestion: Python 2.5). • Establish a minimum Django version (suggestion: Django 1.0). • Test frequently against new versions of dependancies. 72
  • 238. Document obsessively. 73
  • 239. 5. Embrace and extend. 74
  • 240. Don’t touch! 75
  • 241. Don’t touch! • Good applications are extensible without patching. 75
  • 242. Don’t touch! • Good applications are extensible without patching. • Take advantage of every extensibility point an application gives you. 75
  • 243. Don’t touch! • Good applications are extensible without patching. • Take advantage of every extensibility point an application gives you. • You may end up doing something that deserves a new application anyway. 75
  • 244. But this application wasn’t meant to be extended! 76
  • 245. Python Power! 77
  • 246. Extending a view 78
  • 247. Extending a view • Wrap the view with your own code. 78
  • 248. Extending a view • Wrap the view with your own code. • Doing it repetitively? Write a decorator. 78
  • 249. Extending a model 79
  • 250. Extending a model • Relate other models to it. 79
  • 251. Extending a model • Relate other models to it. • Subclass it. 79
  • 252. Extending a model • Relate other models to it. • Subclass it. • Proxy subclasses (Django 1.1). 79
  • 253. Extending a form 80
  • 254. Extending a form • Subclass it. 80
  • 255. Extending a form • Subclass it. • There is no step 2. 80
  • 256. Other tricks 81
  • 257. Other tricks • Signals lets you fire off customized behavior when certain events happen. 81
  • 258. Other tricks • Signals lets you fire off customized behavior when certain events happen. • Middleware offers full control over request/response handling. 81
  • 259. Other tricks • Signals lets you fire off customized behavior when certain events happen. • Middleware offers full control over request/response handling. • Context processors can make additional information available if a view doesn’t. 81
  • 260. If you must make changes to external code… 82
  • 261. Keep changes to a minimum 83
  • 262. Keep changes to a minimum • If possible, instead of adding a feature, add extensibility. 83
  • 263. Keep changes to a minimum • If possible, instead of adding a feature, add extensibility. • Keep as much changed code as you can out of the original app. 83
  • 264. Stay up-to-date 84
  • 265. Stay up-to-date • Don’t want to get out of sync with the original version of the code! 84
  • 266. Stay up-to-date • Don’t want to get out of sync with the original version of the code! • You might miss bugfixes. 84
  • 267. Stay up-to-date • Don’t want to get out of sync with the original version of the code! • You might miss bugfixes. • You might even miss the feature you needed. 84
  • 268. Use a good VCS 85
  • 269. Use a good VCS • Subversion vendor branches don’t cut it. 85
  • 270. Use a good VCS • Subversion vendor branches don’t cut it. • DVCSes are perfect for this: 85
  • 271. Use a good VCS • Subversion vendor branches don’t cut it. • DVCSes are perfect for this: • Mercurial queues. 85
  • 272. Use a good VCS • Subversion vendor branches don’t cut it. • DVCSes are perfect for this: • Mercurial queues. • Git rebasing. 85
  • 273. Use a good VCS • Subversion vendor branches don’t cut it. • DVCSes are perfect for this: • Mercurial queues. • Git rebasing. • At the very least, maintain a patch queue by hand. 85
  • 274. Be a good citizen 86
  • 275. Be a good citizen • If you change someone else’s code, let them know. 86
  • 276. Be a good citizen • If you change someone else’s code, let them know. • Maybe they’ll merge your changes in and you won’t have to fork anymore. 86
  • 277. Further reading 87
  • 278. Deployment 88
  • 279. Deployment should... 89
  • 280. Deployment should... • Be automated. 89
  • 281. Deployment should... • Be automated. • Automatically manage dependencies. 89
  • 282. Deployment should... • Be automated. • Automatically manage dependencies. • Be isolated. 89
  • 283. Deployment should... • Be automated. • Automatically manage dependencies. • Be isolated. • Be repeatable. 89
  • 284. Deployment should... • Be automated. • Automatically manage dependencies. • Be isolated. • Be repeatable. • Be identical in staging and in production. 89
  • 285. Deployment should... • Be automated. • Automatically manage dependencies. • Be isolated. • Be repeatable. • Be identical in staging and in production. • Work the same for everyone. 89
  • 286. Dependency Isolation Automation management 90
  • 287. Dependency Isolation Automation management 90
  • 288. Dependency Isolation Automation management apt/yum/... virtualenv Capistrano easy_install zc.buildout Fabric pip Puppet/Chef/… zc.buildout 90
  • 289. Dependency Isolation Automation management apt/yum/... virtualenv Capistrano easy_install zc.buildout Fabric pip Puppet/Chef/… zc.buildout 90
  • 290. Dependency Isolation Automation management apt/yum/... virtualenv Capistrano easy_install zc.buildout Fabric pip Puppet/Chef/… zc.buildout 90
  • 291. Dependancy management 91
  • 292. Dependancy management • The Python ecosystem rocks! 91
  • 293. Dependancy management • The Python ecosystem rocks! • Python package management doesn’t. 91
  • 294. Dependancy management • The Python ecosystem rocks! • Python package management doesn’t. • Installing packages — and dependancies — correctly is a lot harder than it should be; most defaults are wrong. 91
  • 295. Dependancy management • The Python ecosystem rocks! • Python package management doesn’t. • Installing packages — and dependancies — correctly is a lot harder than it should be; most defaults are wrong. • Here be dragons. 91
  • 296. Vendor packages 92
  • 297. Vendor packages • APT, Yum, … 92
  • 298. Vendor packages • APT, Yum, … • The good: familiar tools; stability; handles dependancies not on PyPI. 92
  • 299. Vendor packages • APT, Yum, … • The good: familiar tools; stability; handles dependancies not on PyPI. • The bad: small selection; not (very) portable; hard to supply user packages. 92
  • 300. Vendor packages • APT, Yum, … • The good: familiar tools; stability; handles dependancies not on PyPI. • The bad: small selection; not (very) portable; hard to supply user packages. • The ugly: installs packages system-wide. 92
  • 301. easy_install 93
  • 302. easy_install • The good: multi-version packages. 93
  • 303. easy_install • The good: multi-version packages. • The bad: requires ‘net connection; can’t uninstall; can’t handle non-PyPI packages; multi-version packages barely work. 93
  • 304. easy_install • The good: multi-version packages. • The bad: requires ‘net connection; can’t uninstall; can’t handle non-PyPI packages; multi-version packages barely work. • The ugly: stale; unsupported; defaults almost totally wrong; installs system-wide. 93
  • 305. pip http://pip.openplans.org/ 94
  • 306. pip http://pip.openplans.org/ • “Pip Installs Packages” 94
  • 307. pip http://pip.openplans.org/ • “Pip Installs Packages” • The good: Just Works™; handles non- PyPI packages (including direct from SCM); repeatable dependancies; integrates with virtualenv for isolation. 94
  • 308. pip http://pip.openplans.org/ • “Pip Installs Packages” • The good: Just Works™; handles non- PyPI packages (including direct from SCM); repeatable dependancies; integrates with virtualenv for isolation. • The bad: still young; not yet bundled. 94
  • 309. pip http://pip.openplans.org/ • “Pip Installs Packages” • The good: Just Works™; handles non- PyPI packages (including direct from SCM); repeatable dependancies; integrates with virtualenv for isolation. • The bad: still young; not yet bundled. • The ugly: haven’t found it yet. 94
  • 310. zc.buildout http://buildout.org/ 95
  • 311. zc.buildout http://buildout.org/ • The good: incredibly flexible; handles any sort of dependancy; repeatable builds; reusable “recipes;” good ecosystem; handles isolation, too. 95
  • 312. zc.buildout http://buildout.org/ • The good: incredibly flexible; handles any sort of dependancy; repeatable builds; reusable “recipes;” good ecosystem; handles isolation, too. • The bad: often cryptic, INI-style configuration file; confusing duplication of recipes; sometimes too flexible. 95
  • 313. zc.buildout http://buildout.org/ • The good: incredibly flexible; handles any sort of dependancy; repeatable builds; reusable “recipes;” good ecosystem; handles isolation, too. • The bad: often cryptic, INI-style configuration file; confusing duplication of recipes; sometimes too flexible. • The ugly: nearly completely undocumented. 95
  • 314. Package isolation 96
  • 315. Package isolation • Why? 96
  • 316. Package isolation • Why? • Site A requires Foo v1.0; site B requires Foo v2.0. 96
  • 317. Package isolation • Why? • Site A requires Foo v1.0; site B requires Foo v2.0. • You need to develop against multiple versions of dependancies. 96
  • 318. Package isolation tools 97
  • 319. Package isolation tools • Virtual machines (Xen, VMWare, EC2, …) 97
  • 320. Package isolation tools • Virtual machines (Xen, VMWare, EC2, …) • Multiple Python installations. 97
  • 321. Package isolation tools • Virtual machines (Xen, VMWare, EC2, …) • Multiple Python installations. • “Virtual” Python installations. 97
  • 322. Package isolation tools • Virtual machines (Xen, VMWare, EC2, …) • Multiple Python installations. • “Virtual” Python installations. • virtualenv http://pypi.python.org/pypi/virtualenv 97
  • 323. Package isolation tools • Virtual machines (Xen, VMWare, EC2, …) • Multiple Python installations. • “Virtual” Python installations. • virtualenv http://pypi.python.org/pypi/virtualenv • zc.buildout http://buildout.org/ 97
  • 324. Why automate? 98
  • 325. Why automate? • “I can’t push this fix to the servers until Alex gets back from lunch.” 98
  • 326. Why automate? • “I can’t push this fix to the servers until Alex gets back from lunch.” • “Sorry, I can’t fix that. I’m new here.” 98
  • 327. Why automate? • “I can’t push this fix to the servers until Alex gets back from lunch.” • “Sorry, I can’t fix that. I’m new here.” • “Oops, I just made the wrong version of our site live.” 98
  • 328. Why automate? • “I can’t push this fix to the servers until Alex gets back from lunch.” • “Sorry, I can’t fix that. I’m new here.” • “Oops, I just made the wrong version of our site live.” • “It’s broken! What’d you do!?” 98
  • 329. Automation basics 99
  • 330. Automation basics • SSH is right out. 99
  • 331. Automation basics • SSH is right out. • Don’t futz with the server. Write a recipe. 99
  • 332. Automation basics • SSH is right out. • Don’t futz with the server. Write a recipe. • Deploys should be idempotent. 99
  • 333. Capistrano http://capify.org/ 100
  • 334. Capistrano http://capify.org/ • The good: lots of features; good documentation; active community. 100
  • 335. Capistrano http://capify.org/ • The good: lots of features; good documentation; active community. • The bad: stale development; very “opinionated” and Rails-oriented. 100
  • 336. Fabric http://fabfile.org/ 101
  • 337. Fabric http://fabfile.org/ • The good: very simple; flexible; actively developed; Python. 101
  • 338. Fabric http://fabfile.org/ • The good: very simple; flexible; actively developed; Python. • The bad: no high-level commands; in flux. 101
  • 339. Configuration management 102
  • 340. Configuration management • CFEngine, Puppet, Chef, … 102
  • 341. Configuration management • CFEngine, Puppet, Chef, … • Will handle a lot more than code deployment! 102
  • 342. Configuration management • CFEngine, Puppet, Chef, … • Will handle a lot more than code deployment! • I only know a little about these. 102
  • 343. Recommendations Pip, Virtualenv, and Fabric Buildout and Fabric. Buildout and Puppet/Chef/…. Utility computing and Puppet/Chef/…. 103
  • 344. Production environments 104
  • 345. net. LiveJournal Backend: Today (Roughly.) BIG-IP perlbal (httpd/proxy) Global Database bigip1 mod_perl bigip2 proxy1 master_a master_b web1 proxy2 web2 proxy3 web3 Memcached slave1 slave2 ... slave5 djabberd proxy4 mc1 web4 djabberd proxy5 ... mc2 User DB Cluster 1 djabberd webN mc3 uc1a uc1b mc4 User DB Cluster 2 ... uc2a uc2b gearmand Mogile Storage Nodes gearmand1 mcN User DB Cluster 3 sto1 sto2 gearmandN uc3a uc3b Mogile Trackers ... sto8 tracker1 tracker3 User DB Cluster N ucNa ucNb MogileFS Database “workers” gearwrkN Job Queues (xN) mog_a mog_b theschwkN jqNa jqNb slave1 slaveN http://danga.com/words/ Brad Fitzpatrik, http://danga.com/words/2007_06_usenix/ 3 105
  • 346. django database media server 106
  • 347. Application servers 107
  • 348. Application servers • Apache + mod_python 107
  • 349. Application servers • Apache + mod_python • Apache + mod_wsgi 107
  • 350. Application servers • Apache + mod_python • Apache + mod_wsgi • Apache/lighttpd + FastCGI 107
  • 351. Application servers • Apache + mod_python • Apache + mod_wsgi • Apache/lighttpd + FastCGI • SCGI, AJP, nginx/mod_wsgi, ... 107
  • 352. Use mod_wsgi 108
  • 353. WSGIScriptAlias / /home/mysite/mysite.wsgi 109
  • 354. import os, sys # Add to PYTHONPATH whatever you need sys.path.append('/usr/local/django') # Set DJANGO_SETTINGS_MODULE os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' # Create the application for mod_wsgi import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() 110
  • 355. “Scale” 111
  • 356. Does this scale? django database media server 112
  • 357. Does this scale? django database media server Maybe! 112
  • 358. Things per secong Number of things 113
  • 359. Real-world example Database A 175 req/s Database B 75 req/s 114
  • 360. Real-world example http://tweakers.net/reviews/657/6 115
  • 361. django media web server database database server 116
  • 362. Why separate hardware? 117
  • 363. Why separate hardware? • Resource contention 117
  • 364. Why separate hardware? • Resource contention • Separate performance concerns 117
  • 365. Why separate hardware? • Resource contention • Separate performance concerns • 0 → 1 is much harder than 1 → N 117
  • 366. DATABASE_HOST = '10.0.0.100' 118
  • 367. DATABASE_HOST = '10.0.0.100' FAIL 118
  • 368. Connection middleware 119
  • 369. Connection middleware • Proxy between web and database layers 119
  • 370. Connection middleware • Proxy between web and database layers • Most implement hot fallover and connection pooling 119
  • 371. Connection middleware • Proxy between web and database layers • Most implement hot fallover and connection pooling • Some also provide replication, load balancing, parallel queries, connection limiting, &c 119
  • 372. Connection middleware • Proxy between web and database layers • Most implement hot fallover and connection pooling • Some also provide replication, load balancing, parallel queries, connection limiting, &c • DATABASE_HOST = '127.0.0.1' 119
  • 373. Connection middleware 120
  • 374. Connection middleware • PostgreSQL: pgpool 120
  • 375. Connection middleware • PostgreSQL: pgpool • MySQL: MySQL Proxy 120
  • 376. Connection middleware • PostgreSQL: pgpool • MySQL: MySQL Proxy • Database-agnostic: sqlrelay 120
  • 377. Connection middleware • PostgreSQL: pgpool • MySQL: MySQL Proxy • Database-agnostic: sqlrelay • Oracle: ? 120
  • 378. django media web server media server database database server 121
  • 379. Media server traits 122
  • 380. Media server traits • Fast 122
  • 381. Media server traits • Fast • Lightweight 122
  • 382. Media server traits • Fast • Lightweight • Optimized for high concurrency 122
  • 383. Media server traits • Fast • Lightweight • Optimized for high concurrency • Low memory overhead 122
  • 384. Media server traits • Fast • Lightweight • Optimized for high concurrency • Low memory overhead • Good HTTP citizen 122
  • 385. Media servers 123
  • 386. Media servers • Apache? 123
  • 387. Media servers • Apache? • lighttpd 123
  • 388. Media servers • Apache? • lighttpd • nginx 123
  • 389. Media servers • Apache? • lighttpd • nginx • S3 123
  • 390. The absolute minimum django media web server media server database database server 124
  • 391. The absolute minimum django media database web server 125
  • 392. proxy media load balancer media server django django django web server cluster database database server 126
  • 393. Why load balancers? 127
  • 394. Load balancer traits 128
  • 395. Load balancer traits • Low memory overhead 128
  • 396. Load balancer traits • Low memory overhead • High concurrency 128
  • 397. Load balancer traits • Low memory overhead • High concurrency • Hot fallover 128
  • 398. Load balancer traits • Low memory overhead • High concurrency • Hot fallover • Other nifty features... 128
  • 399. Load balancers 129
  • 400. Load balancers • Apache + mod_proxy 129
  • 401. Load balancers • Apache + mod_proxy • perlbal 129
  • 402. Load balancers • Apache + mod_proxy • perlbal • nginx 129
  • 403. Load balancers • Apache + mod_proxy • perlbal • nginx • Varnish 129
  • 404. Load balancers • Apache + mod_proxy • perlbal • nginx • Varnish • Squid 129
  • 405. CREATE POOL mypool POOL mypool ADD 10.0.0.100 POOL mypool ADD 10.0.0.101 CREATE SERVICE mysite SET listen = my.public.ip SET role = reverse_proxy SET pool = mypool SET verify_backend = on SET buffer_size = 120k ENABLE mysite 130
  • 406. you@yourserver:~$ telnet localhost 60000 pool mysite add 10.0.0.102 OK nodes 10.0.0.101 10.0.0.101 lastresponse 1237987449 10.0.0.101 requests 97554563 10.0.0.101 connects 129242435 10.0.0.101 lastconnect 1237987449 10.0.0.101 attempts 129244743 10.0.0.101 responsecodes 200 358 10.0.0.101 responsecodes 302 14 10.0.0.101 responsecodes 207 99 10.0.0.101 responsecodes 301 11 10.0.0.101 responsecodes 404 18 10.0.0.101 lastattempt 1237987449 131
  • 407. proxy proxy proxy media media load balancing cluster media server cluster django django django cache cache web server cluster cache cluster database database database database server cluster 132
  • 408. “Shared nothing” 133
  • 409. BALANCE = None def balance_sheet(request): global BALANCE if not BALANCE: bank = Bank.objects.get(...) BALANCE = bank.total_balance() ... 134
  • 410. BALANCE = None def balance_sheet(request): global BALANCE if not BALANCE: bank = Bank.objects.get(...) BALANCE = bank.total_balance() ... FAIL 134
  • 411. Global variables are right out 135
  • 412. from django.cache import cache def balance_sheet(request): balance = cache.get('bank_balance') if not balance: bank = Bank.objects.get(...) balance = bank.total_balance() cache.set('bank_balance', balance) ... 136
  • 413. from django.cache import cache def balance_sheet(request): balance = cache.get('bank_balance') if not balance: bank = Bank.objects.get(...) balance = bank.total_balance() cache.set('bank_balance', balance) ... WIN 136
  • 414. def generate_report(request): report = get_the_report() open('/tmp/report.txt', 'w').write(report) return redirect(view_report) def view_report(request): report = open('/tmp/report.txt').read() return HttpResponse(report) 137
  • 415. def generate_report(request): report = get_the_report() open('/tmp/report.txt', 'w').write(report) return redirect(view_report) def view_report(request): report = open('/tmp/report.txt').read() return HttpResponse(report) FAIL 137
  • 416. Filesystem? What filesystem? 138
  • 417. Further reading 139
  • 418. Further reading • Cal Henderson, Building Scalable Web Sites 139
  • 419. Further reading • Cal Henderson, Building Scalable Web Sites • John Allspaw, The Art of Capacity Planning 139
  • 420. Further reading • Cal Henderson, Building Scalable Web Sites • John Allspaw, The Art of Capacity Planning • http://kitchensoap.com/ 139
  • 421. Further reading • Cal Henderson, Building Scalable Web Sites • John Allspaw, The Art of Capacity Planning • http://kitchensoap.com/ • http://highscalability.com/ 139
  • 422. Monitoring 140
  • 423. Goals 141
  • 424. Goals • When the site goes down, know it immediately. 141
  • 425. Goals • When the site goes down, know it immediately. • Automatically handle common sources of downtime. 141
  • 426. Goals • When the site goes down, know it immediately. • Automatically handle common sources of downtime. • Ideally, handle downtime before it even happens. 141
  • 427. Goals • When the site goes down, know it immediately. • Automatically handle common sources of downtime. • Ideally, handle downtime before it even happens. • Monitor hardware usage to identify hotspots and plan for future growth. 141
  • 428. Goals • When the site goes down, know it immediately. • Automatically handle common sources of downtime. • Ideally, handle downtime before it even happens. • Monitor hardware usage to identify hotspots and plan for future growth. • Aid in postmortem analysis. 141
  • 429. Goals • When the site goes down, know it immediately. • Automatically handle common sources of downtime. • Ideally, handle downtime before it even happens. • Monitor hardware usage to identify hotspots and plan for future growth. • Aid in postmortem analysis. • Generate pretty graphs. 141
  • 430. Availability monitoring principles 142
  • 431. Availability monitoring principles • Check services for availability. 142
  • 432. Availability monitoring principles • Check services for availability. • More then just “ping yoursite.com.” 142
  • 433. Availability monitoring principles • Check services for availability. • More then just “ping yoursite.com.” • Have some understanding of dependancies. 142
  • 434. Availability monitoring principles • Check services for availability. • More then just “ping yoursite.com.” • Have some understanding of dependancies. • Notify the “right” people using the “right” methods, and don’t stop until it’s fixed. 142
  • 435. Availability monitoring principles • Check services for availability. • More then just “ping yoursite.com.” • Have some understanding of dependancies. • Notify the “right” people using the “right” methods, and don’t stop until it’s fixed. • Minimize false positives. 142
  • 436. Availability monitoring principles • Check services for availability. • More then just “ping yoursite.com.” • Have some understanding of dependancies. • Notify the “right” people using the “right” methods, and don’t stop until it’s fixed. • Minimize false positives. • Automatically take action against common sources of downtime. 142
  • 437. Availability monitoring tools 143
  • 438. Availability monitoring tools • Internal tools 143
  • 439. Availability monitoring tools • Internal tools • Nagios 143
  • 440. Availability monitoring tools • Internal tools • Nagios • Monit 143
  • 441. Availability monitoring tools • Internal tools • Nagios • Monit • Zenoss 143
  • 442. Availability monitoring tools • Internal tools • Nagios • Monit • Zenoss • ... 143
  • 443. Availability monitoring tools • Internal tools • Nagios • Monit • Zenoss • ... • External monitoring tools 143
  • 444. Usage monitoring 144
  • 445. Usage monitoring • Keep track of resource usage over time. 144
  • 446. Usage monitoring • Keep track of resource usage over time. • Spot and identify trends. 144
  • 447. Usage monitoring • Keep track of resource usage over time. • Spot and identify trends. • Aid in capacity planning and management. 144
  • 448. Usage monitoring • Keep track of resource usage over time. • Spot and identify trends. • Aid in capacity planning and management. • Look good in reports to your boss. 144
  • 449. Usage monitoring tools 145
  • 450. Usage monitoring tools • RRDTool 145
  • 451. Usage monitoring tools • RRDTool • Munin 145
  • 452. Usage monitoring tools • RRDTool • Munin • Cacti 145
  • 453. Usage monitoring tools • RRDTool • Munin • Cacti • Graphite 145
  • 454. 146
  • 455. 147
  • 456. Logging 148
  • 457. Logging • Record information about what’s happening right now. 148
  • 458. Logging • Record information about what’s happening right now. • Analyze historical data for trends. 148
  • 459. Logging • Record information about what’s happening right now. • Analyze historical data for trends. • Provide postmortem information after failures. 148
  • 460. Logging tools 149
  • 461. Logging tools • print 149
  • 462. Logging tools • print • Python’s logging module 149
  • 463. Logging tools • print • Python’s logging module • syslogd 149
  • 464. Log analysis 150
  • 465. Log analysis • grep | sort | uniq -c | sort -rn 150
  • 466. Log analysis • grep | sort | uniq -c | sort -rn • Load log data into relational databases, then slice & dice. 150
  • 467. Log analysis • grep | sort | uniq -c | sort -rn • Load log data into relational databases, then slice & dice. • OLAP/OLTP engines. 150
  • 468. Log analysis • grep | sort | uniq -c | sort -rn • Load log data into relational databases, then slice & dice. • OLAP/OLTP engines. • Splunk. 150
  • 469. Log analysis • grep | sort | uniq -c | sort -rn • Load log data into relational databases, then slice & dice. • OLAP/OLTP engines. • Splunk. • Analog, AWStats, ... 150
  • 470. Log analysis • grep | sort | uniq -c | sort -rn • Load log data into relational databases, then slice & dice. • OLAP/OLTP engines. • Splunk. • Analog, AWStats, ... • Google Analytics, Mint, ... 150
  • 471. What to monitor? 151
  • 472. What to monitor? • Everything possible. 151
  • 473. What to monitor? • Everything possible. • The answer to “should I monitor this?” is always “yes.” 151
  • 474. Performance And when you should care. 152
  • 475. Ignore performance 153
  • 476. Ignore performance Step 1: write your app. 153
  • 477. Ignore performance Step 1: write your app. Step 2: make it work. 153
  • 478. Ignore performance Step 1: write your app. Step 2: make it work. Step 3: get it live. 153
  • 479. Ignore performance Step 1: write your app. Step 2: make it work. Step 3: get it live. Step 4: get some users. 153
  • 480. Ignore performance Step 1: write your app. Step 2: make it work. Step 3: get it live. Step 4: get some users. … 153
  • 481. Ignore performance Step 1: write your app. Step 2: make it work. Step 3: get it live. Step 4: get some users. … Step 94,211: tune. 153
  • 482. Ignore performance 154
  • 483. Ignore performance • Code isn’t “fast” or “slow” until it’s deployed in production. 154
  • 484. Ignore performance • Code isn’t “fast” or “slow” until it’s deployed in production. • That said, often bad code is obvious. So don’t write it. 154
  • 485. Ignore performance • Code isn’t “fast” or “slow” until it’s deployed in production. • That said, often bad code is obvious. So don’t write it. • YAGNI doesn’t mean you get to be an idiot. 154
  • 486. Low-hanging fruit 155
  • 487. Low-hanging fruit • Lots of DB queries. 155
  • 488. Low-hanging fruit • Lots of DB queries. • Rule of thumb: O(1) queries per view. 155
  • 489. Low-hanging fruit • Lots of DB queries. • Rule of thumb: O(1) queries per view. • Very complex queries. 155
  • 490. Low-hanging fruit • Lots of DB queries. • Rule of thumb: O(1) queries per view. • Very complex queries. • Read-heavy vs. write-heavy. 155
  • 491. Anticipate bottlenecks 156
  • 492. Anticipate bottlenecks • It’s probably going to be your DB. 156
  • 493. Anticipate bottlenecks • It’s probably going to be your DB. • If not, it’ll be I/O. 156
  • 494. “It’s slow!” 157
  • 495. Define “slow” 158
  • 496. Define “slow” • Benchmark in the browser. 158
  • 497. Define “slow” • Benchmark in the browser. • Compare to wget/curl. 158
  • 498. Define “slow” • Benchmark in the browser. • Compare to wget/curl. • The results can be surprising. 158
  • 499. Define “slow” • Benchmark in the browser. • Compare to wget/curl. • The results can be surprising. • Often, “slow” is a matter of perceived performance. 158
  • 500. 159
  • 501. YSlow http://developer.yahoo.com/yslow/ 160
  • 502. Server-side performance tuning 161
  • 503. Tuning in a nutshell 162
  • 504. Tuning in a nutshell • Cache. 162
  • 505. Tuning in a nutshell • Cache. • Cache some more. 162
  • 506. Tuning in a nutshell • Cache. • Cache some more. • Improve your caching strategy. 162
  • 507. Tuning in a nutshell • Cache. • Cache some more. • Improve your caching strategy. • Add more cache layers. 162
  • 508. Tuning in a nutshell • Cache. • Cache some more. • Improve your caching strategy. • Add more cache layers. • Then, maybe, tune your code. 162
  • 509. Caching is magic 163
  • 510. Caching is magic • Turns less hardware into more! 163
  • 511. Caching is magic • Turns less hardware into more! • Makes slow code fast! 163
  • 512. Caching is magic • Turns less hardware into more! • Makes slow code fast! • Lowers hardware budgets! 163
  • 513. Caching is magic • Turns less hardware into more! • Makes slow code fast! • Lowers hardware budgets! • Delays the need for new servers! 163
  • 514. Caching is magic • Turns less hardware into more! • Makes slow code fast! • Lowers hardware budgets! • Delays the need for new servers! • Cures scurvy! 163
  • 515. Caching is about trade-offs 164
  • 516. Caching questions 165
  • 517. Caching questions • Cache for everybody? Only logged-in users? Only non-paying users? 165
  • 518. Caching questions • Cache for everybody? Only logged-in users? Only non-paying users? • Long timeouts/stale data? Short timeouts/ worse performance? 165
  • 519. Caching questions • Cache for everybody? Only logged-in users? Only non-paying users? • Long timeouts/stale data? Short timeouts/ worse performance? • Invalidation: time-based? Data based? Both? 165
  • 520. Caching questions • Cache for everybody? Only logged-in users? Only non-paying users? • Long timeouts/stale data? Short timeouts/ worse performance? • Invalidation: time-based? Data based? Both? • Just cache everything? Or just some views? Or just the expensive parts? 165
  • 521. Caching questions • Cache for everybody? Only logged-in users? Only non-paying users? • Long timeouts/stale data? Short timeouts/ worse performance? • Invalidation: time-based? Data based? Both? • Just cache everything? Or just some views? Or just the expensive parts? • Django’s cache layer? Proxy caches? 165
  • 522. Common caching strategies 166
  • 523. Common caching strategies • Are most of your users anonymous? Use CACHE_MIDDLEWARE_ANONYMOUS_ONLY 166
  • 524. Common caching strategies • Are most of your users anonymous? Use CACHE_MIDDLEWARE_ANONYMOUS_ONLY • Are there just a couple of slow views? Use @cache_page. 166
  • 525. Common caching strategies • Are most of your users anonymous? Use CACHE_MIDDLEWARE_ANONYMOUS_ONLY • Are there just a couple of slow views? Use @cache_page. • Need to cache everything? Use a site wide cache. 166
  • 526. Common caching strategies • Are most of your users anonymous? Use CACHE_MIDDLEWARE_ANONYMOUS_ONLY • Are there just a couple of slow views? Use @cache_page. • Need to cache everything? Use a site wide cache. • Everything except a few views? Use @never_cache. 166
  • 527. Site-wide caches 167
  • 528. Site-wide caches • Good: Django’s cache middleware. 167
  • 529. Site-wide caches • Good: Django’s cache middleware. • Better: A proper upstream cache. (Squid, Varnish, …). 167
  • 530. External caches 168
  • 531. External caches • Most work well with Django. 168
  • 532. External caches • Most work well with Django. • Internally, Django just uses HTTP headers to control caching; those headers are exposed to external caches. 168
  • 533. External caches • Most work well with Django. • Internally, Django just uses HTTP headers to control caching; those headers are exposed to external caches. • Cached requests never even hit Django. 168
  • 534. Conditional view processing 169
  • 535. 170
  • 536. GET / HTTP/1.1 Host: www2.ljworld.com/ 170
  • 537. GET / HTTP/1.1 Host: www2.ljworld.com/ HTTP/1.1 200 OK Server: Apache Expires: Wed, 17 Jun 2009 18:17:18 GMT ETag: "93431744c9097d4a3edd4580bf1204c4" … 170
  • 538. GET / HTTP/1.1 Host: www2.ljworld.com/ HTTP/1.1 200 OK Server: Apache Expires: Wed, 17 Jun 2009 18:17:18 GMT ETag: "93431744c9097d4a3edd4580bf1204c4" … GET / HTTP/1.1 Host: www2.ljworld.com/ If-None-Match: "93431744c9097d4a3edd4580bf1204c4" HTTP/1.1 304 NOT MODIFIED … 170
  • 539. GET / HTTP/1.1 Host: www2.ljworld.com/ HTTP/1.1 200 OK Server: Apache Expires: Wed, 17 Jun 2009 18:17:18 GMT ETag: "93431744c9097d4a3edd4580bf1204c4" … GET / HTTP/1.1 Host: www2.ljworld.com/ If-None-Match: "93431744c9097d4a3edd4580bf1204c4" HTTP/1.1 304 NOT MODIFIED … GET / HTTP/1.1 Host: www2.ljworld.com/ If-Modified-Since: Wed, 17 Jun 2009 18:00:00 GMT 170
  • 540. GET / HTTP/1.1 Host: www2.ljworld.com/ HTTP/1.1 200 OK Server: Apache Expires: Wed, 17 Jun 2009 18:17:18 GMT ETag: "93431744c9097d4a3edd4580bf1204c4" … GET / HTTP/1.1 Host: www2.ljworld.com/ If-None-Match: "93431744c9097d4a3edd4580bf1204c4" HTTP/1.1 304 NOT MODIFIED … GET / HTTP/1.1 Host: www2.ljworld.com/ If-Modified-Since: Wed, 17 Jun 2009 18:00:00 GMT HTTP/1.1 304 NOT MODIFIED … 170
  • 541. Etags 171
  • 542. Etags • Opaque identifiers for a resource. 171
  • 543. Etags • Opaque identifiers for a resource. • Cheaper to compute than the resource itself. 171
  • 544. Etags • Opaque identifiers for a resource. • Cheaper to compute than the resource itself. • Bad: “17”, “some title”, etc. 171
  • 545. Etags • Opaque identifiers for a resource. • Cheaper to compute than the resource itself. • Bad: “17”, “some title”, etc. • Good: “93431744c9097d4a3edd4580bf1204c4”, “74c05a20-5b6f-11de-adc7-001b63944e73”, etc. 171
  • 546. When caching fails… 172
  • 547. “I think I need a bigger box.” 173
  • 548. Where to spend money 174
  • 549. Where to spend money • First, buy more RAM. 174
  • 550. Where to spend money • First, buy more RAM. • Then throw money at your DB. 174
  • 551. Where to spend money • First, buy more RAM. • Then throw money at your DB. • Then buy more web servers. 174
  • 552. No money? 175
  • 553. Web server improvements 176
  • 554. Web server improvements • Start with simple improvements: turn off Keep-Alive, tweak MaxConnections; etc. 176
  • 555. Web server improvements • Start with simple improvements: turn off Keep-Alive, tweak MaxConnections; etc. • Use a better application server (mod_wsgi). 176
  • 556. Web server improvements • Start with simple improvements: turn off Keep-Alive, tweak MaxConnections; etc. • Use a better application server (mod_wsgi). • Investigate light-weight web servers (nginx, lighttpd). 176
  • 557. Database tuning 177
  • 558. Database tuning • Whole books can be — and many have been — written about DB tuning. 177
  • 559. Database tuning • Whole books can be — and many have been — written about DB tuning. • MySQL: High Performance MySQL http://www.amazon.com/dp/0596101716/ 177
  • 560. Database tuning • Whole books can be — and many have been — written about DB tuning. • MySQL: High Performance MySQL http://www.amazon.com/dp/0596101716/ • PostgreSQL: http://www.revsys.com/writings/postgresql-performance.html 177
  • 561. Build a toolkit 178
  • 562. Build a toolkit • profile, cProfile 178
  • 563. Build a toolkit • profile, cProfile • strace, SystemTap, dtrace. 178
  • 564. Build a toolkit • profile, cProfile • strace, SystemTap, dtrace. • Django debug toolbar                                http://bit.ly/django-debug-toolbar 178
  • 565. More… http://jacobian.org/r/django-cache http://jacobian.org/r/django-conditional-views 179
  • 566. Final thoughts 180
  • 567. Final thoughts • Writing the code is the easy part. 180
  • 568. Final thoughts • Writing the code is the easy part. • Making it work in the Real World is that part that’ll make you lose sleep. 180
  • 569. Final thoughts • Writing the code is the easy part. • Making it work in the Real World is that part that’ll make you lose sleep. • Don’t worry too much: performance problems are good problems to have. 180
  • 570. Final thoughts • Writing the code is the easy part. • Making it work in the Real World is that part that’ll make you lose sleep. • Don’t worry too much: performance problems are good problems to have. • But worry a little bit: “an ounce of prevention is worth a pound of cure.” 180
  • 571. Fin. Contact me: jacob@jacobian.org / @jacobian Hire me: http://revsys.com/ 181