Spaces:
Sleeping
Sleeping
updated get otp to support login and register, implemented protected apis and other improvements
1a3a466 | import logging | |
| from typing import Optional | |
| from datetime import datetime, timedelta | |
| from fastapi import APIRouter, HTTPException, Query, Depends, status, Body | |
| from app.models.merchant import MerchantRegister, GetOtpRequest | |
| from app.services.merchant_services import generate_and_send_otp, get_otp_from_cache, verify_otp_and_save_merchant, validate_merchant | |
| # Initialize router and logger | |
| router = APIRouter(prefix="/merchant") | |
| logger = logging.getLogger(__name__) | |
| async def register_customer(user: MerchantRegister = Body(...)): | |
| """ | |
| API endpoint to register a new Merchant. | |
| Args: | |
| user (MerchantRegister): The details of the Merchant to register. | |
| Returns: | |
| dict: Confirmation message indicating email and SMS verification pending. | |
| """ | |
| try: | |
| logger.info("Registering a new Merchant with Merchant name : %s, email: %s and mobile: %s", user.merchant_name, user.email, user.mobile) | |
| # Validate email and mobile format | |
| validation_result = await validate_merchant(user) | |
| if validation_result["status"] == "error": | |
| logger.error("Validation failed: %s", validation_result["errors"]) | |
| raise HTTPException(status_code=400, detail=validation_result["errors"]) | |
| return user.dict() | |
| except HTTPException as e: | |
| logger.error("Failed to register merchant: %s", e.detail) | |
| raise e | |
| except Exception as e: | |
| logger.error("Unexpected error while registering merchant: %s", e) | |
| raise HTTPException(status_code=500, detail="Failed to register Merchant") from e | |
| async def customer_otp_verification(user: MerchantRegister = Body(...)): | |
| """ | |
| API endpoint to validate OTPs and save the complete Merchant object. | |
| Args: | |
| user (MerchantRegister): The complete Merchant object including email, mobile, and OTPs. | |
| Returns: | |
| dict: Confirmation message indicating success or failure. | |
| """ | |
| try: | |
| logger.info("Verifying OTPs and registering merchant with email: %s and mobile: %s", user.email, user.mobile) | |
| # Verify OTPs and save customer | |
| result = await verify_otp_and_save_merchant(user) | |
| if result["status"] == "error": | |
| raise HTTPException(status_code=400, detail=result["errors"]) | |
| return {"message": "Merchant successfully registered and verified."} | |
| except HTTPException as e: | |
| logger.error("Failed to verify and register merchant: %s", e.detail) | |
| raise e | |
| except Exception as e: | |
| logger.error("Unexpected error while verifying and registering merchant: %s", e) | |
| raise HTTPException(status_code=500, detail="Failed to verify and register merchant") from e | |
| async def get_otps(payload: GetOtpRequest): | |
| """ | |
| API endpoint to retrieve the email or SMS OTP from Redis cache. | |
| Args: | |
| payload (GetOtpRequest): The request payload containing the identifier and type. | |
| Returns: | |
| dict: The OTP data if found, or an error message if not found. | |
| """ | |
| try: | |
| logger.info("Retrieving OTP for identifier: %s, type: %s", payload.identifier, payload.type) | |
| # Construct the Redis key based on the type | |
| redis_key = f"otp:{payload.type}:{payload.identifier}" | |
| # Retrieve OTP from Redis | |
| otp_data = await get_otp_from_cache(redis_key) | |
| if not otp_data: | |
| raise HTTPException(status_code=404, detail="OTP not found or expired") | |
| return {"identifier": payload.identifier, "type": payload.type, "otp_data": otp_data} | |
| except HTTPException as e: | |
| logger.error("Failed to retrieve OTP for identifier %s, type %s: %s", payload.identifier, payload.type, e.detail) | |
| raise e | |
| except Exception as e: | |
| logger.error("Unexpected error while retrieving OTP for identifier %s, type %s: %s", payload.identifier, payload.type, e) | |
| raise HTTPException(status_code=500, detail="Failed to retrieve OTP") from e | |
| async def regenerate_otp(user: MerchantRegister = Body(...)): | |
| """ | |
| API endpoint to regenerate an OTP for a given email, mobile number, or both. | |
| Args: | |
| user (MerchantRegister): The Merchant object containing email and mobile details. | |
| Returns: | |
| dict: Confirmation message indicating the OTP has been regenerated. | |
| """ | |
| try: | |
| logger.info("Regenerating OTP for Merchant with email: %s and mobile: %s", user.email, user.mobile) | |
| # Regenerate OTP for email & mobile | |
| if user.email and user.mobile: | |
| await generate_and_send_otp(user.email, user.mobile) | |
| return {"message": "OTP successfully regenerated for email and/or mobile.", "email": user.email, "mobile": user.mobile} | |
| except Exception as e: | |
| logger.error("Failed to regenerate OTP for Merchant with email: %s and mobile: %s. Error: %s", user.email, user.mobile, e) | |
| raise HTTPException(status_code=500, detail="Failed to regenerate OTP") from e |