<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mozilla Web Development &#187; django</title>
	<atom:link href="http://blog.mozilla.org/webdev/tag/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.org/webdev</link>
	<description>Engineering the web</description>
	<lastBuildDate>Tue, 21 May 2013 19:37:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>The restful Marketplace</title>
		<link>http://blog.mozilla.org/webdev/2013/02/22/the-restful-marketplace/</link>
		<comments>http://blog.mozilla.org/webdev/2013/02/22/the-restful-marketplace/#comments</comments>
		<pubDate>Fri, 22 Feb 2013 23:42:12 +0000</pubDate>
		<dc:creator>Andy McKay</dc:creator>
				<category><![CDATA[Marketplace]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3264</guid>
		<description><![CDATA[While the Firefox Marketplace is being built, we are starting to make some fundamental changes in the way the Marketplace is constructed behind the scenes. In the beginning there was one big Django site that served all the requests back &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2013/02/22/the-restful-marketplace/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>While the <a href="https://marketplace.firefox.com">Firefox Marketplace</a> is being built, we are starting to make some fundamental changes in the way the Marketplace is constructed behind the scenes. In the beginning there was one big <a href="http://djangoproject.com">Django</a> site that served all the requests back to the users. </p>
<p>Over the course of the last few months that has changed to being a smaller number of services that provide APIs to each other. We&#8217;ve got separate services for <a href="https://github.com/mozilla/solitude">payments</a> (<a href="https://github.com/mozilla/webpay">and this</a>), <a href="htts://github.com/mozilla/monolith">statistics</a> (<a href="https://github.com/mozilla/monolith-aggregator">and this</a>) and a new <a href="https://github.com/mozilla/fireplace">front end client</a> and plans for more. The main communication mechanism between them is going to be REST APIs.</p>
<p>For REST APIs in Django we are currently using <a href="https://github.com/toastdriven/django-tastypie">Tastypie</a>, which does a pretty good job of doing a lot of things you&#8217;d need. There are a few frustrations with Tastypie and going forward I&#8217;m extremely tempted by <a href="https://github.com/mozilla-services/cornice">Cornice</a>, which we currently use for statistics.</p>
<p>When you ask people about consuming REST APIs in Python, lots of people tell me &#8220;we just use <a href="http://docs.python-requests.org/en/latest/">requests</a>&#8220;. Requests is a great library for making HTTP calls, but when you are developing against a REST API having all the overhead of coping with HTTP is a bit much. Coping with client errors versus HTTP errors, understanding the error responses, scaling and failover and generally coping with an imperfect world.</p>
<p>So we took <a href="http://slumber.readthedocs.org/en/latest/">slumber</a> and wrapped that in our our library called <a href="https://curling.readthedocs.org/en/latest/">curling</a>. Curling is a wrapper that makes some assumptions about the server and the client. It provides us one entry point for all our REST APIs and a place to have consistency on the client side. Below I get a timestamp on a transaction using requests.</p>
<p><script src="https://gist.github.com/andymckay/5017272.js"></script></p>
<p>However in the curling example it will check that one and only one result is returned (and raise meaningful errors if it didn&#8217;t) and correctly raise a meaningful error based on the HTTP response.</p>
<p><script src="https://gist.github.com/andymckay/5017357.js"></script></p>
<p>The result is code that is easier to write and read, but it is still relatively close to the metal of just being a REST API without being as simple as just HTTP requests or as complicated as a Web Services and SOAP stack.</p>
<p>As an extra bonus curling has a command line API that fills some HTTP headers out for you, syntax highlights output and the like. As a bonus, if you are calling a Django server in debug mode, rather than spew lines of HTML to the screen &#8211; it will write the HTML to a file and open a browser to the file.</p>
<p><a href="http://blog.mozilla.org/webdev/files/2013/02/Screen-Shot-2013-02-22-at-3.16.52-PM.png"><img src="http://blog.mozilla.org/webdev/files/2013/02/Screen-Shot-2013-02-22-at-3.16.52-PM.png" alt="Screen Shot 2013-02-22 at 3.16.52 PM" width="642" height="307" class="alignnone size-full wp-image-3269" /></a></p>
<p>These APIs are open and growing rapidly. You can find documentation on them on each project, but the main one to follow is in <a href="http://zamboni.readthedocs.org/en/latest/topics/api.html">zamboni</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2013/02/22/the-restful-marketplace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switching to pip for Python deployments</title>
		<link>http://blog.mozilla.org/webdev/2013/01/11/switching-to-pip-for-python-deployments/</link>
		<comments>http://blog.mozilla.org/webdev/2013/01/11/switching-to-pip-for-python-deployments/#comments</comments>
		<pubDate>Sat, 12 Jan 2013 01:39:08 +0000</pubDate>
		<dc:creator>Andy McKay</dc:creator>
				<category><![CDATA[Marketplace]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3163</guid>
		<description><![CDATA[For the last year or so addons.mozilla.org and marketplace.firefox.com have deployed primarily by pulling the entire project out of github. Required libraries were placed in a git submodule called vendor. Vendor was then a git submodule of our project, meaning &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2013/01/11/switching-to-pip-for-python-deployments/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>For the last year or so <a href="https://addons.mozilla.org">addons.mozilla.org</a> and <a href="https://marketplace.firefox.com">marketplace.firefox.com</a> have deployed primarily by pulling the entire project out of github. Required libraries were placed in a git submodule called <a href="https://github.com/mozilla/zamboni-lib">vendor</a>. Vendor was then a git submodule of our project, meaning we had recursive submodules. At deployment time we recursively pulled all the modules from github to our master server.</p>
<p>This created a few issues. The recursive pull from github was quite slow as we pulled down an awful lot of code. To update something in vendor was quite a tortuous path of updates that generated quite a few expletives from most developers the first few times they tried it. Scripts were written to make that made it easier, but that was just addressing the symptom. Multiple commits appeared in zamboni that had accidental vendor changes in the submodule and more expletives were uttered.</p>
<p>Because everything ended up underneath the main project anything that recursively searched directories took longer. Some git commands, greps, test runs etc took longer and longer as the vendor library grew.</p>
<p>Finally, building packages and using <a href="http://pypi.python.org/pypi">pypi</a> and the existing community infrastructure is a good thing. It means that our code is as close to as normal as possible and our libraries are more likely to be reused if we package them properly from the start.</p>
<h3>How we build</h3>
<p>We don&#8217;t want any surprises about what pip is installing on our server. Often the <code>setup.py</code> script installs dependencies. To prevent that we invoke pip with the <code>--no-deps</code> flag. All dependencies have to be manually specified in the <a href="https://github.com/mozilla/zamboni/tree/master/requirements">requirements files</a>.</p>
<p>For each package we pin to the specific version, for example <code>Django==1.4.3</code>. This is a little faster since pip doesn&#8217;t have to find the relevant version. It means we have to manually update, but it ensures we don&#8217;t get a version we didn&#8217;t expect. Updates are so much simpler and easier to read in source control (<a href="https://github.com/mozilla/zamboni/commit/54365eae">for example</a>).</p>
<p>Unfortunately not everything is a package. We have a few packages that pull directly from github as eggs (as of writing we have 80 python packages and 20 eggs from github). For those we set <code>--exists-action=w</code> to ensure that if those change the deployment continues smoothly. </p>
<h3>Security</h3>
<p>There are more security issues with taking a package from pypi and installing it on the production server than there is with pulling from github. We wanted to be sure that we were being as safe as possible.</p>
<p>So we set up a <a href="https://pyrepo.addons.mozilla.org/">server</a> to store local copies of our packages. It is a simple HTTP server that serves from the file system and developers have to <code>scp</code> packages over to it. The deployment pulls from that instead of from pypi, ensuring that we&#8217;ve got accountability and traceability about what packages are going to our production servers.</p>
<p>Before developers can get access to upload packages, they have to read and sign off a policy for uploading packages.</p>
<h3>Results</h3>
<p>The deployments are now slower because we delete the existing virtualenv and reinstall the packages from scratch each deployment. This was a temporary measure to cope with the large number of package changes over first few deployments. This part of the deployment takes about 2 minutes, which is the slowest part of the deployment. Once we stop deleting the virtualenv that should improve.</p>
<p>The vendor submodule still exists to look after legacy code that hasn&#8217;t been put into packages or is unlikely ever to do so. It also contains one JavaScript library.</p>
<p>The number of expletives issued by developers during library bumps has dropped and the number of commits with random vendor changes has vanished. Although there have been a few expletives uttered at packages. Updates are faster, git and other command line tools are faster. Overall, life is a whole lot better.</p>
<p>We&#8217;ve now got at least four projects using and deploying with pip and we won&#8217;t be going back. Hopefully more Mozilla web sites will now also be able to deploy with pip.</p>
<p>Thanks to help from Jason, Jeremy and Guillaume for making this happen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2013/01/11/switching-to-pip-for-python-deployments/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Things I learned from looking at graphs</title>
		<link>http://blog.mozilla.org/webdev/2012/11/16/things-i-learned-b-looking-at-graphs/</link>
		<comments>http://blog.mozilla.org/webdev/2012/11/16/things-i-learned-b-looking-at-graphs/#comments</comments>
		<pubDate>Sat, 17 Nov 2012 00:48:58 +0000</pubDate>
		<dc:creator>Andy McKay</dc:creator>
				<category><![CDATA[AMO]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[add-ons]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[graphite]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=3070</guid>
		<description><![CDATA[We use Graphite to see how the Firefox Marketplace and Add-ons sites are doing. But the sheer volume of traffic to Add-ons always gives some interesting graphs. A while back we were switching between different clusters for add-on version check &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2012/11/16/things-i-learned-b-looking-at-graphs/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>We use <a href="http://graphite.wikidot.com/">Graphite</a> to see how the <a href="https://marketplace.firefox.com/">Firefox Marketplace</a> and <a href="https://addons.mozilla.org/">Add-ons</a> sites are doing. But the sheer volume of traffic to Add-ons always gives some interesting graphs.</p>
<p>A while back we were switching between different clusters for add-on version check as the hardware behind it changed. As we switched clusters, we also switched from a hot cache to a cold cache. This resulted in a spike in traffic:</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-2.58.50-PM.png"><img src="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-2.58.50-PM.png" alt="" title="Version check traffic" width="582" height="303" class="alignnone size-full wp-image-3072" /></a></p>
<p>That&#8217;s almost 45,000 requests per second coming into version check and being processed by Python and MySQL. With hardly a blip on the hardware loads, we processed that quickly. We can see the affect as the cache picked up the slack,  it falls down to the usual 8,000 requests per second. Crazy traffic.</p>
<p>We get a large number of requests to version check for a small number of add-ons. Like <a href="https://addons.mozilla.org/en-US/firefox/addon/adblock-plus/?src=hp-dl-mostpopular">Adblock Plus</a> which, as of writing this post, has over 15 million users. That&#8217;s pretty awesome.</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-3.14.46-PM.png"><img src="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-3.14.46-PM.png" alt="" title="Adblock Plus" width="200" height="83" class="alignnone size-full wp-image-3073" /></a></p>
<p>Looking at the traffic to Add-ons site (excluding version checks), traffic is very consistent depending upon the time of day.</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-3.24.19-PM.png"><img src="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-3.24.19-PM.png" alt="" title="Daily traffic" width="576" height="266" class="alignnone size-full wp-image-3076" /></a></p>
<p>So when are those times? Here&#8217;s a graph of today&#8217;s traffic that I&#8217;ve annotated.</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-4.20.00-PM.png"><img src="http://blog.mozilla.org/webdev/files/2012/11/Screen-Shot-2012-11-16-at-4.20.00-PM.png" alt="" title="Addon traffic with times" width="579" height="286" class="alignnone size-full wp-image-3077" /></a></p>
<p>Our low point is as India wakes up. It goes up as Europe starts to wake up and then the east coast of the US. It hits its peak at about 11am on the east coast and then as Europe and the east coast goes of line traffic starts to fall.</p>
<p>There&#8217;s no real surprise there and data is backed up by looking at our internal metrics that show after the United States, the biggest traffic for Add-ons comes from Germany, Russia, France in that order. But it&#8217;s always nice to be reminded of the global reach of Mozilla.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2012/11/16/things-i-learned-b-looking-at-graphs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Let&#8217;s talk about password storage</title>
		<link>http://blog.mozilla.org/webdev/2012/06/08/lets-talk-about-password-storage/</link>
		<comments>http://blog.mozilla.org/webdev/2012/06/08/lets-talk-about-password-storage/#comments</comments>
		<pubDate>Fri, 08 Jun 2012 16:52:33 +0000</pubDate>
		<dc:creator>Fred Wenzel</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[browserid]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[hashing]]></category>
		<category><![CDATA[passwords]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=2772</guid>
		<description><![CDATA[During the course of this week, a number of high-profile websites (like LinkedIn and last.fm) have disclosed possible password leaks from their databases. The suspected leaks put huge amounts of important, private user data at risk. What&#8217;s common to both &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2012/06/08/lets-talk-about-password-storage/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>During the course of this week, a number of high-profile websites (like <a href="http://blog.linkedin.com/2012/06/06/updating-your-password-on-linkedin-and-other-account-security-best-practices/">LinkedIn</a> and <a href="http://www.last.fm/passwordsecurity?tag=mncol;txt">last.fm</a>) have disclosed possible password leaks from their databases. The suspected leaks put huge amounts of important, private user data at risk.</p>
<p>What&#8217;s common to both these cases is the weak security they employed to &#8220;safekeep&#8221; their users&#8217; login credentials. In the case of LinkedIn, it is <a href="http://leakedin.org">alleged</a> that an unsalted SHA-1 hash was used, in the case of last.fm, the technology used is, allegedly, an even worse, <a href="http://www.reddit.com/r/netsec/comments/upyu4/lastfm_password_security_update_we_are_currently/c4xj1dw">unsalted MD5 hash</a>.</p>
<p>Neither of the two technologies is following any sort of modern industry standard and, if they were in fact used by these companies in this fashion, exhibit a gross disregard for the protection of user data. Let&#8217;s take a look at the most obvious mistakes our protagonists made here, and then we&#8217;ll discuss the <strong>password hashing standards</strong> that Mozilla web projects routinely apply in order to mitigate these risks.</p>
<h3>A trivial no-no: Plain-text passwords</h3>
<p>This one&#8217;s easy: Nobody should store plain-text passwords in a database. If you do, and someone steals the data through any sort of security hole, they&#8217;ve got all your user&#8217;s plain text passwords. (That a bunch of companies still do that should make you scream and run the other way whenever you encounter it.) Our two protagonists above know that too, so they remembered that they read something about hashing somewhere at some point. <em>&#8220;Hey, this makes our passwords look different! I am sure it&#8217;s secure! Let&#8217;s do it!&#8221;</em></p>
<h3>Poor: Straight hashing</h3>
<p><a href="http://blog.mozilla.org/webdev/files/2012/06/wonka-md5.jpg"><img src="http://blog.mozilla.org/webdev/files/2012/06/wonka-md5-150x150.jpg" alt="" title="Condescending Wonka disapproves of straight hashing" width="150" height="150" class="alignleft size-thumbnail wp-image-2787" style="margin-right:.5em" /></a>Smart mathematicians came up with something called a hashing function or &#8220;one-way function&#8221; <code>H: password -> H(password)</code>. MD5 and SHA-1 mentioned above are examples of those. The idea is that you give this function an input (the password), and it gives you back a &#8220;hash value&#8221;. It is easy to calculate this hash value when you have the original input, but prohibitively hard to do the opposite. So we create the hash value of all passwords, and only store that. If someone steals the database, they will only have the hashes, not the passwords. And because those are hard or impossible to calculate from the hashes, the stolen data is useless.</p>
<p><em>&#8220;Great!&#8221;</em> But wait, there&#8217;s a catch. For starters, <strong>people pick poor passwords.</strong> Write this one in stone, as it&#8217;ll be true as long as passwords exist. So a smart attacker can start with a copy of Merriam-Webster, throw in a few numbers here and there, calculate the hashes for all those words (remember, it&#8217;s easy and fast) and start comparing those hashes against the database they just stole. Because your password was &#8220;cheesecake1&#8243;, they just guessed it. Whoops! To add insult to injury, they just guessed <em>everyone&#8217;s</em> password who also used the same phrase, because the hashes for the same password are the same for every user.</p>
<p>Worse yet, you can actually buy(!) precomputed lists of straight hashes (called <a href="http://en.wikipedia.org/wiki/Rainbow_tables">Rainbow Tables</a>) for alphanumeric passwords up to about 10 characters in length. Thought &#8220;FhTsfdl31a&#8221; was a safe password? Think again.</p>
<p>This attack is called an <strong>offline <a href="http://en.wikipedia.org/wiki/Dictionary_attack">dictionary attack</a></strong> and is well-known to the security community.</p>
<h3>Even passwords taste better with salt</h3>
<p><a href="http://blog.mozilla.org/webdev/files/2012/06/steve-salt.jpg"><img src="http://blog.mozilla.org/webdev/files/2012/06/steve-salt-150x150.jpg" alt="" title="Scumbag Steve salts his passwords" width="150" height="150" class="alignright size-thumbnail wp-image-2784" /></a>The standard way to deal with this is by adding a per-user salt. That&#8217;s a long, random string added to the password at hashing time: <code>H: password -> H(password + salt)</code>. You then store salt and hash in the database, making the hash different for every user, even if they happen to use the same password. In addition, the smart attacker cannot pre-compute the hashes anymore, because they don&#8217;t know <em>your</em> salt. So after stealing the data, they&#8217;ll have to try every possible password for every possible user, using each user&#8217;s personal salt value.</p>
<p>Great! I mean it, if you use this method, you&#8217;re already scores better than our protagonists.</p>
<h3>The 21st century: Slow hashes</h3>
<p>But alas, there&#8217;s another catch: Generic hash functions like MD5 and SHA-1 are built to be fast. And because computers <a href="http://en.wikipedia.org/wiki/Moore%27s_law">keep getting faster</a>, millions of hashes can be calculated very very quickly, making a <strong>brute-force attack</strong> even of salted passwords more and more feasible.</p>
<p><strong>So here&#8217;s what we do at Mozilla</strong>: Our WebApp Security team performed <a href="http://blog.mozilla.org/webappsec/2011/05/10/sha-512-w-per-user-salts-is-not-enough/">some</a> <a href="http://blog.mozilla.org/webappsec/2011/06/01/sha-512-follow-up-and-thank-you/">research</a> and set forth a set of <a href="https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines#Password_Storage">secure coding guidelines</a> (they are public, go check them out, I&#8217;ll wait). These guidelines suggest the use of <strong>HMAC + bcrypt</strong> as a reasonably secure password storage method.</p>
<p>The hashing function has two steps. First, the password is hashed with an algorithm called <a href="http://en.wikipedia.org/wiki/HMAC">HMAC</a>, together with a <strong>local salt</strong>: <code>H: password -> HMAC(local_salt + password)</code>. The local salt is a random value that is stored only on the server, never in the database. Why is this good? If an attacker steals one of our password databases, they would need to <strong>also separately attack</strong> one of our web servers to get file access in order to discover this local salt value. If they don&#8217;t manage to pull off <strong>two successful attacks</strong>, their stolen data is largely useless.</p>
<p>As a second step, this hashed value (or <em>strengthened password</em>, as some call it) is then hashed again with a slow hashing function called <a href="http://en.wikipedia.org/wiki/Bcrypt">bcrypt</a>. The key point here is <strong>slow</strong>. Unlike general-purpose hash functions, bcrypt intentionally takes a relatively long time to be calculated. Unless an attacker has millions of years to spend, they won&#8217;t be able to try out a whole lot of passwords after they steal a password database. Plus, bcrypt hashes are also salted, so no two bcrypt hashes of the same password look the same.</p>
<p>So the whole function looks like: <code>H: password -> bcrypt(HMAC(password, local_salt), bcrypt_salt)</code>.</p>
<p>We wrote a reference implementation for this for Django: <a href="https://github.com/fwenzel/django-sha2">django-sha2</a>. Like all Mozilla projects, it is open source, and you are more than welcome to study, use, and contribute to it!</p>
<h3>What about Mozilla Persona?</h3>
<p>Funny you should mention it. Mozilla Persona (née BrowserID) is a new way for people to log in. Persona is the password specialist, and takes the burden/risk away from sites for having to worry about passwords altogether. Read more about <a href="https://developer.mozilla.org/en/BrowserID/Quick_Setup">Mozilla Persona</a>.</p>
<h3>So you think you&#8217;re cool and can&#8217;t be cracked? Challenge accepted!</h3>
<p>Make no mistake: just like everybody else, we&#8217;re not invincible at Mozilla. But because we <em>actually</em> take our users&#8217; data seriously, we take precautions like this to mitigate the effects of an attack, even in the unfortunate event of a successful security breach in one of our systems.</p>
<p>If you&#8217;re responsible for user data, so should you.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2012/06/08/lets-talk-about-password-storage/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Mozilla Webdev&#8217;s Beer and Tell: April 16, 2012</title>
		<link>http://blog.mozilla.org/webdev/2012/04/24/beer-and-tell-april-2012/</link>
		<comments>http://blog.mozilla.org/webdev/2012/04/24/beer-and-tell-april-2012/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 19:17:57 +0000</pubDate>
		<dc:creator>Matthew Riley MacPherson</dc:creator>
				<category><![CDATA[Beer and Tell]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[beer-and-tell]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[lisp]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=2636</guid>
		<description><![CDATA[In case you missed last month&#8217;s blog post, a Beer and Tell is a monthly Mozilla Webdev gettogether involving cool hacks and malted beverages. We try to structure it like a series of lightning talks and &#8212; because all work &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2012/04/24/beer-and-tell-april-2012/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>In case you missed <a href="http://blog.mozilla.org/webdev/2012/04/04/mozilla-webdev-beer-and-tell-march-16-2012/">last month&#8217;s blog post</a>, a <em>Beer and Tell</em> is a monthly Mozilla Webdev gettogether involving cool hacks and malted beverages. We try to structure it like a series of lightning talks and &#8212; because all work and no play makes web developers go crazy &#8212; some of us have a beer during. Some of the East Coast folks drink scotch instead, but it&#8217;s OK because it&#8217;s after 5pm in Toronto by then.</p>
<p>We didn&#8217;t record this Beer and Tell (my bad!), but I thought I&#8217;d share what was presented. It was pretty gaming-focused and quite cool.</p>
<h3>Django Stats Admin</h3>
<p>Created by <a href="https://twitter.com/Osmose">Michael Kelly</a>, this nifty little app allows you to visualize any of your Django models with <code>datetime</code> fields in the Django Admin. It uses the <a href="http://code.google.com/p/flot/">flot</a> JS library to create pretty charts and lets you specify date ranges.</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/04/Screen-shot-2012-04-23-at-9.13.29-PM.png"><img src="http://blog.mozilla.org/webdev/files/2012/04/Screen-shot-2012-04-23-at-9.13.29-PM-300x206.png" alt="Django Stats Admin screenshot" width="300" height="206" class="size-medium wp-image-2635" /></a></p>
<p>Michael&#8217;s currently working on abstracting the app out into a library that can be used with any Django app.</p>
<h3>Lisp -> DCPU-16 Compiler</h3>
<p>James Long, our resident Lisp champion, started off by telling us about <a href="http://0x10c.com/">0x10c</a> and the DCPU-16 assembly language in the game. It&#8217;s pretty cool stuff for gamers who are language geeks too. Of course, who wants to write machine code of any kind when there&#8217;s Lisp?! No one, that&#8217;s who. Or, well, at least not James.</p>
<p>James wrote a Lisp to DCPU-16 compiler that translates your Lisp to <em>heavily optimized</em> DCPU-16 assembly instructions. His Lisp allows inline assembly and is pretty damn slick.</p>
<p>James walked us threw some Lisp code, showed us the converted assembly, then ran the instructions for us! He also showed us some of the crazier stuff folks have done with the DCPU-16 language, even though it&#8217;s in its early stages. Very cool stuff.</p>
<p><a href="https://github.com/jlongster/dcpu-lisp#readme">Check out his project&#8217;s README</a> for more info and examples. It&#8217;s actually written in James&#8217; own Lisp variant, <a href="https://github.com/jlongster/outlet">Outlet</a>, that compiles to JavaScript and lua. Lisp-ception!</p>
<p><img src="http://blog.mozilla.org/webdev/files/2012/04/3oxtzz.jpg" alt="Yo dawg I heard you liked Lisp so I wrote you a Lisp compiler in Lisp so you can write Lisp for DCPU-16." width="625" height="415" class="size-full wp-image-2634" /></p>
<p>Even I, a steadfast <code>vim</code> user, was impressed.</p>
<h3>Gladius</h3>
<p><a href="http://redpuma.net/blog/">Dan Mosedale</a> showed us some damn fine graphics engine fun in JavaScript, running quite smashingly (with a few browser garbage collection missteps, soon-to-be-resolved) in a browser. It was powered by a new library, <a href="https://github.com/gladiusjs/gladius-core">Gladius</a>.</p>
<p>He started with some basic objects and physics, then progressed onto the beginnings of a 3rd platformer/fighter! We discussed the current state of graphics libraries, 2D vs. 3D libraries (there are a lot of 2D libraries out there &#8212; Gladius is focusing on 3D), and gaming in browsers in general.</p>
<p><img src="http://blog.mozilla.org/webdev/files/2012/04/no-comply.png" alt="Screenshot from the Gladius demo" width="462" height="350" class="size-full wp-image-2633" /></p>
<p>These folks are up to some interesting stuff and it&#8217;s a great time to get started writing games in the browser. <a href="http://blog.mozilla.org/labs/2012/04/gladius-a-modular-3d-game-engine-for-the-web/">Read more about Gladius</a> and be sure to look for some full-fledged games using it in no time.</p>
<h3>Apptastic, an Experiment in <del>Cursing</del> Creating Mobile Platforms</h3>
<p>The developers on the Developer Ecosystem team wanted to see what it was like to develop on various mobile platforms so we&#8217;d know what to do (and what not to do) when creating a sane work flow for developing Open Web Apps. We decided to make simple Bugzilla search apps so the each experiment had a common goal.</p>
<p>Turns out: most mobile platforms are a pretty big pain in the ass to develop for! It&#8217;s important to remember that we&#8217;ve come a long way (before the iPhone, it was sell your &#8220;app&#8221; through each carrier to a specific device for a crazy price), but we still have a ways to go.</p>
<p>Arron wrote <a href="http://pennyfx.github.com/Windows-Phone-Bugzilla-Quick-Search/">a pretty sweet write-up of his Windows Phone experience</a>, and we briefly discussed developing on other platforms, including the bureaucracy involved in iOS development and the general pain of Android&#8230; every step of the way.</p>
<p>Look for more blog posts about our experiences in the future.</p>
<h3>That&#8217;s All Folks!</h3>
<p>Hope you enjoyed my recap of the Beer and Tell. We&#8217;ll be sure to record it for next time!</p>
<p>Until then: keep hacking and having fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2012/04/24/beer-and-tell-april-2012/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tracking deployments in Graphite</title>
		<link>http://blog.mozilla.org/webdev/2012/04/05/tracking-deployments-in-graphite/</link>
		<comments>http://blog.mozilla.org/webdev/2012/04/05/tracking-deployments-in-graphite/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 04:24:51 +0000</pubDate>
		<dc:creator>Andy McKay</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=2561</guid>
		<description><![CDATA[We use Graphite in Web Development to track metrics on our sites. For the Marketplace and Addons team, it has been a real eye opener into the state of our sites. One thing that I&#8217;ve wanted to add is information &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2012/04/05/tracking-deployments-in-graphite/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>We use <a href="http://graphite.wikidot.com/">Graphite</a> in Web Development to track metrics on our sites. For the Marketplace and Addons team, it has been a real eye opener into the state of our sites.</p>
<p>One thing that I&#8217;ve wanted to add is information on when deployments occur as these are often critical periods that can trigger changes in the graphs. Sure enough, this has all been done before and covered in a <a href="http://codeascraft.etsy.com/2010/12/08/track-every-release/">blog post</a>. Following on from that blog post, here&#8217;s how I added this for the Marketplace.</p>
<p>First, I added a management command to <a href="https://github.com/andymckay/django-statsd">django-statsd</a> that allows you to easily send a ping to Graphite for a specific key. The value of the key is set to be a UNIX time stamp. Once that was in place I altered our deployment scripts so that on each update they send a ping with the key &#8220;update&#8221;:</p>
<pre>python2.6 manage.py statsd_ping --key=update</pre>
<p>Then each time a server is deployed that key gets added to Graphite.</p>
<p>Next, I altered our graphs so that they show this ping as a vertical line. That&#8217;s using the command <a href="http://graphite.readthedocs.org/en/1.0/functions.html#graphite.render.functions.drawAsInfinite">drawAsInfinite</a>, for example:</p>
<pre>drawAsInfinite(stats.timers.addons-dev.update.count)</pre>
<p>Our development server updates on every commit. In other words, it continually deploys all the time. This is the graph for the development server, and you can see the large number of small commits we had this afternoon (each commit is indicated by a pink line):</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/04/Screen-Shot-2012-04-05-at-5.40.54-PM.png"><img class="alignnone size-full wp-image-2564" title="Screen Shot 2012-04-05 at 5.40.54 PM" src="http://blog.mozilla.org/webdev/files/2012/04/Screen-Shot-2012-04-05-at-5.40.54-PM.png" alt="" width="597" height="145" /></a></p>
<p>A more realistic view is our production server, where you can see our Thursday afternoon push in context (each push is a pink line):</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/04/Screen-Shot-2012-04-05-at-5.41.14-PM.png"><img title="Screen Shot 2012-04-05 at 5.41.14 PM" src="http://blog.mozilla.org/webdev/files/2012/04/Screen-Shot-2012-04-05-at-5.41.14-PM.png" alt="" width="591" height="144" /></a></p>
<p>Adding this data is crucial to helping the Marketplace get closer to continuous deployment in the coming months.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2012/04/05/tracking-deployments-in-graphite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Scrum and Bugzilla</title>
		<link>http://blog.mozilla.org/webdev/2012/03/27/scrum-and-bugzilla/</link>
		<comments>http://blog.mozilla.org/webdev/2012/03/27/scrum-and-bugzilla/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 16:34:11 +0000</pubDate>
		<dc:creator>Paul McLanahan</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Scrum]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[bootstrap]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[flot]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=2512</guid>
		<description><![CDATA[Not all teams at Mozilla follow the same software development methodology. We&#8217;re free to design our own workflows, use whatever tools we want, and just generally work in whatever way is best for us. The one component that almost every &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2012/03/27/scrum-and-bugzilla/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>Not all teams at Mozilla follow the same software development methodology. We&#8217;re free to design our own workflows, use whatever tools we want, and just generally work in whatever way is best for us. The one component that almost every project uses is <a href="https://bugzilla.mozilla.org/">Bugzilla</a> for issue and feature tracking. If you&#8217;ve ever worked for, or contributed to Mozilla, you have a Bugzilla account. Apart from being a very powerful and configurable tool, this level of participation is a large part of what keeps projects using and wanting to use Bugzilla.</p>
<h2>Enter Scrum</h2>
<p>Being software developers, many of us know and like <a href="http://en.wikipedia.org/wiki/Scrum_%28development%29">Scrum</a>. I&#8217;ve personally found it to be a great method of answering the old questions of &#8220;How long will this take?&#8221;, and &#8220;How much can we get done?&#8221;. I won&#8217;t go into great detail on how Scrum works here, but the main points are as follows:</p>
<ul>
<li>Work units are scored by the team based on difficulty or expected time consumption.</li>
<li>Those work units are included in a &#8220;Sprint&#8221; usually lasting 2 weeks.</li>
<li>Lots of interesting data is generated around team performance.</li>
</ul>
<p>That last point is key. In order to be able to use and appreciate these data, we need to be able to collect and visualize them in a useful way. This normally means awesome charts and graphs. As nice as Bugzilla is for coordination and issue tracking, it has an unfortunate lack of awesome data visualization tools. It does however, have an API.</p>
<h2>The Birth of <a href="http://scrumbu.gs/">Scrumbu.gs</a></h2>
<p>There have been some valiant efforts at improving the interface of Bugzilla. One of these, <a href="https://addons.mozilla.org/en-US/firefox/addon/bugzillajs/">BugzillaJS</a>, even adds some pie charts for Scrum data in a bug-list. But what I really wanted was a <a href="http://en.wikipedia.org/wiki/Scrum_%28development%29#Burn_down">burndown</a>.</p>
<p>The data you need to associate with a bug (or story in Scrum parlance) are the user who will benefit from the work, the component of the product to be affected, and a score (points) representing the perceived difficulty of the work. Bugzilla has no fields for these out of the box, but a catchall field called the &#8220;whiteboard&#8221; can be formatted in such a way as to allow tools like BugzillaJS and Scrumbu.gs to easily find it (see below). This is obviously not optimal, but it&#8217;s what we have for the moment. And when you combine that with the bug history data from the Bugzilla API, you have all you need to calculate burndowns, team and developer velocities, and all sorts of even awesomer things.</p>
<aside style="margin-left:2em;padding:10px;background-color:#eee"><strong>NOTE:</strong> The whiteboard Bugzilla field is overridden to provide formatted data for our scrum tools. If you had the following story: &#8220;As a contributor, I can haz bacon.&#8221;, and your team agreed to give it 2 points, your whiteboard for this bug would be: &#8220;u=contributor c=noms p=2&#8243;, where &#8220;u&#8221; is &#8220;user&#8221;, &#8220;c&#8221; is &#8220;component&#8221;, and &#8220;p&#8221; is &#8220;points&#8221;.</aside>
<p>The result of this need, my excellent bosses allowing me the time to experiment with cool stuff, and the existence of <a href="http://python.org/">Python</a>, <a href="http://djangoproject.com/">Django</a>, <a href="http://slumber.in/">Slumber</a> (REST client), <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>, <a href="http://jquery.com/">jQuery</a>, <a href="http://code.google.com/p/flot/">Flot</a>, and <a href="http://ep.io/">Epio</a> (python/django hosting), is <a href="http://scrumbu.gs/">Scrumbu.gs</a>. It&#8217;s still a work in progress, but you can click through some existing projects and sprints to see how it&#8217;s working so far. The <a href="https://github.com/pmclanahan/scrumbugz">code and issue tracker</a> are on github, so feel free to poke around and see how it works. If you see a problem or have an idea for a feature, please file an issue, and if you have the ability and/or desire, send a pull-request <img src='http://blog.mozilla.org/webdev/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>I recently gave a lightning talk about the project for my team at Mozilla and I&#8217;ve included it below if you&#8217;re interested. My hope with this project was to spread the use of Scrum around Mozilla and other teams who use Bugzilla, and to improve the tools for those who already do. If your team is interested in tracking your sprints using this tool, participating in its development, or just chatting about Scrum, please join us in the #scrum channel on <a href="irc://irc.mozilla.org/">IRC</a>.</p>
<p><video id="movie" width="640" height="360" preload="none" controls poster="http://blog.mozilla.org/webdev/files/2011/07/mozilla_wht.png"><br />
  <source src="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.webm" type='video/webm; codecs="vp8, vorbis"' /><br />
  <source src="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.ogv" type='video/ogg; codecs="theora, vorbis"' /><br />
  <source src="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.mp4" /></p>
<p>Download video as <a href="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.mp4">MP4</a>, <a href="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.webm">WebM</a>, or <a href="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.ogv">Ogg</a>.</p>
<p></video></p>
<p><strong>Edit 3/28</strong>: Added links to Slumber, Epio, and jQuery.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2012/03/27/scrum-and-bugzilla/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
<enclosure url="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.webm" length="32449140" type="video/webm" />
<enclosure url="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.ogv" length="38426688" type="video/ogg" />
<enclosure url="http://videos-cdn.mozilla.net/serv/flux/lightningtalks-q1-2012/1-pmac-scrumbugs.mp4" length="67574309" type="video/mp4" />
		</item>
		<item>
		<title>Timing AMO user experience</title>
		<link>http://blog.mozilla.org/webdev/2012/01/06/timing-amo-user-experience/</link>
		<comments>http://blog.mozilla.org/webdev/2012/01/06/timing-amo-user-experience/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 23:09:28 +0000</pubDate>
		<dc:creator>Andy McKay</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[statsd]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=2410</guid>
		<description><![CDATA[There are lots of ways to measure the performance of a site. On addons.mozilla.org we measure a few of them: how long it takes to render pages, the cache performance and responsiveness for content delivery networks globally. But with the &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2012/01/06/timing-amo-user-experience/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p>There are lots of ways to measure the performance of a site. On <a href="http://addons.mozilla.org">addons.mozilla.org</a> we measure a few of them: how long it takes to render pages, the cache performance and responsiveness for content delivery networks globally. But with the advent of the <a href="http://www.w3.org/TR/navigation-timing/">navigation timing API</a> in <a href="http://hacks.mozilla.org/2011/09/whats-new-for-web-developers-in-firefox-7/">Firefox 7</a> we&#8217;ve been able to add the most important measurement of all &#8211; the actual performance in the browser.</p>
<p>Along with a few other Mozilla sites, we&#8217;ve been using <a href="https://github.com/jsocol/pystatsd">pystatsd</a> and Graphite for a while. This produces useful graphs of the site health and performance. For example, this graph plots HTTP responses we serve out from Python (this is not the amount of traffic to our site which is much larger).</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/01/Screen-Shot-2012-01-06-at-2.10.46-PM.png"><img class="alignnone size-full wp-image-2415" title="Traffic to addon.mozilla.org" src="http://blog.mozilla.org/webdev/files/2012/01/Screen-Shot-2012-01-06-at-2.10.46-PM.png" alt="" width="585" height="307" /></a></p>
<p>To facilitate using the timing API we wrote a module between statsd and Django called <a href="https://github.com/andymckay/django-statsd">django-statsd</a> that, amongst other things, provides a way to interface between the browser and Python backend. The library has support for <a href="https://github.com/yahoo/boomerang">boomerang</a>, a great front end timing library. I quickly wrote a much simpler service called <a href="https://github.com/andymckay/django-statsd/blob/master/django_statsd/static/stick.js">stick</a>, which sends a small subset of timings that we want.</p>
<p>Using stick is straightforward &#8211; once you&#8217;ve setup your Python backed and included your JavaScript, you call it in your page. For example:</p>
<pre>stick.send('https://to.your.site/record')</pre>
<p>The API returns with timestamps for each of the events. To give us meaningful numbers, we then subtract the timestamp for each of the events from <code>navigationStart</code> so we can tell the timings relative to that start point. And here&#8217;s the end result in our Graphite server:</p>
<p><a href="http://blog.mozilla.org/webdev/files/2012/01/Screen-Shot-2012-01-06-at-2.10.33-PM.png"><img class="alignnone size-full wp-image-2416" title="Navigation Timing" src="http://blog.mozilla.org/webdev/files/2012/01/Screen-Shot-2012-01-06-at-2.10.33-PM.png" alt="" width="585" height="309" /></a></p>
<p>For internal sites we collect 100% of the data. However, on our live site we get quite a lot of traffic, so we&#8217;ve rolled this out by collecting only 1% of traffic. We&#8217;ll start increasing this percentage once we are confident this won&#8217;t be causing problems. We&#8217;ll also be adding it to the about:addons page which gets quite a bit of traffic.</p>
<p>We&#8217;ll be tweaking things to ensure we pass through the right numbers and interpret them correctly. The amount of data is probably too low to be useful, right now, but I can&#8217;t help but wonder what the peak around 12.30pm today was&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2012/01/06/timing-amo-user-experience/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Scrubbing your Django database</title>
		<link>http://blog.mozilla.org/webdev/2011/11/18/scrubbing-your-django-database/</link>
		<comments>http://blog.mozilla.org/webdev/2011/11/18/scrubbing-your-django-database/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 23:05:38 +0000</pubDate>
		<dc:creator>Andy McKay</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=2206</guid>
		<description><![CDATA[This is the second in a series of posts, focusing on issues around open sourcing your Django site and data privacy in Django. You&#8217;ll end up with production data in your Django database and that will likely contain different kinds &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2011/11/18/scrubbing-your-django-database/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><em>This is the second in a <a href="http://blog.mozilla.org/webdev/2011/10/20/open-sourcing-your-django-site/">series of posts</a>, focusing on issues around open sourcing your Django site and data privacy in Django.</em></p>
<p>You&#8217;ll end up with production data in your Django database and that will likely contain different kinds of data such as: configuration data, required basic data (categories for example), collected data and personal user data. There&#8217;s a couple of reasons for taking that production data and copying it off your production servers:</p>
<ul>
<li>for developers and contributors you want a sample copy of the app with some key data in.</li>
<li>for testing or staging servers, you might want to copy down the database from the production server so you can test certain scenarios or load.</li>
</ul>
<h3>Extracting parts of your database</h3>
<p>For the first case, it&#8217;s nice to prepare a minimal copy of the database that contains key data. For example, for those wanting to develop or contribute to <a href="https://addons.mozilla.org">addons.mozilla.org</a> we have <a href="http://micropipes.com/blog/2011/03/29/welcome-to-the-landfill/">Landfill</a> by <a href="http://micropipes.com/blog/">Wil Clouser</a>.</p>
<p>Django comes with a nice facility for loading data, fixture dumping and loading. This can be used to pull data out of your database and then reload it. However the built in <a href="https://docs.djangoproject.com/en/dev/ref/django-admin/#dumpdata-appname-appname-appname-model">Django dumpdata</a> dumps all the records for your model (depending upon your default object manager). That might not be what you want for this scenario. So a useful utility for dumping just the records you want is provided <a href="https://github.com/davedash/django-fixture-magic">Django fixture magic</a> written by <a href="http://blog.mozilla.org/webdev/author/ddashmozillacom/">Dave Dash</a>.</p>
<p>A standard dumpdata looks like this:</p>
<pre>manage.py dumpdata users.UserProfile</pre>
<p>And will dump every <code>UserProfile</code>. By contrast:</p>
<pre>manage.py dump_object users.UserProfile 1</pre>
<p>Will just dump the <code>UserProfile</code> with primary key of 1. Django fixture magic also has a few other useful things such as merging and reordering fixtures.</p>
<p>This allows you to trim a set of fixtures from your live database down quickly. Then developers or contributors can load the key parts of the database that they need from those fixtures.</p>
<h3>Anonymising the database</h3>
<p>Sending the production database downstream to internal developers or internal test sites is a pretty common use case. This process does not require a complete clean of the database, but it does require some cleaning of database. If you stored credit card data, for example, you&#8217;d never want to copy that off your production database.</p>
<p>At Mozilla we use an <a href="https://github.com/davedash/mysql-anonymous">anonymising script</a>, written by <a href="http://blog.mozilla.org/webdev/author/ddashmozillacom/">Dave Dash</a> again. There are few options: to truncate, nullify, randomize or selectively delete. The format is a simple YAML file, for example:</p>
<pre>
   tables:
        users:
            random_email: email
            nullify:
                - firstname
</pre>
<p>This is a snippet from <a href="https://github.com/mozilla/zamboni/blob/master/configs/mysql-anonymous/anonymize.yml">the config script</a> for <a href="https://addons.mozilla.org">addons.mozilla.org</a>.</p>
</p>
<p>When the IT copies the databases down from production, this script is run against the database. Ensuring that when us developers access the backups to investigate certain issues, we&#8217;ll be getting the bits we want and not the bits that might expose user data.</p>
<p><em>In the next blog post we&#8217;ll look at logs and tracebacks.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2011/11/18/scrubbing-your-django-database/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Open sourcing your Django site</title>
		<link>http://blog.mozilla.org/webdev/2011/10/20/open-sourcing-your-django-site/</link>
		<comments>http://blog.mozilla.org/webdev/2011/10/20/open-sourcing-your-django-site/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 23:33:38 +0000</pubDate>
		<dc:creator>Andy McKay</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/webdev/?p=2135</guid>
		<description><![CDATA[This is the first in series of posts, focusing on issues around open sourcing your Django site and data privacy in Django. A lot of people focus on open sourcing their Django libraries, but at Mozilla we open source the &#8230; <a class="go" href="http://blog.mozilla.org/webdev/2011/10/20/open-sourcing-your-django-site/">Continue reading</a>]]></description>
				<content:encoded><![CDATA[<p><em>This is the first in series of posts, focusing on issues around open sourcing your Django site and data privacy in Django.</em></p>
<p>A lot of people focus on open sourcing their Django libraries, but at Mozilla we open source the entire site. Releasing your entire source code can lead to a few problems, firstly let&#8217;s look at your Django settings file.</p>
<h3>Separating your settings</h3>
<p>All Django sites come with a <code>settings.py</code> file. This file contains some key settings that you should not be releasing to the general public, such as <a href="https://docs.djangoproject.com/en/dev/ref/settings/#databases">database configuration</a> and the <a href="https://docs.djangoproject.com/en/dev/ref/settings/#secret-key">secret key</a>. The simple way to do this is have another file that contains the secret settings and then import it from <code>settings.py</code>. For example include this at the bottom of your <code>settings.py</code>:</p>
<p><script src="https://gist.github.com/1287619.js"> </script></p>
<p>All your sensitive settings can now kept in that local file on your server and should not be published as part of your site code. This file will override the base settings file.</p>
<p>There are plenty of other examples on different ways to do this. You can do it in <a href="https://github.com/mozilla/zamboni/blob/master/manage.py#L39">manage.py</a>, or turn your <code>settings.py</code> into a folder that Python can import. Make sure that you ignore your <code>settings_local.py</code> file in your source control.</p>
<p>If you add in new settings, make sure you add them into the main <code>settings.py</code> file. Even if they are just empty strings, lists or whatever, it will mean that when you call <code>settings.SOME_KEY</code> in your code, you won&#8217;t have to cope with the setting not being present. There&#8217;s nothing more tedious than writing lots of <a href="http://docs.python.org/library/functions.html#getattr">getattr</a> code to cope with that.</p>
<h3>Viewing settings on the server</h3>
<p>One downside of doing this is that you might not be sure what your settings are on the server. At Mozilla only the system administrators who manage and deploy our servers can see the contents of that file. But it&#8217;s still helpful to check the settings on the server. For that we wrote a settings page that lists them out.</p>
<p>Django helps by providing a method that lists the settings, but obscures those really sensitive values:</p>
<p><script src="https://gist.github.com/1302651.js"> </script></p>
<p>On <a href="https://addons.mozilla.org">addons.mozilla.org</a> we require an account to have certain privileges before showing the page. But even if that did get broken into, you wouldn&#8217;t know our <code>SECRET_KEY</code> or anything very useful. Here&#8217;s how that page looks:</p>
<p><img src="http://farm7.static.flickr.com/6109/6264561859_9e3631ca72_z.jpg"></p>
<p>Now that you&#8217;ve got your settings files ready, you can confidently open source your Django project safe that you won&#8217;t be leaking any key data.</p>
<p><em>In the next blog post we&#8217;ll look at scrubbing personal data from your database.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/webdev/2011/10/20/open-sourcing-your-django-site/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
