IN WHICH OUR HERO NERDS OUT PRETTY HARD

Mar 30

Don’t Learn How To Program

Aaron Schaap recently wrote a great post on why you, as a non-technical entrepreneur, don’t need a programmer. What you really need is a technical co-founder.

I completely agree, and have seen many good ideas go down in flames because the entrepreneur spent more time on the phone with the “coder” they hired off Craigslist to build their web sight than they spent getting out and creating a business.

Other Side of the Coin

However I’ve also heard the following story a lot, and I think it’s just as damaging to would-be non-technical founders. I’m sure this sounds familiar to many of you:

“I’ve got this great idea for a business - it’s a marketplace that facilitates peer-to-peer lawncare equipment rentals, including payment processing and built-in messaging. I couldn’t find a programmer to work with me, but I bought this book called Let’s Learn HTML!. By spending a few hours a day with that I think I should have the first version out myself in a few weeks, a month tops.”

I’ve heard quite a few of variations of this, but it all boils down to “Well, I couldn’t find a technical co-founder, so in the meantime I’ll just learn how to program it myself.”

Every time I hear this I want to squirt the person with a spray bottle like a misbehaving cat. Imagine you went to this same person and said, “I’ve just bought this great lot for my house. It’s location is perfect. But I can’t find an architect to help me build it, and I don’t want to hire one, so I went to Home Depot and bought some lumber and nails. I also got a book on carpentry, so I think I’m pretty set”. They would tell you you’re crazy, and you should go get someone who knows what they’re doing before you’re crushed to death by 2x4’s. But learning to create a website somehow seems like a good strategy.

Building a full-fledged web app is complicated. It’s so hard even programmers consistently underestimate the time it will take. Trying learn how to build on, while simultaneously building your business, is a recipe for disaster (well, not disaster, but usually for a product marketing job at google which you take “just for the moment, to keep me afloat. I can totally do the startup in my spare time”).

Sometimes you just need a lemonade stand

The flip side is, many founders think they need a mansion when what they really need to start with is a lemonade stand. And almost anyone who knows which end of a hammer to use can build a lemonade stand.

When someone comes to me with their 20-page mockup for a website that sells art sourced from the local community, I tell them they’ve managed to over-engineer the problem without even having an engineer. They can vett their idea without needing to sink months into web development.

There are lots of platforms that let you get content onto the interwebs without any programming knowledge. Tumblr and Wordpress are great. You can easily create the lemonade stand equivalent of an ecommerce site with wordpress, google checkout, and yourself manually filling orders. You could do it in a week, in a weekend if you buy a coder friend some pizza and beer.

Your lemonade stand let’s you learn a ton and figure out what business you should actually be building (are you Jack Dorsey? No? Then I’m afraid you haven’t conceived of a brilliant business right from the get go. Oh, you are Jack Dorsey? Wow thanks for reading my blog).

Programming is awesome

I don’t want to disuade anyone from learning to program if they truly have the itch. I love programming and the feeling of creation it brings. It’s also a great feeling to know how the technology behind your business ticks.

It can also be very handy to be able to do some things yourself. And many things are not that hard. At my last startup, I had all the business people using git & fabric to update the static content on our site and push the changes live. Life was much better for all of us when they could decide to change some language, edit the page, commit their changes, and push it live, all solo. And really, that workflow is easy enough for anyone to learn in a couple hours (although my co-founders were ballers who took to using the terminal like pigs to mud, so YMMV. I take no responsibility when your VP of Marketing accidentally issues a git rebase).

But only dive deep into programming if you have the inner passion to learn. It’s an awesome profession and a sweet hobby. But it’s not a shortcut to launching your business.

One hint on finding a programmer

Last point, as this is getting longer than a Steve Yegge intro paragraph (oh burn LOL). After I put the squirt bottle down, lots of people say “But I keep asking around about programmers, and they all have jobs! None of them are looking to jump onto a startup!”

