Field semantic inventory

Purpose and status

This document records the Baserow-specific knowledge currently encoded by baserowapi, the package’s settled semantic decisions, and evidence gaps that still require hosted verification. It does not expand the public API or promise support that the implementation does not currently provide.

The package is a schema-aware client for Baserow’s database-token data API. It provides behavior that callers would otherwise have to rediscover from Baserow, including field metadata, read and write representations, read-only rules, filtering, pagination, linked rows, file upload, and Baserow error responses. General Python collection helpers, permissive argument coercion, logging setup, and HTTP implementation details do not belong in the public contract unless they support one of those behaviors.

Evidence for this inventory was collected from:

  • package implementation and integration tests prepared for release 0.2.0b1;

  • a read-only schema request to the configured hosted baserow.io test table on 2026-09-01;

  • disposable hosted write probes on 2026-09-01 for boolean and rating nulls, number precision beyond the configured decimal places, and a datetime with a non-UTC ISO offset;

  • disposable hosted write probes on 2026-09-01 for select, link-row, and file IDs, labels, returned objects, comma-separated forms, empty forms, and nulls;

  • hosted upload and explicit row-assignment tests on 2026-09-01, including the distinct user-file original_name and attached-file visible_name payloads;

  • a disposable hosted row probe on 2026-09-02 confirming a raw Formula button object, Count decimal string, empty text Lookup list, UUID string, and Autonumber integer;

  • disposable hosted password probes on 2026-09-02 confirming that string, literal true, and null writes are accepted and that reads expose only true or null;

  • a read-only hosted table-discovery probe on 2026-09-02 confirming that the database-token all-tables endpoint returns a list containing integer table and database IDs, string names, and numeric order values;

  • the generated API documentation captured on 2026-09-01, visually checked on 2026-09-02 for configured filter lists, plus hosted equality and empty-result filter probes;

  • the maintainer’s generated API documentation for that database, captured on 2026-09-01 and kept as an ignored local test reference; and

  • Baserow’s current Database API documentation, field overview, and database token documentation.

Hosted Baserow is not version-pinned. Observations dated 2026-09-01 are compatibility evidence, not a claim about a particular Baserow release.

Support levels

Strong

The package encodes material Baserow behavior and integration tests exercise its important read and write forms.

Partial

The package has a dedicated type or behavior, but one or more important representations, settings, operations, or tests are missing or inconsistent.

Pass-through

The package mostly preserves the server value. The class name adds little or no semantic guarantee.

Fallback

An unknown type is preserved through GenericField. This supports reading but deliberately provides no validation or type-specific filtering.

Absent

Current Baserow documentation identifies the field category, but the package has no dedicated support and the configured test table does not exercise it.

Cross-cutting value pipeline

The current row model applies Field-owned semantics uniformly. The table below records the value pipeline.

Path

Current behavior

Guarantee

Required direction

Read row

row[name] decodes the requested raw value through its Field; values and raw_values expose read-only mappings.

Fields decode scalar and structured values in one place. Unknown fields and values remain raw and lossless.

Preserve Field ownership and explicit raw access.

Create rows

Table.add_row and Table.add_rows both validate and encode through each writable Field before sending a singular or batch request.

Singular create returns Row; plural create accepts a non-empty list and returns list[Row].

Keep one internal row encoder authoritative.

Update one Row

Row.update delegates persistence to Table.update_row and synchronizes itself from the returned Row. It requires an explicit mapping and has no staged mutation state.

The same Field encoder owns singular and plural update values.

Keep Row convenience behavior thin.

Batch update mappings

Mapping inputs with explicit row IDs use the same Field encoder. All local validation completes before the first request chunk.

Batch failures report the failed chunk and completed response row IDs; writes are not retried or rolled back.

Preserve this explicit non-atomic contract.

Filter rows

Table sends the sole JSON filter-tree encoding. Fields expose three-state advisory compatibility.

Supported, unsupported, and locally unknown operators are distinguished; no compatibility result blocks a normal query.

Keep structural Filter validation and allow unknown operators to reach the unpinned hosted service.

Unknown type

The Field mapping falls back to GenericField without routine warnings.

Raw values remain readable; writable unknown fields can be sent without semantic validation.

The fallback preserves the original type, metadata, and raw value as expected forward compatibility.

