# pyquickbase API reference: Metadata This describes version 1.0.0rc13. Other pages: [Quickbase](https://matthew-williams-solutions.github.io/pyquickbase/reference/quickbase.txt), [App](https://matthew-williams-solutions.github.io/pyquickbase/reference/app.txt), [Table](https://matthew-williams-solutions.github.io/pyquickbase/reference/table.txt), [Report](https://matthew-williams-solutions.github.io/pyquickbase/reference/report.txt), [Operation](https://matthew-williams-solutions.github.io/pyquickbase/reference/operation.txt), [SchemaOperation](https://matthew-williams-solutions.github.io/pyquickbase/reference/schema-operation.txt), [Queries](https://matthew-williams-solutions.github.io/pyquickbase/reference/queries.txt), [Records and results](https://matthew-williams-solutions.github.io/pyquickbase/reference/records.txt), [Schema changes](https://matthew-williams-solutions.github.io/pyquickbase/reference/schema-changes.txt), [Policies](https://matthew-williams-solutions.github.io/pyquickbase/reference/policies.txt), [Rules](https://matthew-williams-solutions.github.io/pyquickbase/reference/rules.txt), [Retries](https://matthew-williams-solutions.github.io/pyquickbase/reference/retries.txt), [Tools for models](https://matthew-williams-solutions.github.io/pyquickbase/reference/tools.txt), [Errors](https://matthew-williams-solutions.github.io/pyquickbase/reference/errors.txt). These describe an app and what's in it. The client caches them for five minutes by default, and each holds everything Quickbase returned in `raw`. The examples below use `tasks`, made as shown here, and `app`, which is `qb.app("bq1234567")`. `Job Tasks` has `Title`, `Status`, `Hours`, `Due Date`, `Code`, which is unique, and `Attachment`. It starts with three records, and each example starts from those again. A live test runs every example with both clients and checks its output. `projects` is a table named `Job Projects`, with a `Name` field. Sync: ```python from pyquickbase import Quickbase with Quickbase( realm="acme", token="your_user_token" ) as qb: tasks = qb.app("bq1234567").table("Job Tasks") ``` Async: ```python from pyquickbase import AsyncQuickbase async with AsyncQuickbase( realm="acme", token="your_user_token" ) as qb: tasks = qb.app("bq1234567").table("Job Tasks") ``` ## Apps For the full picture, see [Reading records](https://matthew-williams-solutions.github.io/pyquickbase/guides/reading/). ### `AppInfo` An app's metadata. **Attributes** - **`id`** `str` The app's ID. - **`name`** `str` The app's name. - **`description`** `str` The app's description, which may be empty. - **`time_zone`** `str | None` The app's time zone, such as `(UTC) Coordinated Universal Time`, if reported. - **`date_format`** `str | None` How the app writes dates, such as `MM-DD-YYYY`, if reported. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. Sync example: ```python info = app.info() print(info.id) ``` Async example: ```python info = await app.info() print(info.id) ``` Output: ```text bq1234567 ``` ### `Role` A role in an app. **Attributes** - **`id`** `int` The role's ID. - **`name`** `str` The role's name. - **`access`** `str` Quickbase's name for its level, such as `Basic Access`. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. Sync example: ```python for role in app.roles(): if role.name == "Administrator": print(role.name, role.access) ``` Async example: ```python for role in await app.roles(): if role.name == "Administrator": print(role.name, role.access) ``` Output: ```text Administrator Administrator ``` ### `AppEvent` Something in an app that runs when records change or on a schedule, such as a webhook. Quickbase lists webhooks, Quickbase actions, email notifications, subscriptions, reminders, and automations that records trigger. It leaves out scheduled automations, and doesn't say which changes set each one off. **Attributes** - **`type`** `str` `webhook`, `qb-action`, `email-notification`, `subscription`, `reminder`, or `automation`. - **`name`** `str | None` Its name. Quickbase doesn't name automations, so it's None for those. - **`active`** `bool` Whether it's switched on. - **`table_id`** `str | None` The table it watches, if Quickbase said. - **`url`** `str | None` For an automation, a link to it in Quickbase. - **`owner`** `User | None` Who owns it, or None if the client's policy leaves it out. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. - **`runs_on_changes`** `bool` Whether a change to records can set it off. Subscriptions and reminders run on a schedule instead. Sync example: ```python for event in tasks.events(): if event.active and event.runs_on_changes: print(event.type, event.name or event.url) ``` Async example: ```python for event in await tasks.events(): if event.active and event.runs_on_changes: print(event.type, event.name or event.url) ``` ## Tables and reports For the full picture, see [Reading records](https://matthew-williams-solutions.github.io/pyquickbase/guides/reading/). ### `TableInfo` A table's metadata. **Attributes** - **`id`** `str` The table's ID. - **`name`** `str` The table's name. - **`description`** `str` The table's description, which may be empty. - **`key_field_id`** `int | None` The ID of the table's key field, which is 3, `Record ID#`, unless someone changed it in the Quickbase interface. None if Quickbase left it out. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. Sync example: ```python info = tasks.info() print(info.name, info.key_field_id) ``` Async example: ```python info = await tasks.info() print(info.name, info.key_field_id) ``` Output: ```text Job Tasks 3 ``` ### `ReportInfo` A report's metadata. **Attributes** - **`id`** `str` The report's ID. - **`name`** `str` The report's name. - **`type`** `str` `table`, `summary`, `chart`, or another Quickbase type. - **`description`** `str` The report's description, which may be empty. - **`incomplete`** `bool` Whether Quickbase can't run the report through the API, as with one that asks the user for a value. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. Sync example: ```python reports = tasks.reports() first = reports[0] print(first.name, first.type, first.incomplete) ``` Async example: ```python reports = await tasks.reports() first = reports[0] print(first.name, first.type, first.incomplete) ``` Output: ```text List All table False ``` ## Fields and relationships For the full picture, see [Changing the schema](https://matthew-williams-solutions.github.io/pyquickbase/guides/schema/). ### `Field` A field's metadata. **Attributes** - **`id`** `int` The field's ID. - **`label`** `str` The field's label. - **`type`** `str` Quickbase's name for the field's type, such as `text` or `numeric`. - **`mode`** `str | None` `formula`, `lookup`, `summary`, or None for a plain field. - **`required`** `bool` Whether the field must have a value. - **`unique`** `bool` Whether values must be different on every record. - **`appears_by_default`** `bool` Whether a query returns the field when `select` is left out. - **`choices`** `tuple[str, ...]` The options of a multiple-choice field, or empty for other fields. - **`allow_new_choices`** `bool` Quickbase's `allowNewChoices` setting, or False if it isn't reported. - **`formula`** `str | None` The formula's text, or None if the field doesn't have one. - **`help_text`** `str` The help Quickbase shows beside the field on forms, which may be empty. - **`decimal_places`** `int | None` Only how a number is displayed: Quickbase still stores `1.5` in a field set to 0 places. - **`is_foreign_key`** `bool` Whether the field links to a parent table's record. - **`lookup_reference_field_id`** `int | None` For a lookup, the foreign key field on this table. - **`lookup_target_field_id`** `int | None` For a lookup, the field it reads on the parent. - **`summary_reference_field_id`** `int | None` For a summary, the foreign key field on the child table. - **`summary_target_field_id`** `int | None` For a summary, the field it reads on the child. - **`summary_function`** `str | None` For a summary, Quickbase's name for its calculation, such as `SUM`. - **`summary_query`** `str | None` For a summary, the filter on which child records it combines, such as `{7.EX.true}`, or None for all of them. On a client with a policy it's None unless the client can read every field the filter uses on the child table. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. Sync example: ```python for field in tasks.fields(): if field.label == "Status": print(field.id, field.type, field.mode) print(sorted(field.choices), field.required) ``` Async example: ```python for field in await tasks.fields(): if field.label == "Status": print(field.id, field.type, field.mode) print(sorted(field.choices), field.required) ``` Output: ```text 7 text-multiple-choice None ['Done', 'Open'] False ``` ### `FieldUsage` Where a field is used in its app, as counted on the field's Usage page in Quickbase. Quickbase counts a field in the reports it makes for every table, so most fields have a few uses. Counts can take a few seconds to include a change. **Attributes** - **`field_id`** `int` The field's ID. - **`label`** `str` The field's label. - **`counts`** `Mapping[str, int]` How many of each kind of thing use it, such as `{"reports": 2, "forms": 1}`, leaving out the kinds that don't. A kind Quickbase adds later is included too. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. - **`total`** `int` How many things use the field in all. #### `FieldUsage.describe()` The uses in words, most first, such as `2 reports and 1 form`, or `nothing`. ```python describe() -> str ``` **Returns** `str` Sync example: ```python [usage] = tasks.field_usage("Title") print(usage.field_id, usage.label) print(usage.counts["default_reports"], usage.total > 0) print("report" in usage.describe()) ``` Async example: ```python [usage] = await tasks.field_usage("Title") print(usage.field_id, usage.label) print(usage.counts["default_reports"], usage.total > 0) print("report" in usage.describe()) ``` Output: ```text 6 Title 1 True True ``` ### `Relationship` A parent-child link between two tables. `create_relationship()` and `ensure_lookup_field()` take the parent's field to look up, which isn't what `lookup_field_ids` holds. **Attributes** - **`id`** `int` The relationship's ID. - **`parent_table_id`** `str` The parent table's ID. - **`child_table_id`** `str` The child table's ID. - **`foreign_key_field_id`** `int | None` The child's field that holds the parent's Record ID#, if reported. - **`lookup_field_ids`** `tuple[int, ...]` The lookup fields, which are on the child. - **`summary_field_ids`** `tuple[int, ...]` The summary fields, which are on the parent. - **`is_cross_app`** `bool` Whether Quickbase reports the parent as being in another app. - **`raw`** `Mapping[str, Any]` Everything Quickbase returned, for anything not listed here. Sync example: ```python relationship = tasks.ensure_relationship( projects, foreign_key="Project" ) print(relationship.foreign_key_field_id) print( relationship.lookup_field_ids, relationship.is_cross_app ) ``` Async example: ```python relationship = await tasks.ensure_relationship( projects, foreign_key="Project" ) print(relationship.foreign_key_field_id) print( relationship.lookup_field_ids, relationship.is_cross_app ) ``` Output: ```text 12 () False ``` ### `TableSchema` A table's fields and the relationships in which it's the child, as the client can see them. **Attributes** - **`info`** `TableInfo` The table's details. - **`fields`** `tuple[Field, ...]` Its fields. - **`relationships`** `tuple[Relationship, ...]` The relationships in which it's the child. Sync example: ```python describe = app.operation("describe_schema") (schema,) = describe.run({"tables": ["Job Tasks"]}) print(schema.info.name, len(schema.fields)) ``` Async example: ```python describe = await app.operation("describe_schema") (schema,) = await describe.run({"tables": ["Job Tasks"]}) print(schema.info.name, len(schema.fields)) ``` Output: ```text Job Tasks 11 ```