Skip to content

Commit a46fde7

Browse files
committed
fixed openapi generation
1 parent 5ebf0da commit a46fde7

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

fastapi_jsonapi/data_layers/sqla_orm.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""This module is a CRUD interface between resource managers and the sqlalchemy ORM"""
22
import logging
3-
from typing import TYPE_CHECKING, Any, Iterable, List, Optional, Tuple, Type
3+
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Tuple, Type
44

55
from sqlalchemy import delete, func, select
66
from sqlalchemy.exc import DBAPIError, IntegrityError, NoResultFound
@@ -32,6 +32,7 @@
3232
get_related_schema,
3333
)
3434
from fastapi_jsonapi.schema_base import RelationshipInfo
35+
from fastapi_jsonapi.schema_builder import FieldConfig, TransferSaveWrapper
3536
from fastapi_jsonapi.splitter import SPLIT_REL
3637
from fastapi_jsonapi.utils.sqla import get_related_model_cls
3738

@@ -184,6 +185,14 @@ async def apply_relationships(self, obj: TypeModel, data_create: BaseJSONAPIItem
184185
# todo: relation name may be different?
185186
setattr(obj, relation_name, related_data)
186187

188+
def _unwrap_field_config(self, extra: Dict):
189+
field_config_wrapper: TransferSaveWrapper = extra.get("field_config")
190+
191+
if field_config_wrapper:
192+
return field_config_wrapper.field_config
193+
194+
return FieldConfig()
195+
187196
def _apply_client_generated_id(
188197
self,
189198
data_create: BaseJSONAPIItemInSchema,
@@ -199,8 +208,11 @@ def _apply_client_generated_id(
199208
extra = data_create.__fields__["id"].field_info.extra
200209
if extra.get("client_can_set_id"):
201210
id_value = data_create.id
202-
if cast_type := extra.get("id_cast_func"):
203-
id_value = cast_type(id_value)
211+
field_config = self._unwrap_field_config(extra)
212+
213+
if field_config.cast_type:
214+
id_value = field_config.cast_type(id_value)
215+
204216
model_kwargs["id"] = id_value
205217

206218
return model_kwargs

fastapi_jsonapi/schema_builder.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,29 @@
4646
# todo: when 3.9 support is dropped, return back `slots=True to JSONAPIObjectSchemas dataclass`
4747

4848

49+
class FieldConfig:
50+
cast_type: Callable
51+
52+
def __init__(self, cast_type: Optional[Callable] = None):
53+
self.cast_type = cast_type
54+
55+
56+
class TransferSaveWrapper:
57+
"""
58+
Types doesn't allowed to be passed as keywords to pydantic Field,
59+
so this exists to help save them
60+
61+
In other case OpenAPI generation will fail
62+
"""
63+
64+
def __init__(self, field_config: FieldConfig):
65+
self.get_config = lambda: field_config
66+
67+
@property
68+
def field_config(self) -> FieldConfig:
69+
return self.get_config()
70+
71+
4972
@dataclass(frozen=True)
5073
class JSONAPIObjectSchemas:
5174
attributes_schema: Type[BaseModel]
@@ -479,7 +502,9 @@ def _build_jsonapi_object(
479502
**field_info.extra,
480503
}
481504
if id_cast_func:
482-
id_field_kw.update(id_cast_func=id_cast_func)
505+
id_field_kw.update(
506+
field_config=TransferSaveWrapper(field_config=FieldConfig(cast_type=id_cast_func)),
507+
)
483508

484509
object_jsonapi_schema_fields = {
485510
"attributes": (attributes_schema, ...),

0 commit comments

Comments
 (0)