Encode decimals as number in JSON
This commit is contained in:
parent
148275dd98
commit
b1a94c5359
6 changed files with 36 additions and 1 deletions
|
@ -8,6 +8,8 @@ from app.schemas.connector import Connector
|
|||
|
||||
from ocpp.v201.enums import ResetEnumType, ResetStatusEnumType
|
||||
|
||||
from app.util.encoders import decimal_encoder
|
||||
|
||||
class ChargePointBase(BaseModel):
|
||||
identity: str
|
||||
is_active: bool
|
||||
|
@ -32,6 +34,7 @@ class ChargePoint(ChargePointBase):
|
|||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
json_encoders = {Decimal: decimal_encoder}
|
||||
|
||||
class ChargePointPassword(BaseModel):
|
||||
password: str
|
||||
|
|
|
@ -4,6 +4,8 @@ from uuid import UUID
|
|||
from pydantic import BaseModel
|
||||
import enum
|
||||
|
||||
from app.util.encoders import decimal_encoder
|
||||
|
||||
class AttributeType(enum.Enum):
|
||||
ACTUAL = "Actual"
|
||||
TARGET = "Target"
|
||||
|
@ -52,6 +54,7 @@ class ChargepointVariable(BaseModel):
|
|||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
json_encoders = {Decimal: decimal_encoder}
|
||||
|
||||
class ChargepointVariableUpdate(BaseModel):
|
||||
value: str
|
||||
|
|
|
@ -5,6 +5,8 @@ from typing import Optional
|
|||
from uuid import UUID
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.util.encoders import decimal_encoder
|
||||
|
||||
class PhaseType(enum.Enum):
|
||||
L1 = "L1"
|
||||
L2 = "L2"
|
||||
|
@ -55,3 +57,4 @@ class MeterValue(BaseModel):
|
|||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
json_encoders = {Decimal: decimal_encoder}
|
||||
|
|
|
@ -8,4 +8,5 @@ class Session(BaseModel):
|
|||
name: str
|
||||
last_used: datetime
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
class Config:
|
||||
from_attributes = True
|
|
@ -5,6 +5,8 @@ from typing import Optional
|
|||
from uuid import UUID
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.util.encoders import decimal_encoder
|
||||
|
||||
class TransactionStatus(enum.Enum):
|
||||
ONGOING = "ongoing"
|
||||
ENDED = "ended"
|
||||
|
@ -50,6 +52,7 @@ class Transaction(BaseModel):
|
|||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
json_encoders = {Decimal: decimal_encoder}
|
||||
|
||||
class RemoteTransactionStartStopResponse(BaseModel):
|
||||
status: RemoteTransactionStartStopStatus
|
||||
|
|
22
backend/app/util/encoders.py
Normal file
22
backend/app/util/encoders.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
from decimal import Decimal
|
||||
from typing import Union
|
||||
|
||||
def decimal_encoder(dec_value: Decimal) -> Union[int, float]:
|
||||
"""Encodes a Decimal as int of there's no exponent, otherwise float.
|
||||
|
||||
This is useful when we use ConstrainedDecimal to represent Numeric(x,0)
|
||||
where a integer (but not int typed) is used. Encoding this as a float
|
||||
results in failed round-tripping between encode and parse.
|
||||
Our Id type is a prime example of this.
|
||||
|
||||
>>> decimal_encoder(Decimal("1.0"))
|
||||
1.0
|
||||
|
||||
>>> decimal_encoder(Decimal("1"))
|
||||
1
|
||||
"""
|
||||
exponent = dec_value.as_tuple().exponent
|
||||
if isinstance(exponent, int) and exponent >= 0:
|
||||
return int(dec_value)
|
||||
else:
|
||||
return float(dec_value)
|
Loading…
Add table
Reference in a new issue