Skip to content

Markdown

App

An App lists an app's details and gives you its tables. Get one from Quickbase.app(). Getting one doesn't contact Quickbase, so an ID that doesn't exist only fails on first use.

The examples below use app, made as shown here, in an app that has a table named Job Tasks with three records. A live test runs every example with both clients and checks its output. AsyncApp has the same methods, which you await, but table(), url(), and settings_url() are called without it.

from pyquickbase import Quickbase

with Quickbase(
    realm="acme", token="your_user_token"
) as qb:
    app = qb.app("bq1234567")
from pyquickbase import AsyncQuickbase

async with AsyncQuickbase(
    realm="acme", token="your_user_token"
) as qb:
    app = qb.app("bq1234567")

Look up the app's details

For the full picture, see Reading records.

The app's ID

The app's ID, as passed to qb.app().

id: str

Example

print(app.id)
print(app.id)

Output

bq1234567

Get the app's details

Get the app's metadata, from the client's cache if it's there.

Returns AppInfo

An AppInfo, with the app's id, name, description, time_zone, and date_format.

Raises

info() -> AppInfo

Example

info = app.info()
print(info.id)
info = await app.info()
print(info.id)

Output

bq1234567

List tables

List the app's tables, from the cache unless refresh is set.

Parameters

  • refresh bool, default False
    Ask Quickbase instead of using the client's cache, which keeps metadata for five minutes by default. A change made through this client updates the cache, so this is for changes made elsewhere, such as in the Quickbase interface.

Returns list[ TableInfo ]

A TableInfo for each table the token can see.

Raises

  • AuthenticationError: Quickbase doesn't recognize the app ID. It answers with a 401 here, rather than a 404.
tables(*, refresh: bool = False) -> list[TableInfo]

Example

tables = app.tables()
print(sorted(t.name for t in tables if "Job" in t.name))
tables = await app.tables()
print(sorted(t.name for t in tables if "Job" in t.name))

Output

['Job Projects', 'Job Tasks']

List roles

List the app's roles, from the cache unless refresh is set.

Quickbase has no API for reading or changing what a role can do.

Parameters

  • refresh bool, default False
    Ask Quickbase instead of using the client's cache, which keeps metadata for five minutes by default. A change made through this client updates the cache, so this is for changes made elsewhere, such as in the Quickbase interface.

Returns list[ Role ]

A Role for each role in the app.

Raises

roles(*, refresh: bool = False) -> list[Role]

Example

roles = app.roles()
print(any(role.name == "Administrator" for role in roles))
roles = await app.roles()
print(any(role.name == "Administrator" for role in roles))

Output

True

List webhooks and automations

List the app's webhooks, Quickbase actions, notifications, subscriptions, reminders, and the automations that records trigger.

Quickbase leaves out scheduled automations, and doesn't say which changes set each one off. With a policy, only events on tables it shows are listed, without their owners.

Returns list[ AppEvent ]

An AppEvent for each, active or not.

Raises

events() -> list[AppEvent]

Example

events = app.events()
print([event.type for event in events if event.active])
events = await app.events()
print([event.type for event in events if event.active])

Output

[]

Get a table

For the full picture, see Reading records.

Get a table

Get a table in this app by name or ID. It's checked when first used.

This doesn't contact Quickbase, so a table that doesn't exist raises UnknownTableError on first use.

Parameters

  • name_or_id str, required
    The table's name, or its ID.

Returns Table

A Table.

table(name_or_id: str) -> Table

Example

tasks = app.table("Job Tasks")
print(tasks.count())
tasks = app.table("Job Tasks")
print(await tasks.count())

Output

3

For the full picture, see Using pyquickbase from an AI agent.

Link to the app

Link to the app's home page in Quickbase. This makes no network calls.

Returns str

The URL, on the client's realm.

url() -> str

Example

print(app.url())
print(app.url())

Output

https://acme.quickbase.com/nav/app/bq1234567/action/appoverview

