or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

attachments.mdcli.mdcomments.mdcore-api.mdenterprise.mdformulas.mdindex.mdorm.mdrecord-operations.mdtesting.mdwebhooks.md

formulas.mddocs/

0

# Formula System

1

2

Comprehensive formula building and expression system supporting all Airtable formula functions, logical operators, comparisons, and field references. Enables complex queries and data filtering using Airtable's formula language.

3

4

## Capabilities

5

6

### Formula Construction

7

8

Core classes for building formula expressions with proper escaping, type conversion, and operator support.

9

10

```python { .api }

11

class Formula:

12

def __init__(self, value: str):

13

"""

14

Create formula from string expression.

15

16

Parameters:

17

- value: Formula string (e.g., "{Name} = 'John'")

18

"""

19

20

def flatten(self) -> Formula:

21

"""

22

Flatten nested boolean statements for optimization.

23

24

Returns:

25

Optimized Formula instance

26

"""

27

28

def eq(self, value) -> Formula:

29

"""Build equality comparison."""

30

31

def ne(self, value) -> Formula:

32

"""Build not-equal comparison."""

33

34

def gt(self, value) -> Formula:

35

"""Build greater-than comparison."""

36

37

def lt(self, value) -> Formula:

38

"""Build less-than comparison."""

39

40

def gte(self, value) -> Formula:

41

"""Build greater-than-or-equal comparison."""

42

43

def lte(self, value) -> Formula:

44

"""Build less-than-or-equal comparison."""

45

46

class Field(Formula):

47

def __init__(self, name: str):

48

"""

49

Create field reference.

50

51

Parameters:

52

- name: Field name to reference

53

"""

54

55

def to_formula(value) -> Formula:

56

"""

57

Convert value to Formula object.

58

59

Parameters:

60

- value: Python value (str, int, bool, datetime, Formula, etc.)

61

62

Returns:

63

Formula object with proper escaping and type conversion

64

"""

65

66

def to_formula_str(value) -> str:

67

"""

68

Convert value to formula string.

69

70

Parameters:

71

- value: Python value to convert

72

73

Returns:

74

String representation suitable for Airtable formulas

75

"""

76

```

77

78

### Logical Operations

79

80

Boolean logic functions for combining multiple conditions with AND, OR, and NOT operations.

81

82

```python { .api }

83

def AND(*components, **fields) -> Formula:

84

"""

85

Create AND condition combining multiple expressions.

86

87

Parameters:

88

- components: Formula objects or values to combine

89

- fields: Keyword arguments as field=value equality conditions

90

91

Returns:

92

Formula representing AND condition

93

"""

94

95

def OR(*components, **fields) -> Formula:

96

"""

97

Create OR condition for alternative expressions.

98

99

Parameters:

100

- components: Formula objects or values to combine

101

- fields: Keyword arguments as field=value equality conditions

102

103

Returns:

104

Formula representing OR condition

105

"""

106

107

def NOT(component=None, **fields) -> Formula:

108

"""

109

Create NOT condition to negate expression.

110

111

Parameters:

112

- component: Formula object to negate

113

- fields: Single field=value as keyword argument

114

115

Returns:

116

Formula representing negated condition

117

"""

118

119

def match(field_values: dict, *, match_any: bool = False) -> Formula:

120

"""

121

Create equality conditions for multiple fields.

122

123

Parameters:

124

- field_values: Dict mapping field names to values or (operator, value) tuples

125

- match_any: If True, use OR logic. If False, use AND logic

126

127

Returns:

128

Formula with equality or comparison conditions

129

"""

130

```

131

132

### Mathematical Functions

133

134

Comprehensive set of mathematical operations including arithmetic, statistical, and utility functions.

135

136

