Site Notes

API Documentation

Documentation on how to use the RTH Elections API.

Contents

1Introduction
1.1 JSON Backgrounder
1.2 JSON in Python
1.3 JSON in PHP
2The RTH Elections API
2.1 Elections
2.2 Election Details
2.3 Candidates
2.4 Questions
2.5 Wards
2.6 Parties
2.7 Ridings
2.8 Results
2.8.1 Summary
2.8.2 Details
2.8.3 Polls
2.8.4 Wards
2.8.5 Data
3JSONP
3.1 Introduction to JSONP
3.2 How it Works
3.3 Working Sample
4Licence: Creative Commons Attribution-ShareAlike
5Source Code

API Documentation

1 Introduction

The RTH Elections API makes the content of this site available programmatically in JSON format. For now it is a read-only format, accessible via HTTP GET requests.

Every JSON object is returned in the form of a key/value dictionary, and includes an ok key. The ok key returns true if the request was successful and false if the request was unsuccessful - e.g. if you try to get an election ID that doesn't exist.

Unsuccessful requests will also include an error key that explains what went wrong.

1.1 JSON Backgrounder

JSON, or Javascript Object Notation, is a lightweight structured data format that allows you to transfer data objects across a network.

JSON supports the following data types: strings, numbers, booleans (true/false), null, objects, and arrays. The latter two data types are collections: an array is an ordered set of values, and an object is an unordered set of keys and values. You can nest collections arbitrarily, e.g. by having an array of objects.

Among the many benefits of JSON are the following:

  • It's simple.
  • It's lightweight, with minimal 'boilerplate' and other overhead (especially compared to XML).
  • It's human-readable.
  • It's an executable subset of Javascript.
  • It's easy to parse and nearly every programming language has a JSON parser library.

For these and other reasons, JSON has mostly supplanted XML as the "X" in AJAX, or asynchronous data transfer in a web page.

1.2 JSON in Python

If you're using Python 2.x to develop your application, you can use the standard library to download the JSON object and decode it into a native Python format.

import json # if using a version >2.6, you'll need the `simplejson` library
import urllib
url = 'http://elections.raisethehammer.org/api/election/1'
page = urllib.urlopen(url).read()
obj = json.loads(page)

JSON objects are Python dictionaries, and JSON arrays are Python lists.

1.3 JSON in PHP

If you're using PHP version 5.2+ to develop your application, you can use the handy built-in API functions to decode the JSON object into either a native PHP object or a native PHP array.

<$php
$url = 'http://elections.raisethehammer.org/api/election/1';

# fetch the data from the API page
$response = file_get_contents($url);

# json_decode requires PHP 5.2+

# decode JSON object into a PHP object
$obj = json_decode($response);

# decode JSON object into a PHP array instead
$arr = json_decode($response, true);

# process and render the code
?>

Now that you have a native PHP data structure, you can navigate through it using PHP's own tools. Here is a sample script that grabs the JSON object from the API, converts it into a PHP array, and renders the contents into HTML.

2 The RTH Elections API

2.1 Elections

The base URL for the api is:

http://elections.raisethehammer.org/api

This returns a list of elections. Each element in the list is a dictionary object of details for that election, including the URL of the JSON page with the full details for that election.

Example output:

{
  "ok": true,
  "elections":
  [
    {
      "url": "http://elections.raisethehammer.org/api/election/1",
      "type_id": 1,
      "type": "Municipal",
      "title": "Hamilton Municipal Election 2010"
    },
    {
      "url": "http://elections.raisethehammer.org/api/election/2",
      "type_id": 2,
      "type": "Federal",
      "title": "Federal Election 2011"
    }        
  ]
}

2.2 Election Details

Each election returned in the Elections API page includes a URL for that election, e.g.

http://elections.raisethehammer.org/api/election/1

The details page for an election includes:

  • details - the details of the election itself;
  • candidates - a list of candidates, with a dictionary object of details for each candidate; and
  • questions - a list of questions that RTH has posed to the candidates.
  • wards - a list of specific wards with a link to details for each individual ward.
  • articles - a list of RTH articles related to the election.
  • blogs - a list of RTH blog entries related to the election.

Each candidate object includes the URL of the details page for that candidate. Likewise, each question object includes the URL of the details page for that question.

2.3 Candidates

Each candidate returned in the Election Details API page includes a URL for that candidate, e.g.

http://elections.raisethehammer.org/api/candidate/70/1