This brings the bottle back out. Yes, they all have jobs. Technical people are in high demand right now, especially the ones you want for co-founders. But this does not mean they aren’t looking to jump ship and start a startup. Don’t let the fact that they currently have a job disuade you. This is a GOOD thing. If you respect the company they work for, it’s a sign they’re competent. Do that networking thing you got so good at in B-school, find some great people who are tired of their big-biz job (or who’ve hit their vesting cliff), and tell them why your idea is rad. You’ll have a programmer in no time, and you can put Learn Javascript in 24 Hours! in the garbage where it belongs.

Mar 27

User Accounts with Webapp2 + Google App Engine

We recently finished the first rev of Legit’s developer site. We built it on google app engine using the webapp2 framework. Overall the experience was great, albeit with a few hiccups.

One of the hiccups was creating a backend to handle developer accounts (signup/login/logout etc). With other frameworks this is part of the “batteries included.” Django for example has a very robust authentication module.

As far as I can tell a completely pre-built, well maintained solution doesn’t exist for webapp2 + gae (let me know if it does and I missed it!). Fortunately, it’s not that hard to create.

I found a few excellent resources in the webapp2 mailing list, docs, and source. But I couldn’t find a page/blog post/stone tablet cleanly laying everything out. So, I decided to be the change I wanted to see.

Pre reqs

Aside from gae + webapp2, we need:

To use 3rd party libraries that aren’t bundled with gae you’ll need to copy them to your gae app directory. I usually check the library out elsewhere, create a symlink to it inside my gae app, and add the library to my gae app’s .gitignore file:

> cd /where/I/keep/thirparty/libraries/
> hg clone https://bitbucket.org/simplecodes/wtforms
> cd /my/google/app/
> ln -s /where/I/keep/thirdparty/libraries/wtforms/wtforms wtforms
> echo "wtforms" >> .gitignore

Remember to ln to the python module within the library’s source directory, not to the source directory.

Follow this pattern for NDB and wtforms.

Note that NDB is now bundled with google app engine so technically you don’t need to install it like this. You can include it with your app. But, I had trouble getting that way to work correctly. Plus, NDB is in such active development you probably want to check out the latest version from source anyway.

I’m also going to use jinja2 to render templates. You don’t have to use jinja2, but trust me, use jinja2. There’s a technique in the code to make rendering jinja2 templates a breeze. Install jinja2 using the technique above (as with ndb, in theory you can just use the jinja2 bundled with gae, but I like being able to control the jinja2 version myself).

The Plan

What we’re going to whip up is pretty simple:

There are some templates you’ll need to build, but those are for the front-end team amirite?? (yes I am aware that the “front-end team” is just you wearing your tightest pair of jeans).

User Model

Webapp2 comes with a built-in user model. See the docs / source at: webapp2_extras.appengine.auth.models.User. It’s basically ready to go - we’re just going to add an email field. This isn’t strictly necessary since it’s an expando model, but I like having the email field be explicit:

import ndb
import webapp2_extras.appengine.auth.models as auth_models

class AwesomeUser(auth_models.User):
    email = ndb.StringProperty()

Feel free to name your model whatever you’d like, you obviously don’t need to use AwesomeUser.

User Aware RequestHandler

Here is where 90% of the magic (and 99% of the complexity) happens. As you (hopefully) know from working with webapp2, each request made to your app is handled by a subclass of RequestHandler. We’re going to create a subclass of RequestHandler that all the app’s handlers will subclass in turn. This new base class will be aware of the currently logged in user (if there is one). We’ll build it up in pieces.

Sessions

Sessions let us keep track of users across requests by storing information in a browser cookie.

This is slightly complicated as webapp2 splits things into the SessionStore model, which provides/creates sessions, and the Session, a dict-like object that stores session data. This is actually quite cool, as it let’s you have multiple sessions going in a single request, all of which are generated by a single SessionStore. But for simplicity we’ll use a single session from a single session store.

Creating our UserAwareHandler class with session support:

from webapp2_extras import sessions, auth # we'll use auth later on
    
class UserAwareHandler(webapp2.RequestHandler):    
    @webapp2.cached_property
    def session_store(self):
        return sessions.get_store(request=self.request)

    @webapp2.cached_property
    def session(self):
        return self.session_store.get_session(backend="datastore")

