0
# PyAirtable
1
2
A comprehensive Python client library for interacting with the Airtable API. PyAirtable provides high-level classes for managing Airtable databases, tables, and records, with additional support for enterprise features, ORM-style models, formulas, testing utilities, and a command-line interface.
3
4
## Package Information
5
6
- **Package Name**: pyairtable
7
- **Language**: Python
8
- **Installation**: `pip install pyairtable`
9
- **PyPI**: https://pypi.org/project/pyairtable/
10
- **Documentation**: https://pyairtable.readthedocs.io/
11
12
## Core Imports
13
14
```python
15
from pyairtable import Api, Base, Table
16
```
17
18
Additional components:
19
20
```python
21
from pyairtable import Enterprise, Workspace, retry_strategy
22
from pyairtable.api import retrying # For retry strategy types
23
from pyairtable.api.types import UserAndScopesDict, BaseSchema # For type annotations
24
from pyairtable.formulas import Formula, AND, OR, match
25
from pyairtable.orm import Model, fields
26
from pyairtable.testing import MockAirtable, fake_record
27
```
28
29
## Basic Usage
30
31
```python
32
from pyairtable import Api
33
34
# Initialize API connection
35
api = Api('your_access_token')
36
37
# Get a table
38
table = api.table('app1234567890abcde', 'My Table')
39
40
# Create a record
41
new_record = table.create({'Name': 'John Doe', 'Email': 'john@example.com'})
42
print(f"Created record: {new_record['id']}")
43
44
# Retrieve all records
45
records = table.all()
46
for record in records:
47
print(f"{record['id']}: {record['fields']}")
48
49
# Update a record
50
updated = table.update(new_record['id'], {'Name': 'Jane Doe'})
51
52
# Delete a record
53
table.delete(new_record['id'])
54
```
55
56
## Architecture
57
58
PyAirtable follows a hierarchical API structure that mirrors Airtable's organization:
59
60
- **Api**: Top-level connection manager handling authentication and HTTP requests
61
- **Base**: Represents an Airtable base, manages tables and metadata
62
- **Table**: Individual tables within bases, provides CRUD operations for records
63
- **Enterprise**: Enterprise account management (Enterprise billing plans only)
64
- **Workspace**: Workspace management and base organization
65
66
Additional systems provide specialized functionality:
67
68
- **ORM**: Model-based approach with field definitions and automatic type conversion
69
- **Formulas**: Expression building for complex queries and filters
70
- **Testing**: Mock APIs and utilities for unit testing
71
- **CLI**: Command-line interface for direct API interaction
72
73
## Capabilities
74
75
### Core API Operations
76
77
Fundamental Airtable API access through Api, Base, and Table classes. Provides complete CRUD operations, authentication, retry strategies, and base/table management.
78
79
```python { .api }
80
class Api:
81
def __init__(self, api_key: str, *, timeout: Optional[tuple] = None,
82
retry_strategy: Optional[Union[bool, retrying.Retry]] = True,
83
endpoint_url: str = "https://api.airtable.com",
84
use_field_ids: bool = False): ...
85
def base(self, base_id: str, validate: bool = False, force: bool = False) -> Base: ...
86
def table(self, base_id: str, table_name: str, validate: bool = False, force: bool = False) -> Table: ...
87
def whoami(self) -> UserAndScopesDict: ...
88
89
class Base:
90
def table(self, id_or_name: str, validate: bool = False, force: bool = False) -> Table: ...
91
def tables(self, force: bool = False) -> list: ...
92
def schema(self, *, force: bool = False) -> BaseSchema: ...
93
94
class Table:
95
def all(self, **options) -> list: ...
96
def get(self, record_id: str, **options) -> dict: ...
97
def create(self, fields: dict, typecast: bool = False, use_field_ids: Optional[bool] = None) -> dict: ...
98
def update(self, record_id: str, fields: dict, replace: bool = False, typecast: bool = False, use_field_ids: Optional[bool] = None) -> dict: ...
99
def delete(self, record_id: str) -> dict: ...
100
```
101
102
[Core API Operations](./core-api.md)
103
104
### Record Operations
105
106
Advanced record handling including batch operations, upserts, pagination, filtering, and sorting. Supports complex queries and bulk data operations.
107
108
```python { .api }
109
def batch_create(self, records: list, typecast: bool = False, use_field_ids: Optional[bool] = None) -> list: ...
110
def batch_update(self, records: list, replace: bool = False, typecast: bool = False, use_field_ids: Optional[bool] = None) -> list: ...
111
def batch_upsert(self, records: list, key_fields: list, replace: bool = False, typecast: bool = False, use_field_ids: Optional[bool] = None) -> dict: ...
112
def batch_delete(self, record_ids: list) -> list: ...
113
def iterate(self, **options) -> Iterator: ...
114
def first(self, **options) -> Optional[dict]: ...
115
```
116
117
[Record Operations](./record-operations.md)
118
119
### Formula System
120
121
Comprehensive formula building and expression system with support for all Airtable formula functions, logical operators, comparisons, and field references.
122
123
```python { .api }
124
class Formula:
125
def __init__(self, value: str): ...
126
def flatten(self) -> Formula: ...
127
128
def AND(*components, **fields) -> Formula: ...
129
def OR(*components, **fields) -> Formula: ...
130
def NOT(component, **fields) -> Formula: ...
131
def match(field_values: dict, match_any: bool = False) -> Formula: ...
132
133
# Math functions
134
def SUM(number, *numbers) -> Formula: ...
135
def AVERAGE(number, *numbers) -> Formula: ...
136
def MAX(number, *numbers) -> Formula: ...
137
138
# Text functions
139
def CONCATENATE(text, *texts) -> Formula: ...
140
def FIND(string_to_find, where_to_search, start_from_position=None) -> Formula: ...
141
142
# Date functions
143
def DATEADD(date, number, units) -> Formula: ...
144
def DATETIME_FORMAT(date, output_format=None) -> Formula: ...
145
```
146
147
[Formula System](./formulas.md)
148
149
### ORM (Object-Relational Mapping)
150
151
Model-based approach to Airtable tables with field definitions, type validation, and automatic conversions. Provides Django-style model syntax for Python developers.
152
153
```python { .api }
154
class Model:
155
def __init__(self, **field_values): ...
156
def save(self) -> object: ...
157
def delete(self) -> bool: ...
158
def to_record(self) -> dict: ...
159
@classmethod
160
def from_record(cls, record: dict) -> Model: ...
161
@classmethod
162
def all(cls, **options) -> list: ...
163
164
# Field types
165
class TextField:
166
def __init__(self, field_name: str): ...
167
168
class NumberField:
169
def __init__(self, field_name: str): ...
170
171
class CheckboxField:
172
def __init__(self, field_name: str): ...
173
```
174
175
[ORM System](./orm.md)
176
177
### Enterprise Features
178
179
Enterprise account management including user administration, audit logging, workspace management, and organizational controls (requires Enterprise billing plan).
180
181
```python { .api }
182
class Enterprise:
183
def info(self, aggregated: bool = False, descendants: bool = False) -> object: ...
184
def user(self, id_or_email: str, collaborations: bool = True) -> object: ...
185
def users(self, ids_or_emails: list) -> list: ...
186
def audit_log(self, **kwargs) -> Iterator: ...
187
def remove_user(self, user_id: str, replacement: str = None) -> object: ...
188
189
class Workspace:
190
def create_base(self, name: str, tables: list) -> object: ...
191
def collaborators(self, force: bool = False) -> object: ...
192
def delete(self) -> None: ...
193
```
194
195
[Enterprise Features](./enterprise.md)
196
197
### Testing Utilities
198
199
Mock Airtable APIs and helper functions for unit testing applications that use pyAirtable. Provides fake data generation and API simulation.
200
201
```python { .api }
202
class MockAirtable:
203
def __init__(self, passthrough: bool = False): ...
204
def add_records(self, base_id: str, table_name: str, records: list) -> list: ...
205
def set_records(self, base_id: str, table_name: str, records: list) -> None: ...
206
207
def fake_record(fields: dict = None, id: str = None, **other_fields) -> dict: ...
208
def fake_user(value=None) -> dict: ...
209
def fake_attachment(url: str = "", filename: str = "") -> dict: ...
210
```
211
212
[Testing Utilities](./testing.md)
213
214
### Attachments
215
216
File upload and attachment management with support for multiple attachment fields, content type detection, and URL-based attachments.
217
218
```python { .api }
219
def upload_attachment(self, record_id: str, field: str, filename: str,
220
content: Optional[bytes] = None, content_type: str = None) -> dict: ...
221
```
222
223
[Attachment Management](./attachments.md)
224
225
### Comments and Collaboration
226
227
Record-level commenting system with user mentions, collaborative features, and comment management.
228
229
```python { .api }
230
def comments(self, record_id: str) -> list: ...
231
def add_comment(self, record_id: str, text: str) -> object: ...
232
233
class Comment:
234
def save(self) -> Comment: ...
235
def delete(self) -> bool: ...
236
```
237
238
[Comments and Collaboration](./comments.md)
239
240
### Webhooks
241
242
Webhook management for real-time notifications when data changes in Airtable bases.
243
244
```python { .api }
245
def webhooks(self) -> list: ...
246
def add_webhook(self, notify_url: str, spec: dict) -> object: ...
247
248
class Webhook:
249
# Webhook properties and methods
250
pass
251
```
252
253
[Webhook Management](./webhooks.md)
254
255
### Command Line Interface
256
257
Complete CLI for direct API interaction, base exploration, record management, and ORM code generation.
258
259
```python { .api }
260
# CLI commands available via: python -m pyairtable
261
# - whoami: Get current user information
262
# - bases: List all available bases
263
# - base <id> schema: Get base schema
264
# - base <id> table <name> records: Get table records
265
# - enterprise <id> users: List enterprise users
266
```
267
268
[Command Line Interface](./cli.md)
269
270
## Types
271
272
```python { .api }
273
# Record structure
274
RecordDict = {
275
"id": str, # Record ID starting with "rec"
276
"createdTime": str, # ISO 8601 datetime string
277
"fields": dict # Field name -> field value mapping
278
}
279
280
# Common field value types
281
FieldValue = Union[str, int, float, bool, list, dict, None]
282
283
# Attachment structure
284
AttachmentDict = {
285
"id": str, # Attachment ID starting with "att"
286
"url": str, # URL to access the attachment
287
"filename": str, # Original filename
288
"size": int, # File size in bytes
289
"type": str # MIME type
290
}
291
292
# User/Collaborator structure
293
CollaboratorDict = {
294
"id": str, # User ID starting with "usr"
295
"email": str, # User email address
296
"name": str # Display name
297
}
298
299
# Retry strategy for API requests
300
TimeoutTuple = tuple[int, int] # (connect_timeout, read_timeout)
301
```
302
303
## Error Handling
304
305
PyAirtable provides a comprehensive exception hierarchy for different error scenarios:
306
307
```python { .api }
308
class PyAirtableError(Exception):
309
"""Base class for all exceptions raised by PyAirtable."""
310
311
class CircularFormulaError(PyAirtableError, RecursionError):
312
"""A circular dependency was encountered when flattening nested conditions."""
313
314
class InvalidParameterError(PyAirtableError, ValueError):
315
"""Raised when invalid parameters are passed to all(), first(), etc."""
316
317
class MissingValueError(PyAirtableError, ValueError):
318
"""A required field received an empty value, either from Airtable or other code."""
319
320
class MultipleValuesError(PyAirtableError, ValueError):
321
"""SingleLinkField received more than one value from either Airtable or calling code."""
322
323
class ReadonlyFieldError(PyAirtableError, ValueError):
324
"""Attempted to set a value on a readonly field."""
325
326
class UnsavedRecordError(PyAirtableError, ValueError):
327
"""Attempted to perform an unsupported operation on an unsaved record."""
328
```
329
330
Usage example:
331
332
```python
333
import requests
334
from pyairtable import Api
335
from pyairtable.exceptions import PyAirtableError, InvalidParameterError
336
337
try:
338
api = Api('invalid_token')
339
records = api.table('base_id', 'table_name').all()
340
except requests.exceptions.HTTPError as e:
341
print(f"HTTP Error: {e}")
342
except InvalidParameterError as e:
343
print(f"Invalid Parameter: {e}")
344
except PyAirtableError as e:
345
print(f"PyAirtable Error: {e}")
346
```
347
348
Common HTTP exception types include authentication errors (401), permission errors (403), not found errors (404), and rate limiting (429).