Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/example/mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
CreateNoteUseCase,
DeleteNoteInput,
DeleteNoteUseCase,
GetNoteInput,
GetNoteUseCase,
ListNotesInput,
ListNotesUseCase,
Expand All @@ -38,6 +39,7 @@
CreateTagUseCase,
DeleteTagInput,
DeleteTagUseCase,
GetTagInput,
GetTagUseCase,
ListTagsInput,
ListTagsUseCase,
Expand Down Expand Up @@ -81,7 +83,7 @@ def list_notes(limit: int = 20, offset: int = 0) -> list[dict]: # type: ignore[

@server.tool("Get a single note by ID.")
def get_note(note_id: int) -> dict: # type: ignore[type-arg]
return asdict(note_get.execute(note_id))
return asdict(note_get.execute(GetNoteInput(note_id=note_id)))

@server.tool("Create a new note.")
def create_note(title: str, body: str) -> dict: # type: ignore[type-arg]
Expand All @@ -103,7 +105,7 @@ def list_tags(limit: int = 20, offset: int = 0) -> list[dict]: # type: ignore[t

@server.tool("Get a single tag by ID.")
def get_tag(tag_id: int) -> dict: # type: ignore[type-arg]
return asdict(tag_get.execute(tag_id))
return asdict(tag_get.execute(GetTagInput(tag_id=tag_id)))

@server.tool("Create a new tag.")
def create_tag(name: str) -> dict: # type: ignore[type-arg]
Expand Down
3 changes: 2 additions & 1 deletion src/example/note/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CreateNoteUseCase,
DeleteNoteInput,
DeleteNoteUseCase,
GetNoteInput,
GetNoteUseCase,
ListNotesInput,
ListNotesUseCase,
Expand Down Expand Up @@ -54,7 +55,7 @@ async def list_notes(request: Request) -> JSONResponse:

@router.get("/{note_id}")
async def get_note(note_id: int) -> JSONResponse:
note = get_use_case.execute(note_id)
note = get_use_case.execute(GetNoteInput(note_id))
return JSONResponse({"id": note.id, "title": note.title, "body": note.body})

@router.post("", status_code=201)
Expand Down
11 changes: 8 additions & 3 deletions src/example/note/use_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,19 @@ def execute(self, input_: CreateNoteInput) -> Note:
return self._repository.save(input_.title, input_.body)


@dataclass(frozen=True, slots=True)
class GetNoteInput:
note_id: int


class GetNoteUseCase:
def __init__(self, repository: NoteRepositoryInterface) -> None:
self._repository = repository

def execute(self, note_id: int) -> Note:
note = self._repository.find_by_id(note_id)
def execute(self, input_: GetNoteInput) -> Note:
note = self._repository.find_by_id(input_.note_id)
if note is None:
raise NoteNotFoundException(note_id)
raise NoteNotFoundException(input_.note_id)
return note


Expand Down
3 changes: 2 additions & 1 deletion src/example/tag/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CreateTagUseCase,
DeleteTagInput,
DeleteTagUseCase,
GetTagInput,
GetTagUseCase,
ListTagsInput,
ListTagsUseCase,
Expand Down Expand Up @@ -52,7 +53,7 @@ async def list_tags(request: Request) -> JSONResponse:

@router.get("/{tag_id}")
async def get_tag(tag_id: int) -> JSONResponse:
tag = get_use_case.execute(tag_id)
tag = get_use_case.execute(GetTagInput(tag_id))
return JSONResponse({"id": tag.id, "name": tag.name})

@router.post("", status_code=201)
Expand Down
11 changes: 8 additions & 3 deletions src/example/tag/use_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,19 @@ def execute(self, input_: ListTagsInput) -> ListTagsOutput:
)


@dataclass(frozen=True, slots=True)
class GetTagInput:
tag_id: int


class GetTagUseCase:
def __init__(self, repository: TagRepositoryInterface) -> None:
self._repository = repository

def execute(self, tag_id: int) -> Tag:
tag = self._repository.find_by_id(tag_id)
def execute(self, input_: GetTagInput) -> Tag:
tag = self._repository.find_by_id(input_.tag_id)
if tag is None:
raise TagNotFoundException(tag_id)
raise TagNotFoundException(input_.tag_id)
return tag


Expand Down
2 changes: 1 addition & 1 deletion src/nene2/database/sqlalchemy_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ def fetch_one(self, sql: str, params: dict[str, Any] | None = None) -> dict[str,
def write(self, sql: str, params: dict[str, Any] | None = None) -> int:
try:
result = self._conn.execute(text(sql), params or {})
return result.lastrowid or result.rowcount
except OperationalError as exc:
raise DatabaseConnectionException(str(exc)) from exc
return result.lastrowid or result.rowcount


class SqlAlchemyTransactionManager(DatabaseTransactionManagerInterface):
Expand Down
4 changes: 1 addition & 3 deletions tests/example/comment/test_comment_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ def test_get_comment_not_found() -> None:
def test_update_comment() -> None:
client, note_id = _client_with_note()
created = client.post(f"/notes/{note_id}/comments", json={"body": "original"}).json()
response = client.put(
f"/notes/{note_id}/comments/{created['id']}", json={"body": "updated"}
)
response = client.put(f"/notes/{note_id}/comments/{created['id']}", json={"body": "updated"})
assert response.status_code == 200
assert response.json()["body"] == "updated"

Expand Down
3 changes: 2 additions & 1 deletion tests/example/test_mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
CreateNoteUseCase,
DeleteNoteInput,
DeleteNoteUseCase,
GetNoteInput,
GetNoteUseCase,
ListNotesInput,
ListNotesUseCase,
Expand Down Expand Up @@ -44,7 +45,7 @@ def test_note_lifecycle_via_use_cases() -> None:

note = create_uc.execute(CreateNoteInput(title="MCP note", body="content"))
assert list_uc.execute(ListNotesInput(limit=10, offset=0)).total == 1
fetched = get_uc.execute(note.id)
fetched = get_uc.execute(GetNoteInput(note_id=note.id))
assert fetched.title == "MCP note"
delete_uc.execute(DeleteNoteInput(note_id=note.id))
assert list_uc.execute(ListNotesInput(limit=10, offset=0)).total == 0
4 changes: 1 addition & 3 deletions tests/nene2/middleware/test_request_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

from nene2.middleware import RequestIdMiddleware, request_id_var

_UUID_V4_RE = re.compile(
r"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
)
_UUID_V4_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")


def _make_app() -> FastAPI:
Expand Down
Loading