Be WSGI Compliant

It’s the default standard for Python web frameworks. Only a fool wouldn’t support it.

Don’t Reinvent the Wheel

TinCan is mostly Bottle and Chameleon. Why rewrite the basic guts of an application server, when they’ve already been written many times? Why write a new templating engine, when there’s existing ones out there? TinCan tries to leverage existing software as much as possible.

Keep It Simple, Stupid

I wanted to get on with the business of actually using TinCan to do things, so I didn’t clutter it up with extra features that would be difficult to implement. (That’s why there’s currently no way to choose templating engines other than Chameleon. I tried to allow that, and it proved overly complex. Maybe some day.)

Don’t Be Gratuitously Bossy

TinCan is not tightly coupled with an ORM, and never will be. I personally dislike ORM’s, and I am not alone. Moreover, not all web applications need to use an SQL database in the first place.

This is of no loss, even for those who prefer to use an ORM, since it is easy enough use an ORM with TinCan (just add it to the script you make to load the webapp, and include the ORM in the webapp’s config dictionary).


It’s maligned by many, but I personally like it, and it does not necessarily mean repudiating the MVC paradigm (see MVC Comes in Different Forms).

Don’t Repeat Yourself

One of the things I dislike about most Python web frameworks is that I’m always tiresomely repeating “this is route foo, serviced by controller foo (which defines variables bar, baz and blort), which uses template foo (which renders variables bar, baz and blort).” This is completely unnecessary; the relationships should be obvious by virtue of the similar names. The framework should figure it out and just “do the right thing” by default.

MVC Comes in Different Forms

If a programmer shows a little discipline, the template page will describe how data is presented to the user, and how he or she can interact with it. A view by any other name is still a view. The code-behind will tie that view into the underlying business logic, and bridge the gap between the two. A controller by any other name is still a controller.

If a programmer don’t show discipline, s/he can clutter templates up with bits of Python code that represent controller logic, and clutter the controller up with bits of presentation details. Of course s/he can. That’s not the framework’s fault; that’s the programmer’s fault. Bad code can be written in any language, for any platform.

The Alternative is PHP or CGI, not Django or Flask

I’m not the only one out there who doesn’t like all the repeating yourself that most MVC frameworks make you do. There’s still a lot of developers out there writing CGI scripts or using PHP, because CGI and PHP don’t make you do all the busywork that most frameworks do. (Can they be blamed? It really feels silly when all you want is to get a quick, small site up.)

That’s a pity, because CGI is hideously inefficient and PHP is, well, just plain hideous. (A root namespace with literally thousands of builtins cluttering it up, builtins with no consistent naming convention? Ugh!)

Hopefully, by making it easier for people to code efficient web sites using a well-designed language that’s easy to learn, I’ll encourage more people to create efficient sites in a well-designed language. If not, well, at least I’ll enable myself to do so.

Meaningful Error Messages (If You Want Them)

Bottle can be notoriously tight-lipped about what’s going wrong if and when things go wrong. (And when you’re developing and debugging code, things go wrong). TinCan tries as hard as possible to catch errors and log them. Enable logging, and when you see a 500 error, you will almost always have a log file with a traceback in it helping to pinpoint the cause.

(Note that WSGI provides no default means for logging errors, so if you’re running TinCan via WSGI, it will be totally silent unless you pass tincan.launch a suitable logger. The simple test server created by the launch command always logs to standard error.)