Coverage for polar/custom_field/schemas.py: 100%
51 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 12:42 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 12:42 +0000
1from typing import Annotated, Literal
3from pydantic import UUID4, Discriminator, Field, StringConstraints, TypeAdapter
5from polar.kit.metadata import (
6 MetadataInputMixin,
7 MetadataOutputMixin,
8)
9from polar.kit.schemas import (
10 ClassName,
11 IDSchema,
12 MergeJSONSchema,
13 Schema,
14 SetSchemaReference,
15 TimestampedSchema,
16)
17from polar.models.custom_field import (
18 CustomFieldCheckboxProperties,
19 CustomFieldDateProperties,
20 CustomFieldNumberProperties,
21 CustomFieldSelectProperties,
22 CustomFieldTextProperties,
23 CustomFieldType,
24)
25from polar.organization.schemas import OrganizationID
27Slug = Annotated[
28 str,
29 StringConstraints(to_lower=True, min_length=1, pattern=r"^[a-z0-9-_]+$"),
30 Field(
31 description=(
32 "Identifier of the custom field. "
33 "It'll be used as key when storing the value. "
34 "Must be unique across the organization."
35 "It can only contain ASCII letters, numbers and hyphens."
36 ),
37 min_length=1,
38 ),
39]
40Name = Annotated[str, Field(description="Name of the custom field.", min_length=1)]
43class CustomFieldCreateBase(MetadataInputMixin, Schema):
44 """Schema to create a new custom field."""
46 type: CustomFieldType = Field(description="Data type of the custom field.")
47 slug: Slug
48 name: Name
49 organization_id: OrganizationID | None = Field(
50 default=None,
51 description=(
52 "The ID of the organization owning the custom field. "
53 "**Required unless you use an organization token.**"
54 ),
55 )
58class CustomFieldCreateText(CustomFieldCreateBase):
59 """Schema to create a custom field of type text."""
61 type: Literal[CustomFieldType.text]
62 properties: CustomFieldTextProperties
65class CustomFieldCreateNumber(CustomFieldCreateBase):
66 """Schema to create a custom field of type number."""
68 type: Literal[CustomFieldType.number]
69 properties: CustomFieldNumberProperties
72class CustomFieldCreateDate(CustomFieldCreateBase):
73 """Schema to create a custom field of type date."""
75 type: Literal[CustomFieldType.date]
76 properties: CustomFieldDateProperties
79class CustomFieldCreateCheckbox(CustomFieldCreateBase):
80 """Schema to create a custom field of type checkbox."""
82 type: Literal[CustomFieldType.checkbox]
83 properties: CustomFieldCheckboxProperties
86class CustomFieldCreateSelect(CustomFieldCreateBase):
87 """Schema to create a custom field of type select."""
89 type: Literal[CustomFieldType.select]
90 properties: CustomFieldSelectProperties
93CustomFieldCreate = Annotated[
94 CustomFieldCreateText
95 | CustomFieldCreateNumber
96 | CustomFieldCreateDate
97 | CustomFieldCreateCheckbox
98 | CustomFieldCreateSelect,
99 Discriminator("type"),
100 SetSchemaReference("CustomFieldCreate"),
101]
104class CustomFieldUpdateBase(MetadataInputMixin, Schema):
105 """Schema to update an existing custom field."""
107 name: Name | None = None
108 slug: Slug | None = None
111class CustomFieldUpdateText(CustomFieldUpdateBase):
112 """Schema to update a custom field of type text."""
114 type: Literal[CustomFieldType.text]
115 properties: CustomFieldTextProperties | None = None
118class CustomFieldUpdateNumber(CustomFieldUpdateBase):
119 """Schema to update a custom field of type number."""
121 type: Literal[CustomFieldType.number]
122 properties: CustomFieldNumberProperties | None = None
125class CustomFieldUpdateDate(CustomFieldUpdateBase):
126 """Schema to update a custom field of type date."""
128 type: Literal[CustomFieldType.date]
129 properties: CustomFieldDateProperties | None = None
132class CustomFieldUpdateCheckbox(CustomFieldUpdateBase):
133 """Schema to update a custom field of type checkbox."""
135 type: Literal[CustomFieldType.checkbox]
136 properties: CustomFieldCheckboxProperties | None = None
139class CustomFieldUpdateSelect(CustomFieldUpdateBase):
140 """Schema to update a custom field of type select."""
142 type: Literal[CustomFieldType.select]
143 properties: CustomFieldSelectProperties | None = None
146CustomFieldUpdate = Annotated[
147 CustomFieldUpdateText
148 | CustomFieldUpdateNumber
149 | CustomFieldUpdateDate
150 | CustomFieldUpdateCheckbox
151 | CustomFieldUpdateSelect,
152 Discriminator("type"),
153 SetSchemaReference("CustomFieldUpdate"),
154]
157class CustomFieldBase(MetadataOutputMixin, IDSchema, TimestampedSchema):
158 """Schema for a custom field."""
160 type: CustomFieldType = Field(description="Data type of the custom field.")
161 slug: str = Field(
162 description="Identifier of the custom field. "
163 "It'll be used as key when storing the value."
164 )
165 name: str = Field(description="Name of the custom field.")
166 organization_id: OrganizationID = Field(
167 description="The ID of the organization owning the custom field."
168 )
171class CustomFieldText(CustomFieldBase):
172 """Schema for a custom field of type text."""
174 type: Literal[CustomFieldType.text]
175 properties: CustomFieldTextProperties
178class CustomFieldNumber(CustomFieldBase):
179 """Schema for a custom field of type number."""
181 type: Literal[CustomFieldType.number]
182 properties: CustomFieldNumberProperties
185class CustomFieldDate(CustomFieldBase):
186 """Schema for a custom field of type date."""
188 type: Literal[CustomFieldType.date]
189 properties: CustomFieldDateProperties
192class CustomFieldCheckbox(CustomFieldBase):
193 """Schema for a custom field of type checkbox."""
195 type: Literal[CustomFieldType.checkbox]
196 properties: CustomFieldCheckboxProperties
199class CustomFieldSelect(CustomFieldBase):
200 """Schema for a custom field of type select."""
202 type: Literal[CustomFieldType.select]
203 properties: CustomFieldSelectProperties
206CustomField = Annotated[
207 CustomFieldText
208 | CustomFieldNumber
209 | CustomFieldDate
210 | CustomFieldCheckbox
211 | CustomFieldSelect,
212 Discriminator("type"),
213 SetSchemaReference("CustomField"),
214 MergeJSONSchema({"title": "CustomField"}),
215 ClassName("CustomField"),
216]
218CustomFieldAdapter: TypeAdapter[CustomField] = TypeAdapter(CustomField)
221class AttachedCustomField(Schema):
222 """Schema of a custom field attached to a resource."""
224 custom_field_id: UUID4 = Field(description="ID of the custom field.")
225 custom_field: CustomField
226 order: int = Field(description="Order of the custom field in the resource.")
227 required: bool = Field(
228 description="Whether the value is required for this custom field."
229 )
232class AttachedCustomFieldCreate(Schema):
233 """Schema to attach a custom field to a resource."""
235 custom_field_id: UUID4 = Field(description="ID of the custom field to attach.")
236 required: bool = Field(
237 description="Whether the value is required for this custom field."
238 )
241AttachedCustomFieldListCreate = Annotated[
242 list[AttachedCustomFieldCreate],
243 Field(description="List of custom fields to attach."),
244]