Skip to content

Commit a8862c4

Browse files
committed
ENH: refactor attribute collection to use unified collect_attributes function
1 parent a15232d commit a8862c4

File tree

5 files changed

+104
-89
lines changed

5 files changed

+104
-89
lines changed

src/services/environment.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from rocketpy.environment.environment import Environment as RocketPyEnvironment
66
from src.models.environment import EnvironmentModel
77
from src.views.environment import EnvironmentSimulation
8-
from src.utils import collect_simulation_attributes
8+
from src.utils import collect_attributes
99

1010

1111
class EnvironmentService:
@@ -54,9 +54,9 @@ def get_environment_simulation(self) -> EnvironmentSimulation:
5454
EnvironmentSimulation
5555
"""
5656

57-
encoded_attributes = collect_simulation_attributes(
57+
encoded_attributes = collect_attributes(
5858
self.environment,
59-
EnvironmentSimulation,
59+
[EnvironmentSimulation],
6060
)
6161
env_simulation = EnvironmentSimulation(**encoded_attributes)
6262
return env_simulation

src/services/flight.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from src.views.rocket import RocketSimulation
1212
from src.views.motor import MotorSimulation
1313
from src.views.environment import EnvironmentSimulation
14-
from src.utils import collect_simulation_attributes
14+
from src.utils import collect_attributes
1515

1616
class FlightService:
1717
_flight: RocketPyFlight
@@ -57,12 +57,9 @@ def get_flight_simulation(self) -> FlightSimulation:
5757
Returns:
5858
FlightSimulation
5959
"""
60-
encoded_attributes = collect_simulation_attributes(
60+
encoded_attributes = collect_attributes(
6161
self.flight,
62-
FlightSimulation,
63-
RocketSimulation,
64-
MotorSimulation,
65-
EnvironmentSimulation
62+
[FlightSimulation, RocketSimulation, MotorSimulation, EnvironmentSimulation]
6663
)
6764
flight_simulation = FlightSimulation(**encoded_attributes)
6865
return flight_simulation

src/services/motor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from src.models.sub.tanks import TankKinds
1818
from src.models.motor import MotorKinds, MotorModel
1919
from src.views.motor import MotorSimulation
20-
from src.utils import collect_simulation_attributes
20+
from src.utils import collect_attributes
2121

2222

2323
class MotorService:
@@ -140,9 +140,9 @@ def get_motor_simulation(self) -> MotorSimulation:
140140
Returns:
141141
MotorSimulation
142142
"""
143-
encoded_attributes = collect_simulation_attributes(
143+
encoded_attributes = collect_attributes(
144144
self.motor,
145-
MotorSimulation,
145+
[MotorSimulation],
146146
)
147147
motor_simulation = MotorSimulation(**encoded_attributes)
148148
return motor_simulation

src/services/rocket.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from src.services.motor import MotorService
1919
from src.views.rocket import RocketSimulation
2020
from src.views.motor import MotorSimulation
21-
from src.utils import collect_simulation_attributes
21+
from src.utils import collect_attributes
2222

2323
class RocketService:
2424
_rocket: RocketPyRocket
@@ -107,10 +107,9 @@ def get_rocket_simulation(self) -> RocketSimulation:
107107
Returns:
108108
RocketSimulation
109109
"""
110-
encoded_attributes = collect_simulation_attributes(
110+
encoded_attributes = collect_attributes(
111111
self.rocket,
112-
RocketSimulation,
113-
MotorSimulation,
112+
[RocketSimulation, MotorSimulation]
114113
)
115114
rocket_simulation = RocketSimulation(**encoded_attributes)
116115
return rocket_simulation

src/utils.py

Lines changed: 92 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
from typing import NoReturn
77

8+
from views.environment import EnvironmentSimulation
9+
from views.flight import FlightSimulation
10+
from views.motor import MotorSimulation
11+
from views.rocket import RocketSimulation
12+
813
from rocketpy._encoders import RocketPyEncoder
914
from starlette.datastructures import Headers, MutableHeaders
1015
from starlette.types import ASGIApp, Message, Receive, Scope, Send
@@ -37,93 +42,107 @@ def rocketpy_encoder(obj):
3742
return json.loads(json_str)
3843

3944

40-
def collect_simulation_attributes(flight_obj, flight_simulation_class, rocket_simulation_class, motor_simulation_class, environment_simulation_class):
45+
def collect_attributes(obj, attribute_classes=None):
4146
"""
4247
Collect attributes from various simulation classes and populate them from the flight object.
4348
4449
Args:
45-
flight_obj: RocketPy Flight object
46-
flight_simulation_class: FlightSimulation class
47-
rocket_simulation_class: RocketSimulation class
48-
motor_simulation_class: MotorSimulation class
49-
environment_simulation_class: EnvironmentSimulation class
50-
50+
obj: RocketPy Flight object
51+
attribute_classes: List of attribute classes to collect from
52+
5153
Returns:
5254
Dictionary with all collected attributes
5355
"""
54-
attributes = rocketpy_encoder(flight_obj)
55-
56-
flight_attributes_list = [
57-
attr for attr in flight_simulation_class.__annotations__.keys()
58-
if attr not in ['message', 'rocket', 'env']
59-
]
60-
61-
rocket_attributes_list = [
62-
attr for attr in rocket_simulation_class.__annotations__.keys()
63-
if attr not in ['message', 'motor']
64-
]
65-
66-
motor_attributes_list = [
67-
attr for attr in motor_simulation_class.__annotations__.keys()
68-
if attr not in ['message']
69-
]
70-
71-
environment_attributes_list = [
72-
attr for attr in environment_simulation_class.__annotations__.keys()
73-
if attr not in ['message']
74-
]
75-
76-
try:
77-
for key in flight_attributes_list:
56+
if attribute_classes is None:
57+
attribute_classes = []
58+
59+
attributes = rocketpy_encoder(obj)
60+
61+
for attribute_class in attribute_classes:
62+
if issubclass(attribute_class, FlightSimulation):
63+
flight_attributes_list = [
64+
attr for attr in attribute_class.__annotations__.keys()
65+
if attr not in ['message', 'rocket', 'env']
66+
]
7867
try:
79-
value = getattr(flight_obj, key)
80-
attributes[key] = value
81-
except AttributeError as e:
82-
logger.warning(f"Flight attribute '{key}' not found: {e}")
83-
except Exception as e:
84-
logger.error(f"Error getting flight attribute '{key}': {type(e).__name__}: {e}")
85-
except Exception as e:
86-
logger.error(f"Error processing flight attributes: {type(e).__name__}: {e}")
87-
88-
try:
89-
for key in rocket_attributes_list:
68+
for key in flight_attributes_list:
69+
if key not in attributes:
70+
try:
71+
value = getattr(obj, key)
72+
attributes[key] = value
73+
except AttributeError:
74+
pass
75+
except Exception:
76+
pass
77+
except Exception:
78+
pass
79+
80+
elif issubclass(attribute_class, RocketSimulation):
81+
rocket_attributes_list = [
82+
attr for attr in attribute_class.__annotations__.keys()
83+
if attr not in ['message', 'motor']
84+
]
9085
try:
91-
value = getattr(flight_obj.rocket, key)
92-
attributes["rocket"][key] = value
93-
except AttributeError as e:
94-
logger.warning(f"Rocket attribute '{key}' not found: {e}")
95-
except Exception as e:
96-
logger.error(f"Error getting rocket attribute '{key}': {type(e).__name__}: {e}")
97-
except Exception as e:
98-
logger.error(f"Error processing rocket attributes: {type(e).__name__}: {e}")
99-
100-
try:
101-
for key in motor_attributes_list:
86+
for key in rocket_attributes_list:
87+
if key not in attributes.get("rocket", {}):
88+
try:
89+
value = getattr(obj.rocket, key)
90+
if "rocket" not in attributes:
91+
attributes["rocket"] = {}
92+
attributes["rocket"][key] = value
93+
except AttributeError:
94+
pass
95+
except Exception:
96+
pass
97+
except Exception:
98+
pass
99+
100+
elif issubclass(attribute_class, MotorSimulation):
101+
motor_attributes_list = [
102+
attr for attr in attribute_class.__annotations__.keys()
103+
if attr not in ['message']
104+
]
102105
try:
103-
value = getattr(flight_obj.rocket.motor, key)
104-
attributes["rocket"]["motor"][key] = value
105-
except AttributeError as e:
106-
logger.warning(f"Motor attribute '{key}' not found: {e}")
107-
except Exception as e:
108-
logger.error(f"Error getting motor attribute '{key}': {type(e).__name__}: {e}")
109-
except Exception as e:
110-
logger.error(f"Error processing motor attributes: {type(e).__name__}: {e}")
111-
112-
try:
113-
for key in environment_attributes_list:
106+
for key in motor_attributes_list:
107+
if key not in attributes.get("rocket", {}).get("motor", {}):
108+
try:
109+
value = getattr(obj.rocket.motor, key)
110+
if "rocket" not in attributes:
111+
attributes["rocket"] = {}
112+
if "motor" not in attributes["rocket"]:
113+
attributes["rocket"]["motor"] = {}
114+
attributes["rocket"]["motor"][key] = value
115+
except AttributeError:
116+
pass
117+
except Exception:
118+
pass
119+
except Exception:
120+
pass
121+
122+
elif issubclass(attribute_class, EnvironmentSimulation):
123+
environment_attributes_list = [
124+
attr for attr in attribute_class.__annotations__.keys()
125+
if attr not in ['message']
126+
]
114127
try:
115-
value = getattr(flight_obj.env, key)
116-
attributes["env"][key] = value
117-
except AttributeError as e:
118-
logger.warning(f"Environment attribute '{key}' not found: {e}")
119-
except Exception as e:
120-
logger.error(f"Error getting environment attribute '{key}': {type(e).__name__}: {e}")
121-
except Exception as e:
122-
logger.error(f"Error processing environment attributes: {type(e).__name__}: {e}")
128+
for key in environment_attributes_list:
129+
if key not in attributes.get("env", {}):
130+
try:
131+
value = getattr(obj.env, key)
132+
if "env" not in attributes:
133+
attributes["env"] = {}
134+
attributes["env"][key] = value
135+
except AttributeError:
136+
pass
137+
except Exception:
138+
pass
139+
except Exception:
140+
pass
141+
else:
142+
continue
123143

124144
return rocketpy_encoder(attributes)
125145

126-
127146
class RocketPyGZipMiddleware:
128147
def __init__(
129148
self, app: ASGIApp, minimum_size: int = 500, compresslevel: int = 9

0 commit comments

Comments
 (0)