ramanjitsingh1368 commited on
Commit
fcfe4b3
·
1 Parent(s): 33f965d

refactor user model and schemas to consolidate name fields and remove signup schema

Browse files
src/controllers/__init__.py CHANGED
@@ -19,13 +19,11 @@ api_router.include_router(
19
  auth_router,
20
  prefix="/v1",
21
  tags=["Authentication"],
22
- dependencies=[Depends(API_KEY_HEADER)],
23
  )
24
  api_router.include_router(
25
  conversation_api_router,
26
  prefix="/v1",
27
  tags=["Conversation"],
28
- dependencies=[Depends(API_KEY_HEADER)],
29
  )
30
  websocket_router.include_router(
31
  conversation_websocket_router,
@@ -36,7 +34,6 @@ api_router.include_router(
36
  file_router,
37
  prefix="/v1",
38
  tags=["Semantic Search"],
39
- dependencies=[Depends(API_KEY_HEADER)],
40
  )
41
 
42
  __all__ = ["api_router", "websocket_router"]
 
19
  auth_router,
20
  prefix="/v1",
21
  tags=["Authentication"],
 
22
  )
23
  api_router.include_router(
24
  conversation_api_router,
25
  prefix="/v1",
26
  tags=["Conversation"],
 
27
  )
28
  websocket_router.include_router(
29
  conversation_websocket_router,
 
34
  file_router,
35
  prefix="/v1",
36
  tags=["Semantic Search"],
 
37
  )
38
 
39
  __all__ = ["api_router", "websocket_router"]
src/controllers/_auth_controller.py CHANGED
@@ -1,11 +1,6 @@
1
  from fastapi import APIRouter, HTTPException, status, Request
2
  from src.services import AuthService
3
- from src.schemas import (
4
- UserSignInSchema,
5
- UserSignInResponse,
6
- UserSignUpSchema,
7
- UserSignUpResponse,
8
- )
9
  from src.config import logger
10
 
11
 
@@ -13,59 +8,19 @@ class AuthController:
13
  def __init__(self):
14
  self._auth_service = AuthService()
15
  self.api_router = APIRouter(prefix="/auth", tags=["Authentication"])
16
- self.api_router.add_api_route(
17
- methods=["POST"],
18
- path="/register",
19
- endpoint=self._signup,
20
- response_model=UserSignUpResponse,
21
- )
22
  self.api_router.add_api_route(
23
  methods=["POST"],
24
  path="/login",
25
  endpoint=self._signin,
26
  response_model=UserSignInResponse,
27
  )
28
- self.api_router.add_api_route(
29
- methods=["POST"],
30
- path="/logout",
31
- endpoint=self._signout,
32
- )
33
-
34
- async def _signup(self, user_create: UserSignUpSchema):
35
- try:
36
- user = await self._auth_service.sign_up(user_create)
37
- return UserSignUpResponse(user_id=str(user.id))
38
- except HTTPException as e:
39
- raise
40
- except Exception as e:
41
- logger.error(f"Error during signup: {e}")
42
- raise HTTPException(status_code=500, detail="Error during signup")
43
-
44
- async def _signin(
45
- self,
46
- form_data: UserSignInSchema,
47
- request: Request,
48
- ):
49
- try:
50
- client_ip = request.client.host
51
- token = await self._auth_service.sign_in(form_data, client_ip)
52
- return UserSignInResponse(token=token)
53
- except HTTPException as e:
54
- raise
55
- except Exception as e:
56
- logger.error(f"Error during signin: {e}")
57
- raise HTTPException(status_code=500, detail="Error during signin")
58
 
59
- async def _signout(
60
- self,
61
- request: Request,
62
- ):
63
  try:
64
- token = request.headers.get("Authorization").split(" ")[1]
65
- await self._auth_service.sign_out(token)
66
- return status.HTTP_200_OK
67
  except HTTPException as e:
68
  raise