```python { .api }

137

# Arithmetic functions

138

def ABS(value) -> Formula:

139

"""Absolute value of number."""

140

141

def SUM(number, *numbers) -> Formula:

142

"""Sum of all numbers."""

143

144

def AVERAGE(number, *numbers) -> Formula:

145

"""Average of all numbers."""

146

147

def MAX(number, *numbers) -> Formula:

148

"""Maximum value from numbers."""

149

150

def MIN(number, *numbers) -> Formula:

151

"""Minimum value from numbers."""

152

153

def COUNT(number, *numbers) -> Formula:

154

"""Count of numeric values."""

155

156

def COUNTA(value, *values) -> Formula:

157

"""Count of non-empty values."""

158

159

# Rounding functions

160

def ROUND(value, precision) -> Formula:

161

"""Round to specified decimal places."""

162

163

def ROUNDUP(value, precision) -> Formula:

164

"""Round up to specified decimal places."""

165

166

def ROUNDDOWN(value, precision) -> Formula:

167

"""Round down to specified decimal places."""

168

169

def CEILING(value, significance=None) -> Formula:

170

"""Round up to nearest multiple of significance."""

171

172

def FLOOR(value, significance=None) -> Formula:

173

"""Round down to nearest multiple of significance."""

174

175

def INT(value) -> Formula:

176

"""Greatest integer less than or equal to value."""

177

178

# Advanced math

179

def MOD(value, divisor) -> Formula:

180

"""Remainder after division."""

181

182

def POWER(base, power) -> Formula:

183

"""Base raised to power."""

184

185

def SQRT(value) -> Formula:

186

"""Square root of value."""

187

188

def EXP(power) -> Formula:

189

"""e raised to power."""

190

191

def LOG(number, base=None) -> Formula:

192

"""Logarithm with optional base (default 10)."""

193

194

def EVEN(value) -> Formula:

195

"""Smallest even integer >= value."""

196

197

def ODD(value) -> Formula:

198

"""Smallest odd integer >= value."""

199

```

200

201

### Text Functions

202

203

String manipulation and text processing functions for working with text fields.

204

205

```python { .api }

206

def CONCATENATE(text, *texts) -> Formula:

207

"""Join text strings together."""

208

209

def LEFT(string, how_many) -> Formula:

210

"""Extract characters from start of string."""

211

212

def RIGHT(string, how_many) -> Formula:

213

"""Extract characters from end of string."""

214

215

def MID(string, where_to_start, count) -> Formula:

216

"""Extract substring from middle of string."""

217

218

def FIND(string_to_find, where_to_search, start_from_position=None) -> Formula:

219

"""Find position of substring (case-sensitive)."""

220

221

def SEARCH(string_to_find, where_to_search, start_from_position=None) -> Formula:

222

"""Find position of substring (case-insensitive)."""

223

224

def LEN(string) -> Formula:

225

"""Length of string."""

226

227

def TRIM(string) -> Formula:

228

"""Remove leading and trailing whitespace."""

229

230

def UPPER(string) -> Formula:

231

"""Convert to uppercase."""

232

233

def LOWER(string) -> Formula:

234

"""Convert to lowercase."""

235

236

def SUBSTITUTE(string, old_text, new_text, index=None) -> Formula:

237

"""Replace occurrences of old_text with new_text."""

238

239

def REPLACE(string, start_character, number_of_characters, replacement) -> Formula:

240

"""Replace portion of string."""

241

242

def REPT(string, number) -> Formula:

243

"""Repeat string specified number of times."""

244

245

def REGEX_MATCH(string, regex) -> Formula:

246

"""Test if string matches regular expression."""

247

248

def REGEX_EXTRACT(string, regex) -> Formula:

249

"""Extract first substring matching regex."""

250

251

def REGEX_REPLACE(string, regex, replacement) -> Formula:

252

"""Replace all regex matches with replacement."""

253

254

def ENCODE_URL_COMPONENT(component_string) -> Formula:

255

"""URL-encode string for use in URLs."""

256

```

257

258

### Date and Time Functions

259

260

Comprehensive date/time manipulation including formatting, parsing, and arithmetic operations.

261

262

