How I do Python/Django on OS X

(this is a repost from the startup’s devblog)

At the startup I am working at, we currently run our own stack of bits on an Ubuntu AWS EC2 compute unit along with other services on the AWS infrastructure. This server currently has Postgis (Postgres with spatial additions), Apache, Python, Django and various other python specific utilities like Tornado and Celery. Its fairly easy to build a VM image that closely match those specs down to the actual version number of the bits installed, or even to just grab the AMI image and have it run as a VM image locally.

One of the things I loathe the most is cluttering my system with installations of things that I have no control over. As such, I am a huge fan of things like MacPorts and also Homebrew. As far as installing things on OS X, those 2 are the limits I would go. When it comes to writing Python/Django and also perhaps Ruby On Rails, having the “environment” setup is a big deal and OS X is not one that is particularly tolerant. Being a huge fan of “self-containness”, it was unacceptable to hack around too much with the CLI and Macports to get everything working right.

So to deal with all these bullshit, I’ve come up with a setup that I am fairly happy with and am actually fairly productive in. All server sided development is done with a VM image of the environment that closely resembles production but with some additional things to make it easy.

The following is the list of things that can make server sided development easier on OS X,

  1. VMWare Fusion
  2. Avahi (ZeroConf)
  3. Transmit
  4. Git
  5. Your-Favorite-Text-Editor

VMWare Fusion

Runs your average Virtual Machine images. I like it because it is a pretty stable piece of sofware with VMWare’s engineering pedigree when it comes to virtual machines. You don’t really use much of its features for running a purely server type VM, but I like that it has pretty tight integration with OS X and plays nicely with most VM formats.

The added benefit of using a VM is that you technically can have a master cloned copy of the production environment that can be passed around to your developers thus reducing the time to get setup and transitioning to actually doing productive useful work.

VMWare Fusion

Avahi (ZeroConf)

This is the name of the package that contains the ZeroConf daemon for Ubuntu. This is a nice to have as it makes local DNS resolutions really easy since OS X supports ZeroConf out of the box through Bonjour. The added benefit is that if your development team mostly use Macs, everyone can see your VM on the network. Since it has a constant domain name, this fits the self contained principle of my software architecture philsophy and makes moving and packaging the VM image really easy. No more fiddling with IP addresses is always a plus along with the fact that you can work in an IPv4 or IPv6 environment.

Getting Avahi setup on Ubuntu is fairly easy through aptitude. Configuration-wise, I like to advertise the sftp/ssh service along with the django local server parameters. Using the defaults is perfectly fine to get Avahi up and running. All that is left is to create the services that it will advertise.

This is an example .service file for the ssh service,

<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
	<name replace-wildcards="yes">%h</name>
	<service>
		<type>_sftp-ssh._tcp</type>
		<port>22</port>
	</service>
</service-group>

Once these files are created in the /etc/avahi/services directory its just a simple /etc/init.d/avahi restart to get it to reload the configuration and you should see it being advertised.

Safari is nicely Bonjour aware too.

Transmit

You can of course use any other service that lets you mount SFTP shares, but since I already own Transmit, its Transmit Disk feature really makes things easy. Prerequsites when using this method to do development work would be that you have the stuff you are working on be within your home directory on the VM. So at the end, its just a simple matter of firing up the VM, forgetting about it and telling Transmit to mount the Bonjour discovered SFTP share to get access to the physical files.

This setup ensures you would not need to have another copy on your actual Mac and upload files in order to test it on the server within the VM. One caveat is that git doesn’t seem to run well over SFTP so you still would need to deal with actual source control commits within the actual VM. If you’re 1337 enough, you would probably have Terminal open and an SSH session started to the Bonjour domain. Otherwise, its just a simple matter of having Mission Control manage the window that VMWare Fusion is to allow for fast switching.

Transmit Disk

GIT

I cannot state how awesome git is for development work. The fact that it is a decentarlized system allows any number of people to work on features to eventually syncing those changes. I typically work on a branch of a single feature doing constant commits when things change. Once a feature is complete, I would squash those commits to make things more comprehensive before doing a Pull Request to the main repository for code review before merging.

In order to make merging easier, I would constantly rebase my feature branch whenever new things get pushed to the master branch. This causes less headaches when the final merge happens and generally makes the repository maintainer much happier.

One advantage of not being able to use GUI tools for dealing with git over SFTP is that you have a chance to get proficient with the command line commands. No better way to learn things than actually doing it.

Your-Favorite-Text-Editor

So what is the point of all these? Its so you can use your favorite text editor on OS X.

If you’re a hardcore vim or emacs person, this would probably have no meaning for you, but for the rest of the human race that aren’t that proficient at non WYSIWYG text editors, this is a fairly simple way to let you use your favorite text editor to do development work.

Textmate editing django-activitystream

Code-fu mantra

Lately, I’ve been living by some mantras when it comes to dealing with code and large code bases. Not sure if its for everyone, but it works for me.

This mantras of course pertain to Objective-C and the Mac in general.

  1. Subclass as little as possible, composition is better.
  2. Keep implementation files around 500 lines of actual real code, beyond that, you might want to think of refactoring into logical components.
  3. Group logical components by systems.
  4. Readability trumps “generalization”.
  5. Curly brackets are okay if code blocks are greater than 1 single line of code.
  6. Return as early as possible (Wil Shipley).
  7. Companion to returning as early as possible, try not to nest code blocks 3 levels deep.
  8. Async is not always the best solution (refer to mantra #7).
  9. Design for self containment, but more importantly, in areas of responsibility.
  10. Designing public APIs (things that will not change) will probably give you decoupled objects.
  11. Retain/Release is better than autorelease (until ARC of course).
  12. Protocols are awesome.
  13. Composition of data structures at the expense of space might save you time.
  14. Less objects more primitive types.

Thoughts comments? Eager to hear about yours.

10.8: Objective-C Enhancements

cocoaheads:

Objective-C Enhancements

OS X v10.8 includes the following enhancements to Objective-C:

  • Default synthesis of accessor methods for declared properties

  • Type-safe enums

  • New Core Foundation attributes that allow you to specify custom retain semantics

  • Object literals for NSArrayNSDictionary, and NSNumber

  • Streamlined object subscripting

Important Beginning in OS X v10.8, garbage collection is deprecated.

Can’t help be reblog this. Bloody marvelous. 

MNCoder

Its been about 3 weeks, but I’m finally done with a piece of work that will be used (hopefully) in the iCloud capable version of Mindnode.

MNCoder is what I’d call a clever hack using NSKeyedArchiver and NSKeyedUnarchiver to help with portability of certain Apple classes between iOS and the Mac. If you worked on both platforms, you’d know that iOS has its own implementation for colors and fonts. With iOS 4 this has been extended to NSAttributedStrings that take Core Text attributes instead of the nicer AppKit additions to NSAttributedStrings.

While I’d admit this is a somewhat complicated way of going about things, 2KSLOC to be exact, I figured this was the most straightforward and intuitive way to help people understand and possibly contribute additional code in the future.

What MNCoder does is that it uses a neutral platform independent NSCoding compliant object to store the base attributes that is needed to reconstruct an equivalent on either platform. Using #ifs, the object will give you the appropriate object. Adding to the system is NSCoder which helps with the finding and replacement of objects at runtime when doing serialization.

Its pretty much like old school language translation. Translate your source language into a intermediate version and then translate that to the target language. Nothing too fancy and easily understood.

The work is released under a BSD license which Markus has nicely given his approval of so here’s hoping it’ll have more contributors as it goes along.

Nice side effect of this is that I’ve had extensive time with Core Text and I’d say its pretty fun.