Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added __pycache__/database.cpython-311.pyc
Binary file not shown.
Binary file added __pycache__/main.cpython-311.pyc
Binary file not shown.
Binary file added __pycache__/models.cpython-311.pyc
Binary file not shown.
Binary file added __pycache__/schemas.cpython-311.pyc
Binary file not shown.
4 changes: 2 additions & 2 deletions database.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

// Free to use remote db or create a local database. Modify the URl appropriately
# 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()

69 changes: 68 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from sqlalchemy.orm import Session
from database import SessionLocal, engine, Base
import models, schemas

import json
from sqlalchemy import text
app = FastAPI()

Base.metadata.create_all(bind=engine)
Expand Down Expand Up @@ -34,3 +35,69 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
raise HTTPException(status_code=404, detail="User not found")
return user

# this is a update user endpoint
@app.patch("/users/{user_id}", response_model=schemas.User)
def update_user(user_id: int, user_data: schemas.UserUpdate, db: Session = Depends(get_db)):
user = db.query(models.User).filter(models.User.id == user_id).first()
if not user:
raise HTTPException(status_code=404, detail="User not found")

update_data = user_data.dict(exclude_unset=True)
for key, value in update_data.items():
setattr(user, key, value)

db.commit()
db.refresh(user)
return user


# this is a delete user endpoint
@app.delete("/users/{user_id}", response_model=dict)
def delete_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(models.User).filter(models.User.id == user_id).first()
if not user:
raise HTTPException(status_code=404, detail="User not found")
db.delete(user)
db.commit()
return {"detail": "User deleted"}

# this is a find matches for a user endpoint
@app.get("/users/{user_id}/matches", response_model=list[schemas.User])
def find_matches(user_id: int, db: Session = Depends(get_db)):
# Retrieve the given user's profile
user = db.query(models.User).filter(models.User.id == user_id).first()
if not user:
raise HTTPException(status_code=404, detail="User not found")
matches = []
# Retrieve all other users
all_users = db.query(models.User).filter(models.User.id != user_id).all()
for other in all_users:
# If there's at least one common interest, consider it a match
if set(user.interests).intersection(set(other.interests)):
matches.append(other)
return matches

# this is a upgraded matchmaking endpoint that returns a match score 😅
@app.get("/users/{user_id}/matches_score", response_model=list[schemas.UserMatch])
def find_matches_score(user_id: int, db: Session = Depends(get_db)):
user = db.query(models.User).filter(models.User.id == user_id).first()
if not user:
raise HTTPException(status_code=404, detail="User not found")

matches = []
all_users = db.query(models.User).filter(models.User.id != user_id).all()
for other in all_users:
# here we are calculating common interests score
common_interests = set(user.interests).intersection(set(other.interests))
score = len(common_interests)
# here we are adding bonus if both users are in the same city
if user.city.lower() == other.city.lower():
score += 1

# Only consider matches with a score greater than 0
if score > 0:
matches.append({"user": other, "match_score": score})

# Sort matches by score in descending order
matches.sort(key=lambda x: x["match_score"], reverse=True)
return matches
7 changes: 3 additions & 4 deletions models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from sqlalchemy import Column, Integer, String, ARRAY
from sqlalchemy import Column, Integer, String
from database import Base

from sqlalchemy.dialects.sqlite import JSON
class User(Base):
__tablename__ = "users"

Expand All @@ -10,5 +10,4 @@ class User(Base):
gender = Column(String)
email = Column(String, unique=True, index=True)
city = Column(String, index=True)
interests = Column(ARRAY(String))

interests = Column(JSON)
18 changes: 15 additions & 3 deletions schemas.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
from pydantic import BaseModel
from typing import List
from pydantic import BaseModel, EmailStr
from typing import List, Optional

class UserBase(BaseModel):
name: str
age: int
gender: str
email: str
email: EmailStr # EmailStr validates email itself (i dont need to write a custom validator)
city: str
interests: List[str]

class UserCreate(UserBase):
pass

class UserUpdate(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 User(UserBase):
id: int

class Config:
orm_mode = True

class UserMatch(BaseModel):
user: User
match_score: float

Binary file added test.db
Binary file not shown.