cl-airtable is a Common Lisp client for interacting with Airtable.
Current Features:
- List Records
- Create Records
Planned Features: More functionality will be added in future releases.
Supports both:
- β‘ Synchronous Requests (Blocking Calls)
- π Asynchronous Requests (Non-blocking with Blackbird Promises, ideal for Clack/Wookie setups)
Install cl-airtable:
cd ~/quicklisp/local-projects/ && git clone https://github.com/qubit55/cl-airtable.gitMake sure dependencies are loaded before usage.
(ql:quickload '(:cl-airtable :clack :ningle :shasht :serapeum :cl-dotenv))
(defpackage cl-airtable-tutorial
(:use :cl)
(:import-from :cl-airtable
#:airtable
#:base
#:table
#:select
#:create)
(:import-from :arrow-macros #:->)
(:import-from :shasht #:write-json)
(:import-from :serapeum
#:dict
#:toggle-pretty-print-hash-table)
(:local-nicknames (:bb :blackbird)))
(in-package :cl-airtable-tutorial)
(toggle-pretty-print-hash-table)Setup Database and Table:
(defparameter *airtable*
(-> (airtable :key "secret-key")
(base "base-name-or-id")))
(defparameter *test-table*
(-> *airtable*
(table "table-name-or-id")))Best for simple operations where blocking behavior is acceptable.
Create Records:
(-> *test-table*
(create :records (vector (dict "field-1" "a"
"field-2" "abc"
"field-3" "test@gmail.com"
"field-4" 1))))Select Records:
(-> *test-table*
(select :fields #("field-1" "field-2" "field-3" "field-4")
:max-records 20
:sort #(("field-4" "asc"))
:filter-by-formula (format nil "FIND(\"~A\" , {field-2})" "abc")
:page-size 18
:offset nil
:cell-format "string"
:time-zone "America/Indiana/Knox"
:user-locale "en-gb"
:return-fields-by-field-id t
:record-metadata #( "commentCount")))Perfect for web applications or event-driven systems. Set :async t to enable non-blocking behavior.
(defun test-async-create ()
(create *test-table*
:async t
:records (vector (dict "field-1" "a"
"field-2" "abc"
"field-3" "test@gmail.com"
"field-4" 2))))
(as:start-event-loop (lambda () (test-async-create)) :catch-app-errors t)(defun test-async-select ()
(bb:catcher
(bb:alet* ((response
(select *test-table*
:fields #("field-1" "field-2" "field-3" "field-4")
:async t))
(response-string (write-json response nil)))
(print response-string))
(error (e) (format t "Error in test-async-select: ~a~%" e))))
(as:start-event-loop (lambda () (test-async-select)) :catch-app-errors t)cl-airtable seamlessly integrates with web frameworks like Clack, Ningle, and uses Wookie as the backend.
Web Routes Setup:
(defvar *app* (make-instance 'ningle:app))
(setf (ningle:route *app* "/") "Welcome to Ningle!!!")Async Select Route:
(setf (ningle:route *app* "/airtable-async-select" :method :GET)
(lambda (params)
(declare (ignore params))
(lambda (responder)
(bb:catcher
(bb:alet* ((records
(-> *test-table*
(select :fields #("field-1" "field-2" "field-3" "field-4")
:max-records 20
:async t)))
(records-string (shasht:write-json records nil)))
(funcall responder `(200 (:content-type "application/json") (,records-string))))
(error (e) (format t "Error calling airtable-async-select endpoint: ~a~%" e))))))Async Create Route:
(setf (ningle:route *app* "/airtable-async-create" :method :GET)
#'(lambda (params)
(declare (ignore params))
(lambda (responder)
(bb:catcher
(bb:alet* ((response
(create
*test-table*
:async t
:records (vector (dict "field-1" "a"
"field-2" "abc"
"field-3" "test@gmail.com"
"field-4" 2)
(dict "field-1" "a"
"field-2" "abc"
"field-3" "test@gmail.com"
"field-4" 2)
(dict "field-1" "a"
"field-2" "abc"
"field-3" "test@gmail.com"
"field-4" 2))))
(response-str (write-json response nil)))
(print "Called /airtable-async-create")
(funcall responder `(200 (:content-type "application/json")
(,response-str))))
(error (e) (format t "Error calling /airtable-async-create endpoint: ~a~%" e))))))Start Server:
(defparameter *server*
(clack:clackup *app* :port 5030 :server :wookie :catch-app-errors t))
;; (clack:stop *server*) ;; To stop the serverπ API Documentation
(defun select (table &key fields sort filter-by-formula max-records page-size
offset view cell-format time-zone user-locale
return-fields-by-field-id record-metadata (async nil)))π API Documentation
(defun create (table &key records return-fields-by-field-id typecast (async nil)))- Anton Lobach π§ antonlobach@uri.com
Licensed under the MIT License.
Β©οΈ 2024 Anton Lobach