docs(code): add concise docstrings

This commit is contained in:
2026-07-14 11:05:07 +03:30
parent c54f6edc1e
commit 5f88e964f6
20 changed files with 299 additions and 26 deletions

View File

@@ -23,10 +23,15 @@ logger = logging.getLogger(__name__)
class AuthGrpcServicer(auth_pb2_grpc.AuthServiceServicer):
"""gRPC transport adapter that maps protobuf calls to AuthService use cases."""
def __init__(self, auth_service: AuthService) -> None:
"""Bind the servicer to the application auth service."""
self._auth_service = auth_service
async def RequestOtp(self, request, context): # type: ignore[no-untyped-def]
"""Handle public OTP request calls."""
try:
await self._auth_service.request_otp(
mobile=request.mobile,
@@ -38,6 +43,8 @@ class AuthGrpcServicer(auth_pb2_grpc.AuthServiceServicer):
await _abort_for_app_error(context, exc)
async def VerifyOtp(self, request, context): # type: ignore[no-untyped-def]
"""Handle public OTP verification and token issuance calls."""
try:
token_pair = await self._auth_service.verify_otp(
mobile=request.mobile,
@@ -49,6 +56,8 @@ class AuthGrpcServicer(auth_pb2_grpc.AuthServiceServicer):
await _abort_for_app_error(context, exc)
async def RefreshToken(self, request, context): # type: ignore[no-untyped-def]
"""Handle refresh-token rotation calls."""
try:
token_pair = await self._auth_service.refresh_token(request.refresh_token)
return _token_response(token_pair)
@@ -56,6 +65,8 @@ class AuthGrpcServicer(auth_pb2_grpc.AuthServiceServicer):
await _abort_for_app_error(context, exc)
async def RevokeRefreshToken(self, request, context): # type: ignore[no-untyped-def]
"""Handle authenticated refresh-token revocation calls."""
try:
token = _extract_bearer_token(context.invocation_metadata())
await self._auth_service.get_authenticated_user(token)
@@ -65,9 +76,13 @@ class AuthGrpcServicer(auth_pb2_grpc.AuthServiceServicer):
await _abort_for_app_error(context, exc)
async def PublicPing(self, request, context): # type: ignore[no-untyped-def]
"""Return a public response without authentication."""
return auth_pb2.PingResponse(message="public ok")
async def UserOnly(self, request, context): # type: ignore[no-untyped-def]
"""Return a response for any active authenticated user."""
try:
user = await self._auth_service.get_authenticated_user(
_extract_bearer_token(context.invocation_metadata())
@@ -77,6 +92,8 @@ class AuthGrpcServicer(auth_pb2_grpc.AuthServiceServicer):
await _abort_for_app_error(context, exc)
async def AdminOnly(self, request, context): # type: ignore[no-untyped-def]
"""Return a response only for authenticated admin users."""
try:
user = await self._auth_service.require_role(
_extract_bearer_token(context.invocation_metadata()), Role.ADMIN
@@ -87,6 +104,8 @@ class AuthGrpcServicer(auth_pb2_grpc.AuthServiceServicer):
def _token_response(token_pair: TokenPair): # type: ignore[no-untyped-def]
"""Convert an application token pair into a protobuf response."""
return auth_pb2.TokenResponse(
access_token=token_pair.access_token,
refresh_token=token_pair.refresh_token,
@@ -97,10 +116,14 @@ def _token_response(token_pair: TokenPair): # type: ignore[no-untyped-def]
def _protected_response(user: User, message: str): # type: ignore[no-untyped-def]
"""Convert an authenticated user into a protected-method protobuf response."""
return auth_pb2.ProtectedResponse(user_id=user.id, role=user.role.value, message=message)
def _extract_bearer_token(metadata: Sequence[tuple[str, str]]) -> str:
"""Read bearer token metadata from a protected gRPC invocation."""
for key, value in metadata:
if key.lower() == "authorization" and value.startswith("Bearer "):
return value.removeprefix("Bearer ").strip()
@@ -108,6 +131,8 @@ def _extract_bearer_token(metadata: Sequence[tuple[str, str]]) -> str:
async def _abort_for_app_error(context: grpc.aio.ServicerContext, exc: AppError) -> None:
"""Translate expected application errors into meaningful gRPC status codes."""
if isinstance(exc, AuthenticationError | InvalidOtp | OtpExpired | OtpAttemptsExceeded):
await context.abort(grpc.StatusCode.UNAUTHENTICATED, str(exc))
if isinstance(exc, InactiveUser):