69
  except Exception as e:
70
- logger.error(f"Error during signout: {e}")
71
- raise HTTPException(status_code=500, detail="Error during signout")
 
1
  from fastapi import APIRouter, HTTPException, status, Request
2
  from src.services import AuthService
3
+ from src.schemas import UserSignInSchema, UserSignInResponse
 
 
 
 
 
4
  from src.config import logger
5
 
6
 
 
8
  def __init__(self):
9
  self._auth_service = AuthService()
10
  self.api_router = APIRouter(prefix="/auth", tags=["Authentication"])
 
 
 
 
 
 
11
  self.api_router.add_api_route(
12
  methods=["POST"],
13
  path="/login",
14
  endpoint=self._signin,
15
  response_model=UserSignInResponse,
16
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ async def _signin(self, user: UserSignInSchema):
 
 
 
19
  try:
20
+ user = await self._auth_service.sign_in(user)
21
+ return UserSignInResponse(user_id=str(user.user_id))
 
22
  except HTTPException as e:
23
  raise
24
  except Exception as e:
25
+ logger.error(f"Error during implicit signin: {e}")
26
+ raise HTTPException(status_code=500, detail="Error during implicit signin")
src/controllers/_conversation_controller.py CHANGED
@@ -3,7 +3,6 @@ from fastapi import (
3
  APIRouter,
4
  HTTPException,
5
  WebSocket,
6
- Request,
7
  WebSocketDisconnect,
8
  )
9
  from typing import List
@@ -28,21 +27,16 @@ class ConnectionManager:
28
 
29
  async def connect(self, websocket: WebSocket, redis_client):
30
  await websocket.accept()
31
- token = websocket.query_params.get("token")
32
  conversation_id = websocket.query_params.get("conversation_id")
33
- user = self.jwt.validate_jwt(token)
34
-
35
- if not user:
36
- await websocket.close(code=1008, reason="Invalid token")
37
- return None
38
 
39
  self.active_connections.append(websocket)
40
  await self._update_redis_status(
41
- unique_id=f"{user["user_id"]}{conversation_id}",
42
  redis_client=redis_client,
43
  status="active",
44
  )
45
- return user
46
 
47
  async def disconnect(
48
  self, websocket: WebSocket, redis_client, user_id: str, conversation_id: str
@@ -95,14 +89,11 @@ class ConversationController:
95
  )
96
  self.websocket_router.add_websocket_route("/conversations", self.conversation)
97
 
98
- async def create_conversation(
99
- self, request: Request, data: CreateConversationSchema
100
- ):
101
  try:
102
- user_id = request.state.user["user_id"]
103
  async with self.service() as service:
104
  return await service.create_conversation(
105
- user_id=user_id, modality=data.modality
106
  )
107
  except HTTPException as e:
108
  raise
@@ -113,14 +104,12 @@ class ConversationController:
113
 
114
  async def create_webrtc_connection(
115
  self,
116
- request: Request,
117
  data: CreateWebrtcConnectionSchema,
118
  ):
119
  try:
120
- user_id = request.state.user["user_id"]
121
  async with self.service() as service:
122
  return await service.create_webrtc_connection(
123
- user_id=user_id,
124
  conversation_id=data.conversation_id,
125
  offer=data.offer.model_dump(),
126
  )
@@ -134,12 +123,11 @@ class ConversationController:
134
  )
135
 
136
  async def conversation(self, websocket: WebSocket):
137
- user = await self.websocket_connection_manager.connect(
138
  websocket=websocket, redis_client=self.redis_client
139
  )
140
- if not user:
141
  return
142
- user_id = user["user_id"]
143
  conversation_id = websocket.query_params.get("conversation_id")
144
  modality = websocket.query_params.get("modality")
145
  try:
@@ -172,14 +160,11 @@ class ConversationController:
172
  conversation_id=conversation_id,
173
  )
174
 
