NGPVAN

Overview

The VAN module leverages the VAN API and generally follows the naming convention of their API endpoints. It is recommended that you reference their API documentation for additional details and information.

Note

API Keys
  • API Keys are specific to each committee and state.

  • There is a Parsons type API Key that can be requested via the Integrations menu on the main page. If you have an issue gaining access to this key, or an admin has questions, please email <parsons@movementcooperative.org>.

Warning

VANIDs

VANIDs are unique to each state and instance of the VAN. VANIDs used for the AV VAN will not match those of the SmartVAN or VoteBuilder.

Maintenance & Support

VAN/EveryAction is not responsible for support of Parsons. Their support team cannot answer questions about Parsons. Please direct any questions to the Parsons team via the issue tracker or Slack.

QuickStart

To call the VAN class you can either store the api key as an environmental variable VAN_API_KEY or pass it in as an argument.

from parsons import VAN

 van = VAN(db='MyVoters') # Specify the DB type and pass api key via environmental variable.

 van = VAN(api_key='asdfa-sdfadsf-adsfasdf',db='MyVoters') # Pass api key directly

You can then call various endpoints:

from parsons import VAN

 van = VAN(db='MyVoters')

 # List events with a date filter
 events = van.get_events(starting_before='2018-02-01')

 # List all folders shared with API Key User
 folders = van.get_folders()

 # Return to a Redshift database
 saved_lists = van.get_saved_lists().to_redshift('van.my_saved_lists')

This a is just a small sampling of all of the VAN endpoints that you can leverage. We recommend reviewing the documentation for all functions.

Common Workflows

Bulk Import

For some methods, VAN allows you to bulk import multiple records to create or modify them.

The bulk upload endpoint requires access to files on the public internet as it runs the upload asynchronously. Therefore, in order to bulk import, you must pass in cloud storage credentials (either AWS S3 or Google Cloud Storage) so that the file can be posted.

Bulk Apply Activist Codes

In this example we are applying activist codes to a list of contacts. The csv file would have the following columns:

  • vanid

  • activistcodeid

from parsons import VAN, Table

van = VAN(db='EveryAction')

# Load a table containing the VANID, activistcodeid and other options.
tbl = Table.from_csv('new_volunteers.csv')

# Table will be sent to S3 bucket and a POST request will be made to VAN creating
# the bulk import job with all of the valid meta information. The method will
# return the job id.
job_id = van.bulk_apply_activist_codes(tbl, url_type="S3", bucket='my_bucket')

# The bulk import job is run asynchronously, so you may poll the status of a job.
job_status = van.get_bulk_import_job(job_id)

** Bulk Upsert Contacts** In this example we are creating and updating emails and addresses. The csv file would have the following columns:

  • vanid

  • first_name

  • last_name

  • address

  • city

  • state

  • zip

  • email

Note that vanid must be the first column in your table. For additional fields, see the bulk_upsert_contacts() documentation.

If a record contains a null value, it will not be updated.

If the VANID record is null, then a new record will be created.

from parsons import VAN, Table

van = VAN(db=EveryAction)

# Load a table containing VANID and PII columns
tbl = Table.from_csv('hot_leads.csv')

# Table will be sent to S3 bucket and a POST request will be made to VAN creating
# the bulk import job with all of the valid meta information. The method will
# return the job id.
job_id = van.bulk_upsert_contacts(tbl, url_type="S3", bucket='my_bucket')

# The bulk import job is run asynchronously, so you may poll the status of a job.
job_status = van.get_bulk_import_job(job_id)

# When the job is complete, get the results of the job. This file will include newly
# created vanids.
job_results = van.get_bulk_import_job_results(job_id)

Upload Saved List

from parsons import VAN, Table

van = VAN(db='MyVoters')

# Load a table containing VANIDs
tbl = Table.from_csv('gcs_test.csv')

# The destination folder id. You can get a list of folder ids by running the
# VAN.get_folders() method. Remember to share the folder with your API user
# or you will not be able to access it.
folder_id = 1171

# The destination list name
list_name = 'My Winning List v1.0'

# The cloud storage service and kwargs specific to GCS.
url_type = 'GCS'
bucket_name = 'my_bucket'
app_creds = 'my_creds.json' # Not required if stored as env variable.

van.upload_saved_list(tbl, list_name, folder_id, url_type, replace=true,
                      bucket_name=bucket_name, app_creds=app_creds)

Scores: Loading and Updating

Loading a score is a multi-step process. Once a score is set to approved, loading takes place overnight.

Standard Auto Approve Load

from parsons import VAN, Table

van = VAN(db='MyVoters') # API key stored as an environmental variable

# If you don't know the id, you can run van.get_scores() to list the
# slots that are available and their associated score ids.
score_id = 9999

# Load the Parsons table with the scores. The first column of the table
# must be the person id (e.g. VANID). You could create this from Redshift or
# another source.
tbl = Table.from_csv('winning_scores.csv')

# Specify the score id slot and the column name for each score.
config = [{'score_id': score_id, 'score_column': 'winning_model'}]

# If you have multiple models in the same file, you can load them all at the same time.
# In fact, VAN recommends that you do so to reduce their server loads.
config = [{'score_id': 5555, 'score_column': 'score1'}, {'score_id': 5556, 'score_column': 'score2'}]

# The score file must posted to the internet. This configuration uses S3 to do so. In this
# example, your S3 keys are stored as environmental variables. If not, you can pass them
# as arguments.
job_id = van.upload_scores(tbl, config, url_type='S3', email='info@tmc.org', bucket='tmc-fake')

Standard Load Requiring Approval

from parsons import VAN

van = VAN(db='MyVoters') # API key stored as an environmental variable
config = [{'score_id': 3421, 'score_column': 'winning_model'}]

# Note that auto_approve is set to False. This means that you need to manually approve
# the job once it is loaded.
job_id = van.upload_scores(tbl, config, url_type='S3', email='info@tmc.org',
                           bucket='tmc-fake', auto_approve=False)

# Approve the job
van.update_score_status(job_id,'approved')

People: Add Survey Response

The following workflow can be used to apply survey questions, activist codes and canvass responses.