Table.FIELD_TYPE_CLASS_MAP is the sole semantic dispatch table. Fields own scalar and structured decoding, validation, and encoding; format_for_api remains a compatibility alias.

Field-by-field inventory

The read and write columns below describe current package behavior, not every shape the Baserow server may accept. All create and update paths use the field encoders described in the write column.

API type

Baserow knowledge

Current read value

Current accepted or encoded write

Level

Finding

text

Text default, primary-field metadata, text filters.

str or None.

str or None; no transformation.

Partial

The field provides schema metadata and scalar validation without wrapping the returned value. Local filters omit starts_with.

long_text

Text default and rich-text flag.

str or None.

str or None; Markdown semantics are not interpreted.

Partial

The field owns its metadata and scalar behavior. Local filters omit starts_with.

boolean

Boolean filter and API scalar shape.

bool.

Exactly bool; None is rejected locally.

Partial

Hosted baserow.io rejected a null write on 2026-09-01, confirming the non-null write policy.

number

Decimal-place and negative-number settings; numeric filters.

Hosted tests currently receive a decimal string such as "42.00".

int, float, numeric str, or None; value is returned unchanged after validation.

Partial

Reads remain lossless strings. Validation uses Decimal internally to avoid float conversion and enforces hosted precision and negativity settings without exposing Decimal. Local filters omit starts_with.

rating

Maximum value, color, style, and bounded integer validation.

Numeric value.

Integer from zero through max_value; None is rejected.

Partial

Hosted baserow.io rejected a null write on 2026-09-01. Local filters omit inclusive comparisons present in generated documentation.

date

Date-only versus datetime, display format, 12/24-hour display, timezone display, and forced timezone metadata.

ISO date or datetime str; explicit field helpers convert to date or timezone-aware datetime and format using field metadata.

Strict ISO strings, the corresponding Python date or aware datetime, or None. Encoding never invents missing date, time, or timezone information.

Partial

The current encoder rejects two-digit-year guessing, slash normalization, implicit midnight, local-machine display timezone, and unjustified Z handling. Hosted baserow.io accepted a non-UTC ISO offset and returned canonical UTC Z form on 2026-09-01. New date_is* filters remain missing while deprecated operators dominate the local list.

created_on

Computed timestamp and date display metadata.

ISO date or datetime str with date helpers.

Read-only; setter raises.

Partial

Read-only handling is valuable. Tests only check presence, not timestamp shape or field settings.

last_modified

Computed timestamp and date display metadata.

ISO date or datetime str with date helpers.

Read-only; setter raises.

Partial

Same semantic family as date and created_on with Field-owned read-only handling.

url

URL field identity and Baserow filters.

str or None.

Any str or None; URL form is not checked locally.

Partial

Baserow validates URL form, while the package only guarantees a string. Local filters omit starts_with.

email

Email field identity and Baserow filters.

str or None.

Any str or None; email form is not checked locally.

Partial

Baserow validates email form, while the package only guarantees a string. Local filters omit starts_with.

phone_number

Baserow’s 100-character limit and permitted character set.

str.

Empty, None, or a matching phone string.

Partial

The validator encodes real server knowledge. Local filters omit starts_with.

single_select

Option IDs, labels, colors, read object shape, write-by-ID-or-label, and first-match label behavior.

SelectOption retaining ID, label, color, and raw metadata, or None.

Option record, ID, label, returned option dictionary, or None; records returned by Baserow encode to their IDs.

Strong

The canonical option record preserves identity. resolve_option optionally rejects missing or duplicate labels. Local filters omit starts_with, single_select_is_any_of, and single_select_is_none_of.

multiple_select

Option metadata, read object list, and write-by-ID-or-label semantics.

List of SelectOption records retaining identity and raw metadata.

List of option records, IDs, labels, or returned dictionaries; comma-separated labels and empty lists follow hosted behavior.

Strong

Returned records round-trip by ID. Ordinary label writes retain hosted resolution behavior; the strict resolver rejects ambiguity on request.

link_row

Related table ID, reverse field ID, selection-view metadata, complete-set replacement semantics, empty-list clearing, and ID-or-primary-label writes.

List of LinkedRow records retaining table ID, row ID, display value, and raw metadata.

Linked-row records, returned dictionaries, single IDs/labels, lists, or comma-separated labels. Every update replaces the complete set.

Strong

get_linked_rows preserves IDs and honors the selection view. resolve_linked_row optionally rejects absent or ambiguous labels.

