def test_unpack_list(self): test_table = Table([{'a': 1, 'b': [1, 2, 3]}]) # Test that list at the top level test_table.unpack_list('b', replace=True) self.assertEqual(['a', 'b_0', 'b_1', 'b_2'], test_table.columns)
def test_unpack_list_with_mixed_col(self): # Test unpacking column with non-list items mixed_tbl = Table([{ 'id': 1, 'tag': [1, 2, None, 4] }, { 'id': 2, 'tag': None }]) tbl_unpacked = Table(mixed_tbl.unpack_list('tag')) # Make sure result has the right number of columns self.assertEqual(len(tbl_unpacked.columns), 5) result_table = Table([{ 'id': 1, 'tag_0': 1, 'tag_1': 2, 'tag_2': None, 'tag_3': 4 }, { 'id': 2, 'tag_0': None, 'tag_1': None, 'tag_2': None, 'tag_3': None }]) # Check that the values for both rows are distributed correctly self.assertEqual(result_table.data[0] + result_table.data[1], tbl_unpacked.data[0] + tbl_unpacked.data[1])
def get_events_organization(self, organization_id=None, updated_since=None, timeslot_start=None, timeslot_end=None, timeslots_table=False, max_timeslots=None): """ Fetch all public events for an organization. This includes both events owned by the organization (as indicated by the organization field on the event object) and events of other organizations promoted by this specified organization. .. note:: API Key Required `Args:` organization_id: list or int Filter events by a single or multiple organization ids updated_since: str Filter to events updated since given date (ISO Date) timeslot_start: str Filter by a timeslot start of events using ``>``,``>=``,``<``,``<=`` operators and ISO date (ex. ``<=2018-12-13 05:00:00PM``) timeslot_end: str Filter by a timeslot end of events using ``>``,``>=``,``<``,``<=`` operators and ISO date (ex. ``<=2018-12-13 05:00:00PM``) timeslot_table: boolean Return timeslots as a separate long table. Useful for extracting to databases. zipcode: str Filter by a Events' Locations' postal code. If present, returns Events sorted by distance from zipcode. If present, virtual events will not be returned. max_dist: str Filter Events' Locations' distance from provided zipcode. visibility: str Either `PUBLIC` or `PRIVATE`. Private events only return if user is authenticated; if `visibility=PRIVATE` and user doesn't have permission, no events returned. exclude_full: bool If `exclude_full=true`, filter out full Timeslots (and Events if all of an Event's Timeslots are full) is_virtual: bool `is_virtual=false` will return only in-person events, while `is_virtual=true` will return only virtual events. If excluded, return virtual and in-person events. Note that providing a zipcode also implies `is_virtual=false`. event_types:enum The type of the event, one of: `CANVASS`, `PHONE_BANK`, `TEXT_BANK`, `MEETING`, `COMMUNITY`, `FUNDRAISER`, `MEET_GREET`, `HOUSE_PARTY`, `VOTER_REG`, `TRAINING`, `FRIEND_TO_FRIEND_OUTREACH`, `DEBATE_WATCH_PARTY`, `ADVOCACY_CALL`, `OTHER`. This list may expand in the future. max_timeslots: int If not returning a timeslot table, will unpack time slots. If do not set this arg, it will add a column for each time slot. The argument limits the number of columns and discards any additional timeslots after that. For example: If there are 20 timeslots associated with your event, and you set the max time slots to 5, it will only return the first 5 time slots as ``time_slot_0``, ``time_slot_1`` etc. This is helpful in situations where you have a regular sync running and want to ensure that the column headers remain static. `Returns` Parsons Table or dict or Parsons Tables See :ref:`parsons-table` for output options. """ if isinstance(organization_id, (str, int)): organization_id = [organization_id] args = {'organization_id': organization_id, 'updated_since': date_to_timestamp(updated_since), 'timeslot_start': self._time_parse(timeslot_start), 'timeslot_end': self._time_parse(timeslot_end), } tbl = Table(self._request_paginate(self.uri + 'events', args=args, auth=True)) if tbl.num_rows > 0: tbl.unpack_dict('sponsor') tbl.unpack_dict('location', prepend=False) tbl.unpack_dict('location', prepend=False) # Intentional duplicate tbl.table = petl.convert(tbl.table, 'address_lines', lambda v: ' '.join(v)) if timeslots_table: timeslots_tbl = tbl.long_table(['id'], 'timeslots', 'event_id') return {'events': tbl, 'timeslots': timeslots_tbl} else: tbl.unpack_list('timeslots', replace=True, max_columns=max_timeslots) cols = tbl.columns for c in cols: if re.search('timeslots', c, re.IGNORECASE) is not None: tbl.unpack_dict(c) return tbl
def get_events(self, organization_id=None, updated_since=None, timeslot_start=None, timeslot_end=None, timeslots_table=False, max_timeslots=None): """ Fetch all public events on the platform. `Args:` organization_id: list or int Filter events by a single or multiple organization ids updated_since: str Filter to events updated since given date (ISO Date) timeslot_start: str Filter by a timeslot start of events using ``>``,``>=``,``<``,``<=`` operators and ISO date (ex. ``<=2018-12-13 05:00:00PM``) timeslot_end: str Filter by a timeslot end of events using ``>``,``>=``,``<``,``<=`` operators and ISO date (ex. ``<=2018-12-13 05:00:00PM``) timeslot_table: boolean Return timeslots as a separate long table. Useful for extracting to databases. max_timeslots: int If not returning a timeslot table, will unpack time slots. If do not set this kwarg, it will add a column for each time slot. The argument limits the number of columns and discards any additional timeslots after that. For example: If there are 20 timeslots associated with your event, and you set the max time slots to 5, it will only return the first 5 time slots as ``time_slot_0``, ``time_slot_1`` etc. This is helpful in situations where you have a regular sync running and want to ensure that the column headers remain static. `Returns` Parsons Table or dict or Parsons Tables See :ref:`parsons-table` for output options. """ if isinstance(organization_id, (str, int)): organization_id = [organization_id] args = {'organization_id': organization_id, 'updated_since': date_to_timestamp(updated_since), 'timeslot_start': self._time_parse(timeslot_start), 'timeslot_end': self._time_parse(timeslot_end)} tbl = Table(self._request_paginate(self.uri + 'events', args=args)) if tbl.num_rows > 0: tbl.unpack_dict('sponsor') tbl.unpack_dict('location', prepend=False) tbl.unpack_dict('location', prepend=False) # Intentional duplicate tbl.table = petl.convert(tbl.table, 'address_lines', lambda v: ' '.join(v)) if timeslots_table: timeslots_tbl = tbl.long_table(['id'], 'timeslots', 'event_id') return {'events': tbl, 'timeslots': timeslots_tbl} else: tbl.unpack_list('timeslots', replace=True, max_columns=max_timeslots) cols = tbl.columns for c in cols: if re.search('timeslots', c, re.IGNORECASE) is not None: tbl.unpack_dict(c) return tbl