11"""REST server using FastAPI framework."""
2- # pylint: disable=global-statement,too-many-statements
2+ # pylint: disable=global-statement,too-many-statements,too-many-locals
33
44import logging
55import sys
99from pydantic import BaseModel
1010from service_manager import __version__
1111from service_manager .cgroup import CgroupController
12- from service_manager .config import ResourceLimits
1312from service_manager .metrics import MetricsSampler
1413from service_manager .output import OutputCapture
1514from service_manager .registry import ServiceRegistry
@@ -96,7 +95,9 @@ def get_registry() -> ServiceRegistry:
9695def get_supervisor () -> ProcessSupervisor :
9796 """Get the process supervisor, raising HTTPException if not available."""
9897 if _supervisor is None :
99- raise HTTPException (status_code = 503 , detail = "Process supervisor not initialized" )
98+ raise HTTPException (
99+ status_code = 503 , detail = "Process supervisor not initialized"
100+ )
100101 return _supervisor
101102
102103
@@ -153,7 +154,9 @@ async def health() -> HealthResponse:
153154 reg = get_registry ()
154155 running = len (reg .running_services ())
155156 total = len (reg .all ())
156- return HealthResponse (status = "healthy" , services_running = running , services_total = total )
157+ return HealthResponse (
158+ status = "healthy" , services_running = running , services_total = total
159+ )
157160
158161 @app .get ("/version" , response_model = VersionResponse , tags = ["Health" ])
159162 async def version () -> VersionResponse :
@@ -178,7 +181,9 @@ async def get_service(name: str) -> dict[str, Any]:
178181 raise HTTPException (status_code = 404 , detail = f"Service not found: { name } " )
179182 return state .to_dict ()
180183
181- @app .post ("/services/{name}/start" , response_model = MessageResponse , tags = ["Services" ])
184+ @app .post (
185+ "/services/{name}/start" , response_model = MessageResponse , tags = ["Services" ]
186+ )
182187 async def start_service (name : str ) -> MessageResponse :
183188 """Start a stopped service."""
184189 reg = get_registry ()
@@ -195,8 +200,12 @@ async def start_service(name: str) -> MessageResponse:
195200 return MessageResponse (message = f"Service { name } started" )
196201 raise HTTPException (status_code = 500 , detail = f"Failed to start service: { name } " )
197202
198- @app .post ("/services/{name}/stop" , response_model = MessageResponse , tags = ["Services" ])
199- async def stop_service (name : str , body : Optional [StopServiceBody ] = None ) -> MessageResponse :
203+ @app .post (
204+ "/services/{name}/stop" , response_model = MessageResponse , tags = ["Services" ]
205+ )
206+ async def stop_service (
207+ name : str , body : Optional [StopServiceBody ] = None
208+ ) -> MessageResponse :
200209 """Stop a running service."""
201210 reg = get_registry ()
202211 sup = get_supervisor ()
@@ -213,7 +222,9 @@ async def stop_service(name: str, body: Optional[StopServiceBody] = None) -> Mes
213222 return MessageResponse (message = f"Service { name } stopped" )
214223 raise HTTPException (status_code = 500 , detail = f"Failed to stop service: { name } " )
215224
216- @app .post ("/services/{name}/restart" , response_model = MessageResponse , tags = ["Services" ])
225+ @app .post (
226+ "/services/{name}/restart" , response_model = MessageResponse , tags = ["Services" ]
227+ )
217228 async def restart_service (name : str ) -> MessageResponse :
218229 """Restart a service (stop then start)."""
219230 reg = get_registry ()
@@ -228,10 +239,16 @@ async def restart_service(name: str) -> MessageResponse:
228239 success = await sup .start_service (name )
229240 if success :
230241 return MessageResponse (message = f"Service { name } restarted" )
231- raise HTTPException (status_code = 500 , detail = f"Failed to restart service: { name } " )
242+ raise HTTPException (
243+ status_code = 500 , detail = f"Failed to restart service: { name } "
244+ )
232245
233- @app .patch ("/services/{name}/config" , response_model = MessageResponse , tags = ["Services" ])
234- async def update_service_config (name : str , body : UpdateConfigBody ) -> MessageResponse :
246+ @app .patch (
247+ "/services/{name}/config" , response_model = MessageResponse , tags = ["Services" ]
248+ )
249+ async def update_service_config (
250+ name : str , body : UpdateConfigBody
251+ ) -> MessageResponse :
235252 """Update service configuration (limits, restart settings)."""
236253 reg = get_registry ()
237254 cg = get_cgroup ()
@@ -259,15 +276,21 @@ async def update_service_config(name: str, body: UpdateConfigBody) -> MessageRes
259276 if body .limits :
260277 limits = spec .limits
261278 if body .limits .cpu_cores is not None :
262- limits .cpu_cores = body .limits .cpu_cores if body .limits .cpu_cores > 0 else None
279+ limits .cpu_cores = (
280+ body .limits .cpu_cores if body .limits .cpu_cores > 0 else None
281+ )
263282 updated_fields .append ("cpu_cores" )
264283
265284 if body .limits .memory_mb is not None :
266- limits .memory_mb = body .limits .memory_mb if body .limits .memory_mb > 0 else None
285+ limits .memory_mb = (
286+ body .limits .memory_mb if body .limits .memory_mb > 0 else None
287+ )
267288 updated_fields .append ("memory_mb" )
268289
269290 if body .limits .max_pids is not None :
270- limits .max_pids = body .limits .max_pids if body .limits .max_pids > 0 else None
291+ limits .max_pids = (
292+ body .limits .max_pids if body .limits .max_pids > 0 else None
293+ )
271294 updated_fields .append ("max_pids" )
272295
273296 # Apply limits to running service's cgroup if applicable
@@ -284,8 +307,12 @@ async def update_service_config(name: str, body: UpdateConfigBody) -> MessageRes
284307 @app .get ("/services/{name}/logs" , tags = ["Logs" ])
285308 async def get_service_logs (
286309 name : str ,
287- tail : Optional [int ] = Query (default = 100 , description = "Number of lines to return" ),
288- stream : Optional [str ] = Query (default = None , description = "Filter by stream (stdout/stderr)" ),
310+ tail : Optional [int ] = Query (
311+ default = 100 , description = "Number of lines to return"
312+ ),
313+ stream : Optional [str ] = Query (
314+ default = None , description = "Filter by stream (stdout/stderr)"
315+ ),
289316 ) -> dict [str , Any ]:
290317 """Get logs for a specific service."""
291318 reg = get_registry ()
@@ -298,7 +325,11 @@ async def get_service_logs(
298325 if not service_output :
299326 return {"service" : name , "lines" : [], "count" : 0 }
300327 lines = service_output .get_lines (tail = tail , stream = stream )
301- return {"service" : name , "lines" : [line .to_dict () for line in lines ], "count" : len (lines )}
328+ return {
329+ "service" : name ,
330+ "lines" : [line .to_dict () for line in lines ],
331+ "count" : len (lines ),
332+ }
302333
303334 # ----- Metrics Endpoints -----
304335
@@ -307,7 +338,10 @@ async def get_all_metrics() -> dict[str, Any]:
307338 """Get metrics for all services."""
308339 samp = get_sampler ()
309340 metrics = samp .get_all ()
310- return {"metrics" : {name : m .to_dict () for name , m in metrics .items ()}, "count" : len (metrics )}
341+ return {
342+ "metrics" : {name : m .to_dict () for name , m in metrics .items ()},
343+ "count" : len (metrics ),
344+ }
311345
312346 @app .get ("/metrics/{name}" , tags = ["Metrics" ])
313347 async def get_service_metrics (name : str ) -> dict [str , Any ]:
0 commit comments