from parsons import VAN

# Instantiate Class
van = VAN(db="MyVoters")

van_id = 13242
sq = 311838 # Valid survey question id
sr = 1288926 # Valid survey response id
ct = 36 # Valid contact type id
it = 4 # Valid input type id

# Create a valid survey question response
van.apply_survey_response(vanid, sq, sr, contact_type_id=ct, input_type_id=it)

Event: Creating and Modifying

Events are made up of sub objects that need to exist to create an event

  • Event Object - The event itself

  • Event Type - The type of event, such as a Canvass or Phone Bank. These are created in the VAN UI and can be reused for multiple events.

  • Locations - An event can have multiple locations. While not required to initially create an event, these are required to add signups to an event.

  • Roles - The various roles that a person can have at an event, such as Lead or Canvasser. These are set as part of the event type.

  • Shifts - Each event can have multiple shits in which a person can be assigned. These are specified in the event creation.

from parsons import VAN

# Instantiate class
van = VAN(db="EveryAction")

# Create A Location
loc_id = van.location(name='Big `Ol Canvass', address='100 W Washington', city='Chicago', state='IL')

# Create Event
name = 'GOTV Canvass' # Name of event
short_name = 'GOTVCan' # Short name of event, 12 chars or less
start_time = '2018-11-01T15:00:00' # ISO formatted date
end_time = '2018-11-01T18:00:00' # ISO formatted date after start time
event_type_id = 296199 # A valid event type id
roles = [259236] # A list of valid role ids
location_ids = [loc_id] # An optional list of locations ids for the event
description = 'CPD Super Volunteers Canvass' # Optional description of 200 chars or less
shifts = [{'name': 'Shift 1',
           'start_time': '2018-11-01T15:00:00',
           'end_time': '2018-11-11T17:00:00'}] # Shifts must fall within event start/end time.

new_event = van.event_create(name, short_name, start_time, end_time, event_type_id, roles,
                             location_ids=location_ids, shifts=shifts, description=description)

Signup: Adding and Modifying

from parsons import VAN

# Instantiate class
van = VAN(db="EveryAction")

# Create a new signup

vanid = 100349920
event_id = 750001004
shift_id = 19076
role_id = 263920
location_id = 3
role_id = 263920
status_id = 11

