Spaces:
Sleeping
Sleeping
File size: 5,059 Bytes
3e42e33 1a3a466 c96424b 3e42e33 1a3a466 3e42e33 1a3a466 3e42e33 1a3a466 3e42e33 1a3a466 3e42e33 1a3a466 3e42e33 1a3a466 3e42e33 1a3a466 797987e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 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__)
@router.post("/register")
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
@router.post("/otp/verify")
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
@router.post("/otp/get")
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
@router.post("/otp/regenerate")
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 |