TL;DR – Built a crazily simple single serving site for a local coffee shop as a prototype to see if it would help them. You can currently see it at is black chapel coffee open?.
There is an excellent local coffee shop in Wandsworth town, called Black Chapel coffee, that is physically small enough to be only ever really be occupied by a single person (usually the owner himself). Aside from the fact that I highly recommend the coffee and having a chat to Ant the Barista, who owns and runs it, one thing that is noticeable when you’re used to other shops is that because it is dependent upon a single barista to be open on a given day, opening times often vary from the advertised hours. This typically happens when transport is unreliable (which never happens, of course), or when there are personal circumstances which prevent the barista from reaching the shop.
This means that customers can end up heading over to the shop to find it closed unexpectedly. Now you could simply have the barista tweet when the shop is opening, but the barista was telling me that they had considered this, but that this clogged up their feed too much. In order to help with this situation, I thought I’d knock together a quick prototype of a single serving page to tell customers if the Black Chapel coffee shop is open yet.
I considered requirements thus far:
- A clear simple way of a customer being able to tell if the shop is open or not at a glance – I should be able to see the simple fact upon first page load, no scrolling, no clicking, no distractions, less than 15 words on the page.
- As a caffeine deprived customer would be checking it, I want it to load super quickly – it should be served in sub 100ms and under half a second on a mobile.
- It should be easy for the barista’s to operate independently – a simple way for the barista’s that run the shop to operate on a daily basis.
The first step was to create the static front end.
Once I’d put the page together, it’s worth testing on Google PageSpeed insights. I initially got a single UX issue:
The mobile and desktop speedtests provided a 100/100 rating (as they should when your page is just under 1.5kb) and the mobile user experience test recommended adding a viewport.
I then turned my attention to the back-end. Coffee shops tend not to open and close too frequently in the grand scheme of web systems so I expected a heavy read to write ratio. As a result, I a used a quick Python file to generate a static html page of the right shape and write it out as a static html page using pystache for templating to be served by nginx. The next question was how to trigger the state transition.
In an ideal world, I’d have liked to have Raspberry Pi or Intel Edison hooked up to the doors of the coffee shop, or the power of the vintage lever espresso machine that sit in the shop so that this update process was entirely automatic, but I felt this might be a little overkill considering I was prototyping and “do you mind if I plugin in this strange device and borrow your wifi credentials” is an odd question uninvited from a customer.
I could also have just used basic auth, to protect a tiny page to switch the states, but this seemed rather unhelpful as the turnover of staff in the hospitality industry is high and this could quickly mean a lot of people with access to shared credentials. As all of their barista’s are heavy Twitter users, I quickly turned my attention to the Twitter API. Python has great support for the Twitter API and after discarding the idea of using DMs sent to the BlackChapelCoffee Twitter account from barista’s personal accounts because notifications sent over the Twitter streaming API seemed patchy when using multiple devices (it would seem that only one subscriber gets the stream notification).
I settled on using the Twitter social login to authenticate and using a white list of Twitter users who are allowed to change the state. I created a new app in the Twitter dev console and created a small Python Flask app along with the Flask-OAuth extension to handle logins. This was incredibly easy to get started with, and within minutes, I had a redirect to Twitter OAuth login page working:
The basic and crude essentials of the barista login landing page looks like this:
@app.route('/baristalanding') def baristalanding(): if 'twitter_id' in session: if is_authorised_id(session['twitter_id']): return render_admin_html('loggedinlanding') else: return render_admin_html('unauthorised') else: return redirect(url_for('logmein'))
The login flow as a sequence diagram looks like this:
In less than 100 lines of Python (including logging), I then had a very simple Flask app through which barista’s of the Black chapel could login through their own personal Twitter accounts and then open and close the site.
You can see the customer facing site here.
We will see if it turns out to be something that they think will help them, but as it took less than an hour (writing this post took longer) and a 100 lines of Python, it’s a pretty cheap prototype to throw away. The control panel is extremely crude but works well after tracking this issue on the Flask-OAuth github repo. The only oddity I notice is that occasionally when you’re the barista changing the state, you need to refresh the customer facing site to see the new status once you’ve updated whether it’s open or closed.
Potential next steps
If it turns out to be useful, the potential next steps in my mind are:
- Move it to an official Black Chapel coffee domain.
- Adding a bit of polish and making it slightly less crude.
- I would also look at getting rid of the operational overhead and moving it to be hosted on AWS S3 + Amazon Lambda. This would require me to convert the code to a more AWS Lambda friendly language and framework.
- Implement notifications via the html5 notifications API or something similar.