Skip to content

Commit 3a82920

Browse files
committed
Improved swagger doc
1 parent 3050f0b commit 3a82920

8 files changed

Lines changed: 124 additions & 38 deletions

File tree

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
1-
class GroupNotFoundError(Exception):
2-
id: int
1+
from typing import Optional
32

3+
from foxops.errors import FoxopsError
44

5-
class GroupAlreadyExistsError(Exception):
6-
system_name: str
5+
6+
class GroupNotFoundError(FoxopsError):
7+
def __init__(self, system_name: Optional[str] = None, id: Optional[int] = None):
8+
if system_name is None and id is None:
9+
raise ValueError("system_name or id must be provided")
10+
if system_name is not None and id is not None:
11+
raise ValueError("system_name and id cannot both be provided")
12+
if system_name is not None:
13+
self.system_name = system_name
14+
super().__init__(f"Group with system name '{system_name}' not found.")
15+
else:
16+
self.id = id
17+
super().__init__(f"Group with id '{id}' not found.")
18+
19+
20+
class GroupAlreadyExistsError(FoxopsError):
21+
def __init__(self, system_name: str):
22+
self.system_name = system_name
23+
super().__init__(f"Group with System name ${system_name} already exists")

src/foxops/database/repositories/group/repository.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ async def create(self, system_name: str, display_name: str) -> GroupInDB:
2121
try:
2222
result = await conn.execute(query)
2323
except IntegrityError as e:
24-
raise GroupAlreadyExistsError(f"Group with System name ${system_name} already exists") from e
24+
raise GroupAlreadyExistsError(system_name) from e
2525

2626
row = result.one()
2727
return GroupInDB.model_validate(row)
@@ -35,7 +35,7 @@ async def get_by_system_name(self, system_name: str) -> GroupInDB:
3535
try:
3636
row = result.one()
3737
except NoResultFound as e:
38-
raise GroupNotFoundError(f"Group with System name ${system_name} not found") from e
38+
raise GroupNotFoundError(system_name=system_name) from e
3939

4040
return GroupInDB.model_validate(row)
4141

@@ -59,5 +59,5 @@ async def get_by_id(self, group_id: int) -> GroupInDB:
5959
try:
6060
row = result.one()
6161
except NoResultFound as e:
62-
raise GroupNotFoundError(f"Group with ID ${group_id} not found") from e
62+
raise GroupNotFoundError(id=group_id) from e
6363
return GroupInDB.model_validate(row)

src/foxops/database/repositories/incarnation/errors.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
class IncarnationNotFoundError(Exception):
2-
pass
2+
def __init__(self, id: int):
3+
self.id = id
4+
super().__init__(f"Incarnation with id '{id}' not found.")
35

46

57
class IncarnationAlreadyExistsError(Exception):

src/foxops/database/repositories/incarnation/repository.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async def get_by_id(self, id_: int) -> IncarnationInDB:
7373
try:
7474
row = result.one()
7575
except NoResultFound:
76-
raise IncarnationNotFoundError(f"could not find incarnation in DB with id: {id_}")
76+
raise IncarnationNotFoundError(id_)
7777
else:
7878
return IncarnationInDB.model_validate(row)
7979

@@ -84,7 +84,7 @@ async def delete_by_id(self, id_: int) -> None:
8484
result = await conn.execute(query)
8585

8686
if result.rowcount == 0:
87-
raise IncarnationNotFoundError(f"could not find incarnation in DB with id: {id_}")
87+
raise IncarnationNotFoundError(id_)
8888

