Skip to content

Commit 97ac50e

Browse files
committed
Enable getting only a partial AirTable table by view and/or formula.
1 parent 932a24c commit 97ac50e

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

airtable/airtable.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ def __request(self, method, url, params=None, payload=None):
6363
'error': dict(code=r.status_code, message=message)
6464
}
6565

66-
def get(self, table_name, record_id=None, limit=0, offset=None):
66+
def get(
67+
self, table_name, record_id=None, limit=0, offset=None,
68+
filter_by_formula=None, view=None):
6769
params = {}
6870
if check_string(record_id):
6971
url = os.path.join(table_name, record_id)
@@ -73,9 +75,14 @@ def get(self, table_name, record_id=None, limit=0, offset=None):
7375
params.update({'pageSize': limit})
7476
if offset and check_string(offset):
7577
params.update({'offset': offset})
78+
if filter_by_formula is not None:
79+
params.update({'filterByFormula': filter_by_formula})
80+
if view is not None:
81+
params.update({'view': view})
7682
return self.__request('GET', url, params)
7783

78-
def iterate(self, table_name, batch_size=0):
84+
def iterate(
85+
self, table_name, batch_size=0, filter_by_formula=None, view=None):
7986
"""Iterate over all records of a table.
8087
8188
Args:
@@ -84,13 +91,23 @@ def iterate(self, table_name, batch_size=0):
8491
(0) is using the default of the API which is (as of 2016-09)
8592
100. Note that the API does not allow more than that (but
8693
allow for less).
94+
filter_by_formula: a formula used to filter records. The formula
95+
will be evaluated for each record, and if the result is not 0,
96+
false, "", NaN, [], or #Error! the record will be included in
97+
the response. If combined with view, only records in that view
98+
which satisfy the formula will be returned.
99+
view: the name or ID of a view in the table. If set, only the
100+
records in that view will be returned. The records will be
101+
sorted according to the order of the view.
87102
Yields:
88103
A dict for each record containing at least three fields: "id",
89104
"createdTime" and "fields".
90105
"""
91106
offset = None
92107
while True:
93-
response = self.get(table_name, limit=batch_size, offset=offset)
108+
response = self.get(
109+
table_name, limit=batch_size, offset=offset,
110+
filter_by_formula=filter_by_formula, view=view)
94111
for record in response.pop('records'):
95112
yield record
96113
if 'offset' in response:

test_airtable.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,32 @@ def test_get_not_found(self, mock_request):
128128
r = self.airtable.get(FAKE_TABLE_NAME, '123')
129129
self.assertEqual(r['error']['code'], 404)
130130

131+
@mock.patch.object(requests, 'request')
132+
def test_get_view(self, mock_request):
133+
mock_response = mock.MagicMock()
134+
mock_response.status_code = 200
135+
mock_response.json.return_value = {'records': []}
136+
mock_request.return_value = mock_response
137+
138+
r = self.airtable.get(FAKE_TABLE_NAME, view='My view')
139+
mock_request.assert_called_once_with(
140+
'GET', 'https://api.airtable.com/v0/app12345/TableName',
141+
data=None, headers={'Authorization': 'Bearer fake_api_key'},
142+
params={'view': 'My view'})
143+
144+
@mock.patch.object(requests, 'request')
145+
def test_get_filter_by_formula(self, mock_request):
146+
mock_response = mock.MagicMock()
147+
mock_response.status_code = 200
148+
mock_response.json.return_value = {'records': []}
149+
mock_request.return_value = mock_response
150+
151+
r = self.airtable.get(FAKE_TABLE_NAME, filter_by_formula="{title} = ''")
152+
mock_request.assert_called_once_with(
153+
'GET', 'https://api.airtable.com/v0/app12345/TableName',
154+
data=None, headers={'Authorization': 'Bearer fake_api_key'},
155+
params={'filterByFormula': "{title} = ''"})
156+
131157
def test_invalid_get(self):
132158
with self.assertRaises(airtable.IsNotString):
133159
self.airtable.get(FAKE_TABLE_NAME, 123)

0 commit comments

Comments
 (0)