Hopefully pretty straight forward.

The webapp2.cached_property decorator does two things:

I’ve hardcoded the session backend to datastore. The 3 builtin types of session backends are listed in the docs for get_session. I didn’t pick securecookie because I don’t want the user to monkeying with the session by editing with their cookies, and I didn’t use memcache because I didn’t want to tie sessions to memcache. Datastore is the slowest so if you need the performance, change it.

Last we need to persist changes made to the session object at the end of each request so. We add this to the dispatch method, which gets called whenever the request handler handles a request:

    def dispatch(self):        
        try:
            super(UserAwareHandler, self).dispatch()
        finally:
            # Save the session after each request        
            self.session_store.save_sessions(self.response)

Auth & User

Now we need to add the auth backend and users to the request handler. Adding to our existing UserAwareHandler class:

    @webapp2.cached_property
    def auth(self):
        return auth.get_auth(request=self.request)
    
    @webapp2.cached_property
    def user(self):
        user = self.auth.get_user_by_session()
        return user
    
    @webapp2.cached_property
    def user_model(self):
        user_model, timestamp = 
            self.auth.store.user_model.get_by_auth_token(
                self.user['user_id'], 
                self.user['token']) if self.user else (None, None)
        return user_model

This is very similar to the session code above. We’ve added an auth property that handles actually authenticating the user, and user and user_model properties for accessing the currently logged in user.

We have both user and user_model because get_user_by_session() doesn’t actually return a full user object, just minimal identifying user data stored in the session. The user_model property goes to the datastore and gets the model object for the logged in user.

Also note self.auth.store.user_model is used to refer to our user model. Webapp2 is very clever and let’s you configure the model you’re using for users in one place (it defaults to webapp2_extras.appengine.auth.models.User). You can then reference this model with self.auth.store.user_model. If you ever want to change your user model, you just have to change your code in the one place where you do the configuration (it should be clear by now that Rodrigo Moraes and the rest of the webapp2 guys are true nerd ballers).

We need to configure the app to use our AwesomeUser model as auth.store.user_model, and we also need to configure our sessions to with a secret key, so we’ll do both at the same time.

This is done by passing a config dictionary when creating the WSGI app (which app.yaml points to):

config = {}
config['webapp2_extras.sessions'] = {
    'secret_key': 'zomg-this-key-is-so-secret',
}
config['webapp2_extras.auth'] = {
    'user_model': AwesomeUser,
}

app = webapp2.WSGIApplication([
    # ... all of our applications URL routes
], config=config)

Bang! Now we’re cooking with gas.

Remember, subclass ALL of your app’s request handlers from UserAwareHandler. This let’s you access the currently logged in user for every request and in every template.

Jinja2 Templates

Last trick. This isn’t necessary for doing auth, but it has been so useful I couldn’t resist putting it in. I mentioned that I recommend using jinja2 for templating. To make this seamless, we’re going to add a simple render_response method to our request handler so we can render templates in one line. Add the top level function:

def jinja2_factory(app):
    "True ninja method for attaching additional globals/filters to jinja"

    j = jinja2.Jinja2(app)
    j.environment.globals.update({
        'uri_for': webapp2.uri_for,
    })
    return j

And to the end of the UserAwareHandler add two more methods:

    @webapp2.cached_property
    def jinja2(self):
        return jinja2.get_jinja2(factory=jinja2_factory, app=self.app)

    def render_response(self, _template, **context):
        ctx = {'user': self.user_model}
        ctx.update(context)
        rv = self.jinja2.render_template(_template, **ctx)
        self.response.write(rv)

Now when you want to render a jinja template while handling a request, it’s as easy as:

class MyTemplateHandler(UserAwareHandler):
    def get(self):
        self.render_response("path/to/your/template", 
                                context_var1="wow", 
                                context_var2="that was easy")

And thanks to our custom jinja2_factory you can use the uri_for function in your templates and it just works. By adding self.user_model to every context, can also refer to the user variable in any template and have access to the currently logged in user. Heaven.

