From 149a799d6f2057bda62573de3915840ac7e7e2e9 Mon Sep 17 00:00:00 2001 From: sauravyadav2000 Date: Mon, 3 Mar 2025 21:26:52 +0530 Subject: [PATCH 1/2] adding tasks --- database.py | 9 +++---- main.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++--- models.py | 11 ++++++-- schemas.py | 27 ++++++++++++++----- 4 files changed, 104 insertions(+), 17 deletions(-) diff --git a/database.py b/database.py index accf2f5..fd82695 100644 --- a/database.py +++ b/database.py @@ -1,11 +1,8 @@ from sqlalchemy import create_engine -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import sessionmaker, declarative_base # Updated import -// Free to use remote db or create a local database. Modify the URl appropriately SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db" -engine = create_engine(SQLALCHEMY_DATABASE_URL) +engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) -Base = declarative_base() - +Base = declarative_base() # Updated to use SQLAlchemy 2.0 convention diff --git a/main.py b/main.py index f83e868..c1c9d8d 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +import json from fastapi import FastAPI, HTTPException, Depends from sqlalchemy.orm import Session from database import SessionLocal, engine, Base @@ -16,21 +17,88 @@ def get_db(): @app.post("/users/", response_model=schemas.User) def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)): - db_user = models.User(**user.dict()) + existing_user = db.query(models.User).filter(models.User.email == user.email).first() + if existing_user: + raise HTTPException(status_code=400, detail="Email already registered") + + db_user = models.User( + **user.model_dump(exclude={"interests"}), # Use model_dump() instead of dict() + interests=json.dumps(user.interests) # Convert list to JSON + ) db.add(db_user) db.commit() db.refresh(db_user) + db_user.interests = json.loads(db_user.interests) # Convert back to list for response return db_user @app.get("/users/", response_model=list[schemas.User]) def read_users(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)): - users = db.query(models.User).offset(skip).limit(limit).all() + users = db.query(models.User).filter(models.User.is_deleted == False).offset(skip).limit(limit).all() + + # Ensure JSON deserialization for interests field + for user in users: + user.interests = json.loads(user.interests) if user.interests else [] + return users @app.get("/users/{user_id}", response_model=schemas.User) def read_user(user_id: int, db: Session = Depends(get_db)): - user = db.query(models.User).filter(models.User.id == user_id).first() + user = db.query(models.User).filter(models.User.id == user_id, models.User.is_deleted == False).first() if user is None: raise HTTPException(status_code=404, detail="User not found") + + # Ensure JSON deserialization for interests field + user.interests = json.loads(user.interests) if user.interests else [] + return user +@app.get("/users/{user_id}/matches", response_model=list[schemas.User]) +def find_matches(user_id: int, db: Session = Depends(get_db)): + db_user = db.query(models.User).filter(models.User.id == user_id, models.User.is_deleted == False).first() + if db_user is None: + raise HTTPException(status_code=404, detail="User not found") + + user_interests = json.loads(db_user.interests) if db_user.interests else [] + all_users = db.query(models.User).filter(models.User.is_deleted == False, models.User.id != user_id).all() + + matches = [ + user for user in all_users + if set(json.loads(user.interests) if user.interests else []).intersection(user_interests) + ] + + for match in matches: + match.interests = json.loads(match.interests) if match.interests else [] + + return matches + +@app.put("/users/{user_id}", response_model=schemas.User) +def update_user(user_id: int, user_update: schemas.UserUpdate, db: Session = Depends(get_db)): + db_user = db.query(models.User).filter(models.User.id == user_id, models.User.is_deleted == False).first() + if db_user is None: + raise HTTPException(status_code=404, detail="User not found") + + update_data = user_update.model_dump(exclude_unset=True) # Ensure correct Pydantic usage + + if "email" in update_data and not schemas.validate_email(update_data["email"]): + raise HTTPException(status_code=400, detail="Invalid email format") + + if "interests" in update_data: + update_data["interests"] = json.dumps(update_data["interests"]) # Convert list to JSON + + for key, value in update_data.items(): + setattr(db_user, key, value) + + db.commit() + db.refresh(db_user) + db_user.interests = json.loads(db_user.interests) if db_user.interests else [] + return db_user + +@app.delete("/users/{user_id}") +def delete_user(user_id: int, db: Session = Depends(get_db)): + db_user = db.query(models.User).filter(models.User.id == user_id).first() + if db_user is None: + raise HTTPException(status_code=404, detail="User not found") + + db_user.is_deleted = True # Soft delete + db.commit() + return {"message": "User marked as deleted (soft delete)."} diff --git a/models.py b/models.py index 0e42748..c17a638 100644 --- a/models.py +++ b/models.py @@ -1,5 +1,6 @@ -from sqlalchemy import Column, Integer, String, ARRAY +from sqlalchemy import Column, Integer, String, Boolean, Text from database import Base +import json class User(Base): __tablename__ = "users" @@ -10,5 +11,11 @@ class User(Base): gender = Column(String) email = Column(String, unique=True, index=True) city = Column(String, index=True) - interests = Column(ARRAY(String)) + interests = Column(Text, nullable=True) # Store as JSON text + is_deleted = Column(Boolean, default=False) + def set_interests(self, interests_list): + self.interests = json.dumps(interests_list) + + def get_interests(self): + return json.loads(self.interests) if self.interests else [] diff --git a/schemas.py b/schemas.py index 5872710..2296cf5 100644 --- a/schemas.py +++ b/schemas.py @@ -1,20 +1,35 @@ -from pydantic import BaseModel -from typing import List +from pydantic import BaseModel, EmailStr, ValidationError +from typing import List, Optional class UserBase(BaseModel): + name: Optional[str] = None + age: Optional[int] = None + gender: Optional[str] = None + email: Optional[EmailStr] = None + city: Optional[str] = None + interests: Optional[List[str]] = None + +class UserCreate(UserBase): name: str age: int gender: str - email: str + email: EmailStr city: str - interests: List[str] + interests: List[str] -class UserCreate(UserBase): +class UserUpdate(UserBase): pass class User(UserBase): id: int class Config: - orm_mode = True + from_attributes = True +def validate_email(email: str) -> bool: + """Validate email format manually.""" + try: + EmailStr.validate(email) + return True + except ValidationError: + return False From 9592e07dcfd8dafaff4132a8a57f02e782838f99 Mon Sep 17 00:00:00 2001 From: sauravyadav2000 Date: Mon, 3 Mar 2025 21:28:17 +0530 Subject: [PATCH 2/2] removing unwanted code --- database.py | 2 +- main.py | 14 ++++++-------- models.py | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/database.py b/database.py index fd82695..8689298 100644 --- a/database.py +++ b/database.py @@ -5,4 +5,4 @@ engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) -Base = declarative_base() # Updated to use SQLAlchemy 2.0 convention +Base = declarative_base() diff --git a/main.py b/main.py index c1c9d8d..a76709c 100644 --- a/main.py +++ b/main.py @@ -22,20 +22,19 @@ def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)): raise HTTPException(status_code=400, detail="Email already registered") db_user = models.User( - **user.model_dump(exclude={"interests"}), # Use model_dump() instead of dict() - interests=json.dumps(user.interests) # Convert list to JSON + **user.model_dump(exclude={"interests"}), + interests=json.dumps(user.interests) ) db.add(db_user) db.commit() db.refresh(db_user) - db_user.interests = json.loads(db_user.interests) # Convert back to list for response + db_user.interests = json.loads(db_user.interests) return db_user @app.get("/users/", response_model=list[schemas.User]) def read_users(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)): users = db.query(models.User).filter(models.User.is_deleted == False).offset(skip).limit(limit).all() - # Ensure JSON deserialization for interests field for user in users: user.interests = json.loads(user.interests) if user.interests else [] @@ -47,7 +46,6 @@ def read_user(user_id: int, db: Session = Depends(get_db)): if user is None: raise HTTPException(status_code=404, detail="User not found") - # Ensure JSON deserialization for interests field user.interests = json.loads(user.interests) if user.interests else [] return user @@ -77,13 +75,13 @@ def update_user(user_id: int, user_update: schemas.UserUpdate, db: Session = Dep if db_user is None: raise HTTPException(status_code=404, detail="User not found") - update_data = user_update.model_dump(exclude_unset=True) # Ensure correct Pydantic usage + update_data = user_update.model_dump(exclude_unset=True) if "email" in update_data and not schemas.validate_email(update_data["email"]): raise HTTPException(status_code=400, detail="Invalid email format") if "interests" in update_data: - update_data["interests"] = json.dumps(update_data["interests"]) # Convert list to JSON + update_data["interests"] = json.dumps(update_data["interests"]) for key, value in update_data.items(): setattr(db_user, key, value) @@ -99,6 +97,6 @@ def delete_user(user_id: int, db: Session = Depends(get_db)): if db_user is None: raise HTTPException(status_code=404, detail="User not found") - db_user.is_deleted = True # Soft delete + db_user.is_deleted = True db.commit() return {"message": "User marked as deleted (soft delete)."} diff --git a/models.py b/models.py index c17a638..b09a249 100644 --- a/models.py +++ b/models.py @@ -11,7 +11,7 @@ class User(Base): gender = Column(String) email = Column(String, unique=True, index=True) city = Column(String, index=True) - interests = Column(Text, nullable=True) # Store as JSON text + interests = Column(Text, nullable=True) is_deleted = Column(Boolean, default=False) def set_interests(self, interests_list):