file

File object shape, upload endpoints, assignment after upload, public file URL, visible name, and size verification.

List of BaserowFile records retaining stored, visible, and original names plus returned metadata.

File records, returned dictionaries, stored filename forms, empty lists, or None. Upload methods return unattached records.

Strong

Client-level upload and explicit assignment separate the two Baserow operations. Generic downloading is outside the semantic core. Local filters omit files_lower_than.

formula

Formula text, result type, array result type, error, and read-only status.

Raw server value; the configured button is a label/url object.

Read-only.

Partial

The configured formula_type="button" result remains lossless and raw because no equivalent writable field exists. Other observed scalar formula types preserve the corresponding ordinary scalar representation.

count

Link-through metadata, numeric formula result, and read-only status.

Baserow decimal string, using the same decoding as a number field.

Read-only.

Partial

It reuses NumberField behavior and the complete configured filter list while remaining unconditionally read-only.

lookup

Link field, target field, array result metadata, row IDs, values, and read-only status.

List of LookupEntry records retaining row ID, raw entry, and an text inner value; unknown inner result shapes remain raw.

Read-only.

Partial

formula_type and array_formula_type are exposed. The configured text result uses ordinary text semantics; unobserved target result families remain raw rather than being guessed.

multiple_collaborators

Notification metadata, collaborator object shape, and collaborator filters.

List of Collaborator records retaining ID and returned metadata.

List of collaborator records or returned dictionaries; both encode to {"id": ...} objects.

Partial

Identity is preserved offline, but a non-empty hosted collaborator read and the complete documented write surface still need verification.

password

Write-only secret behavior: server reads are null or true and a string write sets the password.

Raw True or None; is_set provides an explicit boolean helper.

str, None, or literal True pass local validation.

Partial

Hosted baserow.io accepted all three write forms and returned only true or null on 2026-09-02. The client preserves the asymmetric wire state instead of converting it implicitly.

uuid

Read-only unique persistent identifier.

UUID string, with an explicit parse_value helper returning uuid.UUID.

Unconditionally read-only.

Strong

Dedicated metadata, equality-filter knowledge, and lossless string reads match the hosted field observed on 2026-09-02.

autonumber

Read-only monotonically assigned row number.

Hosted integer value without conversion.

Unconditionally read-only.

Strong

Dedicated metadata and configured comparison-filter knowledge preserve the hosted integer representation observed on 2026-09-02.

Other unknown API type

Original type string and arbitrary metadata are retained.

Raw server value.

Passed through if Baserow metadata does not mark the field read-only.

Fallback

This behavior is necessary because hosted Baserow changes independently of the package. Unknown writes should be explicitly documented as unvalidated rather than appearing fully supported.

Known field-category gaps

Baserow’s current field overview lists these categories in addition to those above. Their exact API type strings and wire representations have not been verified against the configured database, so display names must not be used as implementation keys without further evidence.

Baserow category

Expected character

Current handling

Evidence needed before implementation

Duration

Writable scalar with display-unit settings.

Generic fallback if encountered.

API type string, raw and write units, precision, metadata, and filters.

Rollup

Read-only computed scalar whose type depends on aggregation and target.

Generic fallback if encountered.

API type string, aggregation metadata, result types, null/error forms, and result-dependent filters.

Created by

Read-only collaborator-like value.

Generic fallback if encountered.

API type string, returned user object, visibility rules, and filters.

Last modified by

Read-only collaborator-like value.

Generic fallback if encountered.

API type string, returned user object, visibility rules, and filters.

AI prompt

Computed or asynchronously populated value.

Generic fallback if encountered.

Availability, API type, result and error states, mutability, and whether database-token use has additional restrictions.

Edit row link

Generated action/link value.

Generic fallback if encountered.

API type, returned representation, token/access behavior, and whether it belongs in a data client rather than an administrative client.

Test coverage inventory

The suite now combines credential-free characterization tests with hosted baserow.io integration tests. Offline payload assertions prove that every create and update route uses the Field encoder; hosted tests separately prove that representative encoded values remain compatible with the unpinned service. Singular and batch row writes were verified against hosted baserow.io on 2026-09-02.

Coverage

Fields

Missing assurance

Create and returned value

Text, long text, boolean, number, rating, three date configurations, URL, email, empty file, selects, phone, empty links, empty collaborators, and password.