# Create the signup. Will return a signup id
signup_id  = van.signup_create(vanid, event_id, shift_id, role_id, status_id, location_id

# Modify a status of the signup
new_status_id = 6
van.signup_update(signup_id, status_id=new_status_id)

API

People

class parsons.ngpvan.van.People(van_connection)[source]
find_person(first_name=None, last_name=None, date_of_birth=None, email=None, phone=None, phone_type=None, street_number=None, street_name=None, zip=None, **kwargs)[source]

Find a person record.

Note

Person find must include the following minimum combinations to conduct a search.

  • first_name, last_name, email

  • first_name, last_name, phone

  • first_name, last_name, zip5, date_of_birth

  • first_name, last_name, street_number, street_name, zip5

  • email_address

Args:
first_name: str

The person’s first name

last_name: str

The person’s last name

dob: str

ISO 8601 formatted date of birth (e.g. 1981-02-01)

email: str

The person’s email address

phone: str

Phone number of any type (Work, Cell, Home)

street_number: str

Street Number

street_name: str

Street Name

zip: str

5 digit zip code

kwargs:

Any additional keyword arguments will be passed to the EveryAction API for matching.

Returns:

A person dict object

find_person_json(match_json)[source]

Find a person record based on json data.

Note

Person find must include the following minimum combinations to conduct a search.

  • first_name, last_name, email

  • first_name, last_name, phone

  • first_name, last_name, zip5, date_of_birth

  • first_name, last_name, street_number, street_name, zip5

  • email_address

Note

A full list of possible values for the json, and its structure can be found here.

Args:
match_json: dict

A dictionary of values to match against.

fields: The fields to return. Leave as default for all available fields

Returns:

A person dict object

update_person(id=None, id_type='vanid', first_name=None, last_name=None, date_of_birth=None, email=None, phone=None, phone_type=None, street_number=None, street_name=None, zip=None)[source]

Update a person record based on a provided ID. All other arguments provided will be updated on the record.

Warning

This method can only be run on MyMembers, EveryAction, MyCampaign databases.

Args:
id: str

A valid id

id_type: str

A known person identifier type available on this VAN instance. Defaults to vanid.

first_name: str

The person’s first name

last_name: str

The person’s last name

dob: str

ISO 8601 formatted date of birth (e.g. 1981-02-01)

email: str

The person’s email address

phone: str

Phone number of any type (Work, Cell, Home)

phone_type: str

One of ‘H’ for home phone, ‘W’ for work phone, ‘C’ for cell, ‘M’ for main phone or ‘F’ for fax line. Defaults to home phone.

street_number: str

Street Number

street_name: str

Street Name

zip: str

5 digit zip code

Returns:

A person dict

update_person_json(id, id_type='vanid', match_json=None)[source]

Update a person record based on a provided ID within the match_json dict.

Note

A full list of possible values for the json, and its structure can be found here.

Args:
id: str

A valid id

id_type: str

A known person identifier type available on this VAN instance. Defaults to vanid.

match_json: dict

A dictionary of values to match against and save.

Returns:

A person dict

upsert_person(first_name=None, last_name=None, date_of_birth=None, email: Optional[Union[str, List[Dict[str, Union[str, bool]]]]] = None, phone=None, phone_type=None, street_number=None, street_name=None, zip=None, **kwargs)[source]

Create or update a person record.

Note

Person find must include the following minimum combinations.

  • first_name, last_name, email

  • first_name, last_name, phone

  • first_name, last_name, zip5, date_of_birth

  • first_name, last_name, street_number, street_name, zip5

  • email_address

Warning

This method can only be run on MyMembers, EveryAction, MyCampaign databases.

Args:
first_name: str

The person’s first name

last_name: str

The person’s last name

dob: str

ISO 8601 formatted date of birth (e.g. 1981-02-01)

email: Union[str, List[Dict[str, Union[str, bool]]], None]

The person’s email address or a list of email dicts. e.g. [{‘email’: ‘abcd@gmail.com’, ‘isSubscribed’: False}] See https://docs.everyaction.com/reference/people-common-models#email

phone: str

Phone number of any type (Work, Cell, Home)

phone_type: str

One of ‘H’ for home phone, ‘W’ for work phone, ‘C’ for cell, ‘M’ for main phone or ‘F’ for fax line. Defaults to home phone.

street_number: str

Street Number

street_name: str

Street Name

zip: str

5 digit zip code

kwargs:

Any additional keyword arguments will be passed to the EveryAction API for matching.

Returns:

A person dict

upsert_person_json(match_json)[source]

Create or update a person record.

Note

Person find must include the following minimum combinations.

  • first_name, last_name, email

  • first_name, last_name, phone

  • first_name, last_name, zip5, date_of_birth

  • first_name, last_name, street_number, street_name, zip5

  • email_address

Note

A full list of possible values for the json, and its structure can be found here. vanId can be passed to ensure the correct record is updated.

Warning

This method can only be run on MyMembers, EveryAction, MyCampaign databases.

Args:
match_json: dict

A dictionary of values to match against and save.

Returns:

A person dict

get_person(id, id_type='vanid', expand_fields=['contribution_history', 'addresses', 'phones', 'emails', 'codes', 'custom_fields', 'external_ids', 'preferences', 'recorded_addresses', 'reported_demographics', 'suppressions', 'cases', 'custom_properties', 'districts', 'election_records', 'membership_statuses', 'notes', 'organization_roles', 'disclosure_field_values'])[source]

Returns a single person record using their VANID or external id.

Args:
id: str

A valid id

id_type: str

A known person identifier type available on this VAN instance such as dwid. Defaults to vanid.

expand_fields: list

A list of fields for which to include data. If a field is omitted, None will be returned for that field. Can be contribution_history, addresses, phones, emails, codes, custom_fields, external_ids, preferences, recorded_addresses, reported_demographics, suppressions, cases, custom_properties, districts, election_records, membership_statuses, notes, organization_roles, scores, disclosure_field_values.

Returns:

A person dict

delete_person(vanid)[source]

Suppress the given VANID in databases where contact records can be suppressed.

Args:
vanid: str

The person’s VAN ID.

Returns:

Success or error.

apply_canvass_result(id, result_code_id, id_type='vanid', contact_type_id=None, input_type_id=None, date_canvassed=None, phone=None)[source]

Apply a canvass result to a person. Use this end point for attempts that do not result in a survey response or an activist code (e.g. Not Home).

Args:
id: str

A valid person id

result_code_idint

Specifies the result code of the attempt. Valid ids can be found by using the get_canvass_responses_result_codes()

id_type: str

A known person identifier type available on this VAN instance such as dwid

contact_type_idint

Optional; A valid contact type id

input_type_idint

Optional; Defaults to 11 (API Input)

date_canvassedstr

Optional; ISO 8601 formatted date. Defaults to todays date

phone: str

Optional; Phone number of any type (Work, Cell, Home)

Returns:

None

toggle_volunteer_action(id, volunteer_activity_id, action, id_type='vanid', result_code_id=None, contact_type_id=None, input_type_id=None, date_canvassed=None)[source]

Apply or remove a volunteer action to or from a person.

Args:
id: str

A valid person id

id_type: str

A known person identifier type available on this VAN instance such as dwid

volunteer_activity_id: int

A valid volunteer activity id

action: str

Either ‘apply’ or ‘remove’

result_code_idint

Optional; Specifies the result code of the response. If not included,responses must be specified. Conversely, if responses are specified, result_code_id must be null. Valid ids can be found by using the get_canvass_responses_result_codes()

contact_type_id: int

Optional; A valid contact type id

input_type_id: int

Optional; Defaults to 11 (API Input)

date_canvassed: str

Optional; ISO 8601 formatted date. Defaults to todays date

** NOT IMPLEMENTED **

apply_response(id, response, id_type='vanid', contact_type_id=None, input_type_id=None, date_canvassed=None, result_code_id=None, omit_contact=False, phone=None, campaignId=None)[source]

Apply responses such as survey questions, activist codes, and volunteer actions to a person record. This method allows you apply multiple responses (e.g. two survey questions) at the same time. It is a low level method that requires that you conform to the VAN API response object format.

Args:
id: str

A valid person id

response: dict

A list of dicts with each dict containing a valid action.

id_type: str

A known person identifier type available on this VAN instance such as dwid

result_code_idint

Optional; Specifies the result code of the response. If not included,responses must be specified. Conversely, if responses are specified, result_code_id must be null. Valid ids can be found by using the get_canvass_responses_result_codes()

contact_type_idint

Optional; A valid contact type id

input_type_idint

Optional; Defaults to 11 (API Input)

date_canvassedstr

Optional; ISO 8601 formatted date. Defaults to todays date

responseslist or dict

The responses to apply.

omit_contact: boolean

Omit adding contact history to the response. This is particularly useful when adding activist codes that are not based on contact attempts.

phone: str

Optional; Phone number of any type (Work, Cell, Home)

campaignId: int

Optional; a valid Campaign ID.

Returns:

True if successful

response = [{"activistCodeId": 18917,
             "action": "Apply",
             "type": "ActivistCode"},
            {"surveyQuestionId": 109149,
             "surveyResponseId": 465468,
             "type": "SurveyResponse"}
            ]
van.apply_response(5222, response)
create_relationship(vanid_1, vanid_2, relationship_id)[source]

Create a relationship between two individuals

Args:
vanid_1int

The vanid of the primary individual; aka the node

vanid_2int

The vanid of the secondary individual; the spoke

relationship_idint

The relationship id indicating the type of relationship

Returns:

None

apply_person_code(id, code_id, id_type='vanid')[source]

Apply a code to a person.

Args:
id: str

A valid person id.

code_id: int

A valid code id.

id_type: str

A known person identifier type available on this VAN instance such as dwid

Returns:

None

merge_contacts(primary_vanid, source_vanid)[source]

Merges two contacts in EveryAction. The source contact record will be deleted as part of the merge and its data will be moved into the primary contact record. In cases where fields conflict between the two contacts and we can’t keep both values, such as if the contacts have different first names, the primary contact record’s data will be retained. For more information see the VAN API documentation here

Args:
primary_vanid: str

The VANID of the primary contact record.

source_vanid: str

The VANID of the source contact record.

Returns:

The VANID of the primary contact record.

Activist Codes

class parsons.ngpvan.van.ActivistCodes(van_connection)[source]
get_activist_codes()[source]

Get activist codes.

Returns:
Parsons Table

See Parsons Table for output options.

get_activist_code(activist_code_id)[source]

Get an activist code.

Args:
activist_code_idint

The activist code id.

Returns:
dict

The activist code

apply_activist_code(id, activist_code_id, id_type='vanid', omit_contact=True)[source]

Apply an activist code to or from a person.

Args:
id: str

A valid person id

activist_code_id: int

A valid activist code id

action: str

Either ‘apply’ or ‘remove’

id_type: str

A known person identifier type available on this VAN instance such as dwid

omit_contact: boolean

If set to false the contact history will be updated with a contact attempt.

Returns:

None

remove_activist_code(id, activist_code_id, id_type='vanid')[source]

Remove an activist code to or from a person.

Args:
id: str

A valid person id

activist_code_id: int

A valid activist code id

action: str

Either ‘apply’ or ‘remove’

id_type: str

A known person identifier type available on this VAN instance such as dwid

Returns:

None

Bulk Import

class parsons.ngpvan.van.BulkImport[source]
get_bulk_import_resources()[source]

Get bulk import resources that available to the user. These define the types of bulk imports that you can run. These might include Contacts, ActivistCodes, ContactsActivistCodes and others.

Returns:
list

A list of resources.

get_bulk_import_job(job_id)[source]

Get a bulk import job status.

Args:
job_idint

The bulk import job id.

Returns:
dict

The bulk import job

get_bulk_import_job_results(job_id)[source]

Get result file of a bulk upload job. This will include one row per record processed as well as the status of each.

If the job results have not been generated, either due to an error in the process or the fact the job is still processing, it will return None.

Args:
job_id: int

The bulk import job id.

Returns:
Parsons Table

See Parsons Table for output options.

get_bulk_import_mapping_types()[source]

Get bulk import mapping types.

Returns:
Parsons Table

See Parsons Table for output options.

get_bulk_import_mapping_type(type_name)[source]

Get a single bulk import mapping type.

Args:

type_name: str

Returns:
dict

A mapping type json

get_bulk_import_mapping_type_fields(type_name, field_name)[source]

Get data about a field in a mapping type.

Args:
type_name: str

The mapping type name

field_name: str

The field name

Returns:
dict

A mapping type fields json

bulk_apply_activist_codes(tbl, url_type, **url_kwargs)[source]

Bulk apply activist codes.

The table may include the following columns. The first column must be vanid.

Column Name

Required

Description

vanid

Yes

A valid VANID primary key

activistcodeid

Yes

A valid activist code id

datecanvassed

No

An ISO formatted date

canvassedby

No

A valid User ID; Required when DateCanvassed is provided

contacttypeid

No

The method of contact.

Args:
table: Parsons table

A Parsons table.

url_type: str

The cloud file storage to use to post the file (S3 or GCS). See Cloud Storage for more details.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
int

The bulk import job id

bulk_upsert_contacts(tbl, url_type, result_fields=None, **url_kwargs)[source]

Bulk create or update contact records. Provide a Parsons table of contact data to create or update records.

Note

  • The first column of the table must be VANID.

  • The other columns can be a combination of the columns listed below. The valid column names also accept permutations with underscores, spaces and capitalization (e.g. phonenumber = Phone_Number).

Table Fields

Column

Valid Column Names

Notes

VANID

vanid

Voter VAN ID

votervanid

The contact’s MyVoters VANID

External ID

externalid, id, pk, voterbaseid

An external id to be stored.

PII

First Name

fn, firstname, first

Middle Name

mn, middlename, middle

Last Name

ln, lastname, last

Date of Birth

dob, dateofbirth, birthdate

An ISO formatted date

Sex

sex, gender

Physical Address

Address Line 1

addressline1, address1, address

Address Line 2

addressline2, address2

Address Line 3

addressline3, address3

City

city

State Or Province

state, st, stateorprovince

Zip or Postal Code

ziporpostal, postal, postalcode, zip, zipcode

Country Code

countrycode, country

A valid two character country code (e.g. US)

Display As Entered

displayasentered

Required values are Y and N. Determines if the address is processed through address correction.

Phones

Cell Phone

cellphone, cell

Cell Phone Country Code

cellcountrycode, cellphonecountrycode

A valid two digit country code (e.g. 01)

Home Phone

homephone, home, phone

Home Phone Country Code

homecountrycode, homephonecountrycode

Email

Email

email, emailaddress

Other Email

otheremail, email2, emailaddress2

Args:
table: Parsons table

A Parsons table.

url_type: str

The cloud file storage to use to post the file. Currently only S3.

results_fields: list

A list of fields to include in the results file.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
int

The bulk import job id

bulk_apply_suppressions(tbl, url_type, **url_kwargs)[source]

Bulk apply contact suppression codes.

The table may include the following columns. The first column must be vanid.

Column Name

Required

Description

vanid

Yes

A valid VANID primary key

suppressionid

Yes

A valid suppression id

Args:
table: Parsons table

A Parsons table.

url_type: str

The cloud file storage to use to post the file (S3 or GCS). See Cloud Storage for more details.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
int

The bulk import job id

bulk_apply_canvass_results(tbl, url_type, **url_kwargs)[source]

Bulk apply contact canvass results.

The table may include the following columns. The first column must be vanid.

Column Name

Required

Description

vanid

Yes

A valid VANID primary key

contacttypeid

Yes

Valid Contact Type ID

resultid

Yes

Valid Contact Result ID

datecanvassed

Yes

ISO Date Format

canvassedby

Yes

Valid User ID

phone

No

Attempted Phone Number

countrycode

No

Country Code (ISO 3166-1 alpha-2)

phonetypeid

No

Phone Type

phoneoptinstatusid

No

SMS Opt-In Status

addressid

No

The Contact Address ID of the address that was canvassed

Args:
table: Parsons table

A Parsons table.

url_type: str

The cloud file storage to use to post the file (S3 or GCS). See Cloud Storage for more details.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
int

The bulk import job id

bulk_apply_contact_custom_fields(custom_field_group_id, tbl, url_type, **url_kwargs)[source]

Bulk apply contact custom fields.

The table may include the following columns. The first column must be vanid.

Column Name

Required

Description

vanid

Yes

A valid VANID primary key

***CF{CustomFieldID}

Yes

At least one custom field column to be loaded associated with the provided custom_field_group_id. The column name should be a valid Custom Field ID prefixed with CF, i.e. CF123.

Args:
custom_field_group_id: int

Valid Custom Contact Field Group ID; must be the parent of the provided Custom Field IDs in the file.

table: Parsons table

A Parsons table.

url_type: str

The cloud file storage to use to post the file (S3 or GCS). See Cloud Storage for more details.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
int

The bulk import job id

Canvass Responses

class parsons.ngpvan.van.CanvassResponses(van_connection)[source]
get_canvass_responses_contact_types()[source]

Get canvass response contact types.

Returns:
Parsons Table

See Parsons Table for output options.

get_canvass_responses_input_types()[source]

Get canvass response input types.

Returns:
Parsons Table

See Parsons Table for output options.

get_canvass_responses_result_codes()[source]

Get canvass response result codes.

Returns:
Parsons Table

See Parsons Table for output options.

Changed Entities

class parsons.ngpvan.van.ChangedEntities[source]
get_changed_entity_resources()[source]

Get changed entity resources available to the API user.

Returns:

list

get_changed_entity_resource_fields(resource_type)[source]

Get export fields avaliable for each changed entity resource.

Args:

resource_type: str

Returns:
Parsons Table

See Parsons Table for output options.

get_changed_entities(resource_type, date_from, date_to=None, include_inactive=False, requested_fields=None, custom_fields=None)[source]

Get modified records for VAN from up to 90 days in the past.

Args:
resource_type: str

The type of resource to export. Use the get_changed_entity_resources() to get a list of potential entities.

date_from: str

The start date in which to search. Must be less than 90 days in the past. Must be``iso8601`` formatted date (2021-10-11).

date_to: str

The end date to search. Must be less than 90 days in the past. Must be``iso8601`` formatted date (2021-10-11).

include_inactive: boolean

Include inactive records

requested_fields: list

A list of optional requested fields to include. These options can be accessed through get_changed_entity_resource_fields() method.

custom_fields: list

A list of ids of custom fields to include in the export.

Returns:
Parsons Table

See Parsons Table for output options.

Codes

class parsons.ngpvan.van.Codes(van_connection)[source]
get_codes(name=None, supported_entities=None, parent_code_id=None, code_type=None)[source]

Get codes.

Args:
namestr

Filter by name of code.

supported_entities: str

Filter by supported entities.

parent_code_id: str

Filter by parent code id.

code_type: str

Filter by code type.

Returns:
Parsons Table

See Parsons Table for output options.

get_code(code_id)[source]

Get a code.

Args:
code_idint

The code id.

Returns:
Parsons Table

See Parsons Table for output options.

get_code_types()[source]

Get code types.

Returns:
list

A list of code types.

create_code(name=None, parent_code_id=None, description=None, code_type='SourceCode', supported_entities=None)[source]

Create a code.

Args:
name: str

The name of the code.

parent_code_id: int

A unique identifier for this code’s parent.

description: str

A description for this code, no longer than 200 characters.

code_type: str

The code type. Tag and SourceCode are valid values.

supported_entities: list

A list of dicts that enumerate the searchability and applicability rules of the code. You can find supported entities with the code_supported_entities()

[
    {
     'name': 'Event',
     'is_searchable': True,
     'is_applicable': True
    }
    {
     'name': 'Locations',
     'start_time': '12-31-2018T13:00:00',
     'end_time': '12-31-2018T14:00:00'
    }
]
update_code(code_id, name=None, parent_code_id=None, description=None, code_type='SourceCode', supported_entities=None)[source]

Update a code.

Args:
code_id: int

The code id.

name: str

The name of the code.

parent_code_id: int

A unique identifier for this code’s parent.

description: str

A description for this code, no longer than 200 characters.

code_type: str

The code type. Tag and SourceCode are valid values.

supported_entities: list

A list of dicts that enumerate the searchability and applicability rules of the code. You can find supported entities with the code_supported_entities()

[
    {
     'name': 'Event',
     'is_searchable': True,
     'is_applicable': True
    }
    {
     'name': 'Locations',
     'start_time': '12-31-2018T13:00:00',
     'end_time': '12-31-2018T14:00:00'
    }
]
delete_code(code_id)[source]

Delete a code.

Args:
code_id: int

The code id.

Returns:

None

get_code_supported_entities()[source]

Get code supported entities.

Returns:
list

A list of code supported entities.

Custom Fields

class parsons.ngpvan.van.CustomFields(van_connection)[source]
get_custom_fields(field_type='contacts')[source]

Get custom fields.

Args:
field_typestr

Filter by custom field group type. Must be one of contacts or contributions.

Returns:
Parsons Table

See Parsons Table for output options.

get_custom_fields_values(field_type='contacts')[source]

Get custom field values as a long table.

Args:
field_typestr

Filter by custom field group type. Must be one of contacts or contributions.

Returns:
Parsons Table

See Parsons Table for output options.

get_custom_field(custom_field_id)[source]

Get a custom field.

Args:
custom_field_id: int

A valid custom field id.

Returns:

A json.

Events

class parsons.ngpvan.van.Events(van_connection)[source]
get_events(code_ids=None, event_type_ids=None, rep_event_id=None, starting_after=None, starting_before=None, district_field=None, expand_fields=['locations', 'codes', 'shifts', 'roles', 'notes', 'financialProgram', 'ticketCategories', 'onlineForms'])[source]

Get events.

Args:
code_ids: str

Filter by code id.

event_type_ids: str

Filter by event_type_ids.

rep_event_id: str

Filters to recurring events that are recurrences the passed event id.

starting_after: str

Events beginning after iso8601 formatted date.

starting_before: str

Events beginning before iso8601 formatted date.

district_field: str

Filter by district field.

expand_fields: list

A list of fields for which to include data. If a field is omitted, None will be returned for that field. Can be locations, codes, shifts,``roles``, notes, financialProgram, ticketCategories, onlineForms.

Returns:
Parsons Table

See Parsons Table for output options.

get_event(event_id, expand_fields=['locations', 'codes', 'shifts', 'roles', 'notes', 'financialProgram', 'ticketCategories', 'voterRegistrationBatches'])[source]

Get an event.

Args:
event_id: int

The event id.

expand_fields: list

A list of fields for which to include data. If a field is omitted, None will be returned for that field. Can be locations, codes, shifts, roles, notes, financialProgram, ticketCategories, ``voterRegistrationBatches`.`

Returns:
Parsons Table

See Parsons Table for output options.

create_event(name, short_name, start_date, end_date, event_type_id, roles, shifts=None, description=None, editable=False, publicly_viewable=False, location_ids=None, code_ids=None, notes=None, district_field_value=None, voter_registration_batches=None)[source]

Create an event

Args:
name: str

A name for this event, no longer than 500 characters.

short_name: str

A shorter name for this event, no longer than 12 characters.

start_date: str

The start date and time for this event.

end_date: str

The end date and time for this event that is after start_date

event_type_id: int

A valid event type id.

roles: list

A list of valid role ids that correspond the with the event type.

shifts:

A list of dicts with shifts formatted as:

[
    {
     'name': 'Shift 1',
     'start_time': '12-31-2018T12:00:00',
     'end_time': '12-31-2018T13:00:00'
    }
    {
     'name': 'Shift 2',
     'start_time': '12-31-2018T13:00:00',
     'end_time': '12-31-2018T14:00:00'
    }
]
description: str

An optional description for this Event, no longer than 500 characters.

editable: boolean

If True, prevents modification of this event by any users other than the user associated the API key. Setting this to true effectively makes the event read-only in the VAN interface.

publicly_viewable: boolean

Used by NGP VAN’s website platform to indicate whether this event can be viewed publicly.

location_ids: list

A list of location_ids where the event is taking place

code_ids: list

A list of codes that are applied to this event for organizational purposes. Note that at most one source code and any number of tags, may be applied to an event.

notes: list

A list of notes

Returns:
int

The event code.

delete_event(event_id)[source]

Delete an event.

Args:
event_id: int

The event id.

Returns:

None

add_event_shift(event_id, shift_name, start_time, end_time)[source]

Add shifts to an event

Args:
event_id: int

The event id.

shift_name: str

The name of the shift

start_time: str

The start time for the shift (iso8601 formatted date).

end_time: str

The end time of the shift (iso8601 formatted date).

Returns:
int

The shift id.

get_event_types()[source]

Get event types.

Returns:
Parsons Table

See Parsons Table for output options.

Export Jobs

class parsons.ngpvan.van.ExportJobs(van_connection)[source]
get_export_job_types()[source]

Get export job types

Returns:
Parsons Table

See Parsons Table for output options.

export_job_create(list_id, export_type=4, webhookUrl='https://www.nothing.com')[source]

Creates an export job

Currently, this is only used for exporting saved lists. It is recommended that you use the saved_list_download() method instead.

Args:
list_id: int

This is where you should input the list id

export_type: int

The export type id, which defines the columns to export

webhookUrl:

A webhook to include to notify as to the status of the export

Returns:
dict

The export job object

get_export_job(export_job_id)[source]

Get an export job.

Args:
export_job_id: int

The xxport job id.

Returns:
Parsons Table

See Parsons Table for output options.

File Loading Jobs

class parsons.ngpvan.van.FileLoadingJobs(van_connection)[source]
create_file_load(file_name, file_url, columns, id_column, id_type, score_id, score_column, delimiter='csv', header=True, quotes=True, description=None, email=None, auto_average=None, auto_tolerance=None)[source]

Warning

Deprecated since version 0.7: Use parsons.VAN.upload_scores() instead.

Loads a file. Only used for loading scores at this time. Scores must be compressed using zip.

Args:
file_name: str

The name of the file contained in the zip file.

file_url: str

The url path to directly download the file. Can also be a path to an FTP site.

columns: list

A list of column names contained in the file.

id_column: str

The column name of the id column in the file.

id_type: str

A valid primary key, such as VANID or DWID. Varies by VAN instance.

score_id: int

The score slot id

score_column: str

The column holding the score

delimiter: str

The file delimiter used.

email: str

A valid email address in which file loading status will be sent.

auto_average: float

The average of scores to be loaded.

auto_tolerance: float

The fault tolerance of the VAN calculated average compared to the auto_average. The tolerance must be less than 10% of the difference between the maximum and minimum possible acceptable values of the score.

Returns:
dict

The file load id

create_file_load_multi(file_name, file_url, columns, id_column, id_type, score_map, delimiter='csv', header=True, quotes=True, description=None, email=None)[source]

Warning

Deprecated since version 0.7: Use parsons.VAN.upload_scores() instead.

An iteration of the file_load() method that allows you to load multiple scores at the same time.

Args:
file_namestr

The name of the file contained in the zip file.

file_urlstr

The url path to directly download the file. Can also be a path to an FTP site.

columns: list

A list of column names contained in the file.

id_columnstr

The column name of the id column in the file.

id_typestr

A valid primary key, such as VANID or DWID. Varies by VAN instance.

score_maplist

A list of dicts that adheres to the following syntax

[{'score_id' : int,
  'score_column': str,
  'auto_average': float,
  'auto_tolerance': float }]
email: str

A valid email address in which file loading status will be sent.

Returns:

The file load job id

Folders

Note

A folder must be shared with the user associated with your API key to be listed.

class parsons.ngpvan.van.Folders(van_connection)[source]
get_folders()[source]

Get all folders owned or shared with the API user.

Returns:
Parsons Table

See Parsons Table for output options.

get_folder(folder_id)[source]

Get a folder owned by or shared with the API user.

Args:
folder_id: int

The folder id.

Returns:
Parsons Table

See Parsons Table for output options.

Locations

class parsons.ngpvan.van.Locations(van_connection)[source]
get_locations(name=None)[source]

Get locations.

Args:
name: str

Filter locations by name.

Returns:
Parsons Table

See Parsons Table for output options.

get_location(location_id)[source]

Get a location.

Args:
location_id: int

The location id.

Returns:

dict

create_location(name, address_line1=None, address_line2=None, city=None, state=None, zip_code=None)[source]

Find or create a location. If location already exists, will return location id.

Args:
name: str

A name for this location, no longer than 50 characters.

address_line1: str

First line of a street address.

address_line2: str

Second line of a street address.

city: str

City or town name.

state: str

Two or three character state or province code (e.g., MN, ON, NSW, etc.).

zip_code: str

ZIP, ZIP+4, Postal Code, Post code, etc.

Returns:
int

A location id.

delete_location(location_id)[source]

Delete a location.

Args:
location_id: int

The location id

Returns:

None

Printed Lists

Note

A printed list must be shared with the user associated with your API key to be listed.

class parsons.ngpvan.van.PrintedLists(van_connection)[source]
get_printed_lists(generated_after=None, generated_before=None, created_by=None, folder_name=None, turf_name=None)[source]

Get printed lists.

Args:
folder_id: int

Filter by the id for a VAN folder. If included returns only the saved lists in the folder

Returns:
Parsons Table

See Parsons Table for output options.

get_printed_list(printed_list_number)[source]

Returns a printed list object.

Args:
printed_list_number: int

The printed list number

Returns:

dict

Saved Lists

Note

A saved list must be shared with the user associated with your API key to be listed.

class parsons.ngpvan.van.SavedLists(van_connection)[source]
get_saved_lists(folder_id=None)[source]

Get saved lists.

Args:
folder_id: int

Filter by the id for a VAN folder. If included returns only the saved lists in the folder

Returns:
Parsons Table

See Parsons Table for output options.

get_saved_list(saved_list_id)[source]

Returns a saved list object.

Args:
saved_list_id: int

The saved list id.

Returns:

dict

download_saved_list(saved_list_id)[source]

Download the vanids associated with a saved list.

Args:
saved_list_id: int

The saved list id.

Returns:
Parsons Table

See Parsons Table for output options.

upload_saved_list_rest(tbl, url_type, folder_id, list_name, description, callback_url, columns, id_column, delimiter='csv', header=True, quotes=True, overwrite=None, **url_kwargs)[source]

Upload a saved list. Invalid or unmatched person id records will be ignored. Your api user must be shared on the target folder.

Args:
tbl: parsons.Table

A parsons table object containing one column of person ids.

url_type: str

The cloud file storage to use to post the file (S3 or GCS). See Cloud Storage for more details.

folder_id: int

The folder id where the list will be stored.

list_name: str

The saved list name.

description: str

Description of the file upload job and the list.

callback_url: string

The configured HTTP listener to which successful list loads will send a standard webhook.

columns: list

A list of column names contained in the file.

id_columnstr

The column name of the VAN ID column in the file. Must be VAN ID.

delimiter: str

The file delimiter used.

header: boolean

Whether or not the source file has a header row.

quotes: boolean

Whether or not fields are enclosed in quotation marks within each column of the file.

overwrite: int

Replace saved list if already exists. Pass in the list id of the existing list that you would like to overwrite.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
dict

Upload results information included the number of matched and saved records in your list.

upload_saved_list(tbl, list_name, folder_id, url_type, id_type='vanid', replace=False, **url_kwargs)[source]

Warning

Deprecated since version 0.X: Use parsons.VAN.upload_saved_list_rest() instead.

Upload a saved list. Invalid or unmatched person id records will be ignored. Your api user must be shared on the target folder.

Args:
tbl: parsons.Table

A parsons table object containing one column of person ids.

list_name: str

The saved list name.

folder_id: int

The folder id where the list will be stored.

url_type: str

The cloud file storage to use to post the file (S3 or GCS). See Cloud Storage for more details.

id_type: str

The primary key type. The options, beyond vanid are specific to your instance of VAN.

replace: boolean

Replace saved list if already exists.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
dict

Upload results information included the number of matched and saved records in your list.

Scores

Prior to loading a score for the first time, you must contact VAN support to request a score slot.

Note

Score Auto Approval

Scores can be automatically set to approved through the VAN.upload_scores() method allowing you to skip calling VAN.update_score_status(), if the average of the scores is within the fault tolerance specified by the user. It is only available to API keys with permission to automatically approve scores.

class parsons.ngpvan.van.Scores(van_connection)[source]
get_scores()[source]

Get all scores.

Returns:
Parsons Table

See Parsons Table for output options.

get_score(score_id)[source]

Get an individual score.

Args:
score_id: int

The score id

Returns:

dict

get_score_updates(created_before=None, created_after=None, score_id=None)[source]

Get score updates.

Args:
created_before: str

Filter score updates to those created before date. Use “YYYY-MM-DD” format.

created_after: str

Filter score updates to those created after date. Use “YYYY-MM-DD” format.

Returns:
Parsons Table

See Parsons Table for output options.

get_score_update(score_update_id)[source]

Get a score update object

Args:
score_update_idint

The score update id

Returns:

dict

update_score_status(score_update_id, status)[source]

Change the status of a score update object. This end point is used to approve a score loading job.

Args:
score_update_id: str

The score update id

status: str

One of ‘pending approval’, ‘approved’, ‘disapproved’

Returns:

None

upload_scores(tbl, config, url_type, id_type='vanid', email=None, auto_approve=True, approve_tolerance=0.1, **url_kwargs)[source]

Upload scores. Use to create or overwrite scores. Multiple score loads should be configured in a single call. 1

Args:
tbl: object

A parsons.Table object. The table must contain the scores and first column in the table must contain the primary key (e.g. vanid).

config: list

The score configuration. A list of dictionaries in which you specify the following

score_column

The name of the column where the score is housed.

score_id

The score slot id.

Example:

[{'score1_id' : int, score1_column': str}
 {'score2_id' : int, score2_column': str}]
url_type: str

The cloud file storage to use to post the file (S3 or GCS). See Cloud Storage for more details.

email: str

An email address to send job load status updates.

auto_approve: boolean

If the scores are within the expected tolerance of deviation from the average values provided, then score will be automatically approved.

approve_tolderance: float

The deviation from the average scores allowed in order to automatically approve the score. Maximum of .1.

**url_kwargs: kwargs

Arguments to configure your cloud storage url type. See Cloud Storage for more details.

Returns:
int

The score load job id.

1

NGPVAN asks that you load multiple scores in a single call to reduce the load on their servers.

Signups

class parsons.ngpvan.van.Signups(van_connection)[source]
get_signups_statuses(event_id=None, event_type_id=None)[source]

Get a list of valid signup statuses for a given event type or event. You must pass one of event_id or event_type_id but not both.

Args:
event_id: int

A valid event id.

event_type_id: int

A valid event type id.

Returns:
Parsons Table

See Parsons Table for output options.

get_person_signups(vanid)[source]

Get the signup history of a person.

Args:
vanid: int

A valid vanid associated with a person.

Returns:
Parsons Table

See Parsons Table for output options.

get_event_signups(event_id)[source]

Get the signup history of an event.

Args:
event_id: int

A valid event_id associated with an event

Returns:
Parsons Table

See Parsons Table for output options.

get_signup(event_signup_id)[source]

Get a single signup object.

Args:
event_signup_id: int

A valid event_signup_id associated with a signup.

Returns:
Parsons Table

See Parsons Table for output options.

create_signup(vanid, event_id, shift_id, role_id, status_id, location_id)[source]

Create a new signup for an event.

Args:
vanid: int

A valid vanid of the person to signup for the event.

event_id: int

A valid event_id to associate the person with the event

shift_id:

A shift_id, associated with the event to assign the person

role_id:

A role_id, associated with the event to assign the person

status_id:

A status_id of the person

location_id:

A location_id for the event

Returns:
Int

The event signup id

update_signup(event_signup_id, shift_id=None, role_id=None, status_id=None, location_id=None)[source]

Update a signup object. All of the kwargs will update the values associated with them.

Args:
event_signup_id: int

A valid event signup id

shift_id: int

The shift_id to update

role_id: int

The role_id to update

status_id: int

The status_id to update

location_id: int

The location_id to update

Returns:

None

delete_signup(event_signup_id)[source]

Delete a signup object

Args:
event_signup_id: int

A valid event signup id

Returns:

None

Supporter Groups

class parsons.ngpvan.van.SupporterGroups(van_connection)[source]
get_supporter_groups()[source]

Get supporter groups.

Returns:
Parsons Table

See Parsons Table for output options.

get_supporter_group(supporter_group_id)[source]

Get a supporter group.

Args:
supporter_group_id: int

The supporter group id.

Returns:

dict

create_supporter_group(name, description)[source]

Create a new supporter group.

Args:
name: str

The name of the supporter group. 100 character limit

description: str

Optional; A description of the supporter group. 200 character limit.

Returns

Parsons Table with the newly createed supporter group id, name and description

delete_supporter_group(supporter_group_id)[source]

Delete a supporter group.

Args:
supporter_group_id: int

The supporter group id

Returns:

None

add_person_supporter_group(supporter_group_id, vanid)[source]

Add a person to a supporter group

Args:
supporter_group_id: int

The supporter group id

vanid: int

The vanid of the person to apply

Returns:

None

delete_person_supporter_group(supporter_group_id, vanid)[source]

Remove a person from a supporter group

Args:
supporter_group_id: int

The supporter group id

vanid: int

The vanid of the person to remove

Returns:

None

Survey Questions

class parsons.ngpvan.van.SurveyQuestions(van_connection)[source]
get_survey_questions(statuses=['Active'], name=None, sq_type=None, question=None, cycle=None)[source]

Get survey questions.

Args:
statuses: list

Filter to a list of statuses of survey questions. One or more of Active, Archived, and Inactive.

name: str

Filter to survey questions with names begin with the input.

type: str

Filter to survey questions of a given type.

question: str

Filter to survey questions with script questions that contain the given input.

cycle: str

Filter to survey suestions with the given cycle. A year in the format “YYYY”.

Returns:
Parsons Table

See Parsons Table for output options.

get_survey_question(survey_question_id)[source]

Get a survey question.

Args:
survey_question_id: int

The survey question id.

Returns:
Parsons Table

See Parsons Table for output options.

apply_survey_response(id, survey_question_id, survey_response_id, id_type='vanid', result_code_id=None, contact_type_id=None, input_type_id=None, date_canvassed=None)[source]

Apply a single survey response to a person.

Args:
id: str

A valid person id

survey_question_id: int

A valid survey question id

survey_response_id: int

A valid survey response id

id_type: str

A known person identifier type available on this VAN instance such as dwid

result_code_idint

Optional; Specifies the result code of the response. If not included,responses must be specified. Conversely, if responses are specified, result_code_id must be null. Valid ids can be found by using the get_canvass_responses_result_codes()

contact_type_idint

Optional; A valid contact type id

input_type_idint

Optional; Defaults to 11 (API Input)

date_canvassedstr

Optional; ISO 8601 formatted date. Defaults to todays date

Targets

class parsons.ngpvan.van.Targets(van_connection)[source]
get_targets()[source]

Get targets.

Returns:
Parsons Table

See Parsons Table for output options.

get_target(target_id)[source]

Get a single target.

Args:
target_idint

The target id.

Returns:
dict

The target

get_target_export(export_job_id)[source]

Get specific target export job id’s status.

Returns:
Parsons Table

See Parsons Table for output options.

create_target_export(target_id, webhook_url=None)[source]

Create new target export job

Args:
target_idint

The target id the export job is creating for.

Returns:
dict

The target export job ID