robogen / airtable.py
HaptalAI's picture
Initial RoboGen v1
f734d80 verified
Raw
History Blame Contribute Delete
2.1 kB
"""
airtable.py β€” email gate logging to Airtable.
Required env vars:
AIRTABLE_BASE_ID β€” e.g. "appXXXXXXXXXXXXXX"
AIRTABLE_API_KEY β€” personal access token ("pat...")
Table name is hardcoded as "RoboGen Leads". Change TABLE_NAME below if needed.
Failures are swallowed β€” caller receives a (success: bool, message: str) tuple
and must allow the download even if logging fails.
"""
import os
import json
import datetime
from typing import Tuple, Optional
try:
import requests
_REQUESTS_OK = True
except ImportError:
_REQUESTS_OK = False
TABLE_NAME = "RoboGen Leads"
_BASE_ID = os.environ.get("AIRTABLE_BASE_ID", "")
_API_KEY = os.environ.get("AIRTABLE_API_KEY", "")
def log_email(
email: str,
robot: str,
task: str,
n_episodes: int,
quality_score: float,
band: str,
) -> Tuple[bool, str]:
"""
POST one record to Airtable.
Returns (True, "Logged") on success, (False, reason) on failure.
Caller MUST still enable the download on failure.
"""
if not _REQUESTS_OK:
return False, "requests library not installed"
if not _BASE_ID or not _API_KEY:
return False, "AIRTABLE_BASE_ID / AIRTABLE_API_KEY not set"
endpoint = f"https://api.airtable.com/v0/{_BASE_ID}/{TABLE_NAME.replace(' ', '%20')}"
headers = {
"Authorization": f"Bearer {_API_KEY}",
"Content-Type": "application/json",
}
payload = {
"fields": {
"Email": email.strip(),
"Robot": robot,
"Task": task,
"Episodes": n_episodes,
"Quality Score": quality_score,
"Band": band,
"Timestamp": datetime.datetime.utcnow().isoformat() + "Z",
}
}
try:
resp = requests.post(endpoint, headers=headers, json=payload, timeout=6)
if resp.status_code in (200, 201):
return True, "Logged"
return False, f"HTTP {resp.status_code}: {resp.text[:200]}"
except Exception as exc:
return False, str(exc)