Scytl

Overview

Scytl, or Clarity Elections, is a company that creates a tool for publishing election results in real-time. It’s used in the U.S. by several states and over 800 counties, including Georgia, Colorado, Arkansas, and Dallas County, Texas.

For each participating election administrator, they publish a site with results that can be published on election night. Unfortunately, while that site contains downloadable data, that data is formatted in a complex way, making it difficult for developers to fetch election results. In general, their results either come zipped in either an unformatted text file or a complex XML document. Summary results come as a zipped CSV, but just contain top-line results. The JSON that powers the site results is even more complicated.

This connector provides methods to download the latest election results from their site and formats them into readable lists of dictionaries, which can easily be converted into a Parsons Table or Pandas dataframe.

Because this connector is can be useful for live reporting, it also contains a polling feature. As long as the class is instantiated, it will only fetch results that are new since the previous fetch of that method. To skip this feature, set force_update to true on any of the fetch methods.

Note

Authentication

All endpoints for Scytl are public, and do not need authentication.

Quickstart

To get started, initialize a Scytl class with the two-letter state code, the election id, and the county name (optional).

To get these details, go to the website for the given election, and look in the url. For example, if the url is “https://results.enr.clarityelections.com/TX/Dallas/114890/web.285569/”, then the state is “TX”, the county is “Dallas”, and the election ID is “114890”. If the url is “https://results.enr.clarityelections.com/GA/114729/web.285569/”, the state is “GA” and the election ID is “114729”.

from parsons import Scytl

scy = Scytl(state = 'GA', election_id = '114729')

# Get detailed results by geography
scy.get_detailed_results()

Scytl Class

class parsons.Scytl(state: str, election_id: str, county='')[source]

Instantiate a Scytl connector.

Args::
state: str

The two letter code of the state the publishing election results. ex: GA

election_id: str

The numeric identifier for the election found in the url of the election’s website. ex: “114729”

county: str (optional)

The name of the county publishing the results. ex: Clarke

get_summary_results(force_update=False) List[Dict][source]

Fetch the latest summary results for the given election, across all contests.

Please note that all electoral entities administer their elections differently,

so not all values will be populated if the entity doesn’t provide them.

Args:
force_update: bool
If this is False, the connector will check to see if the current version

matches the previously fetched version of the results. If the version has not been changed, no results will be fetched or returned.

Default: false

Returns:

list[dict] The list should contain entries for each candidate in each office. Each row will contain the following: - state - county_name (if applicable) - office - ballots_cast (in the contest) - reg_voters (eligible for the contest) - counties_reporting - total_counties - precincts_reporting - total_precincts - candidate_name - candidate_party (many administrators do not use this feature

and instead include the party in the candidate name)

  • recorded_votes (votes cast for the candidate)

get_detailed_results(force_update=False) List[Dict][source]

Fetch the latest detailed results by geography for the given election, across all contests.

Please note that all electoral entities administer their elections differently,

so not all values will be populated if the entity doesn’t provide them.

Args:
force_update: bool
If this is False, the connector will check to see if the current version

matches the previously fetched version of the results. If the version has not been changed, no results will be fetched or returned.

Default: false

Returns:

list[dict] The list should contain entries for each candidate in each office,

per vote method and per county.

If fetching for a state, results will look like: - state - county_name - office - ballots_cast - reg_voters - precincts_reporting - total_precincts - vote_method (note: some administrators choose to differentiate

results by vote method, while others do not)

  • candidate_name

  • candidate_party (many administrators do not use this

    feature and instead include the party in the candidate name)

  • recorded_votes (votes cast for the candidate

    with this vote method in this county)

  • timestamp_last_updated

If fetching for a county, results will look like: - state - county_name - county_id - office - ballots_cast - reg_voters - vote_method (note: some administrators choose to

differentiate results by vote method, while others do not)

  • candidate_name

  • candidate_party (many administrators do not use this

    feature and instead include the party in the candidate name)

  • precinct_name

  • recorded_votes (votes cast for the candidate

    with this vote method in this county)

  • voter_turnout

  • percent_reporting

  • timestamp_last_updated

get_detailed_results_for_participating_counties(county_names: List[str] = None, force_update=False) Tuple[List[str], List[Dict]][source]
Fetch the latest detailed results for the given election for all participating counties

with detailed results, across all contests.

Some counties may not have detailed results. If so, this will attempt

to fetch the summary results for that county. If no results exist for either, the county name will be appended to the missing_counties list.

After the first fetch, only the counties with updates will be returned,

previous results will not be included.

Please note that all electoral entities administer their elections differently,

so not all values will be populated if the entity doesn’t provide them.

Args:
county_names: list[str]

The list of counties to get precinct-level results for. Default: None (get all counties)

force_update: bool
If this is False, the connector will check to see if the current

version matches the previously fetched version of the results. If the version has not been changed, no results will be fetched or returned.

Default: false

Returns:

list[str] The list of county names that could not be fetched

list[dict] The list should contain entries for each candidate in

each office, per vote method, county, and precinct.

Each row will contain the following: - state - county_name - county_id - office - ballots_cast - reg_voters - vote_method (note: some administrators choose to differentiate

results by vote method, while others do not)

  • candidate_name

  • candidate_party (many administrators do not use this feature

    and instead include the party in the candidate name)

  • precinct_name

  • recorded_votes (votes cast for the candidate with this vote method in this county)

  • voter_turnout

  • percent_reporting

  • timestamp_last_updated