8989
async def get_group_permissions(self, incarnation_id: int) -> List[GroupPermissionInDB]:
9090
query = (
@@ -162,10 +162,10 @@ async def set_owner(self, incarnation_id: int, user_id: int):
162162
try:
163163
result = await conn.execute(query)
164164
except IntegrityError as e:
165-
raise UserNotFoundError(f"User with ID {user_id} not found") from e
165+
raise UserNotFoundError(id=user_id) from e
166166
try:
167167
row = result.one()
168168
except NoResultFound as e:
169-
raise IncarnationNotFoundError(f"Incarnation with ID {incarnation_id} not found") from e
169+
raise IncarnationNotFoundError(incarnation_id) from e
170170

171171
return IncarnationInDB.model_validate(row)
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
1-
class UserNotFoundError(Exception):
2-
pass
1+
from typing import Optional
2+
3+
from foxops.errors import FoxopsError
4+
5+
6+
class UserNotFoundError(FoxopsError):
7+
def __init__(self, id: Optional[int] = None, username: Optional[str] = None):
8+
if id is None and username is None:
9+
raise ValueError("id or username must be provided")
10+
if id is not None and username is not None:
11+
raise ValueError("id and username cannot both be provided")
12+
if id is not None:
13+
super().__init__(f"User with id '{id}' not found.")
14+
else:
15+
super().__init__(f"User with username '{username}' not found.")
316

417

518
class UserAlreadyExistsError(Exception):
6-
pass
19+
def __init__(self, username: str):
20+
super().__init__(f"User with username '{username}' already exists.")

src/foxops/database/repositories/user/repository.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ async def create(self, username: str, is_admin: bool) -> UserInDB:
2121
try:
2222
result = await conn.execute(query)
2323
except IntegrityError as e:
24-
raise UserAlreadyExistsError(f"username={username}") from e
24+
raise UserAlreadyExistsError(username=username) from e
2525

2626
row = result.one()
2727
return UserInDB.model_validate(row)
@@ -35,7 +35,7 @@ async def get_by_username(self, username: str) -> UserInDB:
3535
try:
3636
row = result.one()
3737
except NoResultFound as e:
38-
raise UserNotFoundError(f"username={username}") from e
38+
raise UserNotFoundError(username=username) from e
3939

4040
return UserInDB.model_validate(row)
4141

@@ -67,6 +67,6 @@ async def get_by_id(self, user_id: int) -> UserInDB:
6767
try:
6868
row = result.one()
6969
except NoResultFound as e:
70-
raise UserNotFoundError(f"User with ID ${user_id} not found") from e
70+
raise UserNotFoundError(id=user_id) from e
7171

7272
return UserInDB.model_validate(row)

src/foxops/routers/incarnations.py

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from fastapi import APIRouter, Depends, Response, status
44
from pydantic import BaseModel, model_validator
55

6+
from foxops.database.repositories.group.errors import GroupNotFoundError
67
from foxops.database.repositories.incarnation.errors import IncarnationNotFoundError
8+
from foxops.database.repositories.user.errors import UserNotFoundError
79
from foxops.dependencies import (
810
authorization,
911
get_change_service,
@@ -230,9 +232,9 @@ async def reset_incarnation(
230232
message=f"could not initialize the incarnation as the provided template data "
231233
f"is invalid: {'; '.join(error_messages)}"
232234
)
233-
except IncarnationNotFoundError:
235+
except IncarnationNotFoundError as exc:
234236
response.status_code = status.HTTP_404_NOT_FOUND
235-
return ApiError(message="The incarnation was not found in the inventory")
237+
return ApiError(message=str(exc))
236238
except ChangeRejectedDueToNoChanges:
237239
response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
238240
return ApiError(message="The incarnation does not have any customizations. Nothing to reset.")
@@ -295,8 +297,8 @@ class UpdateIncarnationRequest(BaseModel):
295297
template_data: TemplateData
296298
owner_id: int
297299

298-
user_permission: list[UnresolvedUserPermissions]
299-
group_permission: list[UnresolvedGroupPermissions]
300+
user_permissions: list[UnresolvedUserPermissions]
301+
group_permissions: list[UnresolvedGroupPermissions]
300302

301303
automerge: bool
302304

@@ -341,10 +343,32 @@ async def update_incarnation(
341343
"""
342344

343345
await incarnation_service.remove_all_permissions(incarnation_id)
344-
await incarnation_service.set_user_permissions(incarnation_id, request.user_permission)
345-
await incarnation_service.set_group_permissions(incarnation_id, request.group_permission)
346+
try:
347+
await incarnation_service.set_user_permissions(incarnation_id, request.user_permissions)
348+
except UserNotFoundError as exc:
349+
response.status_code = status.HTTP_404_NOT_FOUND
350+
return ApiError(message=str(exc))
351+
except IncarnationNotFoundError as exc:
352+
response.status_code = status.HTTP_404_NOT_FOUND
353+
return ApiError(message=str(exc))
346354

347-
await incarnation_service.set_owner(incarnation_id, request.owner_id)
355+
try:
356+
await incarnation_service.set_group_permissions(incarnation_id, request.group_permissions)
357+
except GroupNotFoundError as exc:
358+
response.status_code = status.HTTP_404_NOT_FOUND
359+
return ApiError(message=str(exc))
360+
except IncarnationNotFoundError as exc:
361+
response.status_code = status.HTTP_404_NOT_FOUND
362+
return ApiError(message=str(exc))
363+
364+
try:
365+
await incarnation_service.set_owner(incarnation_id, request.owner_id)
366+
except UserNotFoundError as exc:
367+
response.status_code = status.HTTP_404_NOT_FOUND
368+
return ApiError(message=str(exc))
369+
except IncarnationNotFoundError as exc:
370+
response.status_code = status.HTTP_404_NOT_FOUND
371+
return ApiError(message=str(exc))
348372

349373
return await _create_change(
350374
incarnation_id=incarnation_id,
@@ -362,8 +386,8 @@ class PatchIncarnationRequest(BaseModel):
362386

363387
requested_version: str | None = None
364388
requested_data: TemplateData | None = None
365-
user_permission: list[UnresolvedUserPermissions] | None = None
366-
group_permission: list[UnresolvedGroupPermissions] | None = None
389+
user_permissions: list[UnresolvedUserPermissions] | None = None
390+
group_permissions: list[UnresolvedGroupPermissions] | None = None
367391
owner_id: int | None = None
368392

369393
automerge: bool | None = None
@@ -373,8 +397,8 @@ def check_either_version_or_data_change_requested(self) -> Self:
373397
if (
374398
self.requested_version is None
375399
and self.requested_data is None
376-
and self.user_permission is None
377-
and self.group_permission is None
400+
and self.user_permissions is None
401+
and self.group_permissions is None
378402
and self.owner_id is None
379403
):
380404
raise ValueError(
@@ -427,16 +451,37 @@ async def patch_incarnation(
427451

428452
requested_data = request.requested_data or {}
429453

430-
if request.group_permission is not None:
431-
await incarnation_service.remove_all_group_permissions(incarnation_id)
432-
await incarnation_service.set_group_permissions(incarnation_id, request.group_permission)
433-
434-
if request.user_permission is not None:
435-
await incarnation_service.remove_all_user_permissions(incarnation_id)
436-
await incarnation_service.set_user_permissions(incarnation_id, request.user_permission)
454+
if request.group_permissions is not None:
455+
try:
456+
await incarnation_service.remove_all_group_permissions(incarnation_id)
457+
await incarnation_service.set_group_permissions(incarnation_id, request.group_permissions)
458+
except GroupNotFoundError as exc:
459+
response.status_code = status.HTTP_404_NOT_FOUND
460+
return ApiError(message=str(exc))
461+
except IncarnationNotFoundError as exc:
462+
response.status_code = status.HTTP_404_NOT_FOUND
463+
return ApiError(message=str(exc))
464+
465+
if request.user_permissions is not None:
466+
try:
467+
await incarnation_service.remove_all_user_permissions(incarnation_id)
468+
await incarnation_service.set_user_permissions(incarnation_id, request.user_permissions)
469+
except UserNotFoundError as exc:
470+
response.status_code = status.HTTP_404_NOT_FOUND
471+
return ApiError(message=str(exc))
472+
except IncarnationNotFoundError as exc:
473+
response.status_code = status.HTTP_404_NOT_FOUND
474+
return ApiError(message=str(exc))
437475

438476
if request.owner_id is not None:
439-
await incarnation_service.set_owner(incarnation_id, request.owner_id)
477+
try:
478+
await incarnation_service.set_owner(incarnation_id, request.owner_id)
479+
except UserNotFoundError as exc:
480+
response.status_code = status.HTTP_404_NOT_FOUND
481+
return ApiError(message=str(exc))
482+
except IncarnationNotFoundError as exc:
483+
response.status_code = status.HTTP_404_NOT_FOUND
484+
return ApiError(message=str(exc))
440485

441486
if request.requested_version is not None or request.requested_data is not None:
442487
return await _create_change(
@@ -449,7 +494,11 @@ async def patch_incarnation(
449494
change_service=change_service,
450495
)
451496
else:
452-
return await change_service.get_incarnation_with_details(incarnation_id)
497+
try:
498+
return await change_service.get_incarnation_with_details(incarnation_id)
499+
except IncarnationNotFoundError as exc:
500+
response.status_code = status.HTTP_404_NOT_FOUND
501+
return ApiError(message=str(exc))
453502

454503

455504
@router.delete(

src/foxops/services/incarnation.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ async def set_user_permissions(
8484
for user_permission in user_permissions
8585
]
8686

87+
await self.incarnation_repository.get_by_id(incarnation_id) # Validate if the incarnation exists
88+
8789
await self.incarnation_repository.set_user_permissions(incarnation_id, resolved_user_permissions)
8890

8991
async def set_group_permissions(
@@ -99,6 +101,8 @@ async def set_group_permissions(
99101
for group_permission in group_permissions
100102
]
101103

104+
await self.incarnation_repository.get_by_id(incarnation_id) # Validate if the incarnation exists
105+
102106
await self.incarnation_repository.set_group_permissions(incarnation_id, resolved_group_permissions)
103107

104108
async def remove_all_user_permissions(self, incarnation_id: int) -> None:

0 commit comments

Comments
 (0)