Skip to main content

Django-inspired library to interface with Airtable

Project description

Pyrtable is a Python 3 library to interface with Airtable‘s REST API.

There are other Python projects to deal with Airtable. However, most of them basically offer a thin layer to ease authentication and filtering – at the end, the programmer still has to manually deal with JSON encoding/decoding, pagination, request rate limits, and so on.

Pyrtable is a high-level, ORM-like library that hides all these details. It performs automatic mapping between Airtable records and Python objects, allowing CRUD operations while aiming to be intuitive and fun. Programmers used to Django will find many similarities and will (hopefully) be able to interface with Airtable bases in just a couple of minutes.

What does it look like?

Ok, let’s have a taste of how one can define a class that maps onto records of a table:

import enum
from pyrtable.record import BaseRecord
from pyrtable.fields import StringField, DateField, SingleSelectionField, \
        SingleRecordLinkField, MultipleRecordLinkField

class Role(enum.Enum):
    DEVELOPER = 'Developer'
    MANAGER = 'Manager'
    CEO = 'C.E.O.'

class EmployeeRecord(BaseRecord):
    class Meta:
        # Open “Help > API documentation” in Airtable and search for a line
        # starting with “The ID of this base is XXX”.
        base_id = 'appABCDE12345'
        table_id = 'Employees'

    @classmethod
    def get_api_key(cls):
        # The API key can be generated in you Airtable Account page.
        # DO NOT COMMIT THIS STRING!
        return 'keyABCDE12345'

    name = StringField('Name')
    birth_date = DateField('Birth date')
    office = SingleRecordLinkField('Office', linked_class='OfficeRecord')
    projects = MultipleRecordLinkField(
            'Allocated in projects', linked_class='ProjectRecord')
    role = SingleSelectionField('Role', choices=Role)

After that, common operations are pretty simple:

# Iterating over all records
for employee in EmployeeRecord.objects.all():
    print("%s is currently working on %d project(s)" % (
        employee.name, len(employee.projects)))

# Filtering
for employee in EmployeeRecord.objects.filter(
        birth_date__gte=datetime.datetime(2001, 1, 1)):
    print("%s was born in this century!" % employee.name)

# Creating, updating and deleting a record
new_employee = EmployeeRecord(
    name='John Doe',
    birth_date=datetime.date(1980, 5, 10),
    role=Role.DEVELOPER)
new_employee.save()

new_employee.role = Role.MANAGER
new_employee.save()

new_employee.delete()

Notice that we don’t deal with Airtable column or table names once record classes are defined.

Beyond the basics

Keep in mind that Airtable is not a database system and is not really designed for tasks that need changing tons of data. In fact, only fetch (list) operations are batched – insert/update/delete operations are limited to a single record per request, and Airtable imposes a 5 requests per second limit even for paid accounts. You will need a full minute to update 300 records!

That said, Pyrtable will respect that limit. In fact, it will track dirty fields to avoid unnecessary server requests and will render .save() calls as no-ops for unchanged objects. That also works with multiple threads, so the following pattern can be used to update and/or create several records:

from concurrent.futures.thread import ThreadPoolExecutor

all_records = list(EmployeeRecord.objects.all())

# Do operations that change some records here
# No need to keep track of which records were changed

with ThreadPoolExecutor(max_workers=10) as executor:
    for record in all_records:
        executor.submit(record.save)

Or, if you want a really nice tqdm progress bar:

from tqdm import tqdm

with ThreadPoolExecutor(max_workers=10) as executor:
    for _ in tqdm(executor.map(lambda record: record.save(), all_records),
                  total=len(all_records), dynamic_ncols=True, unit='',
                  desc='Updating Airtable records'):
        pass

Pyrtable also has some extra tools to cache data and read authentication keys from external JSON/YAML files – check out the APIKeyFromSecretsFileMixin mixin class. Remember to never commit sensitive data to your repository, as Airtable authentication allows full R/W access to all your bases with a single API key!

Compatibility

Pyrtable is compatible with Python 3.8 and 3.9. Python 2.x is not supported at all.

Documentation

Technical documentation is available at https://pyrtable.readthedocs.io.

Questions, bug reports, improvements

Want to try it out, contribute, suggest, offer a hand? Great! The project is available at https://github.com/vilarneto/pyrtable.

License

Pyrtable is released under MIT license.

Copyright (c) 2020,2021 by Vilar Fiuza da Camara Neto

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyrtable-0.7.11.tar.gz (22.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyrtable-0.7.11-py3-none-any.whl (26.1 kB view details)

Uploaded Python 3

File details

Details for the file pyrtable-0.7.11.tar.gz.

File metadata

  • Download URL: pyrtable-0.7.11.tar.gz
  • Upload date:
  • Size: 22.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.4

File hashes

Hashes for pyrtable-0.7.11.tar.gz
Algorithm Hash digest
SHA256 f4f99740917efd4616e550182bb1589323dd64b0a927343c899a5867e2ff53bd
MD5 eccd56ea431f948de051ab676e4ac3af
BLAKE2b-256 47c5092fb30902e1ebee0e73f01f3ae86c3ded0209917698fb4deede7f3e1441

See more details on using hashes here.

File details

Details for the file pyrtable-0.7.11-py3-none-any.whl.

File metadata

  • Download URL: pyrtable-0.7.11-py3-none-any.whl
  • Upload date:
  • Size: 26.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.4

File hashes

Hashes for pyrtable-0.7.11-py3-none-any.whl
Algorithm Hash digest
SHA256 5e87ca1cc1f8ea85d05fb37396451fb7bb6c99c8ca043fc3854592840678af1a
MD5 491826d75d1f2561fb91f7bd0b927c8a
BLAKE2b-256 c413636af77161b15f732b67b6bc7755bba67fb2857ee07b7ff5bf77c1d5e24a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page