openfec

package module
v0.0.0-...-1b61676 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2015 License: ISC Imports: 8 Imported by: 0

README

openfec

GoDoc

This package provides programmatic access to the OpenFEC api.

Included under cmd are example command line utilities showing consumption of this api.

Documentation: http://godoc.org/github.com/tmc/openfec

Status: some endpoints missing, pull requests welcome!

License: ISC

Examples:

list-candidates-potus

⚛ ~$ go get github.com/tmc/openfec/cmd/...
⚛ ~$ 
⚛ ~$ list-candidates-potus -h
Usage of list-candidates-potus:
  -f string
	  Formatting string (default "{{.Name}} {{.Party}}")
  -party string
	  Political party (default: all)
  -v	verbose output
  -year int
	  Election cycle to list candidates from (default 2016)

⚛ ~$ 
⚛ ~$ export DATA_GOV_API_KEY=(YOUR KEY HERE)
⚛ ~$ list-candidates-potus -party DEM
P80000268 - CARTER, WILLIE FELIX DEM
P60008075 - CHAFEE, LINCOLN DAVENPORT MR. DEM
P00003392 - CLINTON, HILLARY RODHAM DEM
P60007267 - KELSO, LLOYD THOMAS DEM
P60007671 - O'MALLEY, MARTIN JOSEPH DEM
P60007168 - SANDERS, BERNARD DEM
P20004065 - WELLS, ROBERT CARR JR DEM
P60005204 - WILLIAMS, ELAINE WHIGHAM DEM
P60007515 - WILSON, WILLIE DEM
P60007754 - WINSLOW, BRAD MR. DEM

list-candidate-filings

⚛ ~$ go get github.com/tmc/openfec/cmd/...
⚛ ~$ 
⚛ ~$ list-candidate-filings -h
$ list-candidate-filings -h
Usage of list-candidate-filings:
  -candidate string
      Candidate ID to fetch filings for
  -f string
      Formatting string (default "{{.}}")
  -v	verbose output
⚛ ~$ 
⚛ ~$ export DATA_GOV_API_KEY=(YOUR KEY HERE)
⚛ ~$ list-candidate-filings -f json -candidate P60007168 |jq .
{
  "amendment_indicator": "N",
  "beginning_image_number": "15031422533",
  "candidate_id": "P60007168",
  "candidate_name": "SANDERS, BERNARD",
  "committee_id": "P60007168",
  "cycle": 2016,
  "document_description": "Statement of candidacy 2015",
  "election_year": 2016,
  "ending_image_number": "15031422535",
  "file_number": -9144826,
  "form_type": "F2",
  "pages": 3,
  "pdf_url": "http://docquery.fec.gov/pdf/533/15031422533/15031422533.pdf",
  "receipt_date": "2015-04-30",
  "report_year": 2015,
  "sub_id": 1050120150017429800
}

Documentation

Overview

Package openfec implements a client library for the OpenFEC API.

See https://api.open.fec.gov

Overview

This package all allows you to explore the way candidates and committees fund their campaigns by accessing FEC (Federal Election Committee) data.

A few restrictions limit the way you can use FEC data. For example, you can’t use contributor lists for commercial purposes or to solicit donations.

Get an API key here: https://api.data.gov/signup/

Endpoints are classified in the following groups: Candidate, Committee, Financial, Filings and Schedules.

Candidate

Candidate endpoints give you access to information about the people running for office. This information is organized by candidate_id. If you're unfamiliar with candidate IDs, using `/candidates/search` will help you locate a particular candidate.

Officially, a candidate is an individual seeking nomination for election to a federal office. People become candidates when they (or agents working on their behalf) raise contributions or make expenditures that exceed $5,000.

