Web Apps in the Cloud: Even Astronomers Can Write Them!

Philip Cowperthwaite and Peter K. G. Williams work in time-domain astronomy at Harvard. Philip is a graduate student working on the detection of electromagnetic counterparts to gravitational wave events, and Peter studies magnetic activity in low-mass stars, brown dwarfs, and planets.

Astronomers that study GRBs are well-known for racing to follow up bursts immediately after they occur — thanks to services like the Gamma-ray Coordinates Network (GCN), you can receive an email with an event position less than 30 seconds after it hits a satellite like Swift. It’s pretty cool that we professionals can get real-time notification of stars exploding across the universe, but it also seems like a great opportunity to convey some of the excitement of cutting-edge science to the broader public. To that end, we decided to try to expand the reach of GCN alerts by bringing them on to social media. Join us for a surprisingly short and painless tale about the development of YOITSAGRB, a tiny piece of Python code on the Google App Engine that distributes GCN alerts through the social media app Yo.

If you’re not familiar with Yo, there’s not much to know. Yo was conceived as a minimalist social media experience: users can register a unique username and send each other a message consisting of “Yo,” and only “Yo.” You can think of it as being like Twitter, but instead of 140 characters, you have zero. (They’ve since added more features such as including links with your “Yo,” but we’re Yo purists so we’ll just be using the base functionality.) A nice consequence of this design is that the Yo API is incredibly straightforward, which is convenient for a “my first web app” kind of project.

Yo is like most web platforms in that you can make programs that talk to it by registering as a developer and obtaining an “API key,” a secret code that all of your programs use to identify themselves to Yo’s servers. We simply registered our YOITSAGRB username at the Yo developer portal, got our API key, and we were good to go. It’s important to point out that because the API key must be kept secret, you must not embed it in your web app’s source code. YOITSAGRB has a special hook that lets us upload the key as a separate data item.

Once we were all set up to send Yo’s, we needed somewhere to host our app. We wanted a host with good uptime, low cost, and the ability to receive emails from the GCN. We decided to turn to the power of cloud computing and host our code on the Google App Engine, which supports many web frameworks in a variety of languages including Java, C++, and Python. (For some reason, IDL isn’t an option.) If you use a modern version control system like git, you can push directly from your computer to deploy to the cloud, which is pretty cool. For simple projects such as ours, the App Engine is completely free; there’s also significant scalability (at a cost) if you would like to use it for more complex projects. Another plus is that the App Engine is ridiculously well documented and comes with a truly impressive infrastructure for local testing of your app.

With our project repository set up on Google App Engine, it was time to begin coding. We chose to code up YOITSAGRB in Python due to a combination of simplicity and mutual familiarity. We’ve mirrored the code on to GitHub so that you can check it out. The main file is fewer than 100 lines.

The first job of the app is to trigger an action when we get an email from the GCN. Fortunately, the App Engine has built-in support for launching an app action when emails arrive at specially allocated addresses. Now, email is very insecure. If this address were public, party-poopers could forge GCN notices and trigger annoying, false GRB alerts. Therefore, like the Yo API key, the target email address is a secret configuration value that we upload separately. Then, when the app receives an email it runs a little bit of code like:

emails = list (db.GqlQuery ('SELECT * FROM ConfigRecord where name = \'email\''))
email = emails[0]

if not self.request.path.startswith('/_ah/mail/' + email.value + '@'):
   logging.warn ('Suspicious e-mail to ' + self.request.path)
   return

This checks to see if the email was directed to the right address. If not, it notes that in the log and ignores the email. (We also added a small quality control feature that checks the email contents to filter out low-significance Fermi triggers, which can happen annoyingly often.)

Once we’ve decided that we’re going to send a Yo, there’s almost nothing to it. As with almost all modern web platforms, you drive the Yo API over HTTP by requesting special URLs and including any needed information (such as your API key) in “POST data”:

form_fields = {
   'api_token': key.value,
}
form_data = urllib.urlencode(form_fields)
result = urlfetch.fetch(url='http://api.justyo.co/yoall/',
   payload=form_data,
   method=urlfetch.POST,
   headers={'Content-Type': 'application/x-www-form-urlencoded'})

It couldn’t be much simpler.

At this point, we registered with the GCN using the unique email address we set up in the app. We configured our site to receive triggers from both Swift and Fermi. Once this was set up our app started receiving emails and sending out Yo’s with essentially no debugging. Overall, the project was super easy to code up — it turns out that if you build on the right infrastructure, complicated-seeming web applications can actually be incredibly simple to implement. If you’re interested in doing something similar for your own projects, we hope that you’re convinced that you don’t need to hire a Silicon Valley engineer to make it happen! Have any questions about what we did? We’ll be happy to answer in the comments.

To subscribe to YOITSAGRB, just send a Yo to it. We have a tiny webpage for the project, and the code is shared on GitHub. YOITSAGRB was developed by Philip Cowperthwaite and Peter K. G. Williams, and the code is released under the MIT open source license.

0 comments… add one

Leave a Reply

Your email address will not be published. Required fields are marked *