Signup / Login / Logout Handlers

Armed with UserAwareHandler it’s easy to create a signup form and handler. First we a wtform form to handle validation and parsing the request data. They’re rather self explanatory so I won’t say much more about forms, but you can get completely up to speed with the wtforms crash course.

I assume you have the templates “auth/signup.html” and “auth/login.html” ready to go. Templates are a whole separate discussion, but wtforms and jinja2 make easy. The templates need to display the form fields and provide a submit button that POSTs to the same URL that’s serving the form. See the wtforms crash course.

First the signup form:

from wtforms import Form, TextField, PasswordField, validators
    
class SignupForm(Form):
    email = TextField('Email', 
                    [validators.Required(), 
                     validators.Email()])
    password = PasswordField('Password', 
                    [validators.Required(), 
                     validators.EqualTo('confirm_password', 
                                    message="Passwords must match.")])
    password_confirm = PasswordField('Confirm Password', 
                        [validators.Required()])

and the signup handler:

class SignupHandler(UserAwareHandler):
    "Serves up a signup form, creates new users"
    def get(self):
        self.render_response("auth/signup.html", form=SignupForm())

    def post(self):
        form = SignupForm(self.request.POST)
        error = None
        if form.validate():
            success, info = self.auth.store.user_model.create_user(
                "auth:" + form.email.data,
                unique_properties=['email'],
                email= form.password.data,
                password_raw= form.password.data)

            if success:
                self.auth.get_user_by_password("auth:"+form.email.data, 
                                                form.password.data)
                return self.redirect_to("home")
            else:
                error = "That email is already in use." if 'email'\
                        in user else "Something has gone horrible wrong."
                                         
        self.render_response("auth/signup.html", form=form, error=error)

The logic of the handler can be broken down as:

The tricky part is the create_user method. The first argument is an auth_id, which needs to be unique to the user. This is different from the user_id, a single, unique, numeric ID automatically assigned upon creation.

In contrast to the user_id, a user can have multiple auth_ids. For instance, the same user could log in with multiple usernames or emails, or through facebook or twitter, and the user could have a separate auth_id for each authentication method. I’ve just used “auth:email@address” as the auth_id, but feel free to use whatever string you like.

create_user is also doing some magic to ensure that each user’s email address is unique. The google app datastore does not support the idea of “unique” properties. Webapp2 gets around this by creating a separate collection of Unique objects. When creating a user, it first tries to create new unique objects for each unique property. It uses transactions to see if the unique properties already exist and only creates them if they do not.

This is all quite clever. If you want to see how they do it, check out the source. Or, just know that by passing a list of strings to unique_properties, create_user will ensure that those properties are not in use by other users. If they are, success will come back false and info will be a dictionary of the problematic fields. If there were no issues info will be a dictionary of user data and success will be true.

On to our last two handlers, Login & Logout, which are even simpler. First, the login form:

class LoginForm(Form):
    email = TextField('Email', 
                [validators.Required(), validators.Email()])
    password = PasswordField('Password', 
                [validators.Required()])

The login handler:

class LoginHandler(UserAwareHandler):
    def get(self):
        self.render_response("auth/login.html", form=LoginForm())

    def post(self):
        form = LoginForm(self.request.POST)
        error = None
        if form.validate():
            try:
                self.auth.get_user_by_password(
                        "auth:"+form.email.data, 
                        form.password.data)
                return self.redirect_to('home')
            except (auth.InvalidAuthIdError, auth.InvalidPasswordError):                    
                error = "Invalid Email / Password"
                
        self.render_response("auth/login.html", 
                                form=form, 
                                error=error)

and the logout handler:

           
class LogoutHandler(UserAwareHandler):
    """Destroy the user session and return them to the login screen."""
    @login_required
    def get(self):
        self.auth.unset_session()
        self.redirect_to('login')

If the login form validates and we find a user matching the email/password combo, we log them in and redirect the user to the homepage. It would be better to redirect the user to whatever page they were looking at, but I’ll leave that as an exercise for the reader (or future post).

If the form doesn’t validate or the email/password doesn’t check out, we re-render the template with the filled in form and any errors.