The candidate endpoints primarily use data from FEC registration [Form 1](http://www.fec.gov/pdf/forms/fecfrm1.pdf), for candidate information, and [Form 2](http://www.fec.gov/pdf/forms/fecfrm2.pdf), for committee information.

Committee

Committees are entities that spend and raise money in an election. Their characteristics and relationships with candidates can change over time.

You might want to use filters or search endpoints to find the committee you're looking for. Then you can use other committee endpoints to explore information about the committee that interests you.

Financial information is organized by `committee_id`, so finding the committee you're interested in will lead you to more granular financial information.

The committee endpoints include all FEC filers, even if they aren't registered as a committee.

Officially, committees include the committees and organizations that file with the FEC. Several different types of organizations file financial reports with the FEC:

* Campaign committees authorized by particular candidates to raise and spend funds in their campaigns * Non-party committees (e.g., PACs), some of which may be sponsored by corporations, unions, trade or membership groups, etc. * Political party committees at the national, state, and local levels * Groups and individuals making only independent expenditures * Corporations, unions, and other organizations making internal communications

The committee endpoints primarily use data from FEC registration Form 1 and Form 2.

Financial

Fetch key information about a committee's Form 3, Form 3X, or Form 3P financial reports.

Most committees are required to summarize their financial activity in each filing; those summaries are included in these files. Generally, committees file reports on a quarterly or monthly basis, but some must also submit a report 12 days before primary elections. Therefore, during the primary season, the period covered by this file may be different for different committees. These totals also incorporate any changes made by committees, if any report covering the period is amended.

Information is made available on the API as soon as it's processed. Keep in mind, complex paper filings take longer to process.

The financial endpoints use data from FEC [form 5](http://www.fec.gov/pdf/forms/fecfrm5.pdf), for independent expenditors; or the summary and detailed summary pages of the FEC [form 3](http://www.fec.gov/pdf/forms/fecfrm3.pdf), for House and Senate committees; [form 3X](http://www.fec.gov/pdf/forms/fecfrm3x.pdf), for PACs and parties; and [form 3P](http://www.fec.gov/pdf/forms/fecfrm3p.pdf), for presidential committees.

Filings

All official records and reports filed by or delivered to the FEC.

Note: because the filings data includes many records, counts for large result sets are approximate.

Schedules

Schedules come from particular sections on forms and contain detailed transactional data.

Schedule A explains where contributions come from. If you are interested in individual donors, this will be the endpoint you use.

For the Schedule A aggregates, "memoed" items are not included to avoid double counting.

Schedule B explains how money is spent.

Index

Examples

Constants

View Source
const (
	Incumbent  = IncumbentChallenge("I")
	Challenger = IncumbentChallenge("C")
	Open       = IncumbentChallenge("O")
)
View Source
const (
	PresentCandidate = CandidateStatus("C")
	FutureCandidate  = CandidateStatus("F")
	NotYetACandidate = CandidateStatus("N")
	PriorCandidate   = CandidateStatus("P")
)
View Source
const (
	House     = Office("H")
	Senate    = Office("S")
	President = Office("P")
)
View Source
const (
	Document24HourContributionNotice                         = DocumentType("2")
	Document48HourContributionNotice                         = DocumentType("4")
	DocumentDebtSettlementStatement                          = DocumentType("A")
	DocumentAcknowledgmentofReceiptofDebtSettlementStatement = DocumentType("B")
	DocumentRFAIDebtSettlementFirstNotice                    = DocumentType("C")
	DocumentCommissionDebtSettlementReview                   = DocumentType("D")
	DocumentCommissionResponseTODebtSettlementRequest        = DocumentType("E")
	DocumentAdministrativeTermination                        = DocumentType("F")
	DocumentDebtSettlementPlanAmendment                      = DocumentType("G")
	DocumentDisavowalNotice                                  = DocumentType("H")
	DocumentDisavowalResponse                                = DocumentType("I")
	DocumentConduitReport                                    = DocumentType("J")
	DocumentTerminationApproval                              = DocumentType("K")
	DocumentRepeatNonFilerNotice                             = DocumentType("L")
	DocumentFilingFrequencyChangeNotice                      = DocumentType("M")
	DocumentPaperAmendmenttoElectronicReport                 = DocumentType("N")
	DocumentAcknowledgmentofFilingFrequencyChange            = DocumentType("O")
	DocumentRFAIDebtSettlementSecond                         = DocumentType("S")
	DocumentMiscellaneousReportTOFEC                         = DocumentType("T")
	DocumentRepeatViolationNotice_441A_Or_441B               = DocumentType("V")
	DocumentNoticeofPaperFiling                              = DocumentType("P")
	DocumentF3LFilingFrequencyChangeNotice                   = DocumentType("R")
	DocumentAcknowledgmentofF3LFilingFrequencyChange         = DocumentType("Q")
	DocumentUnregisteredCommitteeNotice                      = DocumentType("U")
)

Variables

View Source
var (
	ErrUnauthorized = errors.New("openfec: unauthorized")
	ErrNotFound     = errors.New("openfec: not found")
)
View Source
var BaseURL = "https://api.open.fec.gov/v1"

BaseURL is the common URL prefix for all API requests.

Functions

func ToValues

func ToValues(in interface{}) (url.Values, error)

Types

type APIError

type APIError struct {
	Err struct {
		Code    string `json:"code,omitempty"`
		Message string `json:"message,omitempty"`
	} `json:"error,omitempty"`
}

func (*APIError) Error

func (e *APIError) Error() string

type Candidate

type Candidate struct {
	ActiveThrough          int    `json:"active_through,omitempty"`
	CandidateID            string `json:"candidate_id,omitempty"`
	CandidateStatus        string `json:"candidate_status,omitempty"`
	CandidateStatusFull    string `json:"candidate_status_full,omitempty"`
	Cycles                 []int  `json:"cycles,omitempty"`
	District               string `json:"district,omitempty"`
	ElectionYears          []int  `json:"election_years,omitempty"`
	IncumbentChallenge     string `json:"incumbent_challenge,omitempty"`
	IncumbentChallengeFull string `json:"incumbent_challenge_full,omitempty"`
	Name                   string `json:"name,omitempty"`
	Office                 string `json:"office,omitempty"`
	OfficeFull             string `json:"office_full,omitempty"`
	Party                  string `json:"party,omitempty"`
	PartyFull              string `json:"party_full,omitempty"`
	State                  string `json:"state,omitempty"`
}

type CandidateIter

type CandidateIter struct {
	// contains filtered or unexported fields
}

func (*CandidateIter) Err

func (i *CandidateIter) Err() error

func (*CandidateIter) Next

func (i *CandidateIter) Next() bool

func (*CandidateIter) Value

func (i *CandidateIter) Value() *Candidate

type CandidateQuery

type CandidateQuery struct {
	Sort               string               `json:"sort,omitempty"`
	SortHideNull       bool                 `json:"sort_hide_null,omitempty"`
	Party              string               `json:"party,omitempty"`
	IncumbentChallenge []IncumbentChallenge `json:"incumbent_challenge,omitempty"`
	Cycle              []int                `json:"cycle,omitempty"`
	Year               int                  `json:"year,omitempty"`
	CandidateStatus    []CandidateStatus    `json:"candidate_status,omitempty"`
	State              string               `json:"state,omitempty"`
	District           int                  `json:"district,omitempty"`
	Office             []Office             `json:"office,omitempty"`
	Name               string               `json:"name,omitempty"`
	CandidateID        string               `json:"candidate_id,omitempty"`
	Query              string               `json:"q,omitempty"`
}

type CandidateStatus

type CandidateStatus string

type Client

type Client struct {
	APIKey string
	// contains filtered or unexported fields
}

Client is the primary struct that this package provides. It represents the connection to the OpenFEC API.

func NewClient

func NewClient(APIKey string) (*Client, error)

NewClient creates a new Client to interact with the OpenFEC API.

Example
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/tmc/openfec"
)

func main() {
	apiKey := os.Getenv("DATA_GOV_API_KEY")
	client, err := openfec.NewClient(apiKey)
	if err != nil {
		log.Fatalln(client)
	}
	candidates, err := client.GetCandidates(nil)
	fmt.Printf("err:%v\ntype1:%T\n", err, candidates)
}
Output:

err:<nil>
type1:*openfec.CandidateIter

func (*Client) GetCandidateFilings

func (c *Client) GetCandidateFilings(candidateID string) (*FilingIter, error)

GetCandidateFilings fetches filings for a given Candidate ID.

func (*Client) GetCandidates

func (c *Client) GetCandidates(query *CandidateQuery) (*CandidateIter, error)

GetCandidates fetches a list of basic candidate information.

query is an optional parameter that supplies additional parameters

Fetch basic information about candidates, and use parameters to filter results to the candidates you're looking for. Each result reflects a unique FEC candidate ID. That ID is particular to the candidate for a particular office sought. If a candidate runs for the same office multiple times, the ID stays the same. If the same person runs for another office — for example, a House candidate runs for a Senate office — that candidate will get a unique ID for each office.

Example
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/tmc/openfec"
)