The details page for the candidate includes:

  • details - the details of the candidate:

    • url (the URL of the candidate's details page in the API)
    • ward
    • name
    • email
    • home_phone
    • bus_phone
    • fax_number
    • website
    • gender
    • bio
    • incumbent (0 or 1)
    • withdrawn (0 or 1)
  • responses - a list of responses that the candidate has given to RTH election questions.

Note that each response includes the URL of the details page for the question the candidate answered.

2.4 Questions

Each question candidates were asked has a Question Details API page, e.g.

http://elections.raisethehammer.org/api/question/1/1

The details page for each question includes:

  • details - the details of the question;
  • responses - a list of responses by candidates who responded; and
  • non_responses - a list of candidates who have not responded.

The lists of responses and non-responses also include links back to the respective candidate pages.

2.5 Wards

The election details include a list of wards in the election, with a link to details for each individual ward, e.g.

http://elections.raisethehammer.org/api/election/1/mayor

This returns the same results as the Election Details page, but the candidates object only includes candidates in the specified ward.

2.6 Parties

The API provides a list of registered political parties. The main parties page returns a list of levels of government for which party data exists:

http://elections.raisethehammer.org/api/parties

The object returned includes a list of levels and the URL for each level. Currently, only the Federal level has party data:

{
    "levels": [
        {
            "url": "http://elections.raisethehammer.org/api/parties/federal", 
            "level": "Federal"
        }
    ], 
    "ok": true
}

The API page for each level, in turn, includes the party name and website of each party registered at that level of government:

{
    "ok": true, 
    "parties": [
        {
            "website": "http://www.conservative.ca/", 
            "party": "Conservative Party of Canada"
        }, 
        {
            "website": "http://greenparty.ca/", 
            "party": "Green Party of Canada"
        }, 
        ...
    ]
}

2.7 Ridings

You can use the API to find out your riding based on a postal code. For example:

http://elections.raisethehammer.org/api/riding/L8P4P1

This will return the name of the riding and the URL of the RTH Elections page for that riding:

{
    "url": "http://elections.raisethehammer.org/api/election/2/hamilton_centre", 
    "riding": "Hamilton Centre", 
    "ok": true
}

This uses the Google Maps API to find geocoding coordinates for a postal code, and then uses the Vote.ca API to find the riding for that geocode.

Please note that some postal codes - e.g. A0H1A0, A0C1A0, A0A1H0, P0J1A0 - span multiple ridings and that this tool will not work properly in such cases. However, it should work for the Hamilton-area ridings.

2.8 Results

You can also use the API to access election results, sourced from the City's election results page.

http://elections.raisethehammer.org/api/results/1

From the main Results URL, you have access to links to the individual reports:

  • Summary
  • Details
  • Polls
  • Wards
  • Raw Data
2.8.1 Summary

The Summary report provides a list of records per candidate, per ward.

http://elections.raisethehammer.org/api/results/summary/1

Each record includes the ward, candidate ID, candidate name, and votes received in that ward.

{
    "ok": "true",
    "summary": [
        {
            "ward": "Mayor",
            "candidate_id": 70,
            "name": "Baldasaro, Michael James",
            "votes": 2892
        },
        {
            "ward": "Mayor",
            "candidate_id": 701
            "name": "Bratina, Bob",
            "votes": 52684
        }        
    ]
}
2.8.2 Details

The Details report provies a list of records per candidate, per ward, and per poll.

http://elections.raisethehammer.org/api/results/details/1

In addition to the fields included in the Summary report, each record also includes the poll number and poll name. Votes are per poll.

2.8.3 Polls

The Polls report provides a list of all the individual polls in the election.

http://elections.raisethehammer.org/api/results/polls/1

Each record includes the ward, the poll number, the poll name, the number of registered voters, and the City web page that provides the original data.

2.8.4 Wards

The Wards report provides a list of all the invidiual wards in the election.

http://elections.raisethehammer.org/api/results/wards/1

Each record includes the ward and the number of registered voters for that ward.

2.8.5 Data

Finally, the Data report provides low-level results: by candidate, by ward, and by poll.

http://elections.raisethehammer.org/api/results/data/1

Each record includes the ward, poll number, poll name, candidate ID, candidate name, election ID, election (mayor or ward), number of registered voters, number of votes for the candidate, and associated City web page.

3 JSONP

The RTH Elections API supports JSONP so that third-party applications can retrieve resources programmatically.

3.1 Introduction to JSONP

For security reasons, browsers only allow client-side Javascript to make asynchronous HTTP requests to the same server that delivered the web page. This is called the same origin policy, and it limits the ability for a web application to interact programmatically with third-party web APIs.

JSONP, or "JSON with Padding", is a clever way to get around the same origin policy in web page scripts. While it is forbidden to make an AJAX request against a remote server, browsers do allow the source of a javascript file to be on a remote server.

<script type="text/javascript" src="http://some.remote.server.com/script.js"></script>

For example, some web developers use this to include popular Javascript libraries, like jQuery, that are hosted elsewhere:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

Since JSON is basically just Javscript Object Literal syntax, with a little finessing we can convert a JSON object into a valid Javascript file, which the client script running in the browser can then access by importing it as a script.

3.2 How it Works

Let's say you want your web page to display a list of the elections covered in the RTH Elections API.

http://elections.raisethehammer.org/api/

Here's what the returned object looks like:

{
  "ok": true,
  "elections":
  [
    {
      "url": "http://elections.raisethehammer.org/api/election/1",
      "type_id": 1,
      "type": "Municipal",
      "title": "Hamilton Municipal Election 2010"
    },
    {
      "url": "http://elections.raisethehammer.org/api/election/2",
      "type_id": 2,
      "type": "Federal",
      "title": "Federal Election 2011"
    }        
  ]
}

If you tried to load that as a Javascript file, it would evaluate immediately and do nothing else - not very useful.

However, if you enclosed that object in a function call, you could define the function in a separate script that does something with the values in the JSON object:

getElections({
  "ok": true,
  "elections":
  [
    {
      "url": "http://elections.raisethehammer.org/api/election/1",
      "type_id": 1,
      "type": "Municipal",
      "title": "Hamilton Municipal Election 2010"
    },
    {
      "url": "http://elections.raisethehammer.org/api/election/2",
      "type_id": 2,
      "type": "Federal",
      "title": "Federal Election 2011"
    }        
  ]
})

All I've done is wrapped the JSON object in parenthesis and prepended a function name called getElections.

To access the values in my JSON object, all I need to do is define my getElections function in another Javascript that gets included in my web page:

function getElections(obj) {
    if(typeof(obj) != 'undefined') {
        /* do something with my JSON object */
    }
}

Now that I've defined my function, as long as the web service API supports JSONP, I can now include another script element in my page that loads the JSON object as a JSONP function call:

<script type="text/javascript" src="http://elections.raisethehammer.org/api/?jsonp=getElections"></script>

Note the querystring at the end of the URL in the src attribute: ?jsonp=getElections. Because the RTH Elections API supports JSONP, it takes the value of the jsonp parameter and wraps that around the JSON object as a function call.

Note that the value of the jsonp querystring parameter can be whatever you want. If you did this:

<script type="text/javascript" src="http://elections.raisethehammer.org/api/?jsonp=FooBar"></script>

The RTH Elections API would return the following:

FooBar({
  "ok": true,
  "elections":
  [
    {
      "url": "http://elections.raisethehammer.org/api/election/1",
      "type_id": 1,
      "type": "Municipal",
      "title": "Hamilton Municipal Election 2010"
    },
    {
      "url": "http://elections.raisethehammer.org/api/election/2",
      "type_id": 2,
      "type": "Federal",
      "title": "Federal Election 2011"
    }        
  ]
})

The important thing is that you define what you want your Javascript function to do with the JSON object it takes - in this case, a function called FooBar.

3.3 Working Sample

Here's a complete HTML page that grabs the list of elections from the RTH Elections API and displays a list of links to the elections:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>JSONP Example</title>
    </head>
    <body>
        <h1>List of Elections</h1>
        <ul id="elections"><!-- the election list will go here --></ul>
        <script type="text/javascript">
        function getElections(obj) {
            /* grabs an array of elections from a JSON object */
            if(typeof(obj) != 'undefined') {
                var elections = []; /* initialize array to hold elections */
                for(var x=0; x<obj['elections'].length; x++) {
                    elections.push('<li><a href="'+obj['elections'][x]['url']+'">'+obj['elections'][x]['title']+'</a> ('+obj['elections'][x]['type']+')</li>');
                }
                /* Now join the list into a string and insert it into #elections */
                document.getElementById('elections').innerHTML = elections.join('\n');
            }
        }
        </script>
        <script type="text/javascript" src="http://elections.raisethehammer.org/api/?jsonp=getElections">
        /* JSONP call to populate getElections */
        </script>
    </body>
</html>

The main caveat here is that you need to define your Javscript function before you call it via JSONP script inclusion.

Beyond that: as a more general warning, be aware that whenever you load a JSON object via a JSONP call, you are executing arbitrary Javascript code generated dynamically by a third party. That's a potential security risk, so make sure you trust the source of your data.

4 Licence: Creative Commons Attribution-ShareAlike

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

We created an API because we want to share our data. All we ask is that if you use data from the RTH Elections site, please attribute the original source of this data by displaying a link to http://raisethehammer.org or http://elections.raisethehammer.org and make your own re-distributed data available under a compatible licence.

Please let us know if you build something so we can check it out and link to it.

Similarly, if you're building something and require a change to the API, additional data, etc., please contact us and let us know. We'll do our best to help.

5 Source Code

The source code for this web application is available on github.

Last Updated: 2011-04-13 19:12:31