Stavros' Stuff

Angry rants of programming and other things.

Django's per-site caching doesn't work

Surprise! Your cache doesn’t.

A few days ago, I wrote a post about a peculiar piece of code that a friend of mine had sent me. Since it was interesting bit of code, I thought Hacker News would enjoy it, so I posted it there. To my great pleasure, the post shot up to the first place in a few minutes and continued there for a full day, bringing just over 50,000 visitors to this blog, in total.

I was very happy that people were liking and discussing this post (and the discussion was very interesting in its own right), but I noticed that AppEngine, where this blog is hosted, was struggling to serve it. I had to create new instances because the average latency was about ten seconds(!), even though this blog is pretty much only text and static media, and I use Django’s per-site cache to cache every single page.

Continue reading…

Brilliant or insane code?

A Moste Wonderfull Tale of Optimizations and Legibility

I came upon a very interesting and cryptic snippet of code somewhere nameless, and I can’t decide if it is brilliant or completely insane. It is a very obscure way of accomplishing the required task, but it’s around four times faster than the alternatives I’ve tried, so I have to admit that it’s not completely without merit. Still, I cringe a bit at seeing it, since it packs around four unusual Python concepts in almost as many characters.

This is the snippet in question:

Continue reading…

Faster installs with pip

Today’s tip is brought to you by the color green and the number g.

If you’re an industrious Python programmer, you probably use pip and virtualenv to install your packages in an isolated location, which is great, and good job to you. However, having to install Django, pandas and ipython every time you want to experiment with something is a bit tiresome, since they’re all big files and downloading them takes a while, plus what if you’re on a data-limited connection and bla bla bla.

Here’s a very easy way to both speed up your downloads and avoid having to do them in the first place:

Continue reading…

Blogging from the filesystem

DOTA2 LogoIf you see this, run. Away.

I have recently been writing more and more (or, at least, trying to), mainly because I’ve been busying myself with a variety of interesting things and I figured that writing about them could help other people. I am fully expecting to fall back into a DOTA2 binge one of these days and completely cease all productive endeavors, but I’m enjoying it while it lasts.

One of the frustrating things about writing for this website, at least with my current setup, is the interface. I wrote this website in Python using Django because:

Continue reading…

Use two-factor authentication for Mozilla Persona on your own domain

Lately, I have been very happy to see Mozilla’s new proposed authentication system, Persona, gaining popularity. I have tried it in both my capacities as a user and a developer, and, I have to say, it leaves me eminently satisfied in both.

As a developer, it is fantastically easy to integrate. Given how much of a pain all the password change, account creation, password reset, login, etc views (with assorted HTML) were, the 3-minute integration of Persona was a godsend. Since I also don’t need to preoccupy myself with securely storing people’s passwords, Persona wins hands down.

As a user, Persona is very simple to log in. It asks you for your email address, asks you to create a new account (and verify it) if you haven’t been there before (or your password if you have), and you’re logged in. To make things better, it recently got Gmail integration, which means that, if you use Gmail, sites that support Persona effectively now have become “Log in with Gmail” sites, without Google knowing which sites you authenticate on. That’s just fantastic.

There is a bit of a blind spot for people who use their own domains for email addresses, though. If your domain isn’t a Persona identity provider (and most aren’t, by default), you have to log in through the built-in provider. While it does the job, that provider is far from full-featured, only allowing you to sign in with one address and a few aliases.

I wanted something more powerful, so I built a new tool to help manage Persona authentication for your domain. I call it Persowna, and it has a number of very useful features for advanced users or businesses:

Continue reading…

Expandable code blocks in simple CSS3

If you’ve been frequenting programming-themed blogs, you may have noticed expanding code blocks. They’re code blocks that expand when you hover over them, so that text will wrap at a further line and you can read it more easily.

Until today, my blog didn’t have those, and I felt very, very disadvantaged. Why must my code wrap while the other kids’ code is nice and straight? Was I less cool?

Well, no longer. Today I have implemented this expansion, and it only took a few minutes. I Googled around for solutions, but all the proposed ones seemed…

Continue reading…

How to properly configure Google Apps email

I, like many of you, use Google Apps for my email, mainly because it is very convenient and has excellent spam filtering capabilities. However, to ensure that messages show up properly and that they don’t end up in spam, there are some steps that need to be taken. In this post, I will give some helpful hints and samples for configuring your Google Apps’ Gmail service so that your messages aren’t classified as spam, and so that the dreaded “via” field doesn’t show up.

The “via” field is something that Gmail adds when you try to send email through it from alternate email addresses (some clients refer to it as on-behalf-of). For example, my main domain is korokithakis.net, but I want to send mail from stavros.io, without running a separate mail server. When incorrectly configured, Gmail messages with a stavros.io email appear on other Gmail inboxes (and other clients) as “whatever@stavros.io via stavros@korokithakis.net”, which is unsightly.

Without further ado, let’s look at what configuration changes we can make so our stuff shows up properly.

Sender Policy Framework

The Sender Policy Framework system uses DNS records to designate permitted sending domains. To designate that an SMTP server can send email on behalf of some domain name, you need to set a TXT record on your domain (the part of your address after the “@”). Here’s mine:

Continue reading…

On the pitfalls of A/B testing

You’ve (hopefully) heard many things about A/B testing. People rave about it, and with good reason: It provides you with a solid framework on which to evaluate how a change you’ve made has affected your metrics. Gut feeling isn’t always enough, and hard numbers help tremendously in decisions. However, most people (and software packages) make a grave mistake when A/B testing. This post will help you recognize and avoid it.

In case you’re unfamiliar with A/B testing, here’s a small run-down (it might get a bit technical, but shouldn’t be too bad):

Continue reading…

New theme!

After the new domain name, this blog now has a new theme as well! It should hopefully be much, much better (i.e. actually not horribly broken) on mobile, plus the contrast is better and the text is much cleaner now.

It’s not completely done yet (I still want to add post archives to it), but it has the same features as the old one.

Enjoy!

Continue reading…

Automated, large-scale deployments with Ansible's pull-mode

If you’re a regular reader of my blog, you will know two things about me:

  1. I like Ansible.
  2. I frequently begin posts with “if you’re a regular reader of my blog”.

I recently discovered that Ansible got a “pull mode”, which is a super-simple way for Ansible to pull a repository and run commands from a file you specify. Unfortunately, documentation is pretty sparse, but that’s only a disadvantage until you realize that pull mode is really, really simple.

What “pull mode” is.

“Pull mode” is a single, very simple script. You can invoke it with ansible-pull, and all it does is what is described in its man page:

Continue reading…