175
- async def create_conversation_summary(
176
- self, request: Request, data: CreateConversationSummarySchema
177
- ):
178
  try:
179
- user_id = request.state.user["user_id"]
180
  async with self.service() as service:
181
  return await service.create_conversation_summary(
182
- user_id=user_id, conversation_id=data.conversation_id
183
  )
184
 
185
  except HTTPException as e:
 
3
  APIRouter,
4
  HTTPException,
5
  WebSocket,
 
6
  WebSocketDisconnect,
7
  )
8
  from typing import List
 
27
 
28
  async def connect(self, websocket: WebSocket, redis_client):
29
  await websocket.accept()
 
30
  conversation_id = websocket.query_params.get("conversation_id")
31
+ user_id = websocket.query_params.get("user_id")
 
 
 
 
32
 
33
  self.active_connections.append(websocket)
34
  await self._update_redis_status(
35
+ unique_id=f"{user_id}{conversation_id}",
36
  redis_client=redis_client,
37
  status="active",
38
  )
39
+ return user_id
40
 
41
  async def disconnect(
42
  self, websocket: WebSocket, redis_client, user_id: str, conversation_id: str
 
89
  )
90
  self.websocket_router.add_websocket_route("/conversations", self.conversation)
91
 
92
+ async def create_conversation(self, data: CreateConversationSchema):
 
 
93
  try:
 
94
  async with self.service() as service:
95
  return await service.create_conversation(
96
+ user_id=data.user_id, modality=data.modality
97
  )
98
  except HTTPException as e:
99
  raise
 
104
 
105
  async def create_webrtc_connection(
106
  self,
 
107
  data: CreateWebrtcConnectionSchema,
108
  ):
109
  try:
 
110
  async with self.service() as service:
111
  return await service.create_webrtc_connection(
112
+ user_id=data.user_id,
113
  conversation_id=data.conversation_id,
114
  offer=data.offer.model_dump(),
115
  )
 
123
  )
124
 
125
  async def conversation(self, websocket: WebSocket):
126
+ user_id = await self.websocket_connection_manager.connect(
127
  websocket=websocket, redis_client=self.redis_client
128
  )
129
+ if not user_id:
130
  return
 
131
  conversation_id = websocket.query_params.get("conversation_id")
132
  modality = websocket.query_params.get("modality")
133
  try:
 
160
  conversation_id=conversation_id,
161
  )
162
 
163
+ async def create_conversation_summary(self, data: CreateConversationSummarySchema):
 
 
164
  try:
 
165
  async with self.service() as service:
166
  return await service.create_conversation_summary(
167
+ user_id=data.user_id, conversation_id=data.conversation_id
168
  )
169
 
170
  except HTTPException as e:
src/models/_users.py CHANGED
@@ -6,9 +6,7 @@ from beanie import Document, Indexed
6
 
7
 
8
  class User(Document):
9
- first_name: str
10
- last_name: str
11
- hashed_password: str
12
  email: Annotated[str, Indexed(unique=True)]
13
  created_at: datetime = Field(default_factory=datetime.now)
14
  updated_at: datetime = Field(default_factory=datetime.now)
 
6
 
7
 
8
  class User(Document):
9
+ name: str
 
 
10
  email: Annotated[str, Indexed(unique=True)]
11
  created_at: datetime = Field(default_factory=datetime.now)
12
  updated_at: datetime = Field(default_factory=datetime.now)
src/schemas/__init__.py CHANGED
@@ -1,9 +1,7 @@
1
  from ._sessions import SessionCreateSchema
2
  from ._users import (
3
  UserSignInSchema,
4
- UserSignUpSchema,
5
  UserSignInResponse,
6
- UserSignUpResponse,
7
  )
