From d6e5203e41a1348d3e202ad4733d93325c840ef1 Mon Sep 17 00:00:00 2001 From: Benjamin McCormick Date: Thu, 5 Feb 2026 17:36:29 -0500 Subject: [PATCH] fix: get_or_create when crudding peer cards --- src/crud/peer_card.py | 37 ++++++++++++++++-------------------- tests/crud/test_peer_card.py | 33 -------------------------------- 2 files changed, 16 insertions(+), 54 deletions(-) diff --git a/src/crud/peer_card.py b/src/crud/peer_card.py index f04205ed..fded2ad9 100644 --- a/src/crud/peer_card.py +++ b/src/crud/peer_card.py @@ -6,9 +6,9 @@ from typing import cast from sqlalchemy import update from sqlalchemy.ext.asyncio import AsyncSession -from src import exceptions, models, schemas +from src import models, schemas from src.cache.client import cache -from src.crud.peer import get_peer, peer_cache_key +from src.crud.peer import get_or_create_peers, peer_cache_key logger = logging.getLogger(__name__) @@ -34,16 +34,16 @@ async def get_peer_card( Returns: The peer's card text if present, otherwise None (also None if peer not found). """ - try: - peer = await get_peer(db, workspace_name, schemas.PeerCreate(name=observer)) - return cast( - list[str] | None, - peer.internal_metadata.get( - construct_peer_card_label(observer=observer, observed=observed) - ), - ) - except exceptions.ResourceNotFoundException: - return None + result = await get_or_create_peers( + db, workspace_name, [schemas.PeerCreate(name=observer)] + ) + peer = result.resource[0] + return cast( + list[str] | None, + peer.internal_metadata.get( + construct_peer_card_label(observer=observer, observed=observed) + ), + ) async def set_peer_card( @@ -66,9 +66,10 @@ async def set_peer_card( observed: Peer name of the peer described in the peer card observer: Peer name of the observer - Raises: - ResourceNotFoundException: If the peer does not exist """ + # Ensure the peer exists (get-or-create) + await get_or_create_peers(db, workspace_name, [schemas.PeerCreate(name=observer)]) + stmt = ( update(models.Peer) .where(models.Peer.workspace_name == workspace_name) @@ -82,14 +83,8 @@ async def set_peer_card( } ) ) - .returning(models.Peer) ) - result = await db.execute(stmt) - updated_peer = result.scalar_one_or_none() - if updated_peer is None: - raise exceptions.ResourceNotFoundException( - f"Peer {observer} not found in workspace {workspace_name}" - ) + await db.execute(stmt) await db.commit() # Invalidate cache - read-through pattern diff --git a/tests/crud/test_peer_card.py b/tests/crud/test_peer_card.py index c057323b..ae3e954e 100644 --- a/tests/crud/test_peer_card.py +++ b/tests/crud/test_peer_card.py @@ -3,7 +3,6 @@ from sqlalchemy.ext.asyncio import AsyncSession from src import models from src.crud.peer_card import construct_peer_card_label, get_peer_card, set_peer_card -from src.exceptions import ResourceNotFoundException @pytest.mark.asyncio @@ -50,22 +49,6 @@ async def test_peer_card_get_set_roundtrip( ) -@pytest.mark.asyncio -async def test_set_peer_card_missing_peer_raises( - db_session: AsyncSession, sample_data: tuple[models.Workspace, models.Peer] -): - """Setting a peer card for a non-existent peer should raise ResourceNotFoundException.""" - workspace, _existing_peer = sample_data - with pytest.raises(ResourceNotFoundException): - await set_peer_card( - db_session, - workspace.name, - ["card"], - observer="missing-peer", - observed="missing-peer", - ) - - @pytest.mark.asyncio async def test_get_peer_card_missing_peer_returns_none( db_session: AsyncSession, sample_data: tuple[models.Workspace, models.Peer] @@ -96,22 +79,6 @@ async def test_get_peer_card_missing_workspace_returns_none( assert result is None -@pytest.mark.asyncio -async def test_set_peer_card_missing_workspace_raises( - db_session: AsyncSession, sample_data: tuple[models.Workspace, models.Peer] -): - """Setting a peer card for a non-existent workspace should raise ResourceNotFoundException.""" - _workspace, peer = sample_data - with pytest.raises(ResourceNotFoundException): - await set_peer_card( - db_session, - "missing-workspace", - ["card"], - observer=peer.name, - observed=peer.name, - ) - - @pytest.mark.asyncio async def test_peer_card_empty_list( db_session: AsyncSession, sample_data: tuple[models.Workspace, models.Peer]