Singular and batch encoder parity is covered. Non-empty collaborators and hosted duplicate-label configurations remain unverified.

Specialized operation

Date conversion/display, client file upload and upload-by-URL with explicit assignment, and linked-row discovery/update by ID.

Forced-timezone display, duplicate hosted primary labels, selection-view limits, and concurrent complete-set replacement remain unverified.

Presence only

Created on and last modified.

Their hosted shapes and filter behavior still need focused assertions.

Direct scalar field semantics

Text-like pass-through, boolean, rating, number, date/datetime, generic fallback, structured values with retained IDs, Count, UUID, Autonumber, and the evidenced Formula/Lookup results.

Unobserved computed result families remain raw pending hosted evidence; create/update encoding parity is covered.

What should remain central

The inventory supports retaining and strengthening these responsibilities:

  • database-token authentication, Baserow endpoints, pagination, and structured error interpretation;

  • table discovery and lazy schema retrieval, with a new Table instance used when callers need a fresh snapshot after an external schema change;

  • one field semantic authority for decoding, validation, encoding, read-only status, and result-dependent behavior;

  • row reads, singular and batch writes, movement, deletion, and uniform value encoding;

  • query construction for Baserow filters, ordering, search, views, includes, excludes, and pagination;

  • select-option and linked-row identity, including Baserow’s ambiguous label-resolution rules;

  • file upload and assignment; and

  • forward-compatible raw access for field types the package does not yet know.

These responsibilities do not require a public custom field list, a public custom row-value list, one RowValue subclass per Baserow type, global logging configuration, or multiple public request-parsing helpers. Row convenience methods can remain if they delegate to the same singular or batch primitives and therefore preserve one semantic implementation.

Settled design decisions

These decisions describe the current contract prepared for release 0.2.0b1.

Focus and authority

baserowapi focuses on the schema-aware database-token data API. It encodes Baserow field, query, row, file, and error behavior without growing into a complete administration SDK or a general HTTP framework.

Each Field is the single semantic authority for decoding a Baserow response, validating a supported input, encoding an API write, reporting read-only status, exposing advisory filter knowledge, and interpreting computed result metadata. Create, single-update, and batch-update operations use the same field encoder.

Scalar representations

Ordinary reads preserve Baserow scalar representations:

  • Number values remain Baserow decimal strings, including significant trailing zeroes such as "42.00". Validation may use Decimal internally but will not expose Decimal as the row value.

  • Date-only values remain ISO date strings and datetime values remain ISO timestamp strings.

  • Explicit date helpers may parse date-only values to date and datetime values to timezone-aware datetime. Display formatting is also explicit and may apply field metadata such as date_force_timezone.

  • Date writes accept None, the appropriate Python date or timezone-aware datetime, and strict ISO strings. The core path does not guess two-digit years, accept locale-dependent slash formats, assume midnight, append an unjustified Z, or silently use the executing machine’s timezone.

Documented inputs and validation

The core client accepts every input representation documented by Baserow. This includes IDs, labels, lists, comma-separated strings, and empty forms where the relevant field documentation permits them. The package documents Baserow’s first-match behavior for ambiguous option labels and linked-row primary values instead of imposing a narrower contract.

Optional strict helpers may resolve stable IDs and reject absent or ambiguous labels. Local validation enforces stable structural rules but does not use a stale local compatibility matrix to block behavior accepted by the unpinned hosted service. Convenience coercions not documented by Baserow must be explicit, deterministic helpers rather than implicit core behavior.

Structured values with retained IDs

Reads use small, lossless domain objects when Baserow identity or structure would otherwise be discarded. Initial concepts include:

  • a select option retaining ID, value, color, and raw metadata;

  • a linked-row reference retaining row ID, display value, and raw metadata;

  • a Baserow file retaining its server name, visible name, URL, size, MIME type when present, and raw metadata;

  • a collaborator retaining user ID, available display information, and raw metadata; and

  • a lookup entry retaining related row ID, decoded value, and raw metadata.

These are independent value records, not a shared hierarchy or capability framework. They use ordinary Python collections, contain no HTTP behavior, and remain suitable as write inputs. Scalar values are not wrapped merely for symmetry.

Computed fields

Formula, lookup, count, rollup, and other computed fields decode according to result metadata such as formula_type and array_formula_type as well as their declared field type. They reuse the corresponding scalar or structured representation. Count uses number-field decoding; computed dates use date semantics; computed select or linked values preserve identity.

