airtable

package module
v0.0.0-...-fca93f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 14, 2019 License: MPL-2.0 Imports: 12 Imported by: 0

README

airtable

Go package for interacting with the Airtable API.

License

Mozilla Public License 2.0

Install

$ go get github.com/brianloveswords/airtable

API Documentation

See airtable package documentation on godoc.org

Example Usage

package main

import (
    "fmt"
    "strings"
    "time"

    "github.com/brianloveswords/airtable"
)

type PublicDomainBookRecord struct {
    airtable.Record // provides ID, CreatedTime
    Fields          struct {
        Title       string `json:"Book Title"`
        Author      string
        Publication time.Time `json:"Publication Date"`
        FullText    string
        Rating      int
        Tags        airtable.MultiSelect
    }
}

// String shows the book record like "<title> by <author> [<rating>]"
func (r *PublicDomainBookRecord) String() string {
    f := r.Fields
    return fmt.Sprintf("%s by %s %s", f.Title, f.Author, r.Rating())
}

// Rating outputs a rating like [***··]
func (r *PublicDomainBookRecord) Rating() string {
    var (
        max    = 5
        rating = r.Fields.Rating
        stars  = strings.Repeat("*", rating)
        dots   = strings.Repeat("·", max-rating)
    )
    return fmt.Sprintf("[%s%s]", stars, dots)
}

func Example() {
    // Create the Airtable client with your APIKey and BaseID for the
    // base you want to interact with.
    client := airtable.Client{
        APIKey: "keyXXXXXXXXXXXXXX",
        BaseID: "appwNa5g4gHCVZQPm",
    }

    books := client.Table("Public Domain Books")

    bestBooks := []PublicDomainBookRecord{}
    books.List(&bestBooks, &airtable.Options{
        // The whole response would be huge because of FullText so we
        // should just get the title and author. NOTE: even though the
        // field is called "Book Title" in the JSON, we should use field
        // by the name we defined it in our struct.
        Fields: []string{"Title", "Author", "Rating"},

        // Only get books with a rating that's 4 or higher.
        Filter: `{Rating} >= 4`,

        // Let's sort from highest to lowest rating, then by author
        Sort: airtable.Sort{
            {"Rating", airtable.SortDesc},
            {"Author", airtable.SortAsc},
        },
    })

    fmt.Println("Best Public Domain Books:")
    for _, bookRecord := range bestBooks {
        fmt.Println(bookRecord.String())
    }

    // Let's prune our library of books we aren't super into.
    badBooks := []PublicDomainBookRecord{}
    books.List(&badBooks, &airtable.Options{
        Fields: []string{"Title", "Author", "Rating"},
        Filter: `{Rating} < 3`,
    })
    for _, badBook := range badBooks {
        fmt.Println("deleting", badBook)
        books.Delete(&badBook)
    }
}

Contributing

TBD

Documentation

Overview

Package airtable provides a high-level client to the Airtable API that allows the consumer to drop to a low-level request client when needed.

Example
package main

import (
	"fmt"
	"strings"
	"time"

	"github.com/brianloveswords/airtable"
)

type PublicDomainBookRecord struct {
	airtable.Record // provides ID, CreatedTime
	Fields          struct {
		Title       string `json:"Book Title"`
		Author      string
		Publication time.Time `json:"Publication Date"`
		FullText    string
		Rating      int
		Tags        airtable.MultiSelect
	}
}

// String shows the book record like "<title> by <author> [<rating>]"
func (r *PublicDomainBookRecord) String() string {
	f := r.Fields
	return fmt.Sprintf("%s by %s %s", f.Title, f.Author, r.Rating())
}

// Rating outputs a rating like [***··]
func (r *PublicDomainBookRecord) Rating() string {
	var (
		max    = 5
		rating = r.Fields.Rating
		stars  = strings.Repeat("*", rating)
		dots   = strings.Repeat("·", max-rating)
	)
	return fmt.Sprintf("[%s%s]", stars, dots)
}

