Interface

A number of functions have been added to make it a bit easier to interact with the Airtable API. These are built on top of the low-level interface, which is just a thin wrapper around the HTTP.jl functions.

Airtable.query function

If you are interested in retrieving records, your best bet is the Airtable.query function. Because the airtable API will only return 100 records per request[1], and only allows 5 requests/sec, query() automatically handles the "paging", pausing for 0.2 seconds in between each request so that you won't hit your limit.

At minimum, query() requires an AirTable (note the capital 'T'), which requires that you know the base name and table name for your air table. If you only pass the table, you will retrieve all of the records for that table.

julia> tab = AirTable("Table 1", AirBase("appphImnhJO8AXmmo"))
AirTable("Table 1")

julia> Airtable.query(tab)
3-element Vector{AirRecord}:
 AirRecord("recMc1HOSIxQPJyyc", AirTable("Table 1"), (Name = "Record 1", Notes = "Keep this\n", Status = "Todo", Keep = true))
 AirRecord("recMwT4P4tKlSLJoH", AirTable("Table 1"), (Name = "Record 2", Notes = "Also keep this", Status = "In progress", Keep = t
rue))
 AirRecord("recSStgr3yJnQc2Wg", AirTable("Table 1"), (Name = "Record 3", Status = "Done", Keep = true))

Here, the Credential is used automatically from the AIRTABLE_KEY environmental variable. As you can see, unlike the low-level functions that return JSON3.Objects, query() returns AirRecords

You may also pass additional query parameters (passed as keyword arguments) to filter, or otherwise modify the query.

julia> Airtable.query(tab; filterByFormula="{Status} = 'Todo'")
1-element Vector{AirRecord}:
 AirRecord("recMc1HOSIxQPJyyc", AirTable("Table 1"), (Name = "Record 1", Notes = "Keep this\n", Status = "Todo", Keep = true))

julia> Airtable.query(tab; filterByFormula="{Status} != 'Todo'")
2-element Vector{AirRecord}:
 AirRecord("recMwT4P4tKlSLJoH", AirTable("Table 1"), (Name = "Record 2", Notes = "Also keep this", Status = "In progress", Keep = t
rue))
 AirRecord("recSStgr3yJnQc2Wg", AirTable("Table 1"), (Name = "Record 3", Status = "Done", Keep = true))

For more information about usable query parameters, refer to the airtable documentation.

Airtable.AirBaseType
AirBase(id::String)

A wrapper for an Airtable Base, containing its unique identifier. The ID can be identified from the URL of the base (the part right after airtable.com), or by clicking HELP -> API documentation from within your base.

source
Airtable.AirRecordType
AirRecord(id::String, table::AirTable, fields::NamedTuple)

A wrapper for an Airtable Record, containing its unique identifier, parent AirTable, and values for any stored fields in a NamedTuple.

Typically, you won't crete these on your own, but they will be returned from API queries.

Field values can be accessed using getindex.

source
Airtable.queryFunction
Airtable.query(cred::Credential, baseid, tablename; query_kwargs...)

Shorthand for a "GET" request that handles continuation and rate-limiting.

The Airtable API will return a maximum of 100 records per requests, and only allows 5 requests / sec. This function uses the offset field returned as part of a requst that does not contain all possible records to make additional requests after pausing 0.21 seconds in between.

Required arguments:

  • cred: an Airtable.Credential containing your API key
  • baseid: the endpoint of your Airtable base. See https://airtable.com/api for details
  • tablename: the name of the table in your base (eg "Table 1")

Query parameters are in the form of keyword arguments, eg filterByFormla = "NOT({Name} = '')", maxRecords=2. See Airtable API reference for more information.

If you know the exact record id, pass that as a fourth positional argument

source

AirRecords

An AirRecord refers to a specific row of a specific table. Typically, you would not create records on your own, but they are returned from many of the API functions when you use types from Airtable.jl (as opposed to the low-level interface just using strings).

AirRecords contain fields, which refer to columns of the table. Any field values that are not set in the table are not included, But they can be accessed using getindex().

julia> rec = first(Airtable.query(tab))
AirRecord("recMc1HOSIxQPJyyc", AirTable("Table 1"), (Name = "Record 1", Notes = "Keep this\n", Status = "Todo", Keep = true))

julia> rec[:Name]
"Record 1"

julia> rec[:Status]
"Todo"

Adding or changing records

You can add or update records using Airtable.post! and Airtable.patch! respectively. Using post! requires an AirTable as the first argument, while patch! requires an AirRecord.

Using post!

To use post!, pass a table and a NamedTuple with the fields that you want to add. Note that if the fields don't already exist in the parent table, this will throw an error.

julia> new_rec = Airtable.post!(tab, (; Name = "Some Record", Notes = "It's a nice record"))
AirRecord("recYvPIayZx1okJ41", AirTable("Table 1"), (Name = "Some Record", Notes = "It's a nice record"))

Notice that the return value is an AirRecord. It can be useful to hold onto this, since it contains the unique identifier. You can also pass a vector of NamedTuples to create multiple records (post! will automatically limit 10 records at a time, in compliance with the Airtable API).

See the note about rate limits.

Using patch!

If you want to update an existing record, use patch!, with an AirRecord as the first argument, and a NamedTuple for the fields you want to change.

julia> Airtable.patch!(new_rec, (; Status="Done", Notes="It *was* a nice record"))
AirRecord("recYvPIayZx1okJ41", AirTable("Table 1"), (Name = "Some Record", Notes = "It *was* a nice record", Status = "Done"))

Any fields that you don't include will remain the same. If you want to clear a field, pass missing

julia> Airtable.patch!(new_rec, (; Status="Done", Notes=missing))
AirRecord("recYvPIayZx1okJ41", AirTable("Table 1"), (Name = "Some Record", Status = "Done"))

You can also pass a vector of AirRecords along with an equal-length vector of NamedTuples to patch multiple records at once (patch! will automatically limit to 10 records at a time, in compliance with the Airtable API).

Using delete!

To remove a record, simply pass an AirRecord with the same id to delete!.

julia> Airtable.delete!(new_rec)
JSON3.Object{Base.CodeUnits{UInt8, String}, Vector{UInt64}} with 2 entries:
  :deleted => true
  :id      => "recYvPIayZx1okJ41"

A note on rate limits

Airtable.com only allows 5 requests / sec. All functions that make requests will pause if more than 5 requests have been made in the previous second.

Functions and Types

Missing docstring.

Missing docstring for AirBase. Check Documenter's build log for details.

Missing docstring.

Missing docstring for AirTable. Check Documenter's build log for details.

Missing docstring.

Missing docstring for AirRecord. Check Documenter's build log for details.

Missing docstring.

Missing docstring for Airtable.query. Check Documenter's build log for details.

  • 1This is the default, you can change this with the pageSize parameter, but 100 is the maximum.