Computed fields remain read-only when their hosted metadata says so. Unknown result types, including unverified button, AI, and error states, remain raw until their representations are observed. The package does not collapse a formula error or unfamiliar result into None.

Unknown fields

Unknown hosted field types are expected compatibility cases. Their original API type and raw metadata remain inspectable. Reads return the raw value unchanged; writes pass values through unchanged only when hosted metadata marks the field writable. The package does not claim validation, formatting, or filter knowledge for an unknown type. Unknown types do not produce a warning for every field and row. GenericField is the public fallback for unknown hosted types. GenericField.TYPE == "generic" is an internal sentinel; current repository evidence does not establish generic as a hosted Baserow field type. The explicit registry entry remains for compatibility with callers that inspect Table.FIELD_TYPE_CLASS_MAP. Registry lookup also falls back to the same class for every unknown type.

Filters

Normal filter validation covers stable query structure and does not enforce the compatibility lists. Operator names and values pass through to Baserow. FilterCompatibility reports supported, unsupported, or unknown as advisory package knowledge. Field.compatible_filters is an immutable tuple, with identical family knowledge defined once on the nearest common Field base.

The JSON filter-tree representation used by row queries is authoritative. The detached FilterValidator and unused legacy Filter.query_string have been removed. Recursive groups are supported only to the extent verified in current Baserow documentation and hosted behavior.

Rows, containers, and transport

Table.fields and Table.writable_fields are ordered read-only mappings from field name to Field. Row.values is an ordered read-only mapping of Field-decoded values, and Row.raw_values exposes the original Baserow values. The custom FieldList and RowValue containers and all per-type RowValue classes have been removed.

row.update({...}) is the Row update operation. Row item assignment and no-argument staged updates have been removed so raw, decoded, and pending state cannot diverge. Row operation conveniences remain thin delegates to the same Table primitives used for singular requests; batch updates require explicit mappings with row IDs.

Table.get_rows eagerly returns list[Row] and Table.iter_rows lazily returns an iterator. There is no return-type flag or arbitrary query-keyword escape hatch. Each hosted page must contain a results list and an explicit next URL or None before any rows from that page are exposed.

Table.delete_row and Table.move_row own their singular endpoints; Row.delete and Row.move delegate to them. A moved Row is synchronized from the response and returned as the same instance. Table.delete_rows accepts a non-empty list of row IDs, validates all of them before its first request, and reports completed IDs if a later non-atomic chunk fails.

Each Table lazily loads and caches one field-schema snapshot. get_table remains uncached, so callers can construct a new Table after a schema change made through the Baserow UI or a separate administrative client. Database tokens cannot mutate schema, and no current application requires in-place refresh semantics for existing Table and Row objects. The package does not add a schema-refresh method until that need and its Row behavior are demonstrated.

Baserow.make_api_request is the single request boundary for authentication, same-origin URL enforcement, timeouts, safe-read retries, connectivity and HTTP failures, JSON parsing, and Baserow error extraction. Header combination, request execution, session state, and response parsing are private. The method remains a documented low-level escape hatch for hosted database-token endpoints not yet modeled by the package; it provides transport and error handling, not schema semantics or endpoint stability. GET and HEAD requests retry configured transient failures with backoff, while mutating requests are never retried.

Baserow.get_tables uses the database-token discovery endpoint and returns Tables retaining name, database ID, order, and the complete returned metadata. The package emits ordinary logging records without configuring application logging or recording request payloads and file values.

Evidence still required

The design direction is settled, but implementation still requires evidence for several hosted representations:

  • non-empty collaborator reads and every documented collaborator write form;

  • exact API types, metadata, read values, write values, and filters for Duration, Rollup, Created by, Last modified by, AI prompt, and Edit row link;

  • formula and rollup values for each result family, including per-field and per-cell error states;

  • lookup entries whose target is not text;

  • current nested filter-group limits and serialization; and

  • duplicate select labels and linked primary values, selection-view limits, and complete-set replacement behavior.

Do not invent an API type string, result shape, or validation rule to fill these gaps. Add a live field to the disposable test database, inspect the generated documentation and response, record sanitized fixtures, and describe hosted compatibility by verification date.

The implementation sequence and phase exit criteria are recorded in Semantic refactoring plan.