func main() {
	// Create the Airtable client with your APIKey and BaseID for the
	// base you want to interact with.
	client := airtable.Client{
		APIKey: "keyXXXXXXXXXXXXXX",
		BaseID: "appwNa5g4gHCVZQPm",
	}

	books := client.Table("Public Domain Books")

	bestBooks := []PublicDomainBookRecord{}
	books.List(&bestBooks, &airtable.Options{
		// The whole response would be huge because of FullText so we
		// should just get the title and author. NOTE: even though the
		// field is called "Book Title" in the JSON, we should use field
		// by the name we defined it in our struct.
		Fields: []string{"Title", "Author", "Rating"},

		// Only get books with a rating that's 4 or higher.
		Filter: `{Rating} >= 4`,

		// Let's sort from highest to lowest rating, then by author
		Sort: airtable.Sort{
			{"Rating", airtable.SortDesc},
			{"Author", airtable.SortAsc},
		},
	})

	fmt.Println("Best Public Domain Books:")
	for _, bookRecord := range bestBooks {
		fmt.Println(bookRecord.String())
	}

	// Let's prune our library of books we aren't super into.
	badBooks := []PublicDomainBookRecord{}
	books.List(&badBooks, &airtable.Options{
		Fields: []string{"Title", "Author", "Rating"},
		Filter: `{Rating} < 3`,
	})
	for _, badBook := range badBooks {
		fmt.Println("deleting", badBook)
		books.Delete(&badBook)
	}
}
Output:

Index

Examples

Constants

View Source
const (
	SortDesc = "desc"
	SortAsc  = "asc"
)

SortDesc and SortAsc are used in the Sort type to indicate the direction of the sort.

Variables

View Source
var (
	DefaultRootURL    = "https://api.airtable.com"
	DefaultVersion    = "v0"
	DefaultHTTPClient = http.DefaultClient
	DefaultLimiter    = RateLimiter(5) // per second
)

Functions

func NewRecord

func NewRecord(recordPtr interface{}, data Fields)

NewRecord is a convenience method for applying a map of fields to a record container when the Fields struct is anonymous.

Example
package main

import (
	"fmt"

	"github.com/brianloveswords/airtable"
)

func main() {
	type BookRecord struct {
		airtable.Record
		Fields struct {
			Title  string
			Author string
			Rating int
			Tags   airtable.MultiSelect
		}
	}

	binti := &BookRecord{}
	airtable.NewRecord(binti, airtable.Fields{
		"Title":  "Binti",
		"Author": "Nnedi Okorafor",
		"Rating": 4,
		"Tags":   airtable.MultiSelect{"sci-fi", "fantasy"},
	})

	fmt.Println(binti.Fields.Author)
}
Output:

Nnedi Okorafor
Example (WithoutNewRecord)
package main

import (
	"fmt"

	"github.com/brianloveswords/airtable"
)

func main() {
	// You can avoid using NewRecord if you use a named struct instead
	// of an anonymous struct for the Fields field in record struct.

	type Book struct {
		Title  string
		Author string
		Rating int
		Tags   airtable.MultiSelect
	}

	type BookRecord struct {
		airtable.Record
		Fields Book
	}

	binti := &BookRecord{
		Fields: Book{
			Title:  "Binti",
			Author: "Nnedi Okorafor",
			Rating: 4,
			Tags:   airtable.MultiSelect{"sci-fi", "fantasy"},
		},
	}

	fmt.Println(binti.Fields.Author)
}
Output:

Nnedi Okorafor

func RateLimiter

func RateLimiter(n int) ratelimit.Limiter

RateLimiter makes a new rate limiter using n as the number of requests per second that is allowed. If 0 is passed, the limiter will be unlimited.

Types

type Attachment

type Attachment []struct {
	ID         string
	URL        string `json:"url"`
	Filename   string `json:"filename"`
	Size       float64
	Type       string
	Thumbnails struct {
		Small AttachmentThumbnail
		Large AttachmentThumbnail
	}
}

Attachment type. When creating a new attachment, only URL and optionally Filename should be provided.

type AttachmentThumbnail

type AttachmentThumbnail struct {
	URL    string
	Width  float64
	Height float64
}

AttachmentThumbnail holds the details of an individual thumbnail

type Client

type Client struct {
	APIKey     string
	BaseID     string
	Version    string
	RootURL    string
	HTTPClient *http.Client
	Limiter    ratelimit.Limiter
}

Client represents an interface to communicate with the Airtable API.

- APIKey: api key to use for each request. Requests will panic if this is not set.

- BaseID: base this client will operate against. Requests will panic if this not set.

- Version: version of the API to use.

- RootURL: root URL to use.

- HTTPClient: http.Client instance to use. http.DefaultClient

- Limit: max requests to make per second.

func (*Client) Request

func (c *Client) Request(
	method string,
	endpoint string,
	options QueryEncoder,
) ([]byte, error)

Request makes an HTTP request to the Airtable API without a body. See RequestWithBody for documentation.

func (*Client) RequestWithBody

func (c *Client) RequestWithBody(
	method string,
	endpoint string,
	options QueryEncoder,
	body io.Reader,
) ([]byte, error)