Link to the app's settings

Link to the app's settings in Quickbase. This makes no network calls.

Returns str

The URL, on the client's realm.

settings_url() -> str

Example

print(app.settings_url())
print(app.settings_url())

Output

https://acme.quickbase.com/nav/app/bq1234567/action/appsettingshome

Create tables

For the full picture, see Changing the schema.

Get or create a table

Return the table with this name, creating it if it doesn't exist.

This makes a setup script safe to run again. An existing table isn't changed.

Parameters

  • name str, required
    The table's name, ignoring case when looking for an existing table.
  • description str | None, optional
    The new table's description.
  • single_record_name str | None, optional
    What the new table calls one record, such as Project.
  • plural_record_name str | None, optional
    What the new table calls several records, such as Projects.

Returns Table

A Table for the existing or new table.

Raises

ensure_table(
    name: str,
    *,
    description: str | None = None,
    single_record_name: str | None = None,
    plural_record_name: str | None = None,
) -> Table

Example

sites = app.ensure_table("Job Sites")
again = app.ensure_table("Job Sites")
first_info = sites.info()
again_info = again.info()
print(first_info.id == again_info.id)
sites = await app.ensure_table("Job Sites")
again = await app.ensure_table("Job Sites")
first_info = await sites.info()
again_info = await again.info()
print(first_info.id == again_info.id)

Output

True

Create a table

Create a table and return it.

Parameters

  • name str, required
    The table's name.
  • description str | None, optional
    The table's description.
  • single_record_name str | None, optional
    What the table calls one record, such as Project.
  • plural_record_name str | None, optional
    What the table calls several records, such as Projects.

Returns Table

A Table for the new table.

Raises

create_table(
    name: str,
    *,
    description: str | None = None,
    single_record_name: str | None = None,
    plural_record_name: str | None = None,
) -> Table

Example

sites = app.create_table(
    "Job Sites",
    description="Where each job takes place.",
    single_record_name="Site",
    plural_record_name="Sites",
)
info = sites.info()
print(info.name)
sites = await app.create_table(
    "Job Sites",
    description="Where each job takes place.",
    single_record_name="Site",
    plural_record_name="Sites",
)
info = await sites.info()
print(info.name)

Output

Job Sites

Change the schema with a plan

For the full picture, see Changing the schema.

Preview schema changes

Work out what schema changes would do, without making them.

Each change is compared with the app as it is now, in order, so a later one can use a table or field an earlier one makes. The plan says what each would set, what else it would do or affect, such as records that lose a deleted field's values, and anything that stops it, including the client's own limits. A change the app already has counts as done, so planning again after a failed apply shows only what's left.

This only reads. It may count records, and look for duplicates before making a field unique, reading up to 10,000 records.

Parameters

  • changes Sequence[SchemaChange], required
    The changes, such as CreateField(table="Tasks", label="Due", type="date").

Returns SchemaPlan

A SchemaPlan, for apply_schema_changes().

Raises

preview_schema_changes(
    changes: Sequence[SchemaChange],
) -> SchemaPlan

Example

from pyquickbase import CreateField

change = CreateField(
    table="Job Tasks", label="Crew", type="text"
)
plan = app.preview_schema_changes([change])
for planned in plan.changes:
    print(planned.status, planned.summary)
from pyquickbase import CreateField

change = CreateField(
    table="Job Tasks", label="Crew", type="text"
)
plan = await app.preview_schema_changes([change])
for planned in plan.changes:
    print(planned.status, planned.summary)

Output

ready Add field "Crew" (text) to Job Tasks.

Apply schema changes

Make the changes in a plan, in order, if the app hasn't changed since it was made.

The changes are planned again first, and nothing is sent unless that finds the same schema and nothing stopping them. Quickbase has no way to undo a change, so if one fails, the ones before it stay made, and the ones after it aren't attempted.

Parameters

Returns SchemaChangeResult

A SchemaChangeResult, with what was made and what was already there.