The last piece is the @login_required decorator used in the LogoutHandler. We apply it here as it doesn’t make sense to logout a user that isn’t logged in. However, first we need to define the decorator.

login_required Decorator

The objective is to create decorator that we can apply to request methods within our handlers. When the method is invoked: - If the user is logged in, handle the request as per usual. - If they are not logged in, kick them to the login screen.

Here’s the decorator:

def login_required(handler):
    "Requires that a user be logged in to access the resource"
    def check_login(self, *args, **kwargs):     
        if not self.user:
            return self.redirect_to('login')
        else:
            return handler(self, *args, **kwargs)
    return check_login    

This is straight forward thanks to UserAwareHandler. We check the self.user property. If it exists, we have a user. If it does not, redirect to the login page.

To put a page behind the login wall, simply apply the decorator to the handler method as shown in the LogoutHandler.

Missing Pieces

Even though this post has turned out to be longer than the average Java class (LOL JAVA), there are still a few pieces missing that are necessary before going live. From smallest to the most important:

CSRF is by far the most important. Don’t leave your forms vulnerable! There is a CSRF module for wtforms that’s quite helpful. While you’re at it, you should also take advantage of app engine’s SSL features to secure your URLs.

Building these features shouldn’t be too hard if you grok everything going on in this post. I’ll also see about cranking out some subsequent blog posts of some of these topics, in particular the forgot password workflow.

Questions & Comments

I hope this was useful to people just getting started on app engine. GAE’s still a little rough in places, but just keep repeating to yourself “I’ll never have to configure apache again.” Drop any comments below or hit me up on the twitters.

Aug 31

Business Time @ Bolder (Taken with instagram)

Business Time @ Bolder (Taken with instagram)

Aug 07

Asesor: A medical advice app using Django & Twilio

I recently spent a few evenings working on a side project built around helping to get medical advice to those living in extreme rural areas, primarily in 3rd world countries. The idea is to help bring together those in need of medical advice, translators who can communicate with them, and doctors who can answer their questions, even when all 3 are scattered around the world. If you tend towards the geeky, you can think of it as a distributed, asynchronous medical advisement system.

Bit of Background

I got this idea after my girlfriend went on a trip to Nicaragua as a 2nd year medical student. Every year her med school sends a troop of med students and a some doctors to a rural Nicaraguan village to set up a clinic for a couple of weeks. Often, the 2 week span that the med students & doctors are there is the only time the villagers can get their medical questions answered. Normally they’d have to travel for days to get to the nearest clinic, which is a big barrier. While the med students do far more than simply answer questions, it’s a non-trivial part, and it would be awesome if the villagers could have access to medical knowledge (even if not in person checkups) all year round.

Hence, my thinking; There are many communities like this, who certainly need in-person medical attention, but could also benefit greatly from simply having their medical questions answered. There are also many medical professionals who are more than willing to volunteer their time each day but who have packed schedules and may be on very different timezones than those in need of advice. Finally, there may be a language barrier between those in need of advice and the medical professionals, but there are also many translators around the world who would also be willing to donate their time.

My Solution

Fortunately, the one piece of technology that that is almost ubiquitous is the telephone. So centered on that, my solution was to build an asynchronous question->translate->answer system. The basic idea is that someone without ready access to medical advice would call a special phone number, that number being associated with their native language, and record their question. A network of translators proficient in that language would see that question. One of them would translate and transcribe it into English. Once translated, medical professionals on the system would see the translated question and be able to provide an answer. The original translator would then see that the question had been answered and be able to call the patient back, translating the doctor’s answer into the language of the patient.

Here’s a picture of the flow (using Spanish as an example). Each step (except for the very last) is asynchronous, with the parties not needing to interact in real-time:

Asesor Flow

Key Advantages

