style: ruff format 10 python files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-19 13:49:59 -05:00
parent 9d6b68760f
commit 6a5829e0ff
10 changed files with 41 additions and 67 deletions

View File

@@ -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"))

View File

@@ -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")

View File

@@ -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"),

View File

@@ -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(

View File

@@ -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")
# ---------------------------------------------------------------------------

View File

@@ -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(

View File

@@ -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("""

View File

@@ -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:

View File

@@ -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,

View File

@@ -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")