Introducing python-elections
Process AP elections data more easily with this new open-source library.
News organizations have a long history of reporting election results, but reporting results live and for the Web is still a relatively recent development.
Thankfully, the Associated Press has a digital service called the AP Elections Online FTP. It updates a series of files every few minutes, which news organizations hungrily download and process in a race to get the results out first.
At the Data Desk, we’ve written more than our fair share of code to parse these results. And we know we’re not alone. In fact, we bet that if you saved up all of the hours spent processing the same AP election results across all news organizations, there would be enough collective spare cycles to save journalism.
So, with that in mind, take a gander at our attempt to alleviate your election-related issues.
Getting started
First, install the library from PyPI, preferably in a virtualenv, but there’s no accounting for taste.
$ pip install python-elections
Then connect to the AP data service with your FTP login, and grab a state’s data using its postal code. To get a login, you must pay AP for access to the data. More information can be found on the AP’s website or by contacting Anthony Marquez at amarquez@ap.org.
>>> from elections import AP >>> client = AP(uname, pwd) >>> iowa = client.get_state('IA') >>> iowa <State: IA>
From there, you should have access to everything in the initialization and results files for that state. For examples of the following methods, please see our README:
- Get or filter the list of races in the state.
- Get the list of candidates for a race.
- Get results for the whole state.
- Get all counties in the state, with results for each County object.
- Get the number of delegates assigned to a candidate.
A real-world example
Let’s say the GOP is holding its caucuses in Iowa, and your news organization bought access to the AP’s FTP service. Your boss wants you to write a simple widget that will sit on the homepage and output live results. All you need are the candidate names, their vote totals and percentages, the number of precincts reporting, the number of delegates won and whether the AP has called a winner yet. How do you feed it?
Cake.
from elections import AP try: import json except ImportError: import simplejson as json client = AP(uname, pwd) iowa = client.get_state('IA') # Now the iowa variable holds all of the AP result data caucus = iowa.filter_races(office_name='President', party='GOP')[0] # caucus is a Race object containing the results of the GOP caucuses # Set up the main data dict and set the percent of precincts reporting data = { 'precincts_reporting_percent': caucus.state.precincts_reporting_percent, 'candidates': [] } # Loop through the statewide candidate results, and append them # in a format we like into the data dict's candidate list. for result in caucus.state.results: data['candidates'].append({ 'name': result.candidate.last_name, 'vote_total': result.vote_total, 'vote_percent': result.vote_total_percent, 'delegate_total': result.candidate.delegates, 'is_winner': result.candidate.is_winner, }) # Then dump the data dict out as JSON print json.dumps(data, indent=4)
There you have it: a simple JSON dump in about 20 lines of code. From here, you can set this script to upload the JSON file every few minutes to Amazon S3 or a similar file-serving service. Then point your front-end widget to pull from there.
If it’s that simple to get a JSON widget set up, imagine what else you could do.
Issues
The feature set is pretty straightforward and simple right now, but there are a few outstanding issues we could use some help with:
- Verifying that we handle New England counties correctly.
- Developing a method to grab U.S.-wide results.
- Verifying that data for House races not tied specifically to counties or states will work correctly.
- And, of course, more testing.
So please, feel free to dive into our code and send a pull request if you have patches. Check it out on GitHub.