Make lint-backend green, and regenerate the stale client

`wanted_names` never read its `previous` argument — the caller reassigns
`wanted` from the return value — so the parameter goes rather than gaining
an underscore; its one call site and four test calls follow. Sorts the
imports in test_artifacts.py. Both were failing `make lint-backend` at HEAD.

Regenerates the client, which 8cb843e left behind when it corrected the
revoke_client docstring.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CL9zvnnvcp1mvA8o7impxk
This commit is contained in:
2026-09-06 15:29:35 +02:00
co-authored by Claude Opus 5
parent ff612623a1
commit d15520ec8a
4 changed files with 11 additions and 12 deletions
+2 -4
View File
@@ -922,9 +922,7 @@ MAX_FRAME_EVENTS = 64
MAX_MEDIA_NAMES = 32 MAX_MEDIA_NAMES = 32
def wanted_names( def wanted_names(frame: str, only: set[str] | None) -> set[str] | None:
frame: str, only: set[str] | None, previous: set[str]
) -> set[str] | None:
"""What this client is asking to be sent bytes for, or None if it said """What this client is asking to be sent bytes for, or None if it said
something else. something else.
@@ -1061,7 +1059,7 @@ async def flow_events(websocket: WebSocket, token: str = "") -> None:
# say, used to be read as the client going away and cost # say, used to be read as the client going away and cost
# it every live update from then on. # it every live update from then on.
if receiver.exception() is None: if receiver.exception() is None:
asked = wanted_names(receiver.result(), only, wanted) asked = wanted_names(receiver.result(), only)
if asked is not None: if asked is not None:
wanted = asked wanted = asked
receiver = asyncio.create_task(websocket.receive_text()) receiver = asyncio.create_task(websocket.receive_text())
+4 -4
View File
@@ -944,11 +944,11 @@ def test_a_socket_pushes_only_the_frames_it_was_asked_for(tmp_path) -> None:
asking = orjson.dumps({"type": "media", "names": ["cam.frame", "other.frame"]}) asking = orjson.dumps({"type": "media", "names": ["cam.frame", "other.frame"]})
# A person's socket gets what it asked for; a panel's is intersected with # A person's socket gets what it asked for; a panel's is intersected with
# what it draws, so naming a message is not a way around the scope. # what it draws, so naming a message is not a way around the scope.
assert wanted_names(asking.decode(), None, set()) == {"cam.frame", "other.frame"} assert wanted_names(asking.decode(), None) == {"cam.frame", "other.frame"}
assert wanted_names(asking.decode(), {"cam.frame"}, set()) == {"cam.frame"} assert wanted_names(asking.decode(), {"cam.frame"}) == {"cam.frame"}
# Anything else on this socket leaves the set alone. # Anything else on this socket leaves the set alone.
assert wanted_names('{"type":"ping"}', None, set()) is None assert wanted_names('{"type":"ping"}', None) is None
assert wanted_names("not json", None, set()) is None assert wanted_names("not json", None) is None
events = [ events = [
{"type": "message_value", "name": "cam.frame", "value": frame, "ts": 1.0}, {"type": "message_value", "name": "cam.frame", "value": frame, "ts": 1.0},
-1
View File
@@ -7,7 +7,6 @@ from fastapi.testclient import TestClient
from sqlmodel import Session, col, select from sqlmodel import Session, col, select
from fluksio.core.config import settings from fluksio.core.config import settings
from fluksio.core.db import engine as db_engine from fluksio.core.db import engine as db_engine
from fluksio.flow.artifacts import ArtifactStore, VolatileStore from fluksio.flow.artifacts import ArtifactStore, VolatileStore
from fluksio.flow.runs import new_run_id, sweep_artifacts from fluksio.flow.runs import new_run_id, sweep_artifacts
+5 -3
View File
@@ -1486,9 +1486,11 @@ export class OauthService {
* Withdraw one agent's access, leaving every other agent alone. * Withdraw one agent's access, leaving every other agent alone.
* *
* Deleting the client cascades to its codes and refresh tokens, so it can * Deleting the client cascades to its codes and refresh tokens, so it can
* get nothing new and cannot come back without registering again. An access * get nothing new and cannot come back without registering again. The access
* token already in its hands keeps working until it expires * token already in its hands stops working too, even though it is a
* (``MCP_TOKEN_EXPIRE_MINUTES``) — those are stateless by design. * stateless JWT nobody can reach into: every door that takes one looks the
* client up first (``api.deps.oauth_client_lives``), so the row deleted here
* is the whole of the revocation.
* @param data The data for the request. * @param data The data for the request.
* @param data.clientId * @param data.clientId
* @returns Message Successful Response * @returns Message Successful Response