RequestWithBody makes an HTTP request to the Airtable API. endpoint will be combined with the client's RootlURL, Version and BaseID, to create the complete URL. endpoint is expected to already be encoded; if necessary, use url.PathEscape before passing RequestWithBody.

If client is missing APIKey or BaseID, this method will panic.

func (*Client) Table

func (c *Client) Table(name string) Table

Table returns a new Table that will use this client and operate against the table with the passed in name

type ErrClientRequest

type ErrClientRequest struct {
	Err    error
	Method string
	URL    string
}

ErrClientRequest is returned when the client runs into problems making a request.

func (ErrClientRequest) Error

func (e ErrClientRequest) Error() string

type Fields

type Fields map[string]interface{}

Fields is used in NewRecord for constructing new records.

type FormulaResult

type FormulaResult struct {
	Number *float64
	String *string
	Error  *string
}

FormulaResult can be a string, number or error.

func (*FormulaResult) UnmarshalJSON

func (f *FormulaResult) UnmarshalJSON(b []byte) error

UnmarshalJSON tries to figure out if this is an error, a string or a number.

func (*FormulaResult) Value

func (f *FormulaResult) Value() (v interface{}, ok bool)

Value returns the underlying value if the formula results is a string or a number, otherwise return nil pointer and false

type MultiSelect

type MultiSelect []string

MultiSelect type. Alias for string slice.

type Options

type Options struct {
	// Sort the response. See the package example for usage usage
	Sort Sort

	// Which fields to include. Useful when you want to exclude certain
	// fields if you aren't using them to save on network cost.
	Fields []string

	// Maximum amount of record to return. If MaxRecords <= 100, it is
	// guaranteed the results will fit in one network request.
	MaxRecords uint

	// Formula used to filer the results. See the airtable formula
	// reference for more details on how to create a formula:
	// https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference
	Filter string

	// Name of the view to use. If set, only the records in that view
	// will be returned. The records will be sorted and filtered
	// according to the order of the view.
	View string

	// Airtable API performs automatic data conversion from string
	// values if typecast parameter is passed in. Automatic conversion
	// is disabled by default to ensure data integrity, but it may be
	// helpful for integrating with 3rd party data sources.
	Typecast bool
	// contains filtered or unexported fields
}

Options is used in the Table.List method to adjust and control the response

func (Options) Encode

func (o Options) Encode() string

Encode turns the Options object into a query string for use in URLs.

type QueryEncoder

type QueryEncoder interface {
	Encode() string
}

QueryEncoder encodes options to a query string.

type Record

type Record struct {
	ID          string
	CreatedTime time.Time
}

Record is a convenience struct for anonymous inclusion in user-constructed record structs.

type RecordLink []string

RecordLink type. Alias for string slice.

type Sort

type Sort [][2]string

Sort represents a pair of strings: a field and a SortType

type SortType

type SortType string

SortType indicates which direction to sort the results in.

type Table

type Table struct {
	// contains filtered or unexported fields
}

Table represents an table in a base and provides methods for interacting with records in the table.

func (*Table) Create

func (t *Table) Create(recordPtr interface{}) error

Create makes a new record in the table using the record pointed to by recordPtr. On success, updates the ID and CreatedTime of the object pointed to by recordPtr.

recordPtr MUST have a Fields field that is a struct that can be marshaled to JSON or this method will panic.

func (*Table) Delete

func (t *Table) Delete(recordPtr interface{}) error

Delete removes a record from the table. On success, ID and CreatedTime of the object pointed to by recordPtr are removed.

func (*Table) Get

func (t *Table) Get(id string, recordPtr interface{}) error

Get looks up a record from the table by ID and stores in in the object pointed to by recordPtr.

func (*Table) List

func (t *Table) List(listPtr interface{}, options *Options) error

List queries the table for list of records and stores it in the object pointed to by listPtr. By default, List will recurse to get all of the records until there are no more left to get, but this can be overriden by using the MaxRecords option. See Options for a complete list of the options that are supported.

listPtr must be a pointer to a slice of records, which are structs that contain, at a minimum, `ID string` and `Fields struct {...}` fields. For example:

 type BookRecord struct {
		airtable.Record // provides ID and CreatedTime
		Fields struct {
			Title string
			Author string
		}
 }
 listPtr := &[]BookRecord{}

This will be validated and cause a panic at runtime if listPtr is the wrong type.

func (*Table) Update

func (t *Table) Update(recordPtr interface{}) error

Update sends the updated record pointed to by recordPtr to the table

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL