Spaces:
Building
Building
from fastapi import APIRouter, HTTPException, Depends | |
from sqlalchemy.ext.asyncio import AsyncSession | |
from sqlalchemy.future import select | |
from passlib.context import CryptContext | |
from jose import jwt | |
from pydantic.v1 import BaseModel, EmailStr | |
from app.database import get_db # Updated: use the correct async session dependency | |
from app.models import User | |
import os | |
import logging | |
from dotenv import load_dotenv | |
router = APIRouter() | |
logger = logging.getLogger(__name__) | |
load_dotenv() | |
# Load secret key and JWT algorithm | |
SECRET_KEY = os.getenv("SECRET_KEY", "secret") | |
ALGORITHM = "HS256" | |
# Password hashing config | |
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") | |
# Request Schemas | |
class SignUp(BaseModel): | |
email: EmailStr | |
password: str | |
class Login(BaseModel): | |
email: EmailStr | |
password: str | |
async def signup(data: SignUp, db: AsyncSession = Depends(get_db)): | |
# Check if user already exists | |
result = await db.execute(select(User).where(User.email == data.email)) | |
existing_user = result.scalar_one_or_none() | |
if existing_user: | |
raise HTTPException(status_code=400, detail="Email already exists") | |
hashed_password = pwd_context.hash(data.password) | |
new_user = User(email=data.email, hashed_password=hashed_password) | |
try: | |
db.add(new_user) | |
await db.commit() | |
await db.refresh(new_user) | |
return {"message": "User created", "user_id": new_user.id} | |
except Exception as e: | |
await db.rollback() | |
logger.error(f"Signup error: {e}") | |
raise HTTPException(status_code=500, detail="Internal Server Error") | |
async def login(data: Login, db: AsyncSession = Depends(get_db)): | |
result = await db.execute(select(User).where(User.email == data.email)) | |
user = result.scalar_one_or_none() | |
if not user or not pwd_context.verify(data.password, user.hashed_password): | |
raise HTTPException(status_code=401, detail="Invalid credentials") | |
token = jwt.encode({"user_id": user.id}, SECRET_KEY, algorithm=ALGORITHM) | |
return { | |
"access_token": token, | |
"token_type": "bearer", | |
"user": {"id": user.id, "email": user.email}, | |
} | |