fh-pydantic-form 0.3.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fh_pydantic_form/__init__.py +143 -0
- fh_pydantic_form/color_utils.py +598 -0
- fh_pydantic_form/comparison_form.py +1637 -0
- fh_pydantic_form/constants.py +12 -0
- fh_pydantic_form/defaults.py +188 -0
- fh_pydantic_form/field_renderers.py +2330 -0
- fh_pydantic_form/form_parser.py +756 -0
- fh_pydantic_form/form_renderer.py +1004 -0
- fh_pydantic_form/list_path.py +145 -0
- fh_pydantic_form/py.typed +0 -0
- fh_pydantic_form/registry.py +142 -0
- fh_pydantic_form/type_helpers.py +266 -0
- fh_pydantic_form/ui_style.py +115 -0
- fh_pydantic_form-0.3.9.dist-info/METADATA +1168 -0
- fh_pydantic_form-0.3.9.dist-info/RECORD +17 -0
- fh_pydantic_form-0.3.9.dist-info/WHEEL +4 -0
- fh_pydantic_form-0.3.9.dist-info/licenses/LICENSE +13 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import decimal
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Literal, get_origin
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from fh_pydantic_form.comparison_form import (
|
|
9
|
+
ComparisonForm,
|
|
10
|
+
comparison_form_js,
|
|
11
|
+
simple_diff_metrics,
|
|
12
|
+
)
|
|
13
|
+
from fh_pydantic_form.defaults import (
|
|
14
|
+
default_dict_for_model,
|
|
15
|
+
default_for_annotation,
|
|
16
|
+
)
|
|
17
|
+
from fh_pydantic_form.field_renderers import (
|
|
18
|
+
BaseModelFieldRenderer,
|
|
19
|
+
BooleanFieldRenderer,
|
|
20
|
+
DateFieldRenderer,
|
|
21
|
+
DecimalFieldRenderer,
|
|
22
|
+
EnumFieldRenderer,
|
|
23
|
+
ListFieldRenderer,
|
|
24
|
+
LiteralFieldRenderer,
|
|
25
|
+
NumberFieldRenderer,
|
|
26
|
+
StringFieldRenderer,
|
|
27
|
+
TimeFieldRenderer,
|
|
28
|
+
)
|
|
29
|
+
from fh_pydantic_form.form_renderer import PydanticForm, list_manipulation_js
|
|
30
|
+
from fh_pydantic_form.registry import FieldRendererRegistry
|
|
31
|
+
from fh_pydantic_form.type_helpers import (
|
|
32
|
+
MetricEntry,
|
|
33
|
+
MetricsDict,
|
|
34
|
+
_get_underlying_type_if_optional,
|
|
35
|
+
)
|
|
36
|
+
from fh_pydantic_form.ui_style import (
|
|
37
|
+
SpacingTheme,
|
|
38
|
+
SpacingValue,
|
|
39
|
+
spacing,
|
|
40
|
+
spacing_many,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def register_default_renderers() -> None:
|
|
45
|
+
"""
|
|
46
|
+
Register built-in renderers for common types
|
|
47
|
+
|
|
48
|
+
This method sets up:
|
|
49
|
+
- Simple type renderers (str, bool, int, float, date, time)
|
|
50
|
+
- Special field renderers (Detail)
|
|
51
|
+
- Predicate-based renderers (Literal fields, Enum fields, lists, BaseModels)
|
|
52
|
+
"""
|
|
53
|
+
# Import renderers by getting them from globals
|
|
54
|
+
|
|
55
|
+
# Simple types
|
|
56
|
+
FieldRendererRegistry.register_type_renderer(str, StringFieldRenderer)
|
|
57
|
+
FieldRendererRegistry.register_type_renderer(bool, BooleanFieldRenderer)
|
|
58
|
+
FieldRendererRegistry.register_type_renderer(int, NumberFieldRenderer)
|
|
59
|
+
FieldRendererRegistry.register_type_renderer(float, NumberFieldRenderer)
|
|
60
|
+
FieldRendererRegistry.register_type_renderer(decimal.Decimal, DecimalFieldRenderer)
|
|
61
|
+
FieldRendererRegistry.register_type_renderer(datetime.date, DateFieldRenderer)
|
|
62
|
+
FieldRendererRegistry.register_type_renderer(datetime.time, TimeFieldRenderer)
|
|
63
|
+
|
|
64
|
+
# Register Enum field renderer (before Literal to prioritize Enum handling)
|
|
65
|
+
def is_enum_field(field_info):
|
|
66
|
+
"""Check if field is an Enum type"""
|
|
67
|
+
annotation = getattr(field_info, "annotation", None)
|
|
68
|
+
if not annotation:
|
|
69
|
+
return False
|
|
70
|
+
underlying_type = _get_underlying_type_if_optional(annotation)
|
|
71
|
+
return isinstance(underlying_type, type) and issubclass(underlying_type, Enum)
|
|
72
|
+
|
|
73
|
+
FieldRendererRegistry.register_type_renderer_with_predicate(
|
|
74
|
+
is_enum_field, EnumFieldRenderer
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Register Literal field renderer (after Enum to avoid conflicts)
|
|
78
|
+
def is_literal_field(field_info):
|
|
79
|
+
"""Check if field is a Literal type"""
|
|
80
|
+
annotation = getattr(field_info, "annotation", None)
|
|
81
|
+
if not annotation:
|
|
82
|
+
return False
|
|
83
|
+
underlying_type = _get_underlying_type_if_optional(annotation)
|
|
84
|
+
origin = get_origin(underlying_type)
|
|
85
|
+
return origin is Literal
|
|
86
|
+
|
|
87
|
+
FieldRendererRegistry.register_type_renderer_with_predicate(
|
|
88
|
+
is_literal_field, LiteralFieldRenderer
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Register list renderer for List[*] types
|
|
92
|
+
def is_list_field(field_info):
|
|
93
|
+
"""Check if field is a list type, including Optional[List[...]]"""
|
|
94
|
+
annotation = getattr(field_info, "annotation", None)
|
|
95
|
+
if annotation is None:
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
# Handle Optional[List[...]] by unwrapping the Optional
|
|
99
|
+
underlying_type = _get_underlying_type_if_optional(annotation)
|
|
100
|
+
|
|
101
|
+
# Check if the underlying type is a list
|
|
102
|
+
return get_origin(underlying_type) is list
|
|
103
|
+
|
|
104
|
+
FieldRendererRegistry.register_type_renderer_with_predicate(
|
|
105
|
+
is_list_field, ListFieldRenderer
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Register the BaseModelFieldRenderer for Pydantic models
|
|
109
|
+
def is_basemodel_field(field_info):
|
|
110
|
+
"""Check if field is a BaseModel"""
|
|
111
|
+
annotation = getattr(field_info, "annotation", None)
|
|
112
|
+
underlying_type = _get_underlying_type_if_optional(annotation)
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
isinstance(underlying_type, type)
|
|
116
|
+
and issubclass(underlying_type, BaseModel)
|
|
117
|
+
and not is_list_field(field_info)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
FieldRendererRegistry.register_type_renderer_with_predicate(
|
|
121
|
+
is_basemodel_field, BaseModelFieldRenderer
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
register_default_renderers()
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
__all__ = [
|
|
129
|
+
"PydanticForm",
|
|
130
|
+
"FieldRendererRegistry",
|
|
131
|
+
"list_manipulation_js",
|
|
132
|
+
"SpacingTheme",
|
|
133
|
+
"SpacingValue",
|
|
134
|
+
"spacing",
|
|
135
|
+
"spacing_many",
|
|
136
|
+
"default_dict_for_model",
|
|
137
|
+
"default_for_annotation",
|
|
138
|
+
"ComparisonForm",
|
|
139
|
+
"MetricEntry",
|
|
140
|
+
"MetricsDict",
|
|
141
|
+
"comparison_form_js",
|
|
142
|
+
"simple_diff_metrics",
|
|
143
|
+
]
|