8
  from ._conversations import (
9
  OfferSchema,
@@ -21,9 +19,7 @@ from ._files import InsertFileSchema
21
  __all__ = [
22
  "OfferSchema",
23
  "UserSignInSchema",
24
- "UserSignUpSchema",
25
  "UserSignInResponse",
26
- "UserSignUpResponse",
27
  "SessionCreateSchema",
28
  "CreateConversationSchema",
29
  "CreateConversationSummarySchema",
 
1
  from ._sessions import SessionCreateSchema
2
  from ._users import (
3
  UserSignInSchema,
 
4
  UserSignInResponse,
 
5
  )
6
  from ._conversations import (
7
  OfferSchema,
 
19
  __all__ = [
20
  "OfferSchema",
21
  "UserSignInSchema",
 
22
  "UserSignInResponse",
 
23
  "SessionCreateSchema",
24
  "CreateConversationSchema",
25
  "CreateConversationSummarySchema",
src/schemas/_conversations.py CHANGED
@@ -8,15 +8,18 @@ class OfferSchema(BaseModel):
8
 
9
 
10
  class CreateConversationSchema(BaseModel):
 
11
  modality: str = Query(..., regex="^(text|voice)$")
12
 
13
 
14
  class CreateWebrtcConnectionSchema(BaseModel):
 
15
  conversation_id: str = Path(...)
16
  offer: OfferSchema = Body(...)
17
 
18
 
19
  class CreateConversationSummarySchema(BaseModel):
 
20
  conversation_id: str = Path(...)
21
 
22
 
 
8
 
9
 
10
  class CreateConversationSchema(BaseModel):
11
+ user_id: str = Query(...)
12
  modality: str = Query(..., regex="^(text|voice)$")
13
 
14
 
15
  class CreateWebrtcConnectionSchema(BaseModel):
16
+ user_id: str = Query(...)
17
  conversation_id: str = Path(...)
18
  offer: OfferSchema = Body(...)
19
 
20
 
21
  class CreateConversationSummarySchema(BaseModel):
22
+ user_id: str = Query(...)
23
  conversation_id: str = Path(...)
24
 
25
 
src/schemas/_users.py CHANGED
@@ -20,21 +20,10 @@ class Validators:
20
  return password
21
 
22
 
23
- class UserSignUpSchema(BaseModel):
24
- first_name: str
25
- last_name: str
26
- email: Annotated[str, AfterValidator(Validators.validate_email)]
27
- password: Annotated[str, AfterValidator(Validators.validate_password)]
28
-
29
-
30
  class UserSignInSchema(BaseModel):
 
31
  email: Annotated[str, AfterValidator(Validators.validate_email)]
32
- password: Annotated[str, AfterValidator(Validators.validate_password)]
33
 
34
 
35
  class UserSignInResponse(BaseModel):
36
- token: str
37
-
38
-
39
- class UserSignUpResponse(BaseModel):
40
  user_id: str
 
20
  return password
21
 
22
 
 
 
 
 
 
 
 
23
  class UserSignInSchema(BaseModel):
24
+ name: str
25
  email: Annotated[str, AfterValidator(Validators.validate_email)]
 
26
 
27
 
28
  class UserSignInResponse(BaseModel):
 
 
 
 
29
  user_id: str
src/services/_auth_service.py CHANGED
@@ -2,7 +2,10 @@ from fastapi import HTTPException
2
  from datetime import datetime, timedelta
3
 
4
  from src.utils import JWTUtil, BcryptUtil
5
- from src.schemas import UserSignInSchema, UserSignUpSchema, SessionCreateSchema
 
 
 
6
 
7
  from ._user_service import UserService
8
  from ._session_service import SessionService
@@ -14,14 +17,21 @@ class AuthService:
14
  self._user_service = UserService()
15
  self._session_service = SessionService()
16
 
17
- async def sign_up(self, user: UserSignUpSchema):
18
  existing_user = await self._user_service.list_users(
19
  filter_by={"email": user.email}
20
  )
21
- if existing_user:
22
- raise HTTPException(409, "User already exists")
 
 
 
 
 
23
 
24
- return await self._user_service.create_user(user)
 
 
25
 
26
  async def sign_in(self, user: UserSignInSchema, device_ipv4_address: str):
27
  existing_user = await self._user_service.list_users(
 
2
  from datetime import datetime, timedelta
3
 
4
  from src.utils import JWTUtil, BcryptUtil
5
+ from src.schemas import (
6
+ UserSignInSchema,
7
+ SessionCreateSchema,
8
+ )
9
 
10
  from ._user_service import UserService
11
  from ._session_service import SessionService
 
17
  self._user_service = UserService()
18
  self._session_service = SessionService()
19
 
20
+ async def sign_in(self, user: UserSignInSchema):
21
  existing_user = await self._user_service.list_users(
22
  filter_by={"email": user.email}
23
  )
24
+ if not existing_user:
25
+ user_object = await self._user_service.create_user(
26
+ UserSignInSchema(name=user.name, email=user.email)
27
+ )
28
+ return {
29
+ "user_id": str(user_object.id),
30
+ }
31
 
32
+ return {
33
+ "user_id": str(existing_user[0].id),
34
+ }
35
 
36
  async def sign_in(self, user: UserSignInSchema, device_ipv4_address: str):
37
  existing_user = await self._user_service.list_users(
src/services/_meeting_service.py CHANGED
@@ -105,8 +105,7 @@ class MeetingService:
105
  locale: str = "en-us",
106
  ):
107
  user_object: User = await self.user_repository.get_by_id(user_id)
108
- user_first_name = user_object.first_name
109
- user_last_name = user_object.last_name
110
  user_email = user_object.email
111
 
112
  pytz_timezone = pytz.timezone(timezone)
@@ -133,8 +132,7 @@ class MeetingService:
133
  }
134
  data = {
135
  "slug": salesperson_meeting_id,
136
- "firstName": user_first_name,
137
- "lastName": user_last_name,
138
  "email": user_email,
139
  "startTime": preferred_start_time,
140
  "duration": duration_ms,
 
105
  locale: str = "en-us",
106
  ):
107
  user_object: User = await self.user_repository.get_by_id(user_id)
108
+ user_name = user_object.name
 
109
  user_email = user_object.email
110
 
111
  pytz_timezone = pytz.timezone(timezone)
 
132
  }
133
  data = {
134
  "slug": salesperson_meeting_id,
135
+ "firstName": user_name,
 
136
  "email": user_email,
137
  "startTime": preferred_start_time,
138
  "duration": duration_ms,
src/services/_user_service.py CHANGED
@@ -2,7 +2,7 @@ from typing import Dict
2
 
3
  from src.models import User
4
  from src.utils import BcryptUtil
5
- from src.schemas import UserSignUpSchema
6
  from src.repositories import UserRepository
7
 
8
 
@@ -10,16 +10,8 @@ class UserService:
10
  def __init__(self):
11
  self.user_repository = UserRepository()
12
 
13
- async def create_user(self, user: UserSignUpSchema):
14
- hashed_password = BcryptUtil.hash_password(user.password)
15
-
16
- user = User(
17
- first_name=user.first_name,
18
- last_name=user.last_name,
19
- email=user.email,
20
- hashed_password=hashed_password,
21
- )
22
-
23
  return await self.user_repository.insert_one(user)
24
 
25
  async def get_user(self, user_id):
 
2
 
3
  from src.models import User
4
  from src.utils import BcryptUtil
5
+ from src.schemas import UserSignInSchema
6
  from src.repositories import UserRepository
7
 
8
 
 
10
  def __init__(self):
11
  self.user_repository = UserRepository()
12
 
13
+ async def create_user(self, user: UserSignInSchema):
14
+ user = User(name=user.name, email=user.email)
 
 
 
 
 
 
 
 
15
  return await self.user_repository.insert_one(user)
16
 
17
  async def get_user(self, user_id):