Raises

apply_schema_changes(
    plan: SchemaPlan,
) -> SchemaChangeResult

Example

from pyquickbase import CreateField

change = CreateField(
    table="Job Tasks", label="Crew", type="text"
)
plan = app.preview_schema_changes([change])
result = app.apply_schema_changes(plan)
print(len(result.applied))
again = app.preview_schema_changes([change])
print(again.changes[0].status)
from pyquickbase import CreateField

change = CreateField(
    table="Job Tasks", label="Crew", type="text"
)
plan = await app.preview_schema_changes([change])
result = await app.apply_schema_changes(plan)
print(len(result.applied))
again = await app.preview_schema_changes([change])
print(again.changes[0].status)

Output

1
already_done

Give a model the schema

For the full picture, see Using pyquickbase from an AI agent.

Make a schema tool for a model

Make a schema operation into a tool for a model, with its JSON Schema.

describe_schema lists the tables and fields the client can read. preview_schema_changes says what a list of changes would do, without making them, and apply_schema_changes makes them, but only with the confirmation that preview_schema_changes returned for exactly those changes, within 15 minutes, while the schema is as it was then. Show the person each plan before they approve it.

The schema offers only the kinds of change, tables, and field types the client's policy allows, and a plan reports anything it would refuse. Give the model a client with a policy, so that what it can change and see is limited, and a formula, lookup, or summary it adds can only show what it could already read.

plan = app.operation(
    "preview_schema_changes"
)
tool = {
    "name": "plan_changes",
    "input_schema": plan.schema,
}
result = plan.run(arguments)

Parameters

  • name SchemaOperationName, required
    describe_schema, preview_schema_changes, or apply_schema_changes.
  • max_changes int, default 20
    The most changes one plan may hold.

Returns SchemaOperation

A SchemaOperation, with its schema and run().

Raises

  • ConfigurationError: name isn't a schema operation, max_changes isn't a positive whole number, or the client's policy allows no schema change for preview_schema_changes or apply_schema_changes.
operation(
    name: SchemaOperationName, *, max_changes: int = 20
) -> SchemaOperation

Example

plan = app.operation(
    "preview_schema_changes", max_changes=5
)
print(plan.schema["properties"]["changes"]["maxItems"])
plan = await app.operation(
    "preview_schema_changes", max_changes=5
)
print(plan.schema["properties"]["changes"]["maxItems"])

Output

5

Copy or delete the app

For the full picture, see Working with apps.

Copy the app

Copy this app, with the same tables, fields, reports, and forms, and return the copy.

Parameters

  • name str, required
    The copy's name. Quickbase allows several apps with the same name.
  • description str | None, optional
    The copy's description.
  • keep_data bool, default False
    Copy the records too.
3 more: keep_files, keep_users, assign_token
  • keep_files bool, default False
    With keep_data, copy file attachments too.
  • keep_users bool, default False
    Give the copy's users the roles they have here. Otherwise the roles are copied without anyone in them.
  • assign_token bool, default True
    Let this client's token reach the copy, which a token limited to some apps can't otherwise do.

Returns App

An App for the copy.

Raises

copy(
    name: str,
    *,
    description: str | None = None,
    keep_data: bool = False,
    keep_files: bool = False,
    keep_users: bool = False,
    assign_token: bool = True,
) -> App

Example

staging = app.copy("Jobs (staging)")
print(staging.id != app.id)
staging = await app.copy("Jobs (staging)")
print(staging.id != app.id)

Output

True

Delete the app

Delete this app, with all its tables and records. Quickbase can't undo this.

Parameters

  • confirm str, required
    The app's exact name, so a wrong variable can't delete the wrong app.

Raises

drop(*, confirm: str) -> None

Example

staging = app.copy("Jobs (staging)")
staging.drop(confirm="Jobs (staging)")
staging = await app.copy("Jobs (staging)")
await staging.drop(confirm="Jobs (staging)")