Title: | Interface to the Airtable API |
---|---|
Description: | Fork from Darko Bergant's package. Provides access to the Airtable (airtable.com) API. |
Authors: | Darko Bergant |
Maintainer: | Collin Schwantes <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.2.16 |
Built: | 2024-10-24 02:58:08 UTC |
Source: | https://github.com/ecohealthalliance/airtabler |
Provides access to the Airtable API (http://airtable.com/api).
Create and configure the schema of an Airtable base on (http://airtable.com) and check the API on http://airtable.com/api.
Generate the Airtable API token from your Airtable account page (http://airtable.com/create/tokens).
airtabler functions will read the API key from
environment variable AIRTABLE_API_KEY
. To start R session with the
initialized environment variable create an .Renviron
file in your R home
with a line like this:
AIRTABLE_API_KEY=************
To check where your R home is, try normalizePath("~")
.
The usethis and dotenv packages are useful for setting environment
variables.
usethis::edit_r_environ
allow you to modify the .Renviron
file.
dotenv::load_dot_env
allows you to load environment variables from a
.env
file. This second approach is especially helpful if you work
with multiple tokens.
Use airtable
function to get airtable base object
or just call primitives air_get
, air_insert
,
air_update
and air_delete
to access your
airtable data.
Descriptive metadata provides information about the base as a whole, who created it, why, when, where can data be accessed, keywords, what license governs data use, etc. Descriptive metadata facilitates data reuse by providing a point of contact for future users, as well as attributes that allow the data to be entered into searchable catalogs or archives.
air_create_description_table( base, description, table_name = "Description", field_descriptions = NA, type = "singleLineText", options = NA )
air_create_description_table( base, description, table_name = "Description", field_descriptions = NA, type = "singleLineText", options = NA )
base |
String. Base id |
description |
Data frame. Description from air_get_base_description* or air_generate_base_description |
table_name |
String. Name of description table |
field_descriptions |
Character vector. Descriptions of metadata table fields. If NA, DCMI terms will be used where possible. |
type |
Character vector. Column types for metadata table fields. see https://airtable.com/developers/web/api/field-model |
options |
Data frame. Options for fields in metadata table. |
DCMI terms can be found here https://www.dublincore.org/specifications/dublin-core/dcmi-terms/
List. Outputs from creating the table and inserting the records
## Not run: base = "appVjIfAo8AJlfTkx" table_name= "description" description <- air_generate_base_description(title = "Example Base", creator = "Collin Schwantes") air_create_description_table(base,description,table_name) ## End(Not run)
## Not run: base = "appVjIfAo8AJlfTkx" table_name= "description" description <- air_generate_base_description(title = "Example Base", creator = "Collin Schwantes") air_create_description_table(base,description,table_name) ## End(Not run)
See https://airtable.com/developers/web/api/create-field
air_create_field( base, table_id, name, description = NA, type = "singleLineText", options = NA )
air_create_field( base, table_id, name, description = NA, type = "singleLineText", options = NA )
base |
String. Base id |
table_id |
String. Table id. Can be found using |
name |
String. Name of the field |
description |
String. Description of the field |
type |
String. Type of field. See https://airtable.com/developers/web/api/field-model |
options |
Data frame. See https://airtable.com/developers/web/api/field-model |
description of newly created field as a list
## Not run: base_schema <- air_get_schema(base) base_schema$tables air_create_field(base,table_id = base_schema$tables$id[[4]], name = "Has Nucleics", description = "Logical. Does this planet have nucleics?", type = "checkbox", options = list( list( "color"= "greenBright", "icon"= "check" ) ) ) ## End(Not run)
## Not run: base_schema <- air_get_schema(base) base_schema$tables air_create_field(base,table_id = base_schema$tables$id[[4]], name = "Has Nucleics", description = "Logical. Does this planet have nucleics?", type = "checkbox", options = list( list( "color"= "greenBright", "icon"= "check" ) ) ) ## End(Not run)
Create a new structural metadata table in the base
air_create_metadata_table( base, meta_data, table_name = "Meta Data", field_descriptions = NA, type = "singleLineText", options = NA )
air_create_metadata_table( base, meta_data, table_name = "Meta Data", field_descriptions = NA, type = "singleLineText", options = NA )
base |
String. Base id |
meta_data |
Data frame. Contains metadata records. From air_generate_metadata* |
table_name |
String. name of the metadata table. default is "Meta Data" |
field_descriptions |
Character vector. Descriptions of metadata table fields |
type |
Character vector. Column types for metadata table fields. see https://airtable.com/developers/web/api/field-model |
options |
Data frame. Options for fields in metadata table. |
Structural metadata describes the contents of your base and how they are linked. Structural metadata can largely be derived from the base schema.
List with outcome from creating the table and inserting the records
## Not run: # set base id base <- "appXXXXXXXX" # create metadata from api metadata <- air_generate_metadata_from_api(base) # add Meta Data table to base -- will not work if base already has a metadata # table log <- air_create_metadata_table(base,metadata) ## End(Not run)
## Not run: # set base id base <- "appXXXXXXXX" # create metadata from api metadata <- air_generate_metadata_from_api(base) # add Meta Data table to base -- will not work if base already has a metadata # table log <- air_create_metadata_table(base,metadata) ## End(Not run)
Takes a list object with appropriate arguments (see air_table_template
)
converts it to JSON then adds it to the specified base.
air_create_table(base, table_list)
air_create_table(base, table_list)
base |
String. ID for the base |
table_list |
List. see |
Data frame of table schema
See https://airtable.com/developers/web/api/create-table
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df<- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) table_list <- air_table_template(table_name = "Planet", description = "Planets of Foundation", fields_df = field_df) air_create_table(base, table_list) ## End(Not run)
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df<- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) table_list <- air_table_template(table_name = "Planet", description = "Planets of Foundation", fields_df = field_df) air_create_table(base, table_list) ## End(Not run)
Deletes a record and returns the deleted record id if the call succeeded.
air_delete(base, table_name, record_id)
air_delete(base, table_name, record_id)
base |
Airtable base |
table_name |
Table name |
record_id |
Id of the record to be deleted |
Download an attachment stored in air tables. Returns original dataframe with an additional field called attachment_file_paths. The attachment_file_paths field is of class list so it can handle multiple attachments per record. File paths are prepended with record ids so that all file names are unique.
air_download_attachments( x, field, dir_name = "downloads", include_attachment_id = TRUE, ... )
air_download_attachments( x, field, dir_name = "downloads", include_attachment_id = TRUE, ... )
x |
Data frame. Output from air_get or fetch_all. |
field |
String. Name of field with file attachments in base |
dir_name |
String. Where should files be downloaded to? Will create the folder if it does not exist. Folders created are recursively. |
include_attachment_id |
Logical. Should you include the airtable attachment ID to guarantee all file names are unique? Default is true. |
... |
reserved for additional arguments. |
Returns x with an additional field called attachment_file_paths
## Not run: base <- "appXXXXXXXXX" table_name <- "Table With Attachments" table_original <- air_get(base,table_name) table_with_file_paths <- air_download_attachments(x = table_with_attachments, field = "attachment_field", dir_name = "downloads") table_with_file_paths$attachment_file_paths ## End(Not run)
## Not run: base <- "appXXXXXXXXX" table_name <- "Table With Attachments" table_original <- air_get(base,table_name) table_with_file_paths <- air_download_attachments(x = table_with_attachments, field = "attachment_field", dir_name = "downloads") table_with_file_paths$attachment_file_paths ## End(Not run)
Dump all tables from a base into R
air_dump( base, metadata = NULL, description = NULL, add_missing_fields = TRUE, download_attachments = TRUE, attachment_fields = NULL, polite_downloads = TRUE, field_names_to_snakecase = TRUE, ... )
air_dump( base, metadata = NULL, description = NULL, add_missing_fields = TRUE, download_attachments = TRUE, attachment_fields = NULL, polite_downloads = TRUE, field_names_to_snakecase = TRUE, ... )
base |
String. ID for your base from Airtable. Generally 'appXXXXXXXXXXXXXX' |
metadata |
Data.frame.Data frame with structural metadata - describes relationship between tables and fields. Can be left as NULL if base already contains a table called meta data. |
description |
Data.frame. Data frame with descriptive metadata - describes whats in your base and who made it. Can be left as NULL if base already contains a table called description. |
add_missing_fields |
Logical. Should fields described in the metadata data.frame be added to corresponding tables? |
download_attachments |
Logical. Should attached files be downloaded? |
attachment_fields |
Optional. character vector. What field(s) should files be downloaded from? Default is to download all fields with type multipleAttachments in metadata. |
polite_downloads |
Logical. Use if downloading many files. Sets a delay so that server is not overwhelmed by requests. |
field_names_to_snakecase |
Logical. Should field names be converted to snake case? |
... |
Additional arguments to pass to air_download_attachments |
List of data.frames. All tables from metadata plus the description and metadata tables.
To facilitate joining on ids, see purrr::as_vector for converting list type columns to vectors and tidyr::unnest for expanding list columns.
Saves data.frames from air_dump to csv files. File names are determined by
the names of the list objects from air_dump. Files will be saved in folder
with a unique name, inside the folder specified by output_dir
. The
unique name is generated from a hash of the air_dump output.
air_dump_to_csv( table_list, output_dir = "outputs", attachments_dir = NULL, overwrite = FALSE, output_id = NULL, names_to_snake_case = TRUE )
air_dump_to_csv( table_list, output_dir = "outputs", attachments_dir = NULL, overwrite = FALSE, output_id = NULL, names_to_snake_case = TRUE )
table_list |
List. List of data.frames output from |
output_dir |
String. Folder containing output files |
attachments_dir |
String. What folder are base attachments stored in? |
overwrite |
Logical. Should outputs be overwritten if they already exist? |
output_id |
String. Optional identifier for the data set - if NULL an ID will be generated using a hash of the data. |
names_to_snake_case |
Logical. Should field and table names be converted to snake_case? |
Vector of file paths
Essentially air_get without converting to Rs. Does not add fields with empty values.
air_dump_to_json( base, metadata, description = NULL, output_dir = "outputs", overwrite = FALSE )
air_dump_to_json( base, metadata, description = NULL, output_dir = "outputs", overwrite = FALSE )
base |
String. ID for your base from Airtable. Generally 'appXXXXXXXXXXXXXX' |
metadata |
Data.frame.Data frame with structural metadata - describes relationship between tables and fields. |
description |
Data.frame. Data frame with descriptive metadata - describes whats in your base and who made it. Can be left as NULL if base already contains a table called description |
output_dir |
String. Where should json files be saved? |
overwrite |
Logical. If data are not unique, should files be overwritten? |
List of data.frames. All tables from metadata plus the description and metadata tables.
This function helps users work with airtable data that has been exported to CSVs. Because airtable uses nested data structures (json arrays), the data must be flattened to be stored in a csv. The standard way to store arrays in a csv is to wrap the array in quotes and separate each item with commas. So an array stored in a csv would look like "item 1,item 2,...,item n". This function will convert arrays stored in csvs to either a list or a vector and removes the surrounding quotes.
air_expand_csv_arrays(x, simplify_to_vector = FALSE)
air_expand_csv_arrays(x, simplify_to_vector = FALSE)
x |
Character. likely a vector or field in a dataframe. |
simplify_to_vector |
Logical. Should expanded arrays be converted from lists to vectors? For lists with multiple elements at a given position, the length of the output may be greater than the length of the input. See [tidyr::unnest()] for expanding list columns. |
A vector or list of expanded arrays.
# example vector data x <- c("item 1,item 2,item 3","apple,orange,banana","1,2,3","") # to list air_expand_csv_arrays(x) # to vector air_expand_csv_arrays(x,simplify_to_vector = TRUE)
# example vector data x <- c("item 1,item 2,item 3","apple,orange,banana","1,2,3","") # to list air_expand_csv_arrays(x) # to vector air_expand_csv_arrays(x,simplify_to_vector = TRUE)
Convenience function for creating the content of tables that will created or updated viaAPI.
air_fields_df_template(name, description, type, options = NA)
air_fields_df_template(name, description, type, options = NA)
name |
String. Names of fields in the table |
description |
String. Descriptions of fields |
type |
String. Type of columns. For values see https://airtable.com/developers/web/api/model/field-type |
options |
List. Options will be converted from lists to JSON. For field options see https://airtable.com/developers/web/api/field-model |
Tibble with attributes required for fields in a table
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df<- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) table_list <- air_table_template(table_name = "Planet", description = "Planets of Foundation", fields_df = field_tables) air_create_table(base, table_list) ## End(Not run)
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df<- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) table_list <- air_table_template(table_name = "Planet", description = "Planets of Foundation", fields_df = field_tables) air_create_table(base, table_list) ## End(Not run)
Converts the field data frame to a list of easier translation to JSON
air_fields_list_from_template(df)
air_fields_list_from_template(df)
df |
Data frame. From air_fields_df_template |
List. Structured for easy parsing into JSON
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df <- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) fields_list <- air_fields_list_from_template(df = fields_df) ## End(Not run)
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df <- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) fields_list <- air_fields_list_from_template(df = fields_df) ## End(Not run)
Creates a data.frame that describes the base. Descriptive metadata provides information about the base as a whole: who created it, why, when, where can data be accessed, keywords, what license governs data use, etc. Descriptive metadata facilitates data reuse by providing a point of contact for future users, as well as attributes that allow the data to be entered into searchable catalogs or archives.
air_generate_base_description( title = NA, creator = NA, created = NA, primary_contact = NA, email = NA, description = NA, contributor = NA, identifier = NA, license = NA, ... )
air_generate_base_description( title = NA, creator = NA, created = NA, primary_contact = NA, email = NA, description = NA, contributor = NA, identifier = NA, license = NA, ... )
title |
String. Title is a property that refers to the name or names by which a resource is formally known. |
creator |
String. Person or people who created the base |
created |
String. When was the base created? |
primary_contact |
String. Person or entity primarily responsible for making the content of a resource |
email |
String. Email of primary_contact |
description |
String. This property refers to the description of the content of a resource. The description is a potentially rich source of indexable terms and assist the users in their selection of an appropriate resource. |
contributor |
String. An entity responsible for making contributions to the resource. |
identifier |
String. An unambiguous reference to the resource within a given context. |
license |
String. A legal document giving official permission to do something with the resource. "CC BY 4.0" |
... |
String. Additional descriptive metadata elements. See details.
Additional elements can be added as name pair values e.g.
|
See dublin core for inspiration about additional attributes.
data.frame with descriptive metadata
air_generate_base_description(title = "My Awesome Base" , primary_contact= "Base Creator/Maintainer", email = "[email protected]", base_description = "This base contains my awesome data from a project studying XXX in YYY. Data in the base were collected from 1900-01-01 to 1990-01-01 by researchers at Some Long Term Project.", is_part_of = "https://doi.org/10.48321/MyDMP01", isReferencedBy = "https://doi.org/10.5072/zenodo_sandbox.1062705" )
air_generate_base_description(title = "My Awesome Base" , primary_contact= "Base Creator/Maintainer", email = "[email protected]", base_description = "This base contains my awesome data from a project studying XXX in YYY. Data in the base were collected from 1900-01-01 to 1990-01-01 by researchers at Some Long Term Project.", is_part_of = "https://doi.org/10.48321/MyDMP01", isReferencedBy = "https://doi.org/10.5072/zenodo_sandbox.1062705" )
Structural metadata describes the contents of your base and how they are linked.
The structural metadata are created from the base schema. The nested schema
structure is flattened into a more user-friendly table which can then be
inserted as a table into the base with air_created_metadata_table
and/or
used in a data export with air_dump
.
air_generate_metadata_from_api( base, metadata_table_name = "Meta Data", include_metadata_table = FALSE, field_names_to_snake_case = TRUE )
air_generate_metadata_from_api( base, metadata_table_name = "Meta Data", include_metadata_table = FALSE, field_names_to_snake_case = TRUE )
base |
String. Base id |
metadata_table_name |
String. Name of exisiting structural metadata table if it exists |
include_metadata_table |
Logical. Should the structural metadata table be included in the metadata? |
field_names_to_snake_case |
Logical. Should the field names in the metadata table be snake_case? |
This function requires that the api token has the ability to read the base schema.
A data frame with metadata
## Not run: base <- "appXXXXXXXX" metadata <- air_generate_metadata_from_api(base) ## End(Not run)
## Not run: base <- "appXXXXXXXX" metadata <- air_generate_metadata_from_api(base) ## End(Not run)
Deprecated: Use air_generate_metadata_from_api
air_generate_metadata_from_tables(base, table_names, limit = 1)
air_generate_metadata_from_tables(base, table_names, limit = 1)
base |
String. ID for your base from Airtable. Generally 'appXXXXXXXXXXXXXX' |
table_names |
Vector of strings. The names of your tables. eg c("table 1","table 2", etc.) |
limit |
Number from 1-100. How many rows should we pull from each table to create the metdata? Keep in mind that the airtable api will not return fields with "empty" values - "", false, or []. Code runs faster if fewer rows are pulled. |
Generates a structural metadata table - the metadata that describes how tables and fields fit together. Does not include field types.
For information about creating metadata tables in your base see the EHA MA Handbook
data.frame with structural metadata.
Retrieve records or a single record from a table. If you provide a record_id, you cannot specify fields, views, or filterFormulas.
air_get( base, table_name, record_id = NULL, limit = NULL, offset = NULL, view = NULL, fields = NULL, sortField = NULL, sortDirection = NULL, filterByFormula = NULL, combined_result = TRUE )
air_get( base, table_name, record_id = NULL, limit = NULL, offset = NULL, view = NULL, fields = NULL, sortField = NULL, sortDirection = NULL, filterByFormula = NULL, combined_result = TRUE )
base |
Airtable base |
table_name |
Table name |
record_id |
(optional) Use record ID argument to retrieve an existing record details. See https://airtable.com/developers/web/api/get-record |
limit |
(optional) A limit on the number of records to be returned. Limit can range between 1 and 100. |
offset |
(optional) Page offset returned by the previous list-records call. Note that this is represented by a record ID, not a numerical offset. |
view |
(optional) The name or ID of the view |
fields |
List. (optional) Only data for fields whose names are in this list
will be included in the records. Does not work when retrieving individual records with |
sortField |
(optional) The field name to use for sorting |
sortDirection |
(optional) "asc" or "desc". The sort order in which the records will be returned. Defaults to asc. |
filterByFormula |
String. Use a formula to filter results. See https://support.airtable.com/hc/en-us/articles/223247187-How-to-sort-filter-or-retrieve-ordered-records-in-the-API this parameter to reduce the amount of data transferred. |
combined_result |
If TRUE (default) all data is returned in the same data.
If FALSE table fields are returned in separate |
You can retrieve records in an order of a view by providing the name or ID of the view in the view query parameter. The results will include only records visible in the order they are displayed.
A data frame with records or a list with record details if
record_id
is specified.
Extract the contents of an attachment stored in Airtable. Currently only setup to work with Excel files. Planned expansion to other file types. For excel files, returns a named list.
air_get_attachments( base, table_name, field, download_file = FALSE, include_attachment_id = TRUE, dir_name = "downloads", extract_type = "excel", extract_field = "excel_extract", skip = 0, parse_all_sheets = FALSE, ... )
air_get_attachments( base, table_name, field, download_file = FALSE, include_attachment_id = TRUE, dir_name = "downloads", extract_type = "excel", extract_field = "excel_extract", skip = 0, parse_all_sheets = FALSE, ... )
base |
String. ID for the base or app to be fetched |
table_name |
String. Name of the table to be fetched from the base |
field |
String. Name of field with file attachments in base |
download_file |
Logical. Should files be downloaded? |
include_attachment_id |
Logical. Should the attachment ID be included in the file name? Default is true to ensure unique file names. |
dir_name |
String. Where should files be downloaded to? Will create the folder if it does not exist. |
extract_type |
String. File type to be extracted. Should be one of: excel |
extract_field |
String. Name of extract field that will be created |
skip |
Numeric. How many lines should be skipped? See |
parse_all_sheets |
Logical. Should all sheets in spreadsheet be parsed? |
... |
Additional arguments to pass to |
named list of data frames
air_download_attachments
## Not run: base <- "appXXXXXXXXX" table_name <- "table with excel attachments" table_with_attachments <- air_get_attachments(base,table_name, field = "attachment_field" ) ## End(Not run)
## Not run: base <- "appXXXXXXXXX" table_name <- "table with excel attachments" table_with_attachments <- air_get_attachments(base,table_name, field = "attachment_field" ) ## End(Not run)
Pull a table that has descriptive metadata. Requires the following fields: "title","primary_contact","email","description"
air_get_base_description_from_table( base, table_name, field_names_to_snakecase = TRUE )
air_get_base_description_from_table( base, table_name, field_names_to_snakecase = TRUE )
base |
String. ID for your base from Airtable. Generally 'appXXXXXXXXXXXXXX' |
table_name |
String. Name of descriptive metadata table - the metadata that describes the base and provides attribution |
field_names_to_snakecase |
Logical. Should field names be converted to snakecase? |
data.frame with descriptive metadata.
## Not run: base <- "appXXXXXXXX" table_name <- "Description" air_get_base_description_from_table(base, table_name) ## End(Not run)
## Not run: base <- "appXXXXXXXX" table_name <- "Description" air_get_base_description_from_table(base, table_name) ## End(Not run)
General function for parsing airtable URLs to find base, table, view, or record id's
air_get_id_from_url(url, pattern, id_type, split_pattern = "/|\\?") air_get_base_id_from_url(url, pattern = "^app\\w{13}") air_get_table_id_from_url(url, pattern = "^tbl\\w{13}") air_get_view_id_from_url(url, pattern = "^viw\\w{13}") air_get_record_id_from_url(url, pattern = "^rec\\w{13}")
air_get_id_from_url(url, pattern, id_type, split_pattern = "/|\\?") air_get_base_id_from_url(url, pattern = "^app\\w{13}") air_get_table_id_from_url(url, pattern = "^tbl\\w{13}") air_get_view_id_from_url(url, pattern = "^viw\\w{13}") air_get_record_id_from_url(url, pattern = "^rec\\w{13}")
url |
String. A url generated by airtable |
pattern |
String. A regex pattern for identifying the type of id you would like to get |
id_type |
String. One of base_id, table_id, view_id, or record_id. |
split_pattern |
String. Where should the URL be split? default is forward slashes "/" and questionmarks "?" |
String
air_get_base_id_from_url()
: Get the base id
air_get_table_id_from_url()
: Get the table id
air_get_view_id_from_url()
: Get the view id
air_get_record_id_from_url()
: Get the record id
url <- "https://airtable.com/apphDEokVZ9gvPNFk/tblaKC1ADBafoHVXN/viwteUgD7vaMBruHR/recMzdoM43RVRWybD?blocks=hide" # General function for parsing url components air_get_id_from_url(url, '^app',id_type = "base_id") # Get different components air_get_base_id_from_url(url) air_get_table_id_from_url(url) air_get_view_id_from_url(url) air_get_record_id_from_url(url)
url <- "https://airtable.com/apphDEokVZ9gvPNFk/tblaKC1ADBafoHVXN/viwteUgD7vaMBruHR/recMzdoM43RVRWybD?blocks=hide" # General function for parsing url components air_get_id_from_url(url, '^app',id_type = "base_id") # Get different components air_get_base_id_from_url(url) air_get_table_id_from_url(url) air_get_view_id_from_url(url) air_get_record_id_from_url(url)
Returns JSON objects from GET requests
air_get_json( base, table_name, record_id = NULL, limit = NULL, offset = NULL, view = NULL, fields = NULL, sortField = NULL, sortDirection = NULL, combined_result = TRUE, pretty = FALSE )
air_get_json( base, table_name, record_id = NULL, limit = NULL, offset = NULL, view = NULL, fields = NULL, sortField = NULL, sortDirection = NULL, combined_result = TRUE, pretty = FALSE )
base |
Airtable base |
table_name |
Table name |
record_id |
(optional) Use record ID argument to retrieve an existing record details |
limit |
(optional) A limit on the number of records to be returned. Limit can range between 1 and 100. |
offset |
(optional) Page offset returned by the previous list-records call. Note that this is represented by a record ID, not a numerical offset. |
view |
(optional) The name or ID of the view |
fields |
(optional) Only data for fields whose names are in this list will be included in the records. If you don't need every field, you can use |
sortField |
(optional) The field name to use for sorting |
sortDirection |
(optional) "asc" or "desc". The sort order in which the records will be returned. Defaults to asc. |
combined_result |
If TRUE (default) all data is returned in the same data.
If FALSE table fields are returned in separate |
pretty |
Logical. Should JSON be returned in human readable form? this parameter to reduce the amount of data transferred. |
A data frame with records or a list with record details if
record_id
is specified.
Airtable allows all users to access the metadata API. The recommended workflow for creating this table is to use air_generate_metadata_from_api to extract the structural metadata from the base schema and then use air_create_metadata_table to add the table to your base.
air_get_metadata_from_table( base, table_name, add_id_field = FALSE, field_names_to_snakecase = TRUE )
air_get_metadata_from_table( base, table_name, add_id_field = FALSE, field_names_to_snakecase = TRUE )
base |
String. ID for your base from Airtable. Generally 'appXXXXXXXXXXXXXX' |
table_name |
String. Name of structural metadata table - the metadata that describes how tables and fields fit together. |
add_id_field |
Logical. If true, an "id" field is added to each table |
field_names_to_snakecase |
Logical. If true, values in the field_names column and the field in the metadata table themselves are are converted to snake_case |
For information about creating metadata tables in your base see the EHA MA Handbook
Requires the following fields: table_name, field_name
data.frame with metadata table
Get the schema for the tables in a base. This is a wrapper for the api call Get base schema.
air_get_schema(base, ...)
air_get_schema(base, ...)
base |
String. Airtable base ID |
... |
reserved for additional parameters |
list of schema
Metadata api is currently available to all users.
Creates a new record and returns the created record object if the call succeeded, including a record ID which will uniquely identify the record within the table.
air_insert(base, table_name, record_data) air_insert_data_frame(base, table_name, records, typecast) multiple(x)
air_insert(base, table_name, record_data) air_insert_data_frame(base, table_name, records, typecast) multiple(x)
base |
String. Airtable base |
table_name |
String. Table name |
record_data |
Named list of values. You can include all, some, or none of the field values |
records |
Dataframe. Contains records you would like to insert |
typecast |
Logical. Should airtable make new values for select type fields? |
x |
Object to be marked as a multiple value field |
Each token you provisision is given access to a certain set of bases or workspaces. This function lists all bases associated with a token.
air_list_bases(request_url = "https://api.airtable.com/v0/meta/bases")
air_list_bases(request_url = "https://api.airtable.com/v0/meta/bases")
request_url |
String. URL for api endpoint |
list. List of bases a token can access.
## Not run: air_list_bases() ## End(Not run)
## Not run: air_list_bases() ## End(Not run)
Make JSON that is compatible with the Airtable API.
air_make_json( base, table_name, record_data, record_id = NULL, method = "POST", typecast = TRUE )
air_make_json( base, table_name, record_data, record_id = NULL, method = "POST", typecast = TRUE )
base |
String. Base in airtable |
table_name |
String. Table in airtable |
record_data |
Dataframe, list, or vector. Data to be converted to JSON |
record_id |
String or vector of strings. Records to be manipulated |
method |
String. "PATCH" is necessary for |
typecast |
Logical. Should the typecast option be TRUE or FALSE? Typecast allows you to add new options to select type fields. |
JSON with record data
Properly encodes HTTP requests
air_make_request( base, table_name, json_record_data, record_id = NULL, method = c("POST", "PATCH", "DELETE") )
air_make_request( base, table_name, json_record_data, record_id = NULL, method = c("POST", "PATCH", "DELETE") )
base |
String. Base in airtable |
table_name |
String. Table in airtable |
json_record_data |
json or string. JSON formatted text with record data |
record_id |
String or vector of strings. Record id |
method |
String. One of "POST", "PATCH", or "DELETE" |
Status of HTTP request
Retrieve records where the request url would be over 16k characters (e.g. complicated formula) or has more than 21 fields listed in the request.
air_post( base, table_name, limit = NULL, offset = NULL, view = NULL, fields = NULL, sortField = NULL, sortDirection = NULL, filterByFormula = NULL, combined_result = TRUE )
air_post( base, table_name, limit = NULL, offset = NULL, view = NULL, fields = NULL, sortField = NULL, sortDirection = NULL, filterByFormula = NULL, combined_result = TRUE )
base |
String. Airtable base |
table_name |
String. Table name |
limit |
Numeric. (optional) A limit on the number of records to be returned. Limit can range between 1 and 100. |
offset |
Numeric. (optional) Page offset returned by the previous list-records call. Note that this is represented by a record ID, not a numerical offset. |
view |
String. (optional) The name or ID of the view |
fields |
List. (optional) Only data for fields whose names are in this list
will be included in the records. Does not work when retrieving individual records with |
sortField |
String. (optional) The field name to use for sorting |
sortDirection |
String. (optional) "asc" or "desc". The sort order in which the records will be returned. Defaults to asc. |
filterByFormula |
String. Use a formula to filter results. See https://support.airtable.com/hc/en-us/articles/223247187-How-to-sort-filter-or-retrieve-ordered-records-in-the-API this parameter to reduce the amount of data transferred. |
combined_result |
Logical. If TRUE (default) all data is returned in the same data.
If FALSE table fields are returned in separate |
You can retrieve records in an order of a view by providing the name or ID of the view in the view query parameter. The results will include only records visible in the order they are displayed.
A data frame with records
[air_get()]
Select records from table
air_select( base, table_name, record_id = NULL, fields = NULL, filterByFormula = NULL, maxRecord = NULL, sort = NULL, view = NULL, pageSize = NULL, offset = NULL, combined_result = TRUE )
air_select( base, table_name, record_id = NULL, fields = NULL, filterByFormula = NULL, maxRecord = NULL, sort = NULL, view = NULL, pageSize = NULL, offset = NULL, combined_result = TRUE )
base |
Airtable base |
table_name |
Table name |
record_id |
(optional) Use record ID argument to retrieve an existing record details |
fields |
(optional) Only data for fields whose names are in this list will be included in the records. If you don't need every field, you can use this parameter to reduce the amount of data transferred. |
filterByFormula |
(optional) A formula used to filter records. |
maxRecord |
(optional) The maximum total number of records that will be returned. |
sort |
A list of sort objects that specifies how the records will be ordered. |
view |
(optional) The name or ID of the view defined in the table |
pageSize |
(optional) The number of records returned in each request. Must be less than or equal to 100. Default is 100. |
offset |
(optional) To fetch the next page of records set this argument with a value of offset element from previous response |
combined_result |
If TRUE (default) all data is returned in the same
data frame. If FALSE table fields are returned in separate |
A data frame with records or a list with record details if
record_id
is specified.
You can retrieve records in an order of a view by providing the name or ID of the view in the view query parameter. The results will include only records visible in the order they are displayed.
The formula will be evaluated for each record, and if the result is not 0, false, "", NaN, [], or #Error! the record will be included in the response. If combined with view, only records in that view which satisfy the formula will be returned. For example, to only include records where Country isn't empty, pass in: NOT(Country = ”)
Each sort object must have a field key specifying the name of
the field to sort on, and an optional direction key that is either "asc" or
"desc". The default direction is "asc".
For example, to sort records by Country, pass in: list(field =
"Country", direction = "desc")
Template for lists that describe tables in Airtable
air_table_template(table_name, description, fields_df)
air_table_template(table_name, description, fields_df)
table_name |
String. Name of table |
description |
String. Description of the table |
fields_df |
Data frame. Data frame describing the field in a table. Should contain a name, description,type, and options field. if |
List with table name, description, and fields
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df<- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) table_list <- air_table_template(table_name = "Planet", description = "Planets of Foundation", fields_df = field_tables) air_create_table(base, table_list) ## End(Not run)
## Not run: base <- "appQ94sELAtFnXPxx" base_schema <- air_get_schema(base) tables<- base_schema$tables field_names <- c("Planet","Chapter","Book", "Known Inhabitants") field_desc <- c("Name of planet in Foundation Series", "Chapters where planet is referenced", "Books where planet is referenced", "Characters mentioned as living on or being from that planet") field_types <- c("singleLineText",rep("multipleRecordLinks",3)) field_options <- c(NA,list( list( linkedTableId = tables[tables$name == "Chapter","id"] ) ), list( list( linkedTableId = tables[tables$name == "Book","id"] ) ), list( list( linkedTableId = tables[tables$name == "Character","id"] ) ) ) field_df<- air_fields_df_template(name = field_names, description = field_desc, type = field_types, options = field_options) table_list <- air_table_template(table_name = "Planet", description = "Planets of Foundation", fields_df = field_tables) air_create_table(base, table_list) ## End(Not run)
Updates a new record. Any fields that are not included will not be updated.
air_update(base, table_name, record_id, record_data)
air_update(base, table_name, record_id, record_data)
base |
Airtable base |
table_name |
Table name |
record_id |
An id of the record |
record_data |
Named list of values. You can include all, some, or none of the field values |
Updates the values in a table by overwriting their current contents.
air_update_data_frame(base, table_name, record_ids, records)
air_update_data_frame(base, table_name, record_ids, records)
base |
String. Airtable base |
table_name |
String. Table name |
record_ids |
Vector of strings. Records to be modified |
records |
Dataframe. Values to update |
Status of HTTP request
Update the descriptive metadata table in airtable
air_update_description_table( base, description, table_name = "Description", join_field = "title", record_id_field = "id" )
air_update_description_table( base, description, table_name = "Description", join_field = "title", record_id_field = "id" )
base |
String. Base id |
description |
Data frame. Contains updated description |
table_name |
String. Name of description table |
join_field |
String. Field to perform join on |
record_id_field |
String. Name of the record id field |
list that logs updates
## Not run: base <- "appXXXXXXXX" table_name <- "Description" # get description from table description <- air_get_base_description_from_table(base, table_name) # update the identifier field description$identifier <- "fake.doi.xyz/029940" # update the table air_update_description_table(base,description) ## End(Not run)
## Not run: base <- "appXXXXXXXX" table_name <- "Description" # get description from table description <- air_get_base_description_from_table(base, table_name) # update the identifier field description$identifier <- "fake.doi.xyz/029940" # update the table air_update_description_table(base,description) ## End(Not run)
Must update either the name or the description. See "https://airtable.com/developers/web/api/update-field" for more details.
air_update_field(base, table_id, field_id, name = NULL, description = NULL)
air_update_field(base, table_id, field_id, name = NULL, description = NULL)
base |
String. Base id |
table_id |
String. ID for table that contains the field to be updated |
field_id |
String. ID of field to be updated |
name |
String. updated name (optional) |
description |
String. updated description (option) |
List. Describes the changes that happened to the field
## Not run: base <- "appVjIfAo8AJlfTkx" schema <- air_get_schema("appVjIfAo8AJlfTkx") table_id <- schema$tables[1,c("id")] field_id <- schema$tables$fields[[1]][2,]$id ## update name and description name <- "New Name" description <- "Updated Description" out <- air_update_field(base = base,table_id = table_id,field_id = field_id, name = name, description = description) ### just name name <- "New New Name" out <- air_update_field(base = base,table_id = table_id,field_id = field_id, name = name) ## just description description <- "Better description" out <- air_update_field(base = base,table_id = table_id,field_id = field_id, description = description) ## set name to number name <- 1234 out <- air_update_field(base = base,table_id = table_id,field_id = field_id, name = name) # set description to number description <- 1234 out <- air_update_field(base = base,table_id = table_id,field_id = field_id, description = description) # bulk update names and descriptions from a data frame field_ids <- schema$tables$fields[[1]]$id field_names <- sprintf("%s_bulk_update",schema$tables$fields[[1]]$name) field_descriptions <- sprintf("%s BULK UPDATE", schema$tables$fields[[1]]$description) df <- data.frame("field_id"= field_ids,"name"=field_names, "description"=field_descriptions) purrr::pmap(df,function(field_id,name,description){ air_update_field(base = base,table_id = table_id,field_id = field_id, name = name, description = description) }) ## End(Not run)
## Not run: base <- "appVjIfAo8AJlfTkx" schema <- air_get_schema("appVjIfAo8AJlfTkx") table_id <- schema$tables[1,c("id")] field_id <- schema$tables$fields[[1]][2,]$id ## update name and description name <- "New Name" description <- "Updated Description" out <- air_update_field(base = base,table_id = table_id,field_id = field_id, name = name, description = description) ### just name name <- "New New Name" out <- air_update_field(base = base,table_id = table_id,field_id = field_id, name = name) ## just description description <- "Better description" out <- air_update_field(base = base,table_id = table_id,field_id = field_id, description = description) ## set name to number name <- 1234 out <- air_update_field(base = base,table_id = table_id,field_id = field_id, name = name) # set description to number description <- 1234 out <- air_update_field(base = base,table_id = table_id,field_id = field_id, description = description) # bulk update names and descriptions from a data frame field_ids <- schema$tables$fields[[1]]$id field_names <- sprintf("%s_bulk_update",schema$tables$fields[[1]]$name) field_descriptions <- sprintf("%s BULK UPDATE", schema$tables$fields[[1]]$description) df <- data.frame("field_id"= field_ids,"name"=field_names, "description"=field_descriptions) purrr::pmap(df,function(field_id,name,description){ air_update_field(base = base,table_id = table_id,field_id = field_id, name = name, description = description) }) ## End(Not run)
Update the structural metadata table
air_update_metadata_table( base, meta_data, table_name = "Meta Data", join_field = "field_id", record_id_field = "id" )
air_update_metadata_table( base, meta_data, table_name = "Meta Data", join_field = "field_id", record_id_field = "id" )
base |
String. Base id |
meta_data |
Data frame. Contains metadata records. From air_generate_metadata* |
table_name |
String. Name of metadata table |
join_field |
String. Name of field to join new and current metadata. Likely |
record_id_field |
String. Name of record id field. Like |
List. Log of results for updating metadata
## Not run: base = "appVjIfAo8AJlfTkx" metadata <- air_generate_metadata_from_api(base = base) air_update_metadata_table(base,metadata) ## End(Not run)
## Not run: base = "appVjIfAo8AJlfTkx" metadata <- air_generate_metadata_from_api(base = base) air_update_metadata_table(base,metadata) ## End(Not run)
Creates airtable object with tables and functions
airtable(base, tables)
airtable(base, tables)
base |
Airtable base |
tables |
Table names in the airtable base (character vector) |
Airtable base object with elements named by table names. Each element contains functions
get |
returns table records, see |
insert |
insert table record, see |
update |
updates table record, see |
delete |
deletes table record, see |
## Not run: TravelBucketList <- airtable( base = "the_base_id", tables = c("Destinations", "Hotels", "Travel Partners") ) hotels <- TravelBucketList$Hotels$get() destinations <- TravelBucketList$Destinations$get() ## End(Not run)
## Not run: TravelBucketList <- airtable( base = "the_base_id", tables = c("Destinations", "Hotels", "Travel Partners") ) hotels <- TravelBucketList$Hotels$get() destinations <- TravelBucketList$Destinations$get() ## End(Not run)
Airtable limits the number of records that can be pulled from a base to 100. This function pulls records based on a query then checks if there is an offset value. While there is an offset value, it uses that value to generate the next query, thus moving down the records until all records have been fetched from the database.
fetch_all(base, table_name, ...)
fetch_all(base, table_name, ...)
base |
String. ID for the base or app to be fetched |
table_name |
String. Name of the table to be fetched from the base |
... |
Additional arguments to pass to [air_get()]. |
dataframe
Airtable requires an api key to fetch data. Generate the airtable API key from your [Airtable account](http://airtable.com/account) page.
airtabler
functions will read the API key from
environment variable AIRTABLE_API_KEY
. To start R session with the
initialized environment variable create an .Renviron
file in your
home directory with a line like this:
AIRTABLE_API_KEY=your_api_key_here
You can use usethis::edit_r_environ()
to open and edit your .Renviron
file.
Also consider using the 'dotenv' package with a .env file for storing sensitive variables. Remember add to.gitignore or encrypt the .env file to avoid sharing sensitive variables.
# Each base has a fully described API # app_id <- "appVjIfAo8AJlfTkx" # ID for the base we are fetching. # Note that you can pass a `view` argument to air_get or fetch_all to get only # a view of a table (say, only validated records, or some other filtered view), # e.g., # bats <- fetch_all(app_id, "images", view = "Status View") # talks <- fetch_all(app_id, "images")
# Each base has a fully described API # app_id <- "appVjIfAo8AJlfTkx" # ID for the base we are fetching. # Note that you can pass a `view` argument to air_get or fetch_all to get only # a view of a table (say, only validated records, or some other filtered view), # e.g., # bats <- fetch_all(app_id, "images", view = "Status View") # talks <- fetch_all(app_id, "images")
Get the full outputs of a table as single json object
fetch_all_json(base, table_name, ...)
fetch_all_json(base, table_name, ...)
base |
String. Base ID |
table_name |
String. Table name |
... |
additional parameters to pass to air_get_json |
json as string
## Not run: base <- "appXXXXXXX" table_name <- "My Table" fetch_all_json(base, table_name) ## End(Not run)
## Not run: base <- "appXXXXXXX" table_name <- "My Table" fetch_all_json(base, table_name) ## End(Not run)
Similar in spirit to purrr::flatten_chr except that it can handle NULL values in lists and returns outputs that can be written to csv.
flatten_col_to_chr(data_frame)
flatten_col_to_chr(data_frame)
data_frame |
a data frame, tibble or other data frame like object |
Because the outputs are intended for use in CSV files, we must use double quotes to indicate that the commas separating list values do not delimit cells. This conforms to RFC 4180 standard for CSVs. https://datatracker.ietf.org/doc/html/rfc4180
data_frame with list columns converted to character vectors.
data_frame <- data.frame(a = I(list(list("Hello"), list("Aloha"), NULL, list("Hola","Bonjour","Merhaba") )), b = 1:4, c = letters[1:4], d = I(data.frame(id = 1:4, name = "bob", email = "[email protected]")) ) test_df <- flatten_col_to_chr(data_frame) str(test_df)
data_frame <- data.frame(a = I(list(list("Hello"), list("Aloha"), NULL, list("Hola","Bonjour","Merhaba") )), b = 1:4, c = letters[1:4], d = I(data.frame(id = 1:4, name = "bob", email = "[email protected]")) ) test_df <- flatten_col_to_chr(data_frame) str(test_df)
Returns airtable offset id from previous select
get_offset(x)
get_offset(x)
x |
Last result |
Airtable offset id
Because the airtable api lacks an easy solution for getting unique values from a field in a table, we have this function which accepts a list of fields and returns their unique values. Currently, if multiple fields are listed, all unique values from all fields will be returned in a single vector. This may change in future iterations.
get_unique_field_values(base, table_name, fields)
get_unique_field_values(base, table_name, fields)
base |
String. ID of airtable base |
table_name |
String. Name of table in base |
fields |
List. Names of fields |
vector of unique values
Extends readxl::read_excel
to allow for reading from a URL.
read_excel_url(url, fileext = ".xslx", parse_all_sheets = FALSE, ...)
read_excel_url(url, fileext = ".xslx", parse_all_sheets = FALSE, ...)
url |
String. Url for file |
fileext |
String. File extension for temp file |
parse_all_sheets |
Logical. Should all sheets be parsed? |
... |
additional arguments to pass to |
tibble or list of tibbles if parse_all_sheets = TRUE
Unlike setdiff, this function creates the union of x and y then removes values that are in the intersect, providing values that are unique to X and values that are unique to Y.
set_diff(x, y)
set_diff(x, y)
x |
a set of values. |
y |
a set of values. |
Unique values from X and Y, NULL if no unique values.
a <- 1:3 b <- 2:4 set_diff(a,b) # returns 1,4 x <- 1:3 y <- 1:3 set_diff(x,y) # returns NULL
a <- 1:3 b <- 2:4 set_diff(a,b) # returns 1,4 x <- 1:3 y <- 1:3 set_diff(x,y) # returns NULL