This repository enables bidirectional syncing between Airtable and resources related to the NF Data Portal. Specifically, this syncs Synapse projects and associated metadata from the NF Data Portal to an Airtable base for easier viewing and management.
- Bidirectional Syncing:
- Synapse → Airtable: Syncs data from Synapse table
syn52677631to an Airtable table - Airtable → Synapse: Syncs data from Airtable back to Synapse table
- Synapse → Airtable: Syncs data from Synapse table
- Automated Workflows: GitHub Actions workflows for scheduled and manual syncing in both directions
- Incremental Updates: Supports updating existing records based on a key field (prevents duplicates)
- Data Type Conversion: Automatically handles date conversions, text fields, and array/list data
- Python 3.10 or higher
- Airtable Personal Access Token (PAT)
- Synapse Personal Access Token (PAT)
- Airtable Base ID and Table Name
- Clone this repository:
git clone <repository-url>
cd nf-airtable- Create a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install dependencies:
pip install -r requirements.txt- Create credentials file:
cp example_creds.yaml creds.yaml- Edit
creds.yamlwith your credentials:
AIRTABLE_PAT: "patYourTokenHere"
SYNAPSE_PAT: "yourSynapseTokenHere"Before running regular syncs, you need to create the Airtable table. Use the setup script to automatically create the table structure from your Synapse table:
export AIRTABLE_BASE_ID="your_base_id"
export AIRTABLE_TABLE_NAME="Your Table Name" # Optional, defaults to Synapse table name
python setup_airtable_table.pyThe setup script will:
- Check if the table already exists (if so, skips creation)
- Fetch the schema from your Synapse table
- Attempt to create the table in Airtable automatically using the Metadata API
- If automatic creation isn't possible, it will print detailed instructions for manual creation
- Perform an initial data sync to populate the table with all existing data from Synapse
Setup Script Options:
--skip-table-creation: Skip table creation (assumes table already exists)--skip-data-sync: Skip initial data sync (only create table structure)--table-name: Specify a custom table name
Example:
# Create table structure only (no data sync)
python setup_airtable_table.py --skip-data-sync
# Sync data only (table already exists)
python setup_airtable_table.py --skip-table-creationRun the sync script to sync from Synapse to Airtable:
export AIRTABLE_BASE_ID="your_base_id"
export AIRTABLE_TABLE_NAME="Your Table Name"
export SYNAPSE_KEY_FIELD="id" # Required: field to match existing records (prevents duplicates)
python sync_synapse_to_airtable.pyRun the sync script to sync from Airtable back to Synapse:
export AIRTABLE_BASE_ID="your_base_id"
export AIRTABLE_TABLE_NAME="Your Table Name"
export SYNAPSE_KEY_FIELD="id" # Required: field to match existing records (prevents duplicates)
python sync_airtable_to_synapse.pyAIRTABLE_BASE_ID(required): Your Airtable base IDAIRTABLE_TABLE_NAME(required): Name of the Airtable table to sync toSYNAPSE_KEY_FIELD(required): Field name to use for matching existing records for updates (prevents duplicate records)SYNAPSE_TABLE_ID(optional): Synapse table ID (defaults tosyn52677631)
The repository includes GitHub Actions workflows for bidirectional syncing:
-
Synapse → Airtable (
sync_synapse_to_airtable.yml):- Scheduled: Runs daily at 2 AM UTC
- Manual Trigger: Can be triggered manually from the Actions tab
-
Airtable → Synapse (
sync_airtable_to_synapse.yml):- Scheduled: Runs daily at 3 AM UTC (after Synapse → Airtable sync)
- Manual Trigger: Can be triggered manually from the Actions tab
Add the following secrets to your GitHub repository:
- Go to Settings → Secrets and variables → Actions
- Add the following secrets:
AIRTABLE_PAT: Your Airtable Personal Access TokenSYNAPSE_PAT: Your Synapse Personal Access TokenAIRTABLE_BASE_ID: Your Airtable base IDAIRTABLE_TABLE_NAME: Name of your Airtable tableSYNAPSE_KEY_FIELD: (Required) Field name for matching records (prevents duplicates)SYNAPSE_TABLE_ID: (Optional) Synapse table ID (defaults to syn52677631)
- Fetch from Synapse: The script queries the specified Synapse table and retrieves all records
- Transform Data:
- Converts epoch milliseconds to ISO date strings for date fields
- Converts USERID/ENTITYID fields to strings
- Handles lists/arrays by converting to comma-separated strings
- Sync to Airtable:
- Uses
SYNAPSE_KEY_FIELDto match existing records by their key field value - Updates existing records if found
- Creates new records for entries that don't exist
- Prevents duplicate records by requiring a unique key field
- Uses
- Fetch from Airtable: The script retrieves all records from the specified Airtable table
- Transform Data:
- Converts ISO date strings back to epoch milliseconds for date fields
- Ensures text fields (USERID/ENTITYID) are properly formatted
- Handles comma-separated strings and arrays
- Sync to Synapse:
- Uses
SYNAPSE_KEY_FIELDto match existing records by their key field value - Updates existing records if found
- Creates new records for entries that don't exist
- Prevents duplicate records by requiring a unique key field
- Uses
Before running the sync, ensure your Airtable base has:
- A table with the same column names as your Synapse table (or configure field mapping)
- Appropriate field types for the data being synced
- If using incremental updates, ensure the key field is unique
- Authentication Errors: Verify your PATs are correct and have appropriate permissions
- Table Not Found: Ensure the Airtable table name matches exactly (case-sensitive)
- Field Mismatches: Ensure Airtable table has columns matching Synapse table column names
The script provides detailed logging. Check the output for:
- Connection status
- Number of records fetched
- Sync statistics (created/updated/errors)
- Field mapping configuration
- Conflict resolution strategies
- Webhook support for real-time syncing
- Selective field syncing (sync only specific fields)
- Sync direction configuration (one-way or bidirectional)
See LICENSE file for details.