{"id":64,"library":"pyairtable","title":"pyAirtable Python SDK","description":"Official community Python client for the Airtable API. Formerly known as airtable-python-wrapper. Current version is 3.3.0 (Nov 2025). Has gone through major rewrites at 1.0, 2.0, and 3.0 — each with breaking changes. Many tutorials still reference the old airtable-python-wrapper package which is abandoned.","status":"active","version":"3.3.0","language":"python","source_language":"en","source_url":"https://github.com/gtalarico/pyairtable","tags":["airtable","api","spreadsheet","database","nocode","python"],"install":[{"cmd":"pip install pyairtable","lang":"bash","label":"Python (core)"},{"cmd":"pip install pyairtable[cli]","lang":"bash","label":"Python (with CLI and ORM generator)"}],"dependencies":[{"reason":"Pydantic 1.x support dropped in 3.x. Required for model validation.","package":"pydantic>=2.0","optional":false}],"imports":[{"note":"airtable-python-wrapper is the old abandoned package. pyairtable is the maintained successor. Do not confuse the two.","wrong":"from airtable import Airtable","symbol":"Api","correct":"from pyairtable import Api"},{"note":"Passing raw strings to Table() constructor is deprecated since 2.0. Always construct via Api instance.","wrong":"Table(api_key, base_id, table_name)","symbol":"Table","correct":"api = Api(api_key); table = api.table(base_id, table_name)"}],"quickstart":{"code":"from pyairtable import Api\n\napi = Api('YOUR_PERSONAL_ACCESS_TOKEN')  # not API key — deprecated\ntable = api.table('BASE_ID', 'TABLE_NAME')\n\n# fetch all records\nrecords = table.all()\n\n# create a record\ntable.create({'Name': 'New Row', 'Status': 'Active'})","lang":"python","description":"Minimal Airtable read/write using pyairtable 3.3.x."},"warnings":[{"fix":"Generate a Personal Access Token at airtable.com/create/tokens and use that instead. Scopes must be explicitly granted per base.","message":"Airtable deprecated legacy API keys in January 2024. They no longer work. All code using api_key='key...' strings will fail with 401.","severity":"breaking","affected_versions":"all"},{"fix":"pip install pyairtable — not airtable or airtable-python-wrapper.","message":"airtable-python-wrapper is the old abandoned package. Package name changed to pyairtable at 1.0.0. Installing airtable-python-wrapper gives you dead code.","severity":"breaking","affected_versions":"all"},{"fix":"pip install 'pydantic>=2.0'","message":"Pydantic 1.x support dropped in pyairtable 3.x. Will fail to import if Pydantic 1.x is installed.","severity":"breaking","affected_versions":">= 3.0.0"},{"fix":"api = Api(token); table = api.table(base_id, table_name)","message":"Table(api_key, base_id, table_name) constructor with raw strings deprecated in 2.0, raises TypeError in 3.0. Most tutorials and LLM-generated code still use this pattern.","severity":"breaking","affected_versions":">= 2.0.0"},{"fix":"Use api.base(base_id).schema() for metadata access.","message":"pyairtable.metadata module removed in 3.0. Any code importing from it will fail.","severity":"breaking","affected_versions":">= 3.0.0"},{"fix":"Check SaveResult.created or SaveResult.updated explicitly.","message":"Model.save() return type changed from bool to SaveResult in 3.x. Code checking 'if record.save():' will break silently — SaveResult is always truthy.","severity":"gotcha","affected_versions":">= 3.0.0"},{"fix":"Replace return_fields_by_field_id=True with use_field_ids=True.","message":"return_fields_by_field_id= parameter renamed to use_field_ids= in 3.x.","severity":"gotcha","affected_versions":">= 3.0.0"},{"fix":"Use Python 3.10+.","message":"Python 3.9 support dropped in 3.3.0 (Nov 2025).","severity":"deprecated","affected_versions":">= 3.3.0"},{"fix":"Verify that the BASE_ID and TABLE_NAME used in your code are correct and correspond to an existing Airtable base and table. Ensure the Personal Access Token has appropriate scopes and permissions to access the specified base and table.","message":"Airtable API returned 404 Not Found. This typically indicates an incorrect Base ID or Table Name in your configuration, or that the specified base/table does not exist or is not accessible with the provided token.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T06:21:13.710Z","next_check":"2026-07-17T00:00:00.000Z","problems":[{"fix":"Ensure `pyairtable` is installed (`pip install pyairtable`) and update your import statements to use `from pyairtable import Api` or `from pyairtable import Table`.","cause":"You are trying to import the deprecated `airtable-python-wrapper` library, or you have `pyairtable` installed but are using the old import syntax.","error":"ModuleNotFoundError: No module named 'airtable' OR ImportError: cannot import name 'Airtable' from 'airtable'"},{"fix":"Replace `table.get_all()` with `table.all()` to retrieve all records or `table.each()` for an iterator, and update other method calls according to the current `pyairtable` API documentation.","cause":"The method `get_all()` was part of the older `airtable-python-wrapper` or earlier `pyairtable` versions; it has been renamed or replaced in newer `pyairtable` releases (e.g., by `all()` or `each()`).","error":"AttributeError: 'Table' object has no attribute 'get_all'"},{"fix":"Verify that your API key/PAT is correct, has the required scopes (e.g., `data.records:read` for reading), and that you are using a Personal Access Token (API keys are deprecated). Ensure it's passed correctly, e.g., `api = Api('YOUR_PAT')` or via `os.environ['AIRTABLE_API_KEY']`.","cause":"Your Airtable API key or Personal Access Token (PAT) is invalid, missing, or lacks the necessary permissions for the requested operation or base.","error":"HTTP 401 Unauthorized OR HTTP 403 Forbidden"},{"fix":"Consult the `pyairtable` migration guide for your specific version change and update the `Table` or `Api` constructor calls. For `pyairtable` 2.0+, `Table` is typically instantiated as `Table(api_instance, base_id, table_name)` or `api.table(base_id, table_name)`.","cause":"The constructor signature for `pyairtable.Table` or `pyairtable.Api` has changed in a breaking release (e.g., from 1.x to 2.x or 2.x to 3.x), leading to an incorrect number of arguments being passed.","error":"TypeError: Table() takes X positional arguments but Y were given"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.78,"mem_mb":20.5,"disk_size":"32.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.75,"mem_mb":20.5,"disk_size":"32.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.27,"mem_mb":20.5,"disk_size":"32M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.27,"mem_mb":20.5,"disk_size":"32M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.38,"mem_mb":21.7,"disk_size":"35.1M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.32,"mem_mb":21.7,"disk_size":"36.0M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.98,"mem_mb":21.7,"disk_size":"35M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.92,"mem_mb":21.7,"disk_size":"36M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.19,"mem_mb":21.5,"disk_size":"26.6M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.16,"mem_mb":21.5,"disk_size":"27.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.18,"mem_mb":21.5,"disk_size":"26M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.2,"mem_mb":21.5,"disk_size":"27M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.69,"mem_mb":20.5,"disk_size":"26.2M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.67,"mem_mb":20.5,"disk_size":"27.1M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.73,"mem_mb":20.5,"disk_size":"26M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.71,"mem_mb":20.5,"disk_size":"27M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.7,"mem_mb":20.4,"disk_size":"31.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.63,"mem_mb":20.4,"disk_size":"32.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.5,"mem_mb":20.4,"disk_size":"31M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"cli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.5,"mem_mb":20.4,"disk_size":"32M"}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":-1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":-1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}