Defining record classes

To use Pyrtable you will first need to subclass the BaseRecord class, once for each table you need to access. Objects of these subclasses represent records on the corresponding Airtable table, while the subclasses themselves are used to interact with the server (mostly to fetch records).

Each one of these subclasses follow the structure below:

class MyTableRecord(BaseRecord):
    class Meta:
        base_id = '<BASE ID>'
        table_id = '<TABLE ID>'

    # @TODO You need to provide credentials (the API Key) somehow

    # Fields definitions are created by instantiating *Field classes, such as:
    #name = StringField('Name')
    #birth_date = DateField('Birth date')
    #office = SingleRecordLinkField('Office', linked_class='OfficeRecord')

Details about the missing bits are provided below.

Values for base_id and table_id

base_id

Open the desired base in Airtable, go to “Help > API documentation” (top-right corner) and search for a paragraph containing “The ID of this base is base_id”.

table_id

The table_id is the name of the table itself. You can double-click the table name in the top tables to ease copying to the clipboard. Avoid using extraneous characters in the name, as these may render Pyrtable inoperative (accented characters, spaces, dots, hyphens, underlines are all OK).

Fields definitions

Refer to this page for details about using field classes to define the properties that link to Airtable fields.

Authentication methods

To actually interact with the Airtable server, Pyrtable needs to know the API Key. Airtable has a support page explaining how to obtain this key.

Providing the API Key to the record class

The basic way to provide the API Key to Pyrtable is to implement a class method that returns the key:

class MyTableRecord(BaseRecord):
    @classmethod
    def get_api_key(cls):
        return '<API KEY>'

    # other class stuff here

If this class method accepts a base_id parameter, then the caller will fill it – this may be used, e.g., for a dictionary-based lookup:

class MyTableRecord(BaseRecord):
    @classmethod
    def get_api_key(cls, base_id):
        return {
            '<BASE_ID_1>': '<API KEY_1>',
            '<BASE_ID_2>': '<API KEY_2>',
        }[base_id]

    # other class stuff here

Warning

Putting the raw API Key in the source code itself is a bad security practice, as anyone with access to your code will have full R/W access to all your Airtable bases. API Keys are as sensitive as passwords; they should be securely stored in separate, private files or using OS keychain services. See the APIKeyFromSecretsFileMixin and APIKeyFromEnvMixin mixin classes below.

Reading the API Key from a file

Note

This method requires the PyYAML package installed.

Using this approach is surprisingly easy. You only need to add the APIKeyFromSecretsFileMixin mixin when defining the class:

class MyTableRecord(APIKeyFromSecretsFileMixin, BaseRecord):
    class Meta:
        base_id = '<BASE ID>'
        table_id = '<TABLE ID>'

    # Fields definitions go here

Pyrtable will then search for a file named airtable_secrets.yaml in one of the following directories:

  • ./config subdirectory (under the current directory), or
  • /etc/airtable

This file is a YAML file with one of more key-value pairs, where each key is a base ID and the corresponding value is the API Key used to access that base. At the end, the file will contain one or more lines as follows:

appFGHIJ67890fghij: keyABCDE12345abcde

Reading the API Key from an environment variable

This is a mixin class that retrieves the API Key from the AIRTABLE_API_KEY environment variable. It is particularly useful for running Docker containers where all bases are accessible under the same API Key:

class MyTableRecord(APIKeyFromEnvMixin, BaseRecord):
    class Meta:
        base_id = '<BASE ID>'
        table_id = '<TABLE ID>'

    # Fields definitions go here

Now just provide the API Key through the AIRTABLE_API_KEY environment variable, e.g., using the corresponding Docker command-line option or the corresponding Docker Compose configuration key.

Don’t Repeat Yourself!

In the most common scenario, a Python project will interact with several tables across a single Airtable base. That means that base_id value will be the same for all BaseRecord subclasses.

To avoid unnecessary code repetition, you can create a superclass for all record classes of the same base. This superclass will only contain the definition of base_id and the selected authentication method. See the example:

class MyBaseRecord(APIKeyFromSecretsFileMixin, BaseRecord):
    class Meta:
        base_id = '<BASE ID>'


class MyTableRecord(MyBaseRecord):
    class Meta:
        table_id = '<TABLE ID>'

    # Fields definitions go here


class MyOtherTableRecord(MyBaseRecord):
    class Meta:
        table_id = '<OTHER TABLE ID>'

    # Fields definitions go here

Notice that table_id is specific to the actual record classes, while base_id is common for all of them.

Of course this superclass can also be designed to read the API Key from an environment variable:

class MyBaseRecord(APIKeyFromEnvMixin, BaseRecord):
    class Meta:
        base_id = '<BASE ID>'