Testys commited on
Commit
fc76af0
1 Parent(s): 26a61c6

Upload 4 files

Browse files
Files changed (4) hide show
  1. users/models.py +32 -0
  2. users/routes.py +125 -0
  3. users/schemas.py +40 -0
  4. users/services.py +84 -0
users/models.py CHANGED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Float, ARRAY, DateTime
2
+ from sqlalchemy.orm import relationship
3
+ from core.database import Base
4
+ from datetime import datetime
5
+
6
+ class User(Base):
7
+ __tablename__ = "users"
8
+
9
+ id = Column(Integer, primary_key=True, index=True)
10
+ email = Column(String, unique=True, index=True)
11
+ username = Column(String, unique=True, index=True)
12
+ hashed_password = Column(String)
13
+ first_name = Column(String)
14
+ last_name = Column(String)
15
+ age = Column(Integer)
16
+ preferences = Column(ARRAY(String))
17
+ is_active = Column(Boolean, default=True)
18
+ is_admin = Column(Boolean, default=False)
19
+ updated_at = Column(DateTime, default=datetime.utcnow)
20
+ created_at = Column(DateTime, default=datetime.utcnow)
21
+
22
+ orders = relationship("Order", back_populates="user")
23
+ embeddings = relationship("UserEmbeddings", back_populates="user", uselist=False)
24
+
25
+ class UserEmbeddings(Base):
26
+ __tablename__ = "user_embeddings"
27
+
28
+ id = Column(Integer, primary_key=True, index=True)
29
+ user_id = Column(Integer, ForeignKey("users.id"))
30
+ embeddings = Column(ARRAY(Float))
31
+
32
+ user = relationship("User", back_populates="embeddings")
users/routes.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, status, Depends, Request, UploadFile, File, HTTPException
2
+ from fastapi.responses import JSONResponse
3
+ from sqlalchemy.orm import Session
4
+ from core.database import get_db
5
+ from core.security import get_current_user, create_access_token
6
+ from users.schemas import UserCreate, UserBase, UserEmbeddingsBase, User
7
+ from users.services import create_user_account, create_user_embeddings, update_user, update_user_embeddings, get_user_by_id, get_user_by_email
8
+ from services.facial_processing import FacialProcessing
9
+ from services.face_match import FaceMatch
10
+ import os
11
+ from datetime import timedelta
12
+ from dotenv import load_dotenv
13
+ from auth.services import get_token
14
+
15
+
16
+ env_path = (os.path.abspath(os.path.join(os.path.dirname(__file__), '.env')))
17
+ load_dotenv()
18
+
19
+ router = APIRouter(
20
+ prefix="/users",
21
+ tags=["Users"],
22
+ responses={404: {"description": "Not found"}},
23
+ )
24
+
25
+ @router.get("/health", tags=["Health"])
26
+ def health_check():
27
+ return {"status": "ok"}
28
+
29
+ @router.post("/", status_code=status.HTTP_201_CREATED, response_model=UserBase)
30
+ async def create_user(data: UserCreate, db: Session = Depends(get_db)):
31
+ await create_user_account(data, db)
32
+ payload = {"message": "User created successfully"}
33
+ return JSONResponse(content=payload, status_code=status.HTTP_201_CREATED)
34
+
35
+
36
+ @router.post("/me",status_code=status.HTTP_200_OK)
37
+ def get_user_details(request: Request):
38
+ user = request.user
39
+ return user
40
+
41
+ @router.get("/me", response_model=UserBase)
42
+ async def read_users_me(current_user: User = Depends(get_current_user)):
43
+ return current_user
44
+
45
+ @router.put("/me", response_model=UserBase)
46
+ async def updating_user(user: UserBase, current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
47
+ user = update_user(db, current_user.id, user)
48
+ return current_user
49
+
50
+
51
+ @router.post("/me/face",status_code=status.HTTP_200_OK)
52
+ async def create_face_embeddings(file: UploadFile = File(...), user:User = Depends(get_current_user), db: Session = Depends(get_db)):
53
+ face_processor = FacialProcessing()
54
+
55
+ # Process the uploaded image
56
+ image_path = f"faces/{user.id}.jpg"
57
+ with open(image_path, "wb") as buffer:
58
+ buffer.write(await file.read())
59
+
60
+ # Extract embeddings
61
+ embeddings = face_processor.extract_embeddings_vgg(image_path)
62
+ if embeddings:
63
+ create_user_embeddings(user.id, embeddings, db)
64
+ return {"message": "Face embeddings created successfully"}
65
+
66
+ raise HTTPException(status_code=400,
67
+ detail="Failed to process face"
68
+ )
69
+
70
+ @router.get("/me/face",status_code=status.HTTP_200_OK)
71
+ async def get_face_embeddings(user:User = Depends(get_current_user), db: Session = Depends(get_db)):
72
+ face = db.query(UserEmbeddingsBase).filter(UserEmbeddingsBase.user_id == user.id).first()
73
+ if not face:
74
+ raise HTTPException(status_code=404,
75
+ detail="Face embeddings not found"
76
+ )
77
+ return JSONResponse(content={"embeddings": face.embeddings}, status_code=status.HTTP_200_OK)
78
+
79
+ @router.put("/me/face",status_code=status.HTTP_200_OK)
80
+ async def updating_face_embeddings(file: UploadFile = File(...), user:User = Depends(get_current_user), db: Session = Depends(get_db)):
81
+ face_processor = FacialProcessing()
82
+
83
+ # Process the uploaded image
84
+ image_path = f"faces/{user.id}.jpg"
85
+ with open(image_path, "wb") as buffer:
86
+ buffer.write(await file.read())
87
+
88
+ # Extract embeddings
89
+ embeddings = face_processor.extract_embeddings_vgg(image_path)
90
+ if embeddings:
91
+ update_user_embeddings(user.id, embeddings, db)
92
+ return {"message": "Face embeddings updated successfully"}
93
+
94
+ raise HTTPException(status_code=400,
95
+ detail="Failed to process face"
96
+ )
97
+
98
+ @router.post("/login/face")
99
+ async def face_login(file: UploadFile = File(...), db: Session = Depends(get_db)):
100
+ face_processor = FacialProcessing()
101
+ face_matcher = FaceMatch(db)
102
+
103
+ # Process the uploaded image
104
+ image_path = f"temp_{file.filename}"
105
+ with open(image_path, "wb") as buffer:
106
+ buffer.write(await file.read())
107
+
108
+ # Extract embeddings
109
+ embeddings = await face_processor.extract_embeddings(image_path)
110
+ if not embeddings:
111
+ raise HTTPException(status_code=400, detail="Failed to process face")
112
+
113
+ # Match face
114
+ match_result = face_matcher.new_face_matching(embeddings)
115
+ if match_result['status'] == 'Success':
116
+ user = get_user_by_id(match_result['user_id'], db)
117
+ if not user:
118
+ raise HTTPException(status_code=404, detail="User not found")
119
+
120
+ access_token_expires = timedelta(minutes=os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES"))
121
+ payload = {"id":user.id, "sub": user.email}
122
+ token = get_token(payload, db)
123
+ return JSONResponse(content=token.dict(), status_code=status.HTTP_200_OK)
124
+
125
+ raise HTTPException(status_code=401, detail="Face not recognized")
users/schemas.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, EmailStr
2
+ from typing import Optional, List
3
+
4
+ class UserBase(BaseModel):
5
+ username: str
6
+ first_name: str
7
+ last_name: str
8
+ email: EmailStr
9
+ age: Optional[int] = None
10
+ preferences: Optional[dict] = None
11
+ is_active: Optional[bool] = True
12
+
13
+
14
+ class UserCreate(UserBase):
15
+ password: str
16
+
17
+
18
+ class UserUpdate(UserBase):
19
+ password: Optional[str] = None
20
+
21
+ class User(UserBase):
22
+ id: int
23
+
24
+ class Config:
25
+ orm_mode = True
26
+
27
+ class UserEmbeddingsBase(BaseModel):
28
+ embeddings: List[float]
29
+
30
+ class UserEmbeddingsCreate(UserEmbeddingsBase):
31
+ pass
32
+
33
+
34
+ class UserEmbeddings(UserEmbeddingsBase):
35
+ id: int
36
+ user_id: int
37
+
38
+ class Config:
39
+ orm_mode = True
40
+
users/services.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from users.models import User, UserEmbeddings
2
+ from fastapi.exceptions import HTTPException
3
+ from core.security import get_password_hash
4
+ from datetime import datetime
5
+ from sqlalchemy.orm import Session
6
+ from users.schemas import UserCreate, UserUpdate, UserEmbeddingsModel
7
+
8
+
9
+ async def create_user_account(data:UserCreate, db:Session):
10
+ user = db.query(User).filter(User.email == data.email).first()
11
+ if user:
12
+ raise HTTPException(status_code=422, detail="Email already registered")
13
+
14
+ new_user = User(
15
+ email=data.email,
16
+ first_name=data.first_name,
17
+ last_name=data.last_name,
18
+ age=data.age,
19
+ preferences=data.preferences,
20
+ password = get_password_hash(data.password),
21
+ registered_at=datetime.now(),
22
+ updated_at=datetime.now(),
23
+ )
24
+
25
+ db.add(new_user)
26
+ db.commit()
27
+ db.refresh(new_user)
28
+ return new_user
29
+
30
+ async def create_user_embeddings(user_id:int, embeddings:UserEmbeddingsModel, db:Session):
31
+ user = db.query(User).filter(User.id == user_id).first()
32
+ if not user:
33
+ embeddings = UserEmbeddings(user_id=user_id, embeddings=embeddings.embeddings)
34
+ db.add(embeddings)
35
+ db.commit()
36
+ db.refresh(embeddings)
37
+ return embeddings
38
+
39
+ def get_user_by_id(user_id, db:Session):
40
+ return db.query(User).filter(User.id == user_id).first()
41
+
42
+
43
+ def get_user_by_email(email, db:Session):
44
+ return db.query(User).filter(User.email == email).first()
45
+
46
+
47
+ def get_users(db:Session, skip=0, limit=100):
48
+ return db.query(User).offset(skip).limit(limit).all()
49
+
50
+
51
+ def update_user(db:Session, user_id:int, user:UserUpdate):
52
+ user = db.query(User).filter(User.id == user_id).first()
53
+ if user:
54
+ update_data = user.dict(exclude_unset=True)
55
+ if 'password' in update_data:
56
+ update_data['password'] = get_password_hash(update_data['password'])
57
+ del update_data['password']
58
+
59
+ for key, value in update_data.items():
60
+ setattr(user, key, value)
61
+ db.commit()
62
+ db.refresh(user)
63
+ return user
64
+
65
+
66
+ def delete_user(user_id, db:Session):
67
+ user = db.query(User).filter(User.id == user_id).first()
68
+ if user:
69
+ db.delete(user)
70
+ db.commit()
71
+ return user
72
+ return None
73
+
74
+
75
+ async def update_user_embeddings(user_id:int, embeddings:UserEmbeddingsModel, db:Session):
76
+ embeddings = db.query(UserEmbeddings).filter(UserEmbeddings.user_id == user_id).first()
77
+ if embeddings:
78
+ embeddings.embeddings = embeddings.embeddings
79
+ db.commit()
80
+ db.refresh(embeddings)
81
+ return embeddings
82
+ return None
83
+
84
+