Skip to main content

Hey Guys,


How can I access Airtable’s pagination by including a given offset in either the url or query?


My attempt below at including in the url has failed with the error “KeyError: ‘offset’”.


I’ve been able to access the 1st offset per the function at_page(). For simplicity’s sake, I took the result from the function and hardcoded it to the variable offset_01.


Thank you!


import requests
import pandas as pd

offset_01 = 'itrCG3VDp2c34x1j1/recKTJGYMICe13iA8'
url = 'https://api.airtable.com/v0/PRIVATETABLEKEY/accounts' + \
'&offset=' + offset_01
headers = {'Authorization': 'Bearer PRIVATEAPIKEY'}


# Calling API
response = requests.get(
url,
headers=headers,
)
json_response = response.json()


# Finding AT page offset

def at_page(at_json):
df_initial = pd.DataFrame(at_json)
at_offset = df_initialt'offset']t0]

return at_offset

offset = at_page(json_response)

PS also have an open stackoverflow:


Accessing Airtable's Pagination Using Python's Requests Library




python-3.x, api, python-requests, airtable









Any reason you’re not using a library for this?


I think this is sort’a what you want -


def get_iter(self, **options):

“”"

Record Retriever Iterator


    Returns iterator with lists in batches according to pageSize.
To get all records at once use :any:`get_all`

>>> for page in airtable.get_iter():
... for record in page:
... print(record)
b{'fields': ... }, ...]

Keyword Args:
max_records (``int``, optional): The maximum total number of
records that will be returned. See :any:`MaxRecordsParam`
view (``str``, optional): The name or ID of a view.
See :any:`ViewParam`.
page_size (``int``, optional ): The number of records returned
in each request. Must be less than or equal to 100.
Default is 100. See :any:`PageSizeParam`.
fields (``str``, ``list``, optional): Name of field or fields to
be retrieved. Default is all fields. See :any:`FieldsParam`.
sort (``list``, optional): List of fields to sort by.
Default order is ascending. See :any:`SortParam`.
formula (``str``, optional): Airtable formula.
See :any:`FormulaParam`.

Returns:
iterator (``list``): List of Records, grouped by pageSize

"""
offset = None
while True:
data = self._get(self.url_table, offset=offset, **options)
records = data.get("records", r])
time.sleep(self.API_LIMIT)
yield records
offset = data.get("offset")
if not offset:
break


Any reason you’re not using a library for this?


I think this is sort’a what you want -


def get_iter(self, **options):

“”"

Record Retriever Iterator


    Returns iterator with lists in batches according to pageSize.
To get all records at once use :any:`get_all`

>>> for page in airtable.get_iter():
... for record in page:
... print(record)
b{'fields': ... }, ...]

Keyword Args:
max_records (``int``, optional): The maximum total number of
records that will be returned. See :any:`MaxRecordsParam`
view (``str``, optional): The name or ID of a view.
See :any:`ViewParam`.
page_size (``int``, optional ): The number of records returned
in each request. Must be less than or equal to 100.
Default is 100. See :any:`PageSizeParam`.
fields (``str``, ``list``, optional): Name of field or fields to
be retrieved. Default is all fields. See :any:`FieldsParam`.
sort (``list``, optional): List of fields to sort by.
Default order is ascending. See :any:`SortParam`.
formula (``str``, optional): Airtable formula.
See :any:`FormulaParam`.

Returns:
iterator (``list``): List of Records, grouped by pageSize

"""
offset = None
while True:
data = self._get(self.url_table, offset=offset, **options)
records = data.get("records", r])
time.sleep(self.API_LIMIT)
yield records
offset = data.get("offset")
if not offset:
break

Thank you so much! Will review this and properly reply shortly.


I chose not to use the wrapper as I’m concerned it’ll lose support and get stale. It’s not supported by any legit orgs. There’s also a lot of stale issues open, which can speak to a small community as it is.


Requests won’t have that issue.


Thank you so much! Will review this and properly reply shortly.


I chose not to use the wrapper as I’m concerned it’ll lose support and get stale. It’s not supported by any legit orgs. There’s also a lot of stale issues open, which can speak to a small community as it is.


Requests won’t have that issue.



Yep - I fear this as well, but the code itself might provide you with some insights that you can apply to your own code.


I think there may be another one out there too with more support.



Yep - I fear this as well, but the code itself might provide you with some insights that you can apply to your own code.


I think there may be another one out there too with more support.


Hi Bill,


Funny enough, your discussion with @Bastiaan_Bijl helped me find how to query within the requests library:



It’s the params={‘offset’: ‘itrXXXXXX/recXXXXXX’} query that allowed me to access the next 100 records.


# Calling API
response = requests.get(
url,
headers=headers,
params={'offset': 'itrXXXXXX/recXXXXXX'}
)
json_response = response.json()

Thank you for your contributions and looking forward to continue to support the community as well 🙂


Reply