This distributed, asynchronous setup has a few key advantages as I see it:

  1. Minimal Patient Technology - The patient does not more technology than a telephone, which let’s this work for many remote populations.
  2. Native Language - The answer is delivered in the same language it which it is asked, which is key for populations without a strong knowledge of English.
  3. Doctor’s Convenience - Doctors are able to answer the questions when they have time. They don’t need to conform to the timezones of those asking questions. They also only need to know English.
  4. Global Supply of Experts - There is never a worry of needing doctors who speak a specific language. So long as there are enough translators of that language, there simply need to be sufficient English speaking doctors. The system can also tap into a global supply of translators and doctors.

Twilio

Shortly after having this idea, I heard about Twilio’s recently launched Twilio Client, which allows voice calls to and from the browser. This seemed like a good technological fit, as it lets patients record messages from their phone as well as let translators call back patients straight from their web browser.

Twilio also started a contest around the launch of Twilio Client for people to build apps using their new library. This was all the excuse I needed to spend some evenings building a proof of concept implementation.

There are many advantages to using Twilio, but I’ll call out a couple. First it makes associating a phone number with a specific language a snap. The app that handles incoming calls can easily determine what language to answer in, and how to tag the question once it’s recorded. Secondly, being able to call the patient from the browser is not only convenient, it’s private. The translator can never actually find out the phone number of the patient being called. The app itself handles the connection, while Twilio Client handles the voice communication. This makes all the questions asked truly anonymous.

Asesor

The fruits of my labors are available here: http://asesor.importrob.com. It’s a fairly straight forward Django app that uses Twilio and Twilio Client to handle the voice communication. I won’t dig too deep into the actual implementation (I’ll leave that for a follow-up post) but I have posted the source on github, so you can dig through it if you want to see how it’s built: https://github.com/robboyle/asesor.

Try it Yourself!

Using the app on display at http://asesor.importrob.com is fairly simply. The first step is to get a question into the system. To do that, I’ve set up two Twilio numbers that you can call, one for Spanish and one for German (the only languages I’m even passingly familiar with). I apologize for the google-translate level greetings, but if you know either language it should be easy to decode:

  1. Spanish - (415) 237-2135
  2. German - (650) 241-4435

You’ll be greeted by a voice in the given language asking you to state some information about yourself (the patient) and your question. Record your information and your question after the beep.

Then, go to http://asesor.importrob.com/register/ and create a translator account. Make sure you select that you are proficient in the language in which you recorded your question. Once you’ve made your account and logged in, visit http://asesor.importrob.com/dashboard/. You should see your question waiting to be claimed. Claim it and translate it into English. Once you’ve translated it it will disappear off your lists, as it’s now waiting on a doctor for an answer.

To pick it up again, you’ll need to become a doctor. Don’t worry, for the moment you can skip all the years of schooling and simply go to http://asesor.importrob.com/register/ again to create a doctor account. Logged in as a doctor, you’ll see that your question on the dashboard in need of answering. Claim it and answer it.

Once you’ve done so, log back in with your translator account. You’ll see your question again, but this time with the medical answer you just provided. There will also be a big button right in your browser allowing you to call the patient (in this case yourself, if you created the question) and tell them the answer to their question in their own language.

This may feel a bit complicated, but remember that you’re playing the part of 3 separate people here. In a live system the patient, translator, and doctor would only have to worry about their individual part of the overall puzzle.

Looking Forward

Obviously there are many places this could be improved. Letting doctors speak directly to patients, having a standardized patient questionnaire, allowing for doctors that are also translators. However, I think the seed is here. I could see this easily becoming the technological underpinnings of a pretty sweet non-profit. The technology would actually be the easy part. Gathering together the translators and doctors to make the system function would definitely require the most legwork. However, what encourages me is that there are lots of doctors and translators out there, ready and willing to volunteer their time. This kind of app may be just what’s needed to unlock all that willingness and give a helping hand to those that need it.

So, there you have it, my little project. Hope it sparks some thoughts if nothing else. No matter what though, let me know what you think by shooting me a question or a comment!

Feb 12

JB showing off some hair that would make A Flock of Seagulls hide their heads in shame. My confidence in Bolder’s future has increased precipitously. 

JB showing off some hair that would make A Flock of Seagulls hide their heads in shame. My confidence in Bolder’s future has increased precipitously.