Skip to content

Commit 52d4fd2

Browse files
committed
Refactor user account functions to enhance parameter documentation and type annotations
1 parent 377d265 commit 52d4fd2

File tree

1 file changed

+45
-39
lines changed

1 file changed

+45
-39
lines changed

services/web/server/src/simcore_service_webserver/users/_accounts_service.py

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import logging
2-
from typing import Any
2+
from typing import Annotated, Any
33

44
from aiohttp import web
5+
from annotated_types import doc
56
from common_library.users_enums import AccountRequestStatus
67
from models_library.api_schemas_webserver.users import UserAccountGet
78
from models_library.emails import LowerCaseEmailStr
9+
from models_library.list_operations import OrderDirection
810
from models_library.products import ProductName
911
from models_library.users import UserID
1012
from notifications_library._email import create_email_session
1113
from pydantic import HttpUrl
1214
from settings_library.email import SMTPSettings
13-
from simcore_service_webserver.products._service import get_product
1415

1516
from ..db.plugin import get_asyncpg_engine
17+
from ..products._service import get_product
1618
from . import _accounts_repository, _users_repository
19+
from ._accounts_repository import OrderKeys
1720
from .exceptions import (
1821
AlreadyPreRegisteredError,
1922
PendingPreRegistrationNotFoundError,
@@ -31,7 +34,10 @@ async def pre_register_user(
3134
app: web.Application,
3235
*,
3336
profile: UserAccountRestPreRegister,
34-
creator_user_id: UserID | None,
37+
creator_user_id: Annotated[
38+
UserID | None,
39+
doc("ID of the user creating the pre-registration (None for anonymous)"),
40+
],
3541
product_name: ProductName,
3642
) -> UserAccountGet:
3743

@@ -92,19 +98,23 @@ async def list_user_accounts(
9298
app: web.Application,
9399
*,
94100
product_name: ProductName,
95-
filter_any_account_request_status: list[AccountRequestStatus] | None = None,
101+
filter_any_account_request_status: Annotated[
102+
list[AccountRequestStatus] | None,
103+
doc("List of any account request statuses to filter by"),
104+
] = None,
96105
pagination_limit: int = 50,
97106
pagination_offset: int = 0,
98-
) -> tuple[list[dict[str, Any]], int]:
107+
order_by: Annotated[
108+
list[tuple[OrderKeys, OrderDirection]] | None,
109+
doc("List of (field_name, direction) tuples for ordering"),
110+
] = None,
111+
) -> Annotated[
112+
tuple[list[dict[str, Any]], int],
113+
doc("Tuple containing (list of user dictionaries, total count of users)"),
114+
]:
99115
"""
100116
Get a paginated list of users for admin view with filtering options.
101117
102-
Args:
103-
app: The web application instance
104-
filter_any_account_request_status: List of *any* account request statuses to filter by
105-
pagination_limit: Maximum number of users to return
106-
pagination_offset: Number of users to skip for pagination
107-
108118
Returns:
109119
A tuple containing (list of user dictionaries, total count of users)
110120
"""
@@ -118,6 +128,7 @@ async def list_user_accounts(
118128
filter_any_account_request_status=filter_any_account_request_status,
119129
pagination_limit=pagination_limit,
120130
pagination_offset=pagination_offset,
131+
order_by=order_by,
121132
)
122133
)
123134

@@ -155,8 +166,7 @@ async def search_users_accounts(
155166
product_name: ProductName | None = None,
156167
include_products: bool = False,
157168
) -> list[UserAccountGet]:
158-
"""
159-
WARNING: this information is reserved for admin users. Note that the returned model include UserForAdminGet
169+
"""WARNING: this information is reserved for admin users. Note that the returned model include UserForAdminGet
160170
161171
NOTE: Functions in the service layer typically validate the caller's access rights
162172
using parameters like product_name and user_id. However, this function skips
@@ -238,18 +248,14 @@ async def approve_user_account(
238248
pre_registration_email: LowerCaseEmailStr,
239249
product_name: ProductName,
240250
reviewer_id: UserID,
241-
invitation_extras: dict[str, Any] | None = None,
242-
) -> int:
251+
invitation_extras: Annotated[
252+
dict[str, Any] | None, doc("Optional invitation data to store in extras field")
253+
] = None,
254+
) -> Annotated[int, doc("The ID of the approved pre-registration record")]:
243255
"""Approve a user account based on their pre-registration email.
244256
245-
Args:
246-
app: The web application instance
247-
pre_registration_email: Email of the pre-registered user to approve
248-
product_name: Product name for which the user is being approved
249-
reviewer_id: ID of the user approving the account
250-
251257
Returns:
252-
int: The ID of the approved pre-registration record
258+
The ID of the approved pre-registration record
253259
254260
Raises:
255261
PendingPreRegistrationNotFoundError: If no pre-registration is found for the email/product
@@ -291,17 +297,9 @@ async def reject_user_account(
291297
pre_registration_email: LowerCaseEmailStr,
292298
product_name: ProductName,
293299
reviewer_id: UserID,
294-
) -> int:
300+
) -> Annotated[int, doc("The ID of the rejected pre-registration record")]:
295301
"""Reject a user account based on their pre-registration email.
296302
297-
Args:
298-
app: The web application instance
299-
pre_registration_email: Email of the pre-registered user to reject
300-
product_name: Product name for which the user is being rejected
301-
reviewer_id: ID of the user rejecting the account
302-
303-
Returns:
304-
int: The ID of the rejected pre-registration record
305303
306304
Raises:
307305
PendingPreRegistrationNotFoundError: If no pre-registration is found for the email/product
@@ -343,9 +341,17 @@ def _create_product_and_user_data(
343341
user_email: LowerCaseEmailStr,
344342
first_name: str,
345343
last_name: str,
346-
):
344+
) -> Annotated[
345+
tuple[Any, Any],
346+
doc("Tuple containing (ProductData, UserData) objects for email rendering"),
347+
]:
347348
"""Create ProductData and UserData objects for email rendering."""
348-
from notifications_library._models import ProductData, ProductUIData, UserData
349+
350+
from notifications_library._models import ( # noqa: PLC0415
351+
ProductData,
352+
ProductUIData,
353+
UserData,
354+
)
349355

350356
# Get product data from the app
351357
product = get_product(app, product_name=product_name)
@@ -399,13 +405,13 @@ async def send_approval_email_to_user(
399405
first_name: str,
400406
last_name: str,
401407
) -> None:
402-
from notifications_library._email import compose_email
403-
from notifications_library._email_render import (
408+
from notifications_library._email import compose_email # noqa: PLC0415
409+
from notifications_library._email_render import ( # noqa: PLC0415
404410
get_support_address,
405411
get_user_address,
406412
render_email_parts,
407413
)
408-
from notifications_library._render import (
414+
from notifications_library._render import ( # noqa: PLC0415
409415
create_render_environment_from_notifications_library,
410416
)
411417

@@ -456,13 +462,13 @@ async def send_rejection_email_to_user(
456462
last_name: str,
457463
host: str,
458464
) -> None:
459-
from notifications_library._email import compose_email
460-
from notifications_library._email_render import (
465+
from notifications_library._email import compose_email # noqa: PLC0415
466+
from notifications_library._email_render import ( # noqa: PLC0415
461467
get_support_address,
462468
get_user_address,
463469
render_email_parts,
464470
)
465-
from notifications_library._render import (
471+
from notifications_library._render import ( # noqa: PLC0415
466472
create_render_environment_from_notifications_library,
467473
)
468474

0 commit comments

Comments
 (0)