|
16 | 16 |
|
17 | 17 |
|
18 | 18 | class BulkArgsResolverGenerator:
|
| 19 | + """ |
| 20 | + This class splits Schema into different ModelFields to he resolved independently and computed back later. |
| 21 | + class ASchema(BaseModel): |
| 22 | + A: int |
| 23 | + B: int |
| 24 | +
|
| 25 | + def endpoint(a: ASchema = Query()) |
| 26 | + pass |
| 27 | +
|
| 28 | + args_resolver = BulkArgsResolverGenerator(a) where `a` is `endpoint` parameter. |
| 29 | + args_resolver.generate_resolvers() == [AModelFieldResolver, BModelFieldResolver] |
| 30 | +
|
| 31 | + The generated ModelFieldResolvers are saved to self.param_field.field_info.extra with MULTI_RESOLVER_KEY key |
| 32 | + Which will be available when creating a resolver and cleared afterwards |
| 33 | +
|
| 34 | + def create_resolver(self, model_field: ModelField) -> RouteParameterResolver: |
| 35 | + multiple_resolvers = model_field.field_info.extra.get(MULTI_RESOLVER_KEY) |
| 36 | + if multiple_resolvers: |
| 37 | + model_field.field_info.extra.clear() |
| 38 | + return self.bulk_resolver( |
| 39 | + model_field=model_field, resolvers=multiple_resolvers |
| 40 | + ) |
| 41 | + return self.resolver(model_field) |
| 42 | + """ |
| 43 | + |
19 | 44 | __slots__ = ("param_field", "pydantic_outer_type")
|
20 | 45 |
|
21 | 46 | def __init__(self, pydantic_type: ModelField) -> None:
|
22 | 47 | self.pydantic_outer_type = t.cast(BaseModel, pydantic_type.outer_type_)
|
23 | 48 | self.param_field = pydantic_type
|
24 | 49 |
|
25 | 50 | def validate(self, field_name: str, field: ModelField) -> None:
|
26 |
| - if not is_scalar_field(field=field) and not is_scalar_sequence_field( |
27 |
| - self.param_field |
28 |
| - ): |
| 51 | + if not is_scalar_field(field=field): |
29 | 52 | raise ImproperConfiguration(
|
30 |
| - f"field: '{field_name}' with annotation:'{field.type_}' " |
31 |
| - f"can't be processed. Field type should belong to {sequence_types} " |
32 |
| - f"or any primitive type" |
| 53 | + f"field: '{field_name}' with annotation:'{field.outer_type_}' in '{self.param_field.type_}'" |
| 54 | + f"can't be processed. Field type is not a primitive type" |
33 | 55 | )
|
34 | 56 |
|
35 | 57 | def get_parameter_field(
|
@@ -91,21 +113,28 @@ def generate_resolvers(self, body_field_class: t.Type[FieldInfo]) -> None:
|
91 | 113 | self.param_field.field_info.extra[MULTI_RESOLVER_KEY] = resolvers
|
92 | 114 |
|
93 | 115 |
|
94 |
| -class FormArgsResolverGenerator(BulkArgsResolverGenerator): |
| 116 | +class QueryHeaderResolverGenerator(BulkArgsResolverGenerator): |
95 | 117 | def validate(self, field_name: str, field: ModelField) -> None:
|
96 |
| - """ "Do nothing""" |
| 118 | + if not is_scalar_field(field=field) and not is_scalar_sequence_field(field): |
| 119 | + raise ImproperConfiguration( |
| 120 | + f"field: '{field_name}' with annotation:'{field.outer_type_}' in '{self.param_field.type_}'" |
| 121 | + f"can't be processed. Field type should belong to {sequence_types} " |
| 122 | + f"or any primitive type" |
| 123 | + ) |
| 124 | + |
97 | 125 |
|
| 126 | +class FormArgsResolverGenerator(QueryHeaderResolverGenerator): |
98 | 127 | def generate_resolvers(self, body_field_class: t.Type[FieldInfo]) -> None:
|
99 | 128 | super().generate_resolvers(body_field_class=body_field_class)
|
100 | 129 | self.param_field.field_info.extra[MULTI_RESOLVER_FORM_GROUPED_KEY] = True
|
101 | 130 |
|
102 | 131 |
|
103 | 132 | class PathArgsResolverGenerator(BulkArgsResolverGenerator):
|
104 | 133 | def validate(self, field_name: str, field: ModelField) -> None:
|
105 |
| - """ "Do nothing""" |
106 |
| - assert is_scalar_field( |
107 |
| - field=field |
108 |
| - ), "Path params must be of one of the supported types" |
| 134 | + if not is_scalar_field(field=field): |
| 135 | + raise ImproperConfiguration( |
| 136 | + "Path params must be of one of the supported types. Only primitive types" |
| 137 | + ) |
109 | 138 |
|
110 | 139 | def get_parameter_field(
|
111 | 140 | self,
|
|
0 commit comments