```python { .api }

263

def NOW() -> Formula:

264

"""Current date and time."""

265

266

def TODAY() -> Formula:

267

"""Current date (time set to midnight)."""

268

269

def DATEADD(date, number, units) -> Formula:

270

"""Add time units to date."""

271

272

def DATETIME_DIFF(date1, date2, units) -> Formula:

273

"""Difference between dates in specified units."""

274

275

def DATETIME_FORMAT(date, output_format=None) -> Formula:

276

"""Format date as string."""

277

278

def DATETIME_PARSE(date, input_format=None, locale=None) -> Formula:

279

"""Parse string as date."""

280

281

def DATESTR(date) -> Formula:

282

"""Format date as YYYY-MM-DD string."""

283

284

def TIMESTR(timestamp) -> Formula:

285

"""Format time as HH:mm:ss string."""

286

287

def SET_TIMEZONE(date, tz_identifier) -> Formula:

288

"""Set timezone for date (use with DATETIME_FORMAT)."""

289

290

def SET_LOCALE(date, locale_modifier) -> Formula:

291

"""Set locale for date (use with DATETIME_FORMAT)."""

292

293

# Date component extraction

294

def YEAR(date) -> Formula:

295

"""Extract year from date."""

296

297

def MONTH(date) -> Formula:

298

"""Extract month from date (1-12)."""

299

300

def DAY(date) -> Formula:

301

"""Extract day from date (1-31)."""

302

303

def WEEKDAY(date, start_day_of_week=None) -> Formula:

304

"""Day of week (0-6, Sunday=0)."""

305

306

def WEEKNUM(date, start_day_of_week=None) -> Formula:

307

"""Week number in year."""

308

309

def HOUR(datetime) -> Formula:

310

"""Extract hour from datetime (0-23)."""

311

312

def MINUTE(datetime) -> Formula:

313

"""Extract minute from datetime (0-59)."""

314

315

def SECOND(datetime) -> Formula:

316

"""Extract second from datetime (0-59)."""

317

318

# Date comparisons

319

def IS_BEFORE(date1, date2) -> Formula:

320

"""Check if date1 is before date2."""

321

322

def IS_AFTER(date1, date2) -> Formula:

323

"""Check if date1 is after date2."""

324

325

def IS_SAME(date1, date2, unit) -> Formula:

326

"""Check if dates are same up to time unit."""

327

328

# Relative dates

329

def FROMNOW(date) -> Formula:

330

"""Days from current date to specified date."""

331

332

def TONOW(date) -> Formula:

333

"""Days from specified date to current date."""

334

335

# Business date functions

336

def WORKDAY(start_date, num_days, holidays=None) -> Formula:

337

"""Add working days to date, excluding weekends and holidays."""

338

339

def WORKDAY_DIFF(start_date, end_date, holidays=None) -> Formula:

340

"""Count working days between dates."""

341

```

342

343

### Conditional and Utility Functions

344

345

Control flow, data type handling, and utility functions for complex formula logic.

346

347

```python { .api }

348

def IF(expression, if_true, if_false) -> Formula:

349

"""Conditional expression - return if_true if expression is true."""

350

351

def SWITCH(expression, pattern, result, *pattern_results) -> Formula:

352

"""Switch statement with pattern matching."""

353

354

def ISERROR(expr) -> Formula:

355

"""Check if expression causes an error."""

356

357

def BLANK() -> Formula:

358

"""Return blank/empty value."""

359

360

def ERROR() -> Formula:

361

"""Return error value."""

362

363

def TRUE() -> Formula:

364

"""Boolean true value."""

365

366

def FALSE() -> Formula:

367

"""Boolean false value."""

368

369

def T(value) -> Formula:

370

"""Return value if it's text, blank otherwise."""

371

372

def VALUE(text) -> Formula:

373

"""Convert text to number."""

374

375

def RECORD_ID() -> Formula:

376

"""ID of current record."""

377

378

def CREATED_TIME() -> Formula:

379

"""Creation time of current record."""

380

381

def LAST_MODIFIED_TIME(*fields) -> Formula:

382

"""Last modification time of record or specific fields."""

383

```

384

385

### Usage Examples

386

387

#### Basic Formula Construction

388

389

```python

390

from pyairtable import Api

391

from pyairtable.formulas import Formula, Field, match, AND, OR

392

393

api = Api('your_token')

394

table = api.table('base_id', 'table_name')

395

396

# Simple string formula

397

formula = Formula("{Status} = 'Active'")

398

records = table.all(formula=formula)

399

400

# Using Field objects

401

name_field = Field('Name')

402

status_field = Field('Status')

403

formula = AND(

404

name_field.eq('John'),

405

status_field.ne('Inactive')

406

)

407

408

# Using match() helper

409

formula = match({

410

'Department': 'Engineering',

411

'Level': ('>=', 5), # Comparison tuple

412

'Status': 'Active'

413

})

414

```

