Skip to content

Commit 0558bb1

Browse files
add json string parsing globally
1 parent 08600bf commit 0558bb1

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

src/models/flight.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,28 @@ def RETRIEVED(model_instance: type(Self)):
7373
)
7474
)
7575

76+
@field_validator('environment', mode='before')
77+
@classmethod
78+
def _coerce_environment(cls, value):
79+
if isinstance(value, str):
80+
try:
81+
return json.loads(value)
82+
except json.JSONDecodeError as exc:
83+
raise ValueError(
84+
'Invalid JSON for environment payload'
85+
) from exc
86+
return value
87+
88+
@field_validator('rocket', mode='before')
89+
@classmethod
90+
def _coerce_rocket(cls, value):
91+
if isinstance(value, str):
92+
try:
93+
return json.loads(value)
94+
except json.JSONDecodeError as exc:
95+
raise ValueError('Invalid JSON for rocket payload') from exc
96+
return value
97+
7698

7799
class FlightPartialModel(BaseModel):
78100
"""Flight attributes required when rocket/environment are referenced."""

src/models/motor.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import json
12
from enum import Enum
23
from typing import Optional, Tuple, List, Union, Self, ClassVar, Literal
3-
from pydantic import model_validator
4+
from pydantic import model_validator, field_validator
45

56
from src.models.interface import ApiBaseModel
67
from src.models.sub.tanks import MotorTank
@@ -57,6 +58,18 @@ class MotorModel(ApiBaseModel):
5758
] = 'nozzle_to_combustion_chamber'
5859
reshape_thrust_curve: Union[bool, tuple] = False
5960

61+
@field_validator('tanks', mode='before')
62+
@classmethod
63+
def _coerce_tanks(cls, value):
64+
if isinstance(value, str):
65+
try:
66+
value = json.loads(value)
67+
except json.JSONDecodeError as exc:
68+
raise ValueError('Invalid JSON for tanks payload') from exc
69+
if isinstance(value, dict):
70+
value = [value]
71+
return value
72+
6073
@model_validator(mode='after')
6174
# TODO: extend guard to check motor kinds and tank kinds specifics
6275
def validate_motor_kind(self):

src/models/rocket.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@
1313
)
1414

1515

16+
def _maybe_parse_json(value):
17+
if isinstance(value, str):
18+
try:
19+
return json.loads(value)
20+
except json.JSONDecodeError as exc:
21+
raise ValueError('Invalid JSON payload') from exc
22+
return value
23+
24+
1625
class RocketModel(ApiBaseModel):
1726
NAME: ClassVar = "rocket"
1827
METHODS: ClassVar = ("POST", "GET", "PUT", "DELETE")
@@ -40,6 +49,42 @@ class RocketModel(ApiBaseModel):
4049
rail_buttons: Optional[RailButtons] = None
4150
tail: Optional[Tail] = None
4251

52+
@field_validator('motor', mode='before')
53+
@classmethod
54+
def _coerce_motor(cls, value):
55+
return _maybe_parse_json(value)
56+
57+
@field_validator('nose', mode='before')
58+
@classmethod
59+
def _coerce_nose(cls, value):
60+
return _maybe_parse_json(value)
61+
62+
@field_validator('fins', mode='before')
63+
@classmethod
64+
def _coerce_fins(cls, value):
65+
value = _maybe_parse_json(value)
66+
if isinstance(value, dict):
67+
value = [value]
68+
return value
69+
70+
@field_validator('parachutes', mode='before')
71+
@classmethod
72+
def _coerce_parachutes(cls, value):
73+
value = _maybe_parse_json(value)
74+
if isinstance(value, dict):
75+
value = [value]
76+
return value
77+
78+
@field_validator('rail_buttons', mode='before')
79+
@classmethod
80+
def _coerce_rail_buttons(cls, value):
81+
return _maybe_parse_json(value)
82+
83+
@field_validator('tail', mode='before')
84+
@classmethod
85+
def _coerce_tail(cls, value):
86+
return _maybe_parse_json(value)
87+
4388
@staticmethod
4489
def UPDATED():
4590
return

0 commit comments

Comments
 (0)