Source code for pyairtable.models.schema

import importlib
from datetime import datetime
from enum import Enum
from functools import partial
from typing import (
    TYPE_CHECKING,
    Any,
    Dict,
    Iterable,
    List,
    Literal,
    Optional,
    TypeVar,
    Union,
    cast,
)

import pydantic
from typing_extensions import TypeAlias

from pyairtable.api.types import AddCollaboratorDict
from pyairtable.models._base import (
    AirtableModel,
    CanDeleteModel,
    CanUpdateModel,
    RestfulModel,
    rebuild_models,
)

if TYPE_CHECKING:
    from pyairtable import orm


[docs]class FieldType(str, Enum): """ Enumeration of all field types supported by Airtable. Usage: >>> from pyairtable.models.schema import FieldType >>> FieldType.SINGLE_LINE_TEXT FieldType('singleLineText') """ AI_TEXT = "aiText" AUTO_NUMBER = "autoNumber" BARCODE = "barcode" BUTTON = "button" CHECKBOX = "checkbox" COUNT = "count" CREATED_BY = "createdBy" CREATED_TIME = "createdTime" CURRENCY = "currency" DATE = "date" DATE_TIME = "dateTime" DURATION = "duration" EMAIL = "email" EXTERNAL_SYNC_SOURCE = "externalSyncSource" FORMULA = "formula" LAST_MODIFIED_BY = "lastModifiedBy" LAST_MODIFIED_TIME = "lastModifiedTime" MANUAL_SORT = "manualSort" MULTILINE_TEXT = "multilineText" MULTIPLE_ATTACHMENTS = "multipleAttachments" MULTIPLE_COLLABORATORS = "multipleCollaborators" MULTIPLE_LOOKUP_VALUES = "multipleLookupValues" MULTIPLE_RECORD_LINKS = "multipleRecordLinks" MULTIPLE_SELECTS = "multipleSelects" NUMBER = "number" PERCENT = "percent" PHONE_NUMBER = "phoneNumber" RATING = "rating" RICH_TEXT = "richText" ROLLUP = "rollup" SINGLE_COLLABORATOR = "singleCollaborator" SINGLE_LINE_TEXT = "singleLineText" SINGLE_SELECT = "singleSelect" URL = "url" def __repr__(self) -> str: return f"FieldType({self.value!r})"
FieldSpecifier: TypeAlias = Union[str, "orm.fields.AnyField"] _T = TypeVar("_T", bound=Any) _FL = partial(pydantic.Field, default_factory=list) _FD = partial(pydantic.Field, default_factory=dict) def _F(classname: str, **kwargs: Any) -> Any: def _create_default_from_classname() -> Any: this_module = importlib.import_module(__name__) obj: Any = this_module for segment in classname.split("."): obj = getattr(obj, segment) return obj() kwargs["default_factory"] = _create_default_from_classname return pydantic.Field(**kwargs) def _find(collection: List[_T], id_or_name: str) -> _T: """ For use on a collection model to find objects by either id or name. """ items_by_name: Dict[str, _T] = {} for item in collection: if getattr(item, "deleted", None): continue if item.id == id_or_name: return item items_by_name[item.name] = item return items_by_name[id_or_name] class _Collaborators(RestfulModel): """ Mixin for use with RestfulModel subclasses that have a /collaborators endpoint. """ def add_user(self, user_id: str, permission_level: str) -> None: """ Add a user as a collaborator to this Airtable object. Args: user_id: The user ID. permission_level: |kwarg_permission_level| """ self.add("user", user_id, permission_level) def add_group(self, group_id: str, permission_level: str) -> None: """ Add a group as a collaborator to this Airtable object. Args: group_id: The group ID. permission_level: |kwarg_permission_level| """ self.add("group", group_id, permission_level) def add( self, collaborator_type: str, collaborator_id: str, permission_level: str, ) -> None: """ Add a user or group as a collaborator to this Airtable object. Args: collaborator_type: Either ``'user'`` or ``'group'``. collaborator_id: The user or group ID. permission_level: |kwarg_permission_level| """ if collaborator_type not in ("user", "group"): raise ValueError("collaborator_type must be 'user' or 'group'") self.add_collaborators( [ cast( AddCollaboratorDict, { collaborator_type: {"id": collaborator_id}, "permissionLevel": permission_level, }, ) ] ) def add_collaborators(self, collaborators: Iterable[AddCollaboratorDict]) -> None: """ Add multiple collaborators to this Airtable object. Args: collaborators: A list of ``dict`` that conform to the specification laid out in the `Add base collaborator <https://airtable.com/developers/web/api/add-base-collaborator#request-collaborators>`__ API documentation. """ payload = {"collaborators": list(collaborators)} self._api.post(f"{self._url}/collaborators", json=payload) self._reload() def update(self, collaborator_id: str, permission_level: str) -> None: """ Change the permission level granted to a user or group. Args: collaborator_id: The user or group ID. permission_level: |kwarg_permission_level| """ self._api.patch( f"{self._url}/collaborators/{collaborator_id}", json={"permissionLevel": permission_level}, ) def remove(self, collaborator_id: str) -> None: """ Remove a user or group as a collaborator. Args: collaborator_id: The user or group ID. """ self._api.delete(f"{self._url}/collaborators/{collaborator_id}")
[docs]class Bases(AirtableModel): """ The list of bases visible to the API token. See https://airtable.com/developers/web/api/list-bases """ bases: List["Bases.Info"] = _FL()
[docs] def base(self, base_id: str) -> "Bases.Info": """ Get basic information about the base with the given ID. """ return _find(self.bases, base_id)
[docs] class Info(AirtableModel): id: str name: str permission_level: str
[docs]class BaseCollaborators(_Collaborators, url="meta/bases/{base.id}"): """ Detailed information about who can access a base. See https://airtable.com/developers/web/api/get-base-collaborators """ id: str name: str created_time: datetime permission_level: str workspace_id: str interfaces: Dict[str, "BaseCollaborators.InterfaceCollaborators"] = _FD() group_collaborators: "BaseCollaborators.GroupCollaborators" = _F("BaseCollaborators.GroupCollaborators") # fmt: skip individual_collaborators: "BaseCollaborators.IndividualCollaborators" = _F("BaseCollaborators.IndividualCollaborators") # fmt: skip invite_links: "BaseCollaborators.InviteLinks" = _F("BaseCollaborators.InviteLinks") # fmt: skip sensitivity_label: Optional["BaseCollaborators.SensitivityLabel"] = None package_installations: List["BaseCollaborators.PackageInstallation"] = _FL()
[docs] class InterfaceCollaborators( _Collaborators, url="meta/bases/{base.id}/interfaces/{key}", ): id: str name: str created_time: datetime first_publish_time: Optional[datetime] = None group_collaborators: List["GroupCollaborator"] = _FL() individual_collaborators: List["IndividualCollaborator"] = _FL() invite_links: List["InterfaceInviteLink"] = _FL()
[docs] class GroupCollaborators(AirtableModel): via_base: List["GroupCollaborator"] = _FL(alias="baseCollaborators") via_workspace: List["GroupCollaborator"] = _FL(alias="workspaceCollaborators")
[docs] class IndividualCollaborators(AirtableModel): via_base: List["IndividualCollaborator"] = _FL(alias="baseCollaborators") via_workspace: List["IndividualCollaborator"] = _FL(alias="workspaceCollaborators") # fmt: skip
[docs] class SensitivityLabel(AirtableModel): id: str description: str name: str
[docs] class PackageInstallation(AirtableModel): id: str package_id: str package_release_id: Optional[str] = None installation_type: str
[docs]class BaseShares(AirtableModel): """ Collection of shared views in a base. See https://airtable.com/developers/web/api/list-shares """ shares: List["BaseShares.Info"]
[docs] class Info( CanUpdateModel, CanDeleteModel, url="meta/bases/{base.id}/shares/{self.share_id}", writable=["state"], reload_after_save=False, ): state: str created_by_user_id: str created_time: datetime share_id: str type: str can_be_synced: Optional[bool] = None is_password_protected: bool block_installation_id: Optional[str] = None restricted_to_email_domains: List[str] = _FL() restricted_to_enterprise_members: bool view_id: Optional[str] = None effective_email_domain_allow_list: List[str] = _FL()
[docs] def enable(self) -> None: """ Enable the base share. """ self.state = "enabled" self.save()
[docs] def disable(self) -> None: """ Disable the base share. """ self.state = "disabled" self.save()
[docs]class BaseSchema(AirtableModel): """ Schema of all tables within the base. See https://airtable.com/developers/web/api/get-base-schema Usage: >>> schema = api.base(base_id).schema() >>> schema.tables [TableSchema(...), ...] >>> schema.table("Table Name") TableSchema( id='tbl6jG0XedVMNxFQW', name='Table Name', primary_field_id='fld0XedVMNxFQW6jG', description=None, fields=[...], views=[...] ) """ tables: List["TableSchema"]
[docs] def table(self, id_or_name: str) -> "TableSchema": """ Get the schema for the table with the given ID or name. """ return _find(self.tables, id_or_name)
[docs]class TableSchema( CanUpdateModel, save_null_values=False, writable=["name", "description", "date_dependency"], url="meta/bases/{base.id}/tables/{self.id}", ): """ Metadata for a table. See https://airtable.com/developers/web/api/get-base-schema Usage: >>> schema = base.table("Table Name").schema() >>> schema.id 'tbl6clmhESAtaCCwF' >>> schema.name 'Table Name' >>> schema.fields [FieldSchema(...), ...] >>> schema().field("fld6jG0XedVMNxFQW") SingleLineTextFieldSchema( id='fld6jG0XedVMNxFQW', name='Name', type='singleLineText' ) >>> schema.views [ViewSchema(...), ...] >>> schema().view("View Name") ViewSchema( id='viw6jG0XedVMNxFQW', name='My Grid View', type='grid' ) """ id: str name: str primary_field_id: str description: Optional[str] = None fields: List["FieldSchema"] views: List["ViewSchema"] date_dependency: Optional["DateDependency"] = pydantic.Field( alias="dateDependencySettings", default=None )
[docs] def field(self, id_or_name: FieldSpecifier) -> "FieldSchema": """ Get the schema for the field with the given ID or name. """ from pyairtable import orm if isinstance(id_or_name, orm.fields.Field): id_or_name = id_or_name.field_name return _find(self.fields, id_or_name)
[docs] def view(self, id_or_name: str) -> "ViewSchema": """ Get the schema for the view with the given ID or name. """ return _find(self.views, id_or_name)
[docs] def set_date_dependency( self, start_date_field: FieldSpecifier, end_date_field: FieldSpecifier, duration_field: FieldSpecifier, rescheduling_mode: str, predecessor_field: Optional[FieldSpecifier] = None, skip_weekends_and_holidays: bool = False, holidays: Optional[List[str]] = None, ) -> None: """ Create or replace the `date dependency settings <https://airtable.com/developers/web/api/model/date-dependency-settings>`__ for the table. You still need to call :meth:`~TableSchema.save` to persist the changes. Usage: >>> table_schema = base.table("Table Name").schema() >>> table_schema.set_date_dependency( ... start_date_field="Start Date", ... end_date_field="End Date", ... duration_field="Duration", ... rescheduling_mode="flexible", ... skip_weekends_and_holidays=True, ... holidays=["2026-01-01", "2026-12-25"], ... predecessor_field="Depends On", ... ) >>> table_schema.save() This method also accepts ORM model fields as shorthand for those fields' IDs: >>> table_schema = SomeModel.meta.table.schema() >>> table_schema.set_date_dependency( ... start_date_field=SomeModel.start_date, ... end_date_field=SomeModel.end_date, ... duration_field=SomeModel.duration, ... rescheduling_mode="flexible", ... ) >>> table_schema.save() Args: start_date_field: The field ID or name for the start date. end_date_field: The field ID or name for the end date. duration_field: The field ID or name for the duration. rescheduling_mode: Either "flexible", "fixed", or "none". skip_weekends_and_holidays: Whether to skip weekends and holidays. holidays: A list of holiday dates in ISO format (YYYY-MM-DD). predecessor_field: Optional; the field ID or name for predecessor tasks. """ duration_field = self.field(duration_field).id start_date_field = self.field(start_date_field).id end_date_field = self.field(end_date_field).id if predecessor_field is not None: predecessor_field = self.field(predecessor_field).id self.date_dependency = TableSchema.DateDependency( is_enabled=True, duration_field_id=duration_field, start_date_field_id=start_date_field, end_date_field_id=end_date_field, predecessor_field_id=predecessor_field, rescheduling_mode=rescheduling_mode, should_skip_weekends_and_holidays=skip_weekends_and_holidays, holidays=holidays or [], )
[docs] class DateDependency(AirtableModel): """ Settings for date dependencies in the table. See https://airtable.com/developers/web/api/model/date-dependency-settings """ is_enabled: bool duration_field_id: str start_date_field_id: str end_date_field_id: str predecessor_field_id: Optional[str] = None rescheduling_mode: str should_skip_weekends_and_holidays: bool holidays: List[str] = _FL() is_forward_only: Optional[bool] = None
[docs]class ViewSchema(CanDeleteModel, url="meta/bases/{base.id}/views/{self.id}"): """ Metadata for a view. See https://airtable.com/developers/web/api/get-view-metadata Usage: >>> vw = table.schema().view("View name") >>> vw.name 'View name' >>> vw.type 'grid' >>> vw.delete() """ id: str type: str name: str personal_for_user_id: Optional[str] = None visible_field_ids: Optional[List[str]] = None
[docs]class GroupCollaborator(AirtableModel): created_time: datetime granted_by_user_id: str group_id: str name: str permission_level: str
[docs]class IndividualCollaborator(AirtableModel): created_time: datetime granted_by_user_id: str user_id: str email: str permission_level: str
[docs]class BaseIndividualCollaborator(IndividualCollaborator): base_id: str
[docs]class BaseGroupCollaborator(GroupCollaborator): base_id: str
# URL generation for an InviteLink assumes that it is nested within # a RestfulModel class named "InviteLink" that provides URL context.
[docs]class EnterpriseInfo(AirtableModel): """ Information about groups, users, workspaces, and email domains associated with an enterprise account. See https://airtable.com/developers/web/api/get-enterprise """ id: str created_time: datetime group_ids: List[str] user_ids: List[str] workspace_ids: List[str] email_domains: List["EnterpriseInfo.EmailDomain"] root_enterprise_id: str = pydantic.Field(alias="rootEnterpriseAccountId") descendant_enterprise_ids: List[str] = _FL(alias="descendantEnterpriseAccountIds") aggregated: Optional["EnterpriseInfo.AggregatedIds"] = None descendants: Dict[str, "EnterpriseInfo.AggregatedIds"] = _FD()
[docs] class EmailDomain(AirtableModel): email_domain: str is_sso_required: bool
[docs] class AggregatedIds(AirtableModel): group_ids: List[str] = _FL() user_ids: List[str] = _FL() workspace_ids: List[str] = _FL()
[docs]class Package(AirtableModel): """ Represents an enterprise package. Returned from the `List packages <https://airtable.com/developers/web/api/list-enterprise-packages>`__ endpoint. """ id: str type: str created_by_user_id: str created_time: datetime description: Optional[str] = None enterprise_account_id: Optional[str] = None install_count: int last_updated_by_user_id: str last_updated_time: datetime latest_release_id: Optional[str] = None name: str source_application_id: str tagline: Optional[str] = None
[docs]class WorkspaceCollaborators(_Collaborators, url="meta/workspaces/{self.id}"): """ Detailed information about who can access a workspace. See https://airtable.com/developers/web/api/get-workspace-collaborators """ id: str name: str created_time: datetime base_ids: List[str] restrictions: "WorkspaceCollaborators.Restrictions" = pydantic.Field(alias="workspaceRestrictions") # fmt: skip group_collaborators: "WorkspaceCollaborators.GroupCollaborators" = _F("WorkspaceCollaborators.GroupCollaborators") # fmt: skip individual_collaborators: "WorkspaceCollaborators.IndividualCollaborators" = _F("WorkspaceCollaborators.IndividualCollaborators") # fmt: skip invite_links: "WorkspaceCollaborators.InviteLinks" = _F("WorkspaceCollaborators.InviteLinks") # fmt: skip
[docs] class Restrictions( CanUpdateModel, url="{workspace_collaborators._url}/updateRestrictions", save_method="POST", reload_after_save=False, ): invite_creation: str = pydantic.Field(alias="inviteCreationRestriction") share_creation: str = pydantic.Field(alias="shareCreationRestriction")
[docs] class GroupCollaborators(AirtableModel): via_base: List["BaseGroupCollaborator"] = _FL(alias="baseCollaborators") via_workspace: List["GroupCollaborator"] = _FL(alias="workspaceCollaborators")
[docs] class IndividualCollaborators(AirtableModel): via_base: List["BaseIndividualCollaborator"] = _FL(alias="baseCollaborators") via_workspace: List["IndividualCollaborator"] = _FL( alias="workspaceCollaborators" )
[docs]class NestedId(AirtableModel): id: str
[docs]class NestedFieldId(AirtableModel): field_id: str
[docs]class Collaborations(AirtableModel): """ The full set of collaborations granted to a user or user group. See https://airtable.com/developers/web/api/model/collaborations """ base_collaborations: List["Collaborations.BaseCollaboration"] = _FL() interface_collaborations: List["Collaborations.InterfaceCollaboration"] = _FL() workspace_collaborations: List["Collaborations.WorkspaceCollaboration"] = _FL() def __bool__(self) -> bool: return bool( self.base_collaborations or self.interface_collaborations or self.workspace_collaborations ) @property def bases(self) -> Dict[str, "Collaborations.BaseCollaboration"]: """ Mapping of base IDs to collaborations, to make lookups easier. """ return {c.base_id: c for c in self.base_collaborations} @property def interfaces(self) -> Dict[str, "Collaborations.InterfaceCollaboration"]: """ Mapping of interface IDs to collaborations, to make lookups easier. """ return {c.interface_id: c for c in self.interface_collaborations} @property def workspaces(self) -> Dict[str, "Collaborations.WorkspaceCollaboration"]: """ Mapping of workspace IDs to collaborations, to make lookups easier. """ return {c.workspace_id: c for c in self.workspace_collaborations}
[docs] class BaseCollaboration(AirtableModel): base_id: str created_time: datetime granted_by_user_id: str permission_level: str
[docs] class InterfaceCollaboration(BaseCollaboration): interface_id: str
[docs] class WorkspaceCollaboration(AirtableModel): workspace_id: str created_time: datetime granted_by_user_id: str permission_level: str
[docs]class UserInfo( CanUpdateModel, CanDeleteModel, url="{enterprise.urls.users}/{self.id}", writable=["state", "email", "first_name", "last_name"], ): """ Detailed information about a user. See https://airtable.com/developers/web/api/get-user-by-id """ id: str name: str email: str state: str is_service_account: bool is_sso_required: bool is_two_factor_auth_enabled: bool last_activity_time: Optional[datetime] = None created_time: Optional[datetime] = None license_type: Optional[str] = None enterprise_user_type: Optional[str] = None invited_to_airtable_by_user_id: Optional[str] = None is_managed: bool = False is_admin: bool = False is_super_admin: bool = False groups: List[NestedId] = _FL() collaborations: "Collaborations" = _F("Collaborations") descendants: Dict[str, "UserInfo.DescendantIds"] = _FD() aggregated: Optional["UserInfo.AggregatedIds"] = None
[docs] def logout(self) -> None: self._api.post(self._url + "/logout")
[docs] class DescendantIds(AirtableModel): license_type: Optional[str] = None last_activity_time: Optional[datetime] = None collaborations: Optional["Collaborations"] = None is_admin: bool = False is_managed: bool = False groups: List[NestedId] = _FL()
[docs] class AggregatedIds(AirtableModel): license_type: Optional[str] = None last_activity_time: Optional[datetime] = None collaborations: Optional["Collaborations"] = None is_admin: bool = False groups: List[NestedId] = _FL()
[docs]class UserGroup(AirtableModel): """ Detailed information about a user group and its members. See https://airtable.com/developers/web/api/get-user-group """ id: str name: str enterprise_account_id: str created_time: datetime updated_time: datetime members: List["UserGroup.Member"] collaborations: "Collaborations" = _F("Collaborations") mapped_user_license_type: Optional[str] = None
[docs] class Member(AirtableModel): user_id: str email: str first_name: str last_name: str role: str created_time: datetime
# The data model is a bit confusing here, but it's designed for maximum reuse. # SomethingFieldConfig contains the `type` and `options` values for each field type. # _FieldSchemaBase contains the `id`, `name`, and `description` values. # SomethingFieldSchema inherits from _FieldSchemaBase and SomethingFieldConfig. # FieldConfig is a union of all available *FieldConfig classes. # FieldSchema is a union of all available *FieldSchema classes.
[docs]class AITextFieldConfig(AirtableModel): """ Field configuration for `AI text <https://airtable.com/developers/web/api/field-model#aitext>`__. """ type: Literal[FieldType.AI_TEXT] options: "AITextFieldOptions"
[docs]class AITextFieldOptions(AirtableModel): prompt: List[Union[str, "AITextFieldOptions.PromptField"]] = _FL() referenced_field_ids: List[str] = _FL()
[docs] class PromptField(AirtableModel): field: NestedFieldId
[docs]class AutoNumberFieldConfig(AirtableModel): """ Field configuration for `Auto number <https://airtable.com/developers/web/api/field-model#autonumber>`__. """ type: Literal[FieldType.AUTO_NUMBER]
[docs]class BarcodeFieldConfig(AirtableModel): """ Field configuration for `Barcode <https://airtable.com/developers/web/api/field-model#barcode>`__. """ type: Literal[FieldType.BARCODE]
[docs]class ButtonFieldConfig(AirtableModel): """ Field configuration for `Button <https://airtable.com/developers/web/api/field-model#button>`__. """ type: Literal[FieldType.BUTTON]
[docs]class CheckboxFieldConfig(AirtableModel): """ Field configuration for `Checkbox <https://airtable.com/developers/web/api/field-model#checkbox>`__. """ type: Literal[FieldType.CHECKBOX] options: "CheckboxFieldOptions"
[docs]class CheckboxFieldOptions(AirtableModel): color: str icon: str
[docs]class CountFieldConfig(AirtableModel): """ Field configuration for `Count <https://airtable.com/developers/web/api/field-model#count>`__. """ type: Literal[FieldType.COUNT] options: "CountFieldOptions"
[docs]class CountFieldOptions(AirtableModel): is_valid: bool record_link_field_id: Optional[str] = None
[docs]class CreatedByFieldConfig(AirtableModel): """ Field configuration for `Created by <https://airtable.com/developers/web/api/field-model#createdby>`__. """ type: Literal[FieldType.CREATED_BY]
[docs]class CreatedTimeFieldConfig(AirtableModel): """ Field configuration for `Created time <https://airtable.com/developers/web/api/field-model#createdtime>`__. """ type: Literal[FieldType.CREATED_TIME]
[docs]class CurrencyFieldConfig(AirtableModel): """ Field configuration for `Currency <https://airtable.com/developers/web/api/field-model#currencynumber>`__. """ type: Literal[FieldType.CURRENCY] options: "CurrencyFieldOptions"
[docs]class CurrencyFieldOptions(AirtableModel): precision: int symbol: str
[docs]class DateFieldConfig(AirtableModel): """ Field configuration for `Date <https://airtable.com/developers/web/api/field-model#dateonly>`__. """ type: Literal[FieldType.DATE] options: "DateFieldOptions"
[docs]class DateFieldOptions(AirtableModel): date_format: "DateTimeFieldOptions.DateFormat"
[docs]class DateTimeFieldConfig(AirtableModel): """ Field configuration for `Date and time <https://airtable.com/developers/web/api/field-model#dateandtime>`__. """ type: Literal[FieldType.DATE_TIME] options: "DateTimeFieldOptions"
[docs]class DateTimeFieldOptions(AirtableModel): time_zone: str date_format: "DateTimeFieldOptions.DateFormat" time_format: "DateTimeFieldOptions.TimeFormat"
[docs] class DateFormat(AirtableModel): format: str name: str
[docs] class TimeFormat(AirtableModel): format: str name: str
[docs]class DurationFieldConfig(AirtableModel): """ Field configuration for `Duration <https://airtable.com/developers/web/api/field-model#durationnumber>`__. """ type: Literal[FieldType.DURATION] options: "DurationFieldOptions"
[docs]class DurationFieldOptions(AirtableModel): duration_format: str
[docs]class EmailFieldConfig(AirtableModel): """ Field configuration for `Email <https://airtable.com/developers/web/api/field-model#email>`__. """ type: Literal[FieldType.EMAIL]
[docs]class ExternalSyncSourceFieldConfig(AirtableModel): """ Field configuration for `Sync source <https://airtable.com/developers/web/api/field-model#syncsource>`__. """ type: Literal[FieldType.EXTERNAL_SYNC_SOURCE] options: "SingleSelectFieldOptions"
[docs]class FormulaFieldConfig(AirtableModel): """ Field configuration for `Formula <https://airtable.com/developers/web/api/field-model#formula>`__. """ type: Literal[FieldType.FORMULA] options: "FormulaFieldOptions"
[docs]class FormulaFieldOptions(AirtableModel): formula: str is_valid: bool referenced_field_ids: Optional[List[str]] = None result: Optional["FieldConfig"] = None
[docs]class LastModifiedByFieldConfig(AirtableModel): """ Field configuration for `Last modified by <https://airtable.com/developers/web/api/field-model#lastmodifiedby>`__. """ type: Literal[FieldType.LAST_MODIFIED_BY]
[docs]class LastModifiedTimeFieldConfig(AirtableModel): """ Field configuration for `Last modified time <https://airtable.com/developers/web/api/field-model#lastmodifiedtime>`__. """ type: Literal[FieldType.LAST_MODIFIED_TIME] options: "LastModifiedTimeFieldOptions"
[docs]class LastModifiedTimeFieldOptions(AirtableModel): is_valid: bool referenced_field_ids: Optional[List[str]] = None result: Optional[Union["DateFieldConfig", "DateTimeFieldConfig"]] = None
[docs]class ManualSortFieldConfig(AirtableModel): """ Field configuration for ``manualSort`` field type (not documented). """ type: Literal[FieldType.MANUAL_SORT]
[docs]class MultilineTextFieldConfig(AirtableModel): """ Field configuration for `Long text <https://airtable.com/developers/web/api/field-model#multilinetext>`__. """ type: Literal[FieldType.MULTILINE_TEXT]
[docs]class MultipleAttachmentsFieldConfig(AirtableModel): """ Field configuration for `Attachments <https://airtable.com/developers/web/api/field-model#multipleattachment>`__. """ type: Literal[FieldType.MULTIPLE_ATTACHMENTS] options: "MultipleAttachmentsFieldOptions"
[docs]class MultipleAttachmentsFieldOptions(AirtableModel): """ Field configuration for `Attachments <https://airtable.com/developers/web/api/field-model#multipleattachment>`__. """ is_reversed: bool
[docs]class MultipleCollaboratorsFieldConfig(AirtableModel): """ Field configuration for `Multiple Collaborators <https://airtable.com/developers/web/api/field-model#multicollaborator>`__. """ type: Literal[FieldType.MULTIPLE_COLLABORATORS]
[docs]class MultipleLookupValuesFieldConfig(AirtableModel): """ Field configuration for `Lookup <https://airtable.com/developers/web/api/field-model#lookup>__`. """ type: Literal[FieldType.MULTIPLE_LOOKUP_VALUES] options: "MultipleLookupValuesFieldOptions"
[docs]class MultipleLookupValuesFieldOptions(AirtableModel): is_valid: bool field_id_in_linked_table: Optional[str] = None record_link_field_id: Optional[str] = None result: Optional["FieldConfig"] = None
[docs]class MultipleRecordLinksFieldConfig(AirtableModel): """ Field configuration for `Link to another record <https://airtable.com/developers/web/api/field-model#foreignkey>__`. """ type: Literal[FieldType.MULTIPLE_RECORD_LINKS] options: "MultipleRecordLinksFieldOptions"
[docs]class MultipleRecordLinksFieldOptions(AirtableModel): is_reversed: bool linked_table_id: str prefers_single_record_link: bool inverse_link_field_id: Optional[str] = None view_id_for_record_selection: Optional[str] = None
[docs]class MultipleSelectsFieldConfig(AirtableModel): """ Field configuration for `Multiple select <https://airtable.com/developers/web/api/field-model#multiselect>`__. """ type: Literal[FieldType.MULTIPLE_SELECTS] options: "SingleSelectFieldOptions"
[docs]class NumberFieldConfig(AirtableModel): """ Field configuration for `Number <https://airtable.com/developers/web/api/field-model#decimalorintegernumber>`__. """ type: Literal[FieldType.NUMBER] options: "NumberFieldOptions"
[docs]class NumberFieldOptions(AirtableModel): precision: int
[docs]class PercentFieldConfig(AirtableModel): """ Field configuration for `Percent <https://airtable.com/developers/web/api/field-model#percentnumber>`__. """ type: Literal[FieldType.PERCENT] options: "NumberFieldOptions"
[docs]class PhoneNumberFieldConfig(AirtableModel): """ Field configuration for `Phone <https://airtable.com/developers/web/api/field-model#phone>`__. """ type: Literal[FieldType.PHONE_NUMBER]
[docs]class RatingFieldConfig(AirtableModel): """ Field configuration for `Rating <https://airtable.com/developers/web/api/field-model#rating>`__. """ type: Literal[FieldType.RATING] options: "RatingFieldOptions"
[docs]class RatingFieldOptions(AirtableModel): color: str icon: str max: int
[docs]class RichTextFieldConfig(AirtableModel): """ Field configuration for `Rich text <https://airtable.com/developers/web/api/field-model#rich-text>`__. """ type: Literal[FieldType.RICH_TEXT]
[docs]class RollupFieldConfig(AirtableModel): """ Field configuration for `Rollup <https://airtable.com/developers/web/api/field-model#rollup>__`. """ type: Literal[FieldType.ROLLUP] options: "RollupFieldOptions"
[docs]class RollupFieldOptions(AirtableModel): field_id_in_linked_table: Optional[str] = None is_valid: bool record_link_field_id: Optional[str] = None referenced_field_ids: Optional[List[str]] = None result: Optional["FieldConfig"] = None
[docs]class SingleCollaboratorFieldConfig(AirtableModel): """ Field configuration for `Collaborator <https://airtable.com/developers/web/api/field-model#collaborator>`__. """ type: Literal[FieldType.SINGLE_COLLABORATOR]
[docs]class SingleLineTextFieldConfig(AirtableModel): """ Field configuration for `Single line text <https://airtable.com/developers/web/api/field-model#simpletext>`__. """ type: Literal[FieldType.SINGLE_LINE_TEXT]
[docs]class SingleSelectFieldConfig(AirtableModel): """ Field configuration for `Single select <https://airtable.com/developers/web/api/field-model#select>`__. """ type: Literal[FieldType.SINGLE_SELECT] options: "SingleSelectFieldOptions"
[docs]class SingleSelectFieldOptions(AirtableModel): choices: List["SingleSelectFieldOptions.Choice"]
[docs] class Choice(AirtableModel): id: str name: str color: Optional[str] = None
[docs]class UrlFieldConfig(AirtableModel): """ Field configuration for `Url <https://airtable.com/developers/web/api/field-model#urltext>`__. """ type: Literal[FieldType.URL]
[docs]class UnknownFieldConfig(AirtableModel): """ Field configuration class used as a fallback for unrecognized types. This ensures we don't raise pydantic.ValidationError if Airtable adds new types. """ type: str options: Optional[Dict[str, Any]] = None
class _FieldSchemaBase( CanUpdateModel, save_null_values=False, writable=["name", "description"], url="meta/bases/{base.id}/tables/{table_schema.id}/fields/{self.id}", ): id: str name: str description: Optional[str] = None # This section is auto-generated so that FieldSchema and FieldConfig are kept aligned. # See .pre-commit-config.yaml, or just run `tox -e pre-commit` to refresh it. # fmt: off r"""[[[cog]]] import re with open(cog.inFile) as fp: field_types = re.findall( r"class (\w+Field)Config\(.*?\):(?:\n \"{3}(.*?)\"{3})?", fp.read(), re.MULTILINE + re.DOTALL ) cog.out("\n\n") cog.outl("FieldConfig: TypeAlias = Union[") for fld, _ in field_types: cog.outl(f" {fld}Config,") cog.outl("]") cog.out("\n\n") for fld, doc in field_types: cog.out(f"class {fld}Schema(_FieldSchemaBase, {fld}Config):\n ") if doc: doc = doc.replace('ield configuration', 'ield schema') cog.outl("\"\"\"" + doc + "\"\"\"") else: cog.outl("pass") cog.out("\n\n") cog.outl("FieldSchema: TypeAlias = Union[") for fld, _ in field_types: cog.outl(f" {fld}Schema,") cog.outl("]") [[[out]]]""" FieldConfig: TypeAlias = Union[ AITextFieldConfig, AutoNumberFieldConfig, BarcodeFieldConfig, ButtonFieldConfig, CheckboxFieldConfig, CountFieldConfig, CreatedByFieldConfig, CreatedTimeFieldConfig, CurrencyFieldConfig, DateFieldConfig, DateTimeFieldConfig, DurationFieldConfig, EmailFieldConfig, ExternalSyncSourceFieldConfig, FormulaFieldConfig, LastModifiedByFieldConfig, LastModifiedTimeFieldConfig, ManualSortFieldConfig, MultilineTextFieldConfig, MultipleAttachmentsFieldConfig, MultipleCollaboratorsFieldConfig, MultipleLookupValuesFieldConfig, MultipleRecordLinksFieldConfig, MultipleSelectsFieldConfig, NumberFieldConfig, PercentFieldConfig, PhoneNumberFieldConfig, RatingFieldConfig, RichTextFieldConfig, RollupFieldConfig, SingleCollaboratorFieldConfig, SingleLineTextFieldConfig, SingleSelectFieldConfig, UrlFieldConfig, UnknownFieldConfig, ]
[docs]class AITextFieldSchema(_FieldSchemaBase, AITextFieldConfig): """ Field schema for `AI text <https://airtable.com/developers/web/api/field-model#aitext>`__. """
[docs]class AutoNumberFieldSchema(_FieldSchemaBase, AutoNumberFieldConfig): """ Field schema for `Auto number <https://airtable.com/developers/web/api/field-model#autonumber>`__. """
[docs]class BarcodeFieldSchema(_FieldSchemaBase, BarcodeFieldConfig): """ Field schema for `Barcode <https://airtable.com/developers/web/api/field-model#barcode>`__. """
[docs]class ButtonFieldSchema(_FieldSchemaBase, ButtonFieldConfig): """ Field schema for `Button <https://airtable.com/developers/web/api/field-model#button>`__. """
[docs]class CheckboxFieldSchema(_FieldSchemaBase, CheckboxFieldConfig): """ Field schema for `Checkbox <https://airtable.com/developers/web/api/field-model#checkbox>`__. """
[docs]class CountFieldSchema(_FieldSchemaBase, CountFieldConfig): """ Field schema for `Count <https://airtable.com/developers/web/api/field-model#count>`__. """
[docs]class CreatedByFieldSchema(_FieldSchemaBase, CreatedByFieldConfig): """ Field schema for `Created by <https://airtable.com/developers/web/api/field-model#createdby>`__. """
[docs]class CreatedTimeFieldSchema(_FieldSchemaBase, CreatedTimeFieldConfig): """ Field schema for `Created time <https://airtable.com/developers/web/api/field-model#createdtime>`__. """
[docs]class CurrencyFieldSchema(_FieldSchemaBase, CurrencyFieldConfig): """ Field schema for `Currency <https://airtable.com/developers/web/api/field-model#currencynumber>`__. """
[docs]class DateFieldSchema(_FieldSchemaBase, DateFieldConfig): """ Field schema for `Date <https://airtable.com/developers/web/api/field-model#dateonly>`__. """
[docs]class DateTimeFieldSchema(_FieldSchemaBase, DateTimeFieldConfig): """ Field schema for `Date and time <https://airtable.com/developers/web/api/field-model#dateandtime>`__. """
[docs]class DurationFieldSchema(_FieldSchemaBase, DurationFieldConfig): """ Field schema for `Duration <https://airtable.com/developers/web/api/field-model#durationnumber>`__. """
[docs]class EmailFieldSchema(_FieldSchemaBase, EmailFieldConfig): """ Field schema for `Email <https://airtable.com/developers/web/api/field-model#email>`__. """
[docs]class ExternalSyncSourceFieldSchema(_FieldSchemaBase, ExternalSyncSourceFieldConfig): """ Field schema for `Sync source <https://airtable.com/developers/web/api/field-model#syncsource>`__. """
[docs]class FormulaFieldSchema(_FieldSchemaBase, FormulaFieldConfig): """ Field schema for `Formula <https://airtable.com/developers/web/api/field-model#formula>`__. """
[docs]class LastModifiedByFieldSchema(_FieldSchemaBase, LastModifiedByFieldConfig): """ Field schema for `Last modified by <https://airtable.com/developers/web/api/field-model#lastmodifiedby>`__. """
[docs]class LastModifiedTimeFieldSchema(_FieldSchemaBase, LastModifiedTimeFieldConfig): """ Field schema for `Last modified time <https://airtable.com/developers/web/api/field-model#lastmodifiedtime>`__. """
[docs]class ManualSortFieldSchema(_FieldSchemaBase, ManualSortFieldConfig): """ Field schema for ``manualSort`` field type (not documented). """
[docs]class MultilineTextFieldSchema(_FieldSchemaBase, MultilineTextFieldConfig): """ Field schema for `Long text <https://airtable.com/developers/web/api/field-model#multilinetext>`__. """
[docs]class MultipleAttachmentsFieldSchema(_FieldSchemaBase, MultipleAttachmentsFieldConfig): """ Field schema for `Attachments <https://airtable.com/developers/web/api/field-model#multipleattachment>`__. """
[docs]class MultipleCollaboratorsFieldSchema(_FieldSchemaBase, MultipleCollaboratorsFieldConfig): """ Field schema for `Multiple Collaborators <https://airtable.com/developers/web/api/field-model#multicollaborator>`__. """
[docs]class MultipleLookupValuesFieldSchema(_FieldSchemaBase, MultipleLookupValuesFieldConfig): """ Field schema for `Lookup <https://airtable.com/developers/web/api/field-model#lookup>__`. """
[docs]class MultipleRecordLinksFieldSchema(_FieldSchemaBase, MultipleRecordLinksFieldConfig): """ Field schema for `Link to another record <https://airtable.com/developers/web/api/field-model#foreignkey>__`. """
[docs]class MultipleSelectsFieldSchema(_FieldSchemaBase, MultipleSelectsFieldConfig): """ Field schema for `Multiple select <https://airtable.com/developers/web/api/field-model#multiselect>`__. """
[docs]class NumberFieldSchema(_FieldSchemaBase, NumberFieldConfig): """ Field schema for `Number <https://airtable.com/developers/web/api/field-model#decimalorintegernumber>`__. """
[docs]class PercentFieldSchema(_FieldSchemaBase, PercentFieldConfig): """ Field schema for `Percent <https://airtable.com/developers/web/api/field-model#percentnumber>`__. """
[docs]class PhoneNumberFieldSchema(_FieldSchemaBase, PhoneNumberFieldConfig): """ Field schema for `Phone <https://airtable.com/developers/web/api/field-model#phone>`__. """
[docs]class RatingFieldSchema(_FieldSchemaBase, RatingFieldConfig): """ Field schema for `Rating <https://airtable.com/developers/web/api/field-model#rating>`__. """
[docs]class RichTextFieldSchema(_FieldSchemaBase, RichTextFieldConfig): """ Field schema for `Rich text <https://airtable.com/developers/web/api/field-model#rich-text>`__. """
[docs]class RollupFieldSchema(_FieldSchemaBase, RollupFieldConfig): """ Field schema for `Rollup <https://airtable.com/developers/web/api/field-model#rollup>__`. """
[docs]class SingleCollaboratorFieldSchema(_FieldSchemaBase, SingleCollaboratorFieldConfig): """ Field schema for `Collaborator <https://airtable.com/developers/web/api/field-model#collaborator>`__. """
[docs]class SingleLineTextFieldSchema(_FieldSchemaBase, SingleLineTextFieldConfig): """ Field schema for `Single line text <https://airtable.com/developers/web/api/field-model#simpletext>`__. """
[docs]class SingleSelectFieldSchema(_FieldSchemaBase, SingleSelectFieldConfig): """ Field schema for `Single select <https://airtable.com/developers/web/api/field-model#select>`__. """
[docs]class UrlFieldSchema(_FieldSchemaBase, UrlFieldConfig): """ Field schema for `Url <https://airtable.com/developers/web/api/field-model#urltext>`__. """
[docs]class UnknownFieldSchema(_FieldSchemaBase, UnknownFieldConfig): """ Field schema class used as a fallback for unrecognized types. This ensures we don't raise pydantic.ValidationError if Airtable adds new types. """
FieldSchema: TypeAlias = Union[ AITextFieldSchema, AutoNumberFieldSchema, BarcodeFieldSchema, ButtonFieldSchema, CheckboxFieldSchema, CountFieldSchema, CreatedByFieldSchema, CreatedTimeFieldSchema, CurrencyFieldSchema, DateFieldSchema, DateTimeFieldSchema, DurationFieldSchema, EmailFieldSchema, ExternalSyncSourceFieldSchema, FormulaFieldSchema, LastModifiedByFieldSchema, LastModifiedTimeFieldSchema, ManualSortFieldSchema, MultilineTextFieldSchema, MultipleAttachmentsFieldSchema, MultipleCollaboratorsFieldSchema, MultipleLookupValuesFieldSchema, MultipleRecordLinksFieldSchema, MultipleSelectsFieldSchema, NumberFieldSchema, PercentFieldSchema, PhoneNumberFieldSchema, RatingFieldSchema, RichTextFieldSchema, RollupFieldSchema, SingleCollaboratorFieldSchema, SingleLineTextFieldSchema, SingleSelectFieldSchema, UrlFieldSchema, UnknownFieldSchema, ] # [[[end]]] (sum: yhWbyMdrHR) # fmt: on # Shortcut to allow parsing unions, which is not possible otherwise in Pydantic v1. # See https://github.com/pydantic/pydantic/discussions/4950 class _HasFieldSchema(AirtableModel): field_schema: FieldSchema
[docs]def parse_field_schema(obj: Dict[str, Any]) -> FieldSchema: """ Given a ``dict`` representing a field schema, parse it into the appropriate FieldSchema subclass. """ return _HasFieldSchema.model_validate({"field_schema": obj}).field_schema
rebuild_models(vars())