415

416

#### Complex Logical Expressions

417

418

```python

419

from pyairtable.formulas import AND, OR, NOT, match

420

421

# Complex conditions

422

engineering_seniors = AND(

423

match({'Department': 'Engineering'}),

424

OR(

425

match({'Level': ('>=', 5)}),

426

match({'Title': 'Senior Engineer'})

427

)

428

)

429

430

# Exclusion patterns

431

not_interns = NOT(match({'Title': 'Intern'}))

432

433

# Multiple department filter

434

tech_departments = OR(

435

match({'Department': 'Engineering'}),

436

match({'Department': 'Data Science'}),

437

match({'Department': 'DevOps'})

438

)

439

440

records = table.all(formula=AND(engineering_seniors, not_interns))

441

```

442

443

#### Mathematical Formulas

444

445

```python

446

from pyairtable.formulas import SUM, AVERAGE, IF, ROUND

447

448

# Calculate totals and averages

449

total_formula = SUM(Field('Q1_Sales'), Field('Q2_Sales'), Field('Q3_Sales'), Field('Q4_Sales'))

450

451

# Conditional calculations

452

bonus_formula = IF(

453

Field('Sales_Total').gt(100000),

454

Field('Sales_Total') * 0.1, # 10% bonus

455

0

456

)

457

458

# Rounded averages

459

avg_score = ROUND(AVERAGE(Field('Score1'), Field('Score2'), Field('Score3')), 2)

460

```

461

462

#### Date and Time Operations

463

464

```python

465

from pyairtable.formulas import DATEADD, DATETIME_DIFF, DATETIME_FORMAT, IS_AFTER

466

import datetime

467

468

# Date arithmetic

469

deadline_formula = DATEADD(Field('Start_Date'), 30, 'days')

470

471

# Date comparisons

472

overdue_formula = IS_AFTER(Formula('TODAY()'), Field('Due_Date'))

473

474

# Date formatting

475

formatted_date = DATETIME_FORMAT(Field('Created_Date'), 'MM/DD/YYYY')

476

477

# Time calculations

478

project_duration = DATETIME_DIFF(Field('End_Date'), Field('Start_Date'), 'days')

479

```

480

481

#### Text Processing

482

483

```python

484

from pyairtable.formulas import CONCATENATE, UPPER, LEFT, FIND

485

486

# String concatenation

487

full_name = CONCATENATE(Field('First_Name'), ' ', Field('Last_Name'))

488

489

# Text formatting

490

formatted_code = CONCATENATE('ID-', UPPER(LEFT(Field('Name'), 3)))

491

492

# Text search and validation

493

has_email = FIND('@', Field('Email')).gt(0)

494

```

495

496

#### Advanced Pattern Matching

497

498

```python

499

# Using match() with multiple operators

500

advanced_filter = match({

501

'Salary': ('>', 75000),

502

'Experience': ('>=', 3),

503

'Department': 'Engineering',

504

'Status': 'Active'

505

}, match_any=False) # All conditions must match

506

507

# Alternative matching (any condition)

508

priority_candidates = match({

509

'Referral': True,

510

'Experience': ('>', 10),

511

'Education': 'PhD'

512

}, match_any=True) # Any condition matches

513

514

# Combining with other logic

515

final_filter = AND(

516

advanced_filter,

517

OR(priority_candidates, match({'Urgency': 'High'}))

518

)

519

```

520

521

#### Field Reference Utilities

522

523

```python

524

# Utility functions for field names and escaping

525

from pyairtable.formulas import field_name, quoted

526

527

# Handle field names with special characters

528

special_field = field_name("Field with spaces & symbols")

529

# Results in: {Field with spaces & symbols}

530

531

# Properly quote string values

532

search_value = quoted("Text with 'quotes' and \\ backslashes")

533

# Results in: 'Text with \'quotes\' and \\\\ backslashes'

534

535

# Convert Python values to formula strings

536

from pyairtable.formulas import to_formula_str

537

538

formula_string = to_formula_str(datetime.date(2023, 12, 25))

539

# Results in: DATETIME_PARSE('2023-12-25')

540

```