A Tiny Julia Webservice

One benefit of using Julia for playing with
statistics is that it's a modern, usable language for general purposes
as well. Earlier I built a k-Nearest Neighbor classifier for
predicting crime from the data on
hbg-crime.org, so I thought it would be fun to
build a web service in Julia that could return those results.

using Morsel
using Datetime
import JSON
require("knn_classification")

app = Morsel.app()

Morsel is a small
Sinatra-like web framework for Julia that we're going to be using.

function jsonResponse(res, data)
    res.headers["Content-Type"] = "application/json"
    JSON.json(data)
end

Here's a quick function to handle building a JSON response out of a
hash; we just set the Content-Type header on the response in place,
and then write out our response data as JSON.

function parseNearestParams(params)
    lat = parsefloat(Float64, get(params, "lat", "0"))
    lon = parsefloat(Float64, get(params, "lon", "0"))
    k = parseint(get(params, "k", "7"))
    timestring = get(params, "time", nothing)
    time = isdefined(:timestring) ? Datetime.datetime("yyyy-MM-ddTHH:mm:ss", timestring) : Datetime.now()
    lat, lon, k, time
end

This is how we're going to parse the params for a request, which will
look like this: /nearest?lat=40.27258&lon=-76.87438 For lat and
lon we just call parsefloat on the string we receive; for k (how
many nearest neighbors to use) we use parseint, and for time we
either parse a string we receive or use the current time.

get(app, "/nearest") do req, res
    lat, lon, k, time = parseNearestParams(req.state[:url_params])
    if (lat == 0 || lon == 0)
        jsonResponse(res, {:error => "You must supply lat and lon parameters."})
    else
        result = nearest(lat, lon, time, k)
        jsonResponse(res, {"beware-of" => result})
    end
end

Here's our only route. We are pulling the params out of the
req.state hash, and either rendering an error if lat and lon
aren't specified, or returning the result of our prediction.

start(app, 8000)

And then we start the app; once the kNN engine parses the reports data
and is ready to go, you'll see a ready message from Morsel and you can
start making requests to http://localhost:8000/nearest.