Skip to content

Commit 3f90dfb

Browse files
Use AliasGenerator for camelCase serialization aliases (#296)
1 parent d00bc2f commit 3f90dfb

File tree

6 files changed

+77
-72
lines changed

6 files changed

+77
-72
lines changed

src/python-fastui/fastui/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from pydantic import AliasGenerator, ConfigDict
2+
from pydantic import BaseModel as _BaseModel
3+
from pydantic.alias_generators import to_camel
4+
5+
6+
class BaseModel(_BaseModel):
7+
model_config = ConfigDict(alias_generator=AliasGenerator(serialization_alias=to_camel))

src/python-fastui/fastui/components/__init__.py

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .. import class_name as _class_name
1313
from .. import events
1414
from .. import types as _types
15+
from ..base import BaseModel
1516
from .display import Details, Display
1617
from .forms import (
1718
Form,
@@ -69,7 +70,7 @@
6970
)
7071

7172

72-
class Text(_p.BaseModel, extra='forbid'):
73+
class Text(BaseModel, extra='forbid'):
7374
"""Text component that displays a string."""
7475

7576
text: str
@@ -79,7 +80,7 @@ class Text(_p.BaseModel, extra='forbid'):
7980
"""The type of the component. Always 'Text'."""
8081

8182

82-
class Paragraph(_p.BaseModel, extra='forbid'):
83+
class Paragraph(BaseModel, extra='forbid'):
8384
"""Paragraph component that displays a string as a paragraph."""
8485

8586
text: str
@@ -92,7 +93,7 @@ class Paragraph(_p.BaseModel, extra='forbid'):
9293
"""The type of the component. Always 'Paragraph'."""
9394

9495

95-
class PageTitle(_p.BaseModel, extra='forbid'):
96+
class PageTitle(BaseModel, extra='forbid'):
9697
"""Sets the title of the HTML page via the `document.title` property."""
9798

9899
text: str
@@ -102,7 +103,7 @@ class PageTitle(_p.BaseModel, extra='forbid'):
102103
"""The type of the component. Always 'PageTitle'."""
103104

104105

105-
class Div(_p.BaseModel, extra='forbid'):
106+
class Div(BaseModel, extra='forbid'):
106107
"""A generic container component."""
107108

108109
components: '_t.List[AnyComponent]'
@@ -115,7 +116,7 @@ class Div(_p.BaseModel, extra='forbid'):
115116
"""The type of the component. Always 'Div'."""
116117

117118

118-
class Page(_p.BaseModel, extra='forbid'):
119+
class Page(BaseModel, extra='forbid'):
119120
"""Similar to `container` in many UI frameworks, this acts as a root component for most pages."""
120121

121122
components: '_t.List[AnyComponent]'
@@ -128,7 +129,7 @@ class Page(_p.BaseModel, extra='forbid'):
128129
"""The type of the component. Always 'Page'."""
129130

130131

131-
class Heading(_p.BaseModel, extra='forbid'):
132+
class Heading(BaseModel, extra='forbid'):
132133
"""Heading component."""
133134

134135
text: str
@@ -137,7 +138,7 @@ class Heading(_p.BaseModel, extra='forbid'):
137138
level: _t.Literal[1, 2, 3, 4, 5, 6] = 1
138139
"""The level of the heading. 1 is the largest, 6 is the smallest."""
139140

140-
html_id: _t.Union[str, None] = _p.Field(default=None, serialization_alias='htmlId')
141+
html_id: _t.Union[str, None] = None
141142
"""Optional HTML ID to apply to the heading's HTML component."""
142143

143144
class_name: _class_name.ClassNameField = None
@@ -169,7 +170,7 @@ def __get_pydantic_json_schema__(
169170
"""
170171

171172

172-
class Markdown(_p.BaseModel, extra='forbid'):
173+
class Markdown(BaseModel, extra='forbid'):
173174
"""Markdown component that renders markdown text."""
174175

175176
text: str
@@ -185,7 +186,7 @@ class Markdown(_p.BaseModel, extra='forbid'):
185186
"""The type of the component. Always 'Markdown'."""
186187

187188

188-
class Code(_p.BaseModel, extra='forbid'):
189+
class Code(BaseModel, extra='forbid'):
189190
"""Code component that renders code with syntax highlighting."""
190191

191192
text: str
@@ -204,7 +205,7 @@ class Code(_p.BaseModel, extra='forbid'):
204205
"""The type of the component. Always 'Code'."""
205206

206207

207-
class Json(_p.BaseModel, extra='forbid'):
208+
class Json(BaseModel, extra='forbid'):
208209
"""JSON component that renders JSON data."""
209210

210211
value: _types.JsonData
@@ -217,18 +218,16 @@ class Json(_p.BaseModel, extra='forbid'):
217218
"""The type of the component. Always 'JSON'."""
218219

219220

220-
class Button(_p.BaseModel, extra='forbid'):
221+
class Button(BaseModel, extra='forbid'):
221222
"""Button component."""
222223

223224
text: str
224225
"""The text to display on the button."""
225226

226-
on_click: _t.Union[events.AnyEvent, None] = _p.Field(default=None, serialization_alias='onClick')
227+
on_click: _t.Union[events.AnyEvent, None] = None
227228
"""Optional event to trigger when the button is clicked."""
228229

229-
html_type: _t.Union[_t.Literal['button', 'reset', 'submit'], None] = _p.Field(
230-
default=None, serialization_alias='htmlType'
231-
)
230+
html_type: _t.Union[_t.Literal['button', 'reset', 'submit'], None] = None
232231
"""Optional HTML type of the button. If None, defaults to 'button'."""
233232

234233
named_style: _class_name.NamedStyleField = None
@@ -241,13 +240,13 @@ class Button(_p.BaseModel, extra='forbid'):
241240
"""The type of the component. Always 'Button'."""
242241

243242

244-
class Link(_p.BaseModel, extra='forbid'):
243+
class Link(BaseModel, extra='forbid'):
245244
"""Link component."""
246245

247246
components: '_t.List[AnyComponent]'
248247
"""List of components to render attached to the link."""
249248

250-
on_click: _t.Union[events.AnyEvent, None] = _p.Field(default=None, serialization_alias='onClick')
249+
on_click: _t.Union[events.AnyEvent, None] = None
251250
"""Optional event to trigger when the link is clicked."""
252251

253252
mode: _t.Union[_t.Literal['navbar', 'footer', 'tabs', 'vertical', 'pagination'], None] = None
@@ -266,7 +265,7 @@ class Link(_p.BaseModel, extra='forbid'):
266265
"""The type of the component. Always 'Link'."""
267266

268267

269-
class LinkList(_p.BaseModel, extra='forbid'):
268+
class LinkList(BaseModel, extra='forbid'):
270269
"""List of Link components."""
271270

272271
links: _t.List[Link]
@@ -282,19 +281,19 @@ class LinkList(_p.BaseModel, extra='forbid'):
282281
"""The type of the component. Always 'LinkList'."""
283282

284283

285-
class Navbar(_p.BaseModel, extra='forbid'):
284+
class Navbar(BaseModel, extra='forbid'):
286285
"""Navbar component used for moving between pages."""
287286

288287
title: _t.Union[str, None] = None
289288
"""Optional title to display in the navbar."""
290289

291-
title_event: _t.Union[events.AnyEvent, None] = _p.Field(default=None, serialization_alias='titleEvent')
290+
title_event: _t.Union[events.AnyEvent, None] = None
292291
"""Optional event to trigger when the title is clicked. Often used to navigate to the home page."""
293292

294-
start_links: _t.List[Link] = _p.Field(default=[], serialization_alias='startLinks')
293+
start_links: _t.List[Link] = []
295294
"""List of links to render at the start of the navbar."""
296295

297-
end_links: _t.List[Link] = _p.Field(default=[], serialization_alias='endLinks')
296+
end_links: _t.List[Link] = []
298297
"""List of links to render at the end of the navbar."""
299298

300299
class_name: _class_name.ClassNameField = None
@@ -313,13 +312,13 @@ def __get_pydantic_json_schema__(
313312
return json_schema
314313

315314

316-
class Footer(_p.BaseModel, extra='forbid'):
315+
class Footer(BaseModel, extra='forbid'):
317316
"""Footer component."""
318317

319318
links: _t.List[Link]
320319
"""List of links to render in the footer."""
321320

322-
extra_text: _t.Union[str, None] = _p.Field(default=None, serialization_alias='extraText')
321+
extra_text: _t.Union[str, None] = None
323322
"""Optional extra text to display in the footer."""
324323

325324
class_name: _class_name.ClassNameField = None
@@ -329,7 +328,7 @@ class Footer(_p.BaseModel, extra='forbid'):
329328
"""The type of the component. Always 'Footer'."""
330329

331330

332-
class Modal(_p.BaseModel, extra='forbid'):
331+
class Modal(BaseModel, extra='forbid'):
333332
"""Modal component that displays a modal dialog."""
334333

335334
title: str
@@ -341,10 +340,10 @@ class Modal(_p.BaseModel, extra='forbid'):
341340
footer: '_t.Union[_t.List[AnyComponent], None]' = None
342341
"""Optional list of components to render in the modal footer."""
343342

344-
open_trigger: _t.Union[events.PageEvent, None] = _p.Field(default=None, serialization_alias='openTrigger')
343+
open_trigger: _t.Union[events.PageEvent, None] = None
345344
"""Optional event to trigger when the modal is opened."""
346345

347-
open_context: _t.Union[events.ContextType, None] = _p.Field(default=None, serialization_alias='openContext')
346+
open_context: _t.Union[events.ContextType, None] = None
348347
"""Optional context to pass to the open trigger event."""
349348

350349
class_name: _class_name.ClassNameField = None
@@ -354,13 +353,13 @@ class Modal(_p.BaseModel, extra='forbid'):
354353
"""The type of the component. Always 'Modal'."""
355354

356355

357-
class ServerLoad(_p.BaseModel, extra='forbid'):
356+
class ServerLoad(BaseModel, extra='forbid'):
358357
"""A component that will be replaced by the server with the component returned by the given URL."""
359358

360359
path: str
361360
"""The URL to load the component from."""
362361

363-
load_trigger: _t.Union[events.PageEvent, None] = _p.Field(default=None, serialization_alias='loadTrigger')
362+
load_trigger: _t.Union[events.PageEvent, None] = None
364363
"""Optional event to trigger when the component is loaded."""
365364

366365
components: '_t.Union[_t.List[AnyComponent], None]' = None
@@ -369,7 +368,7 @@ class ServerLoad(_p.BaseModel, extra='forbid'):
369368
sse: _t.Union[bool, None] = None
370369
"""Optional flag to enable server-sent events (SSE) for the server load."""
371370

372-
sse_retry: _t.Union[int, None] = _p.Field(default=None, serialization_alias='sseRetry')
371+
sse_retry: _t.Union[int, None] = None
373372
"""Optional time in milliseconds to retry the SSE connection."""
374373

375374
method: _t.Union[_t.Literal['GET', 'POST', 'PATCH', 'PUT', 'DELETE'], None] = None
@@ -379,7 +378,7 @@ class ServerLoad(_p.BaseModel, extra='forbid'):
379378
"""The type of the component. Always 'ServerLoad'."""
380379

381380

382-
class Image(_p.BaseModel, extra='forbid'):
381+
class Image(BaseModel, extra='forbid'):
383382
"""Image container component."""
384383

385384
src: str
@@ -406,15 +405,15 @@ class Image(_p.BaseModel, extra='forbid'):
406405
'unsafe-url',
407406
],
408407
None,
409-
] = _p.Field(None, serialization_alias='referrerPolicy')
408+
] = None
410409
"""Optional referrer policy for the image. Specifies what information to send when fetching the image.
411410
412411
For more info, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy."""
413412

414413
loading: _t.Union[_t.Literal['eager', 'lazy'], None] = None
415414
"""Optional loading strategy for the image."""
416415

417-
on_click: _t.Union[events.AnyEvent, None] = _p.Field(default=None, serialization_alias='onClick')
416+
on_click: _t.Union[events.AnyEvent, None] = None
418417
"""Optional event to trigger when the image is clicked."""
419418

420419
class_name: _class_name.ClassNameField = None
@@ -424,7 +423,7 @@ class Image(_p.BaseModel, extra='forbid'):
424423
"""The type of the component. Always 'Image'."""
425424

426425

427-
class Iframe(_p.BaseModel, extra='forbid'):
426+
class Iframe(BaseModel, extra='forbid'):
428427
"""Iframe component that displays content from a URL."""
429428

430429
src: _p.HttpUrl
@@ -452,7 +451,7 @@ class Iframe(_p.BaseModel, extra='forbid'):
452451
"""The type of the component. Always 'Iframe'."""
453452

454453

455-
class Video(_p.BaseModel, extra='forbid'):
454+
class Video(BaseModel, extra='forbid'):
456455
"""Video component that displays a video or multiple videos."""
457456

458457
sources: _t.List[_p.AnyUrl]
@@ -486,7 +485,7 @@ class Video(_p.BaseModel, extra='forbid'):
486485
"""The type of the component. Always 'Video'."""
487486

488487

489-
class FireEvent(_p.BaseModel, extra='forbid'):
488+
class FireEvent(BaseModel, extra='forbid'):
490489
"""Fire an event."""
491490

492491
event: events.AnyEvent
@@ -499,7 +498,7 @@ class FireEvent(_p.BaseModel, extra='forbid'):
499498
"""The type of the component. Always 'FireEvent'."""
500499

501500

502-
class Error(_p.BaseModel, extra='forbid'):
501+
class Error(BaseModel, extra='forbid'):
503502
"""Utility component used to display an error."""
504503

505504
title: str
@@ -508,7 +507,7 @@ class Error(_p.BaseModel, extra='forbid'):
508507
description: str
509508
"""The description of the error."""
510509

511-
status_code: _t.Union[int, None] = _p.Field(None, serialization_alias='statusCode')
510+
status_code: _t.Union[int, None] = None
512511
"""Optional status code of the error."""
513512

514513
class_name: _class_name.ClassNameField = None
@@ -527,7 +526,7 @@ def __get_pydantic_json_schema__(
527526
return json_schema
528527

529528

530-
class Spinner(_p.BaseModel, extra='forbid'):
529+
class Spinner(BaseModel, extra='forbid'):
531530
"""Spinner component that displays a loading spinner."""
532531

533532
text: _t.Union[str, None] = None
@@ -540,7 +539,7 @@ class Spinner(_p.BaseModel, extra='forbid'):
540539
"""The type of the component. Always 'Spinner'."""
541540

542541

543-
class Toast(_p.BaseModel, extra='forbid'):
542+
class Toast(BaseModel, extra='forbid'):
544543
"""Toast component that displays a toast message (small temporary message)."""
545544

546545
title: str
@@ -566,10 +565,10 @@ class Toast(_p.BaseModel, extra='forbid'):
566565
] = None
567566
"""Optional position of the toast."""
568567

569-
open_trigger: _t.Union[events.PageEvent, None] = _p.Field(default=None, serialization_alias='openTrigger')
568+
open_trigger: _t.Union[events.PageEvent, None] = None
570569
"""Optional event to trigger when the toast is opened."""
571570

572-
open_context: _t.Union[events.ContextType, None] = _p.Field(default=None, serialization_alias='openContext')
571+
open_context: _t.Union[events.ContextType, None] = None
573572
"""Optional context to pass to the open trigger event."""
574573

575574
class_name: _class_name.ClassNameField = None
@@ -579,13 +578,13 @@ class Toast(_p.BaseModel, extra='forbid'):
579578
"""The type of the component. Always 'Toast'."""
580579

581580

582-
class Custom(_p.BaseModel, extra='forbid'):
581+
class Custom(BaseModel, extra='forbid'):
583582
"""Custom component that allows for special data to be rendered."""
584583

585584
data: _types.JsonData
586585
"""The data to render in the custom component."""
587586

588-
sub_type: str = _p.Field(serialization_alias='subType')
587+
sub_type: str
589588
"""The sub-type of the custom component."""
590589

591590
library: _t.Union[str, None] = None

0 commit comments

Comments
 (0)