pyquickbase¶
A typed Python SDK for the Quickbase API, with matching sync and async clients, and policies that limit what a client, or an AI agent, can do.
Get started Try it in your browser
from datetime import date
from pyquickbase import F, Quickbase
with Quickbase(realm="acme", token="your_user_token") as qb:
tasks = qb.app("bq1234567").table("Tasks")
overdue = (F("Status") != "Done") & (F("Due Date") < date.today())
for task in tasks.query(where=overdue, select=["Title", "Due Date"], order_by="-Due Date"):
print(task.id, task["Title"], task["Due Date"])
tasks.update([{"Record ID#": 7, "Status": "Done"}])
Why use it¶
-
Names, not IDs
Field labels and table names everywhere, with real
dateanddatetimevalues. -
Queries that can't silently fail
F("Status") == "Done"instead of{7.EX.'Done'}, checked before it's sent. -
Errors that say what happened
A failed row raises
WriteError, listing what was written and what wasn't. -
Limit a client to the tables, fields, and records its job needs.
-
Typed operations for tool calls, results as plain data, and these docs as llms.txt.
The Quickbase REST API accepts many mistakes without complaint. A lowercase operator acts like
"contains", an unknown field matches nothing, a failed row sits inside a successful response, and
writing null to a field does nothing. This SDK turns those into errors or correct behavior.
| With the REST API | With pyquickbase |
|---|---|
| Numeric field IDs everywhere | Field labels and table names, or IDs if you prefer |
{7.EX.'Done'}AND{9.BF.'today'} |
(F("Status") == "Done") & (F("Due Date") < date.today()) |
| Broken queries return plausible results | Broken queries raise QueryError before sending |
Manual skip and top paging |
for record in table.query(...) |
Rows like {"7": {"value": "Done"}} |
record["Status"], with real date and datetime values |
| Failed rows inside a successful response | WriteError, listing what failed and what was written |
See the difference¶
You import three rows, and one has an invalid status:
rows = [
{"Title": "Order chairs", "Status": "Open"},
{"Title": "Book venue", "Status": "Finished"}, # Not a valid status
{"Title": "Send invites", "Status": "Open"},
]
The REST API saves the other two and returns HTTP 207. That's a success status, so a normal check passes, and the failed row is only listed inside the response body:
response = httpx.post(url, headers=headers, json=body)
response.raise_for_status() # Passes, because 207 is a success status
print("Import finished") # But one row wasn't saved
pyquickbase checks the response for you and raises an error that says what happened:
try:
tasks.insert(rows)
except WriteError as error:
print("Saved:", error.result.created_ids)
for failed in error.result.errors:
print("Failed:", rows[failed.index]["Title"], "-", *failed.messages)
Saved: (25, 26)
Failed: Book venue - The field with ID '7' has an invalid choice.
Try it in the playground, which uses simulated data based on recorded API behavior.
Install¶
pip install pyquickbase==1.0.0rc13
It needs Python 3.11 or newer. Next, see Getting started.