Skip to content

validation

construct_schema_function()

Modifies model example and description if needed.

Note that schema extra has to be a function, otherwise it's called to soon before all the relations are expanded.

Returns:

Type Description
Callable

callable that will be run by pydantic to modify the schema

Source code in ormar\models\helpers\validation.py
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
def construct_schema_function() -> Callable:
    """
    Modifies model example and description if needed.

    Note that schema extra has to be a function, otherwise it's called to soon
    before all the relations are expanded.

    :return: callable that will be run by pydantic to modify the schema
    :rtype: Callable
    """

    def schema_extra(schema: Dict[str, Any], model: Type["Model"]) -> None:
        overwrite_example_and_description(schema=schema, model=model)
        overwrite_binary_format(schema=schema, model=model)

    return staticmethod(schema_extra)  # type: ignore

generate_example_for_nested_types(type_)

Process nested types like Union[X, Y] or List[X]

Source code in ormar\models\helpers\validation.py
150
151
152
153
154
155
156
157
def generate_example_for_nested_types(type_: Any) -> Any:
    """
    Process nested types like Union[X, Y] or List[X]
    """
    if type_.__origin__ == Union:
        return generate_example_for_union(type_=type_)
    if type_.__origin__ == list:
        return [get_pydantic_example_repr(type_.__args__[0])]

generate_example_for_union(type_)

Generates a pydantic example for Union[X, Y, ...]. Note that Optional can also be set as Union[X, None]

Source code in ormar\models\helpers\validation.py
160
161
162
163
164
165
166
167
168
def generate_example_for_union(type_: Any) -> Any:
    """
    Generates a pydantic example for Union[X, Y, ...].
    Note that Optional can also be set as Union[X, None]
    """
    values = tuple(
        get_pydantic_example_repr(x) for x in type_.__args__ if x is not type(None)
    )
    return values[0] if len(values) == 1 else values

generate_model_example(model, relation_map=None)

Generates example to be included in schema in fastapi.

Parameters:

Name Type Description Default
model Type[Model]

ormar.Model

required
relation_map Optional[Dict]

dict with relations to follow

None

Returns:

Type Description
Dict[str, int]

dict with example values

Source code in ormar\models\helpers\validation.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def generate_model_example(
    model: Type["Model"], relation_map: Optional[Dict] = None
) -> Dict:
    """
    Generates example to be included in schema in fastapi.

    :param model: ormar.Model
    :type model: Type["Model"]
    :param relation_map: dict with relations to follow
    :type relation_map: Optional[Dict]
    :return: dict with example values
    :rtype: Dict[str, int]
    """
    example: Dict[str, Any] = dict()
    relation_map = (
        relation_map
        if relation_map is not None
        else translate_list_to_dict(model._iterate_related_models())
    )
    for name, field in model.ormar_config.model_fields.items():
        populates_sample_fields_values(
            example=example, name=name, field=field, relation_map=relation_map
        )
    to_exclude = {name for name in model.ormar_config.model_fields}
    pydantic_repr = generate_pydantic_example(pydantic_model=model, exclude=to_exclude)
    example.update(pydantic_repr)

    return example

generate_pydantic_example(pydantic_model, exclude=None)

Generates dict with example.

Parameters:

Name Type Description Default
pydantic_model Type[BaseModel]

model to parse

required
exclude Optional[Set]

list of fields to exclude

None

Returns:

Type Description
Dict

dict with fields and sample values

Source code in ormar\models\helpers\validation.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
def generate_pydantic_example(
    pydantic_model: Type[pydantic.BaseModel], exclude: Optional[Set] = None
) -> Dict:
    """
    Generates dict with example.

    :param pydantic_model: model to parse
    :type pydantic_model: Type[pydantic.BaseModel]
    :param exclude: list of fields to exclude
    :type exclude: Optional[Set]
    :return: dict with fields and sample values
    :rtype: Dict
    """
    example: Dict[str, Any] = dict()
    exclude = exclude or set()
    name_to_check = [
        name for name in pydantic_model.model_fields if name not in exclude
    ]
    for name in name_to_check:
        field = pydantic_model.model_fields[name]
        type_ = field.annotation
        example[name] = get_pydantic_example_repr(type_)
    return example

get_nested_model_example(name, field, relation_map)

Gets representation of nested model.

Parameters:

Name Type Description Default
name str

name of the field to follow

required
field BaseField

ormar field

required
relation_map Dict

dict with relation map

required

Returns:

Type Description
Union[List, Dict]

nested model or list of nested model repr

