How to directly serialize Decimals to JSON numbers? (FHIR spec decimal cmpliance) #14929
Replies: 2 comments
-
|
The root issue: FastAPI calls Solution: Return a import simplejson
from fastapi import Response
class FHIRResponse(Response):
media_type = "application/fhir+json"
def render(self, content) -> bytes:
return simplejson.dumps(content, use_decimal=True).encode("utf-8")
@app.get("/observation", response_class=FHIRResponse)
async def get_observation():
data = {"valueDecimal": Decimal("3.5000")}
return FHIRResponse(content=data) # Return directly, not just the dictBy returning Alternative with import orjson
class FHIRResponse(Response):
def render(self, content) -> bytes:
return orjson.dumps(content, option=orjson.OPT_PASSTHROUGH_DECIMAL,
default=lambda x: float(x) if isinstance(x, Decimal) else x)The key insight: |
Beta Was this translation helpful? Give feedback.
-
|
Since FastAPI 0.130.0, from decimal import Decimal
from fastapi import FastAPI
from fastapi.routing import APIRouter
from pydantic import BaseModel, field_serializer
app = FastAPI()
router = APIRouter()
class Foo(BaseModel):
value: Decimal
@field_serializer("value", mode="plain")
def serialize_value(self, value: Decimal) -> float:
return float(value)
@router.post("/")
async def foo() -> Foo:
return Foo(value=Decimal("0.01"))
app.include_router(router)Or, using custom type with serializer: from decimal import Decimal
from typing import Annotated, TypeAlias
from fastapi import FastAPI
from fastapi.routing import APIRouter
from pydantic import BaseModel, PlainSerializer
app = FastAPI()
router = APIRouter()
MyDecimal: TypeAlias = Annotated[Decimal, PlainSerializer(lambda v: float(v))]
class Foo(BaseModel):
value: MyDecimal
@router.post("/")
async def foo() -> Foo:
return Foo(value=Decimal("0.01"))
app.include_router(router)BTW, could you please explain why we may need to serialize |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
First Check
Commit to Help
Example Code
Output:
After reading the webpages #5023 and https://fastapi.tiangolo.com/advanced/custom-response/#custom-response-class I proceeded to configure simplejson into my backend
Curl:
With console log as
First of all I'd like to say deserialization is not the issue as there within the function the type is being seen as a Decimal.
However when the object is being returned Decimal is being turned into a string somewhere in the middle before simplejson gets to serialize the Decimal.
There is a fix which is to return the JSONResponse directly.
But how do i override the part where fastapi turns Decimal into a string?
Beta Was this translation helpful? Give feedback.
All reactions