From 6a5829e0ff89d76667146bfbd3dea171c32c5484 Mon Sep 17 00:00:00 2001 From: Jason Staack Date: Thu, 19 Mar 2026 13:49:59 -0500 Subject: [PATCH] style: ruff format 10 python files Co-Authored-By: Claude Opus 4.6 (1M context) --- .../031_wireless_registrations_hypertable.py | 20 +++++-------------- .../035_site_alert_rules_and_events.py | 20 ++++--------------- backend/app/models/site_alert.py | 4 +--- backend/app/routers/links.py | 12 ++++++++--- backend/app/routers/site_alerts.py | 12 +++-------- backend/app/routers/sites.py | 4 +--- backend/app/services/alert_evaluator_site.py | 14 ++++++------- backend/app/services/interface_subscriber.py | 4 +--- .../app/services/link_discovery_subscriber.py | 10 ++++++---- backend/app/services/site_service.py | 8 ++++---- 10 files changed, 41 insertions(+), 67 deletions(-) diff --git a/backend/alembic/versions/031_wireless_registrations_hypertable.py b/backend/alembic/versions/031_wireless_registrations_hypertable.py index 17e04ea..9d5b30e 100644 --- a/backend/alembic/versions/031_wireless_registrations_hypertable.py +++ b/backend/alembic/versions/031_wireless_registrations_hypertable.py @@ -58,9 +58,7 @@ def upgrade() -> None: ) conn.execute( - sa.text( - "SELECT create_hypertable('wireless_registrations', 'time', if_not_exists => TRUE)" - ) + sa.text("SELECT create_hypertable('wireless_registrations', 'time', if_not_exists => TRUE)") ) # Primary lookup: device + time range @@ -126,9 +124,7 @@ def upgrade() -> None: ) conn.execute( - sa.text( - "SELECT create_hypertable('rf_monitor_stats', 'time', if_not_exists => TRUE)" - ) + sa.text("SELECT create_hypertable('rf_monitor_stats', 'time', if_not_exists => TRUE)") ) conn.execute( @@ -157,23 +153,17 @@ def upgrade() -> None: conn.execute(sa.text("GRANT SELECT, INSERT ON rf_monitor_stats TO app_user")) conn.execute(sa.text("GRANT SELECT, INSERT ON rf_monitor_stats TO poller_user")) - conn.execute( - sa.text("SELECT add_retention_policy('rf_monitor_stats', INTERVAL '30 days')") - ) + conn.execute(sa.text("SELECT add_retention_policy('rf_monitor_stats', INTERVAL '30 days')")) def downgrade() -> None: conn = op.get_bind() # Remove retention policies before dropping tables - conn.execute( - sa.text("SELECT remove_retention_policy('rf_monitor_stats', if_exists => true)") - ) + conn.execute(sa.text("SELECT remove_retention_policy('rf_monitor_stats', if_exists => true)")) conn.execute(sa.text("DROP TABLE IF EXISTS rf_monitor_stats CASCADE")) conn.execute( - sa.text( - "SELECT remove_retention_policy('wireless_registrations', if_exists => true)" - ) + sa.text("SELECT remove_retention_policy('wireless_registrations', if_exists => true)") ) conn.execute(sa.text("DROP TABLE IF EXISTS wireless_registrations CASCADE")) diff --git a/backend/alembic/versions/035_site_alert_rules_and_events.py b/backend/alembic/versions/035_site_alert_rules_and_events.py index 1ddb2a7..d507b93 100644 --- a/backend/alembic/versions/035_site_alert_rules_and_events.py +++ b/backend/alembic/versions/035_site_alert_rules_and_events.py @@ -183,11 +183,7 @@ def upgrade() -> None: ) """) ) - conn.execute( - sa.text( - "GRANT SELECT, INSERT, UPDATE, DELETE ON site_alert_rules TO app_user" - ) - ) + conn.execute(sa.text("GRANT SELECT, INSERT, UPDATE, DELETE ON site_alert_rules TO app_user")) # site_alert_events RLS conn.execute(sa.text("ALTER TABLE site_alert_events ENABLE ROW LEVEL SECURITY")) @@ -205,23 +201,15 @@ def upgrade() -> None: ) """) ) - conn.execute( - sa.text( - "GRANT SELECT, INSERT, UPDATE, DELETE ON site_alert_events TO app_user" - ) - ) + conn.execute(sa.text("GRANT SELECT, INSERT, UPDATE, DELETE ON site_alert_events TO app_user")) def downgrade() -> None: conn = op.get_bind() # Drop RLS policies - conn.execute( - sa.text("DROP POLICY IF EXISTS tenant_isolation ON site_alert_events") - ) - conn.execute( - sa.text("DROP POLICY IF EXISTS tenant_isolation ON site_alert_rules") - ) + conn.execute(sa.text("DROP POLICY IF EXISTS tenant_isolation ON site_alert_events")) + conn.execute(sa.text("DROP POLICY IF EXISTS tenant_isolation ON site_alert_rules")) # Drop tables (indexes drop automatically with tables) op.drop_table("site_alert_events") diff --git a/backend/app/models/site_alert.py b/backend/app/models/site_alert.py index ab6dc55..8c44b04 100644 --- a/backend/app/models/site_alert.py +++ b/backend/app/models/site_alert.py @@ -150,9 +150,7 @@ class SiteAlertEvent(Base): triggered_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False ) - resolved_at: Mapped[datetime | None] = mapped_column( - DateTime(timezone=True), nullable=True - ) + resolved_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) resolved_by: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), diff --git a/backend/app/routers/links.py b/backend/app/routers/links.py index 7e9b201..44e8588 100644 --- a/backend/app/routers/links.py +++ b/backend/app/routers/links.py @@ -36,14 +36,18 @@ router = APIRouter(tags=["links"]) ) async def list_links( tenant_id: uuid.UUID, - state: Optional[str] = Query(None, description="Filter by link state (active, degraded, down, stale)"), + state: Optional[str] = Query( + None, description="Filter by link state (active, degraded, down, stale)" + ), device_id: Optional[uuid.UUID] = Query(None, description="Filter by device (AP or CPE side)"), current_user: CurrentUser = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> LinkListResponse: """List all wireless links for a tenant with optional state and device filters.""" await _check_tenant_access(current_user, tenant_id, db) - return await link_service.get_links(db=db, tenant_id=tenant_id, state=state, device_id=device_id) + return await link_service.get_links( + db=db, tenant_id=tenant_id, state=state, device_id=device_id + ) @router.get( @@ -91,7 +95,9 @@ async def list_device_registrations( ) -> RegistrationListResponse: """Get latest wireless registration data for a device (most recent per MAC).""" await _check_tenant_access(current_user, tenant_id, db) - return await link_service.get_device_registrations(db=db, tenant_id=tenant_id, device_id=device_id) + return await link_service.get_device_registrations( + db=db, tenant_id=tenant_id, device_id=device_id + ) @router.get( diff --git a/backend/app/routers/site_alerts.py b/backend/app/routers/site_alerts.py index 3c29782..29d152c 100644 --- a/backend/app/routers/site_alerts.py +++ b/backend/app/routers/site_alerts.py @@ -98,9 +98,7 @@ async def get_alert_rule( db=db, tenant_id=tenant_id, site_id=site_id, rule_id=rule_id ) if not result: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, detail="Alert rule not found" - ) + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Alert rule not found") return result @@ -124,9 +122,7 @@ async def update_alert_rule( db=db, tenant_id=tenant_id, site_id=site_id, rule_id=rule_id, data=data ) if not result: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, detail="Alert rule not found" - ) + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Alert rule not found") return result @@ -149,9 +145,7 @@ async def delete_alert_rule( db=db, tenant_id=tenant_id, site_id=site_id, rule_id=rule_id ) if not deleted: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, detail="Alert rule not found" - ) + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Alert rule not found") # --------------------------------------------------------------------------- diff --git a/backend/app/routers/sites.py b/backend/app/routers/sites.py index 63701db..f789cef 100644 --- a/backend/app/routers/sites.py +++ b/backend/app/routers/sites.py @@ -166,9 +166,7 @@ async def unassign_device( ) -> None: """Remove a device from a site. Requires operator role or above.""" await _check_tenant_access(current_user, tenant_id, db) - await site_service.remove_device_from_site( - db=db, tenant_id=tenant_id, device_id=device_id - ) + await site_service.remove_device_from_site(db=db, tenant_id=tenant_id, device_id=device_id) @router.post( diff --git a/backend/app/services/alert_evaluator_site.py b/backend/app/services/alert_evaluator_site.py index e98e78b..50bedd6 100644 --- a/backend/app/services/alert_evaluator_site.py +++ b/backend/app/services/alert_evaluator_site.py @@ -43,8 +43,7 @@ async def _evaluate_condition(session, rule) -> bool: # noqa: ANN001 offline_result = await session.execute( text( - "SELECT count(*) AS cnt FROM devices " - "WHERE site_id = :site_id AND is_online = false" + "SELECT count(*) AS cnt FROM devices WHERE site_id = :site_id AND is_online = false" ), {"site_id": site_id}, ) @@ -55,8 +54,7 @@ async def _evaluate_condition(session, rule) -> bool: # noqa: ANN001 elif rule_type == "device_offline_count": offline_result = await session.execute( text( - "SELECT count(*) AS cnt FROM devices " - "WHERE site_id = :site_id AND is_online = false" + "SELECT count(*) AS cnt FROM devices WHERE site_id = :site_id AND is_online = false" ), {"site_id": site_id}, ) @@ -171,9 +169,11 @@ async def _evaluate_rules() -> None: # Events with consecutive_hits < 2 are considered "pending" # (not yet confirmed). On next evaluation if still met, # consecutive_hits increments to 2 (confirmed alert). - severity = "critical" if rule.rule_type in ( - "device_offline_percent", "device_offline_count" - ) else "warning" + severity = ( + "critical" + if rule.rule_type in ("device_offline_percent", "device_offline_count") + else "warning" + ) await session.execute( text(""" diff --git a/backend/app/services/interface_subscriber.py b/backend/app/services/interface_subscriber.py index 6460690..bdc7d98 100644 --- a/backend/app/services/interface_subscriber.py +++ b/backend/app/services/interface_subscriber.py @@ -122,9 +122,7 @@ async def _subscribe_with_retry(js: JetStreamContext) -> None: durable="api-interface-consumer", stream="DEVICE_EVENTS", ) - logger.info( - "NATS: subscribed to device.interfaces.> (durable: api-interface-consumer)" - ) + logger.info("NATS: subscribed to device.interfaces.> (durable: api-interface-consumer)") return except Exception as exc: if attempt < max_attempts: diff --git a/backend/app/services/link_discovery_subscriber.py b/backend/app/services/link_discovery_subscriber.py index 9e55618..9ce0f44 100644 --- a/backend/app/services/link_discovery_subscriber.py +++ b/backend/app/services/link_discovery_subscriber.py @@ -31,8 +31,8 @@ _link_discovery_client: Optional[NATSClient] = None # Configurable thresholds for link state transitions DEGRADED_SIGNAL_THRESHOLD = -80 # dBm — signals weaker than this mark link as degraded -CONSECUTIVE_MISS_THRESHOLD = 3 # Missed polls before marking link as down -STALE_HOURS = 24 # Hours after down before marking link as stale +CONSECUTIVE_MISS_THRESHOLD = 3 # Missed polls before marking link as down +STALE_HOURS = 24 # Hours after down before marking link as stale # ============================================================================= @@ -187,14 +187,16 @@ async def on_wireless_registration_for_links(msg) -> None: # Mark stale: any links in 'down' state where last_seen > STALE_HOURS ago await session.execute( - text(""" + text( + """ UPDATE wireless_links SET state = 'stale', updated_at = NOW() WHERE ap_device_id = :ap_device_id AND tenant_id = :tenant_id AND state = 'down' AND last_seen < NOW() - INTERVAL ':stale_hours hours' - """.replace(":stale_hours", str(STALE_HOURS))), + """.replace(":stale_hours", str(STALE_HOURS)) + ), { "ap_device_id": device_id, "tenant_id": tenant_id, diff --git a/backend/app/services/site_service.py b/backend/app/services/site_service.py index 81ce462..6e5b132 100644 --- a/backend/app/services/site_service.py +++ b/backend/app/services/site_service.py @@ -29,7 +29,9 @@ logger = structlog.get_logger("site_service") # --------------------------------------------------------------------------- -def _site_response(site: Site, device_count: int = 0, online_count: int = 0, alert_count: int = 0) -> SiteResponse: +def _site_response( + site: Site, device_count: int = 0, online_count: int = 0, alert_count: int = 0 +) -> SiteResponse: """Build a SiteResponse from an ORM Site instance with health stats.""" online_percent = (online_count / device_count * 100) if device_count > 0 else 0.0 return SiteResponse( @@ -51,9 +53,7 @@ def _site_response(site: Site, device_count: int = 0, online_count: int = 0, ale async def _get_site_or_404(db: AsyncSession, tenant_id: uuid.UUID, site_id: uuid.UUID) -> Site: """Fetch a site by id and tenant, or raise 404.""" - result = await db.execute( - select(Site).where(Site.id == site_id, Site.tenant_id == tenant_id) - ) + result = await db.execute(select(Site).where(Site.id == site_id, Site.tenant_id == tenant_id)) site = result.scalar_one_or_none() if not site: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Site not found")