Source code in ormar\models\helpers\validation.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def get_nested_model_example(
    name: str, field: "BaseField", relation_map: Dict
) -> Union[List, Dict]:
    """
    Gets representation of nested model.

    :param name: name of the field to follow
    :type name: str
    :param field: ormar field
    :type field: BaseField
    :param relation_map: dict with relation map
    :type relation_map: Dict
    :return: nested model or list of nested model repr
    :rtype: Union[List, Dict]
    """
    value = generate_model_example(field.to, relation_map=relation_map.get(name, {}))
    new_value: Union[List, Dict] = [value] if field.is_multi or field.virtual else value
    return new_value

get_pydantic_example_repr(type_)

Gets sample representation of pydantic field for example dict.

Parameters:

Name Type Description Default
type_ Any

type of pydantic field

required

Returns:

Type Description
Any

representation to include in example

Source code in ormar\models\helpers\validation.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def get_pydantic_example_repr(type_: Any) -> Any:
    """
    Gets sample representation of pydantic field for example dict.

    :param type_: type of pydantic field
    :type type_: Any
    :return: representation to include in example
    :rtype: Any
    """
    if hasattr(type_, "__origin__"):
        return generate_example_for_nested_types(type_)
    if issubclass(type_, (numbers.Number, decimal.Decimal)):
        return 0
    if issubclass(type_, pydantic.BaseModel):
        return generate_pydantic_example(pydantic_model=type_)
    return "string"

modify_schema_example(model)

Modifies the schema example in openapi schema.

Parameters:

Name Type Description Default
model Type[Model]

newly constructed Model

required
Source code in ormar\models\helpers\validation.py
222
223
224
225
226
227
228
229
230
def modify_schema_example(model: Type["Model"]) -> None:  # noqa CCR001
    """
    Modifies the schema example in openapi schema.

    :param model: newly constructed Model
    :type model: Model class
    """
    if not config_field_not_set(model=model, field_name="model_fields"):
        model.model_config["json_schema_extra"] = construct_schema_function()

overwrite_binary_format(schema, model)

Overwrites format of the field if it's a LargeBinary field with a flag to represent the field as base64 encoded string.

Parameters:

Name Type Description Default
schema Dict[str, Any]

schema of current model

required
model Type[Model]

model class

required
Source code in ormar\models\helpers\validation.py
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def overwrite_binary_format(schema: Dict[str, Any], model: Type["Model"]) -> None:
    """
    Overwrites format of the field if it's a LargeBinary field with
    a flag to represent the field as base64 encoded string.

    :param schema: schema of current model
    :type schema: Dict[str, Any]
    :param model: model class
    :type model: Type["Model"]
    """
    for field_id, prop in schema.get("properties", {}).items():
        if (
            field_id in model._bytes_fields
            and model.ormar_config.model_fields[field_id].represent_as_base64_str
        ):
            prop["format"] = "base64"

overwrite_example_and_description(schema, model)

Overwrites the example with properly nested children models. Overwrites the description if it's taken from ormar.Model.

Parameters:

Name Type Description Default
schema Dict[str, Any]

schema of current model

required
model Type[Model]

model class

required
Source code in ormar\models\helpers\validation.py
171
172
173
174
175
176
177
178
179
180
181
182
183
def overwrite_example_and_description(
    schema: Dict[str, Any], model: Type["Model"]
) -> None:
    """
    Overwrites the example with properly nested children models.
    Overwrites the description if it's taken from ormar.Model.

    :param schema: schema of current model
    :type schema: Dict[str, Any]
    :param model: model class
    :type model: Type["Model"]
    """
    schema["example"] = generate_model_example(model=model)

populates_sample_fields_values(example, name, field, relation_map=None)

Iterates the field and sets fields to sample values

Parameters:

Name Type Description Default
field BaseField

ormar field

required
name str

name of the field

required
example Dict[str, Any]

example dict

required
relation_map Optional[Dict]

dict with relations to follow

None
Source code in ormar\models\helpers\validation.py
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def populates_sample_fields_values(
    example: Dict[str, Any],
    name: str,
    field: "BaseField",
    relation_map: Optional[Dict] = None,
) -> None:
    """
    Iterates the field and sets fields to sample values

    :param field: ormar field
    :type field: BaseField
    :param name: name of the field
    :type name: str
    :param example: example dict
    :type example: Dict[str, Any]
    :param relation_map: dict with relations to follow
    :type relation_map: Optional[Dict]
    """
    if not field.is_relation:
        is_bytes_str = field.__type__ == bytes and field.represent_as_base64_str
        example[name] = field.__sample__ if not is_bytes_str else "string"
    elif isinstance(relation_map, dict) and name in relation_map:
        example[name] = get_nested_model_example(
            name=name, field=field, relation_map=relation_map
        )