func main() {
	apiKey := os.Getenv("DATA_GOV_API_KEY")
	if apiKey == "" {
		apiKey = "DEMO_KEY"
	}
	client, err := openfec.NewClient(apiKey)
	if err != nil {
		log.Fatalln(client)
	}
	query := &openfec.CandidateQuery{
		Sort:   "name",
		Office: []openfec.Office{openfec.President},
		Cycle:  []int{2016},
	}
	candidates, err := client.GetCandidates(query)
	if err != nil {
		log.Fatalln(err)
	}
	for candidates.Next() {
		c := candidates.Value()
		_ = c
		// do something with each candidate here
	}
	fmt.Println(err)
}
Output:

<nil>

func (*Client) TraceOff

func (c *Client) TraceOff()

TraceOff turns on API response tracing

func (*Client) TraceOn

func (c *Client) TraceOn(logger *log.Logger)

TraceOn turns on API response tracing to the given logger.

type DocumentType

type DocumentType string

type Filing

type Filing struct {
	AmendmentIndicator           string       `json:"amendment_indicator,omitempty"`
	BeginningImageNumber         string       `json:"beginning_image_number,omitempty"`
	CandidateID                  string       `json:"candidate_id,omitempty"`
	CandidateName                string       `json:"candidate_name,omitempty"`
	CashOnHandBeginningPeriod    int          `json:"cash_on_hand_beginning_period,omitempty"`
	CashOnHandEndPeriod          int          `json:"cash_on_hand_end_period,omitempty"`
	Committee                    string       `json:"committee,omitempty"`
	CommitteeID                  string       `json:"committee_id,omitempty"`
	CommitteeName                string       `json:"committee_name,omitempty"`
	CoverageEndDate              string       `json:"coverage_end_date,omitempty"`
	CoverageStartDate            string       `json:"coverage_start_date,omitempty"`
	Cycle                        int          `json:"cycle,omitempty"`
	DebtsOwedByCommittee         int          `json:"debts_owed_by_committee,omitempty"`
	DebtsOwedToCommittee         int          `json:"debts_owed_to_committee,omitempty"`
	DocumentDescription          string       `json:"document_description,omitempty"`
	DocumentType                 DocumentType `json:"document_type,omitempty"`
	DocumentTypeFull             string       `json:"document_type_full,omitempty"`
	ElectionYear                 int          `json:"election_year,omitempty"`
	EndingImageNumber            string       `json:"ending_image_number,omitempty"`
	FileNumber                   int          `json:"file_number,omitempty"`
	FormType                     string       `json:"form_type,omitempty"`
	HousePersonalFunds           int          `json:"house_personal_funds,omitempty"`
	NetDonations                 int          `json:"net_donations,omitempty"`
	OppositionPersonalFunds      int          `json:"opposition_personal_funds,omitempty"`
	Pages                        int          `json:"pages,omitempty"`
	PdfURL                       string       `json:"pdf_url,omitempty"`
	PreviousFileNumber           string       `json:"previous_file_number,omitempty"`
	PrimaryGeneralIndicator      string       `json:"primary_general_indicator,omitempty"`
	ReceiptDate                  string       `json:"receipt_date,omitempty"`
	ReportType                   string       `json:"report_type,omitempty"`
	ReportTypeFull               string       `json:"report_type_full,omitempty"`
	ReportYear                   int          `json:"report_year,omitempty"`
	RequestType                  string       `json:"request_type,omitempty"`
	SenatePersonalFunds          int          `json:"senate_personal_funds,omitempty"`
	SubID                        int          `json:"sub_id,omitempty"`
	TotalCommunicationCost       int          `json:"total_communication_cost,omitempty"`
	TotalDisbursements           int          `json:"total_disbursements,omitempty"`
	TotalIndependentExpenditures int          `json:"total_independent_expenditures,omitempty"`
	TotalIndividualContributions int          `json:"total_individual_contributions,omitempty"`
	TotalReceipts                int          `json:"total_receipts,omitempty"`
	TreasurerName                string       `json:"treasurer_name,omitempty"`
	UpdateDate                   string       `json:"update_date,omitempty"`
}

type FilingIter

type FilingIter struct {
	// contains filtered or unexported fields
}

func (*FilingIter) Err

func (i *FilingIter) Err() error

func (*FilingIter) Next

func (i *FilingIter) Next() bool

func (*FilingIter) Value

func (i *FilingIter) Value() *Filing

type FilingQuery

type FilingQuery struct {
	CandidateID  string `json:"candidate_id,omitempty"`
	Sort         string `json:"sort,omitempty"`
	SortHideNull bool   `json:"sort_hide_null,omitempty"`
}

type IncumbentChallenge

type IncumbentChallenge string

type Office

type Office string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL