Permissive Update: Implement x-ae-ignore-extra-fields header support for nested routes
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from fastapi import APIRouter, Depends, Path, Query, Request, Response
|
||||
from fastapi import APIRouter, Depends, Path, Query, Request, Response, Header
|
||||
from pydantic import ValidationError
|
||||
from typing import Optional, Union
|
||||
import asyncio
|
||||
import logging
|
||||
@@ -132,6 +133,7 @@ async def post_child_obj(
|
||||
parent_obj_id: str = Path(min_length=11, max_length=22),
|
||||
child_obj_type: str = Path(min_length=2, max_length=50),
|
||||
return_obj: Optional[bool] = True,
|
||||
x_ae_ignore_extra_fields: Optional[bool] = Header(False),
|
||||
account: AccountContext = Depends(get_account_context),
|
||||
serialization: SerializationParams = Depends(),
|
||||
delay: DelayParams = Depends(),
|
||||
@@ -170,22 +172,28 @@ async def post_child_obj(
|
||||
input_model = obj_cfg.get('mdl_in', obj_cfg.get('mdl'))
|
||||
output_model = obj_cfg.get('mdl_out', obj_cfg.get('mdl_default', obj_cfg.get('mdl')))
|
||||
|
||||
if not table_name_insert or not input_model or not table_name_select or not output_model:
|
||||
return mk_resp(data=False, status_code=500, response=response, status_message=f"Configuration error.")
|
||||
|
||||
if not account.super and account.auth_method != 'bypass' and account.account_id:
|
||||
if 'account_id' in input_model.__fields__:
|
||||
obj_data['account_id'] = account.account_id
|
||||
|
||||
obj_data[f'{parent_obj_type}_id'] = resolved_parent_id
|
||||
|
||||
# Sanitize payload (ID resolution, virtual fields, and optionally extra fields)
|
||||
sanitize_payload(obj_data, input_model, ignore_extra=x_ae_ignore_extra_fields)
|
||||
|
||||
try:
|
||||
validated_obj = input_model(**obj_data)
|
||||
except ValidationError as e:
|
||||
structured_errors = {err['loc'][-1]: err['msg'] for err in e.errors()}
|
||||
return mk_resp(data=False, status_code=400, response=response, status_message="Validation Failed", details=structured_errors)
|
||||
except Exception as e:
|
||||
return mk_resp(data=False, status_code=400, response=response, status_message="Validation Failed", details=str(e))
|
||||
|
||||
data_to_insert = validated_obj.dict(exclude_unset=True)
|
||||
|
||||
# Sanitize payload (remove virtual fields and view-only fields)
|
||||
sanitize_payload(data_to_insert, input_model)
|
||||
|
||||
if sql_insert_result := sql_insert(data=data_to_insert, table_name=table_name_insert):
|
||||
new_obj_id = sql_insert_result
|
||||
new_obj_id_random = get_id_random(record_id=new_obj_id, table_name=child_obj_type)
|
||||
@@ -248,6 +256,7 @@ async def patch_child_obj(
|
||||
child_obj_type: str = Path(min_length=2, max_length=50),
|
||||
child_obj_id: str = Path(min_length=11, max_length=22),
|
||||
return_obj: Optional[bool] = True,
|
||||
x_ae_ignore_extra_fields: Optional[bool] = Header(False),
|
||||
account: AccountContext = Depends(get_account_context),
|
||||
serialization: SerializationParams = Depends(),
|
||||
delay: DelayParams = Depends(),
|
||||
@@ -271,6 +280,7 @@ async def patch_child_obj(
|
||||
obj_cfg = obj_type_kv_li[child_obj_type]
|
||||
table_name_update = obj_cfg.get('tbl_update', obj_cfg.get('tbl'))
|
||||
table_name_select = obj_cfg.get('tbl_default', obj_cfg.get('tbl'))
|
||||
input_model = obj_cfg.get('mdl_in', obj_cfg.get('mdl'))
|
||||
output_model = obj_cfg.get('mdl_out', obj_cfg.get('mdl_default', obj_cfg.get('mdl')))
|
||||
|
||||
if existing_child := sql_select(table_name=table_name_select, record_id=resolved_child_id):
|
||||
@@ -279,8 +289,8 @@ async def patch_child_obj(
|
||||
else:
|
||||
return mk_resp(data=False, status_code=404, response=response, status_message="Child not found.")
|
||||
|
||||
# Sanitize payload (remove virtual fields and view-only fields)
|
||||
sanitize_payload(obj_data, output_model)
|
||||
# Sanitize payload (ID resolution, virtual fields, and optionally extra fields)
|
||||
sanitize_payload(obj_data, input_model, ignore_extra=x_ae_ignore_extra_fields)
|
||||
|
||||
if sql_update(data=obj_data, table_name=table_name_update, record_id=resolved_child_id):
|
||||
if return_obj:
|
||||
|
||||
Reference in New Issue
Block a user