Ajit Panday commited on
Commit
dff9fde
·
2 Parent(s): 96c5d66 ba20dd5

Fix circular imports by reorganizing module structure

Browse files
Files changed (4) hide show
  1. .env +2 -1
  2. app/__init__.py +4 -1
  3. app/auth.py +13 -13
  4. main.py +26 -25
.env CHANGED
@@ -1,5 +1,6 @@
1
  # Database Configuration
2
- DATABASE_URL=mysql+pymysql://user:password@localhost:3306/vbot
 
3
 
4
  # Security
5
  JWT_SECRET=FUx5idT6meiSYB8KJ0giFYYOKGIm5MY5x1LV9IyyfTg
 
1
  # Database Configuration
2
+ DATABASE_URL=mysql+pymysql://root:iDRQAHDfVGyScnQBOMMrLjqmmSxBbNLw@mainline.proxy.rlwy.net:29819/railway
3
+
4
 
5
  # Security
6
  JWT_SECRET=FUx5idT6meiSYB8KJ0giFYYOKGIm5MY5x1LV9IyyfTg
app/__init__.py CHANGED
@@ -1,2 +1,5 @@
1
  from . import models
2
- from . import auth
 
 
 
 
1
  from . import models
2
+ from . import auth
3
+
4
+ # This file can be empty or just contain version info
5
+ __version__ = "1.0.0"
app/auth.py CHANGED
@@ -6,12 +6,12 @@ from jose import JWTError, jwt
6
  from passlib.context import CryptContext
7
  from typing import Optional
8
  import secrets
9
- from . import models
10
  from .settings import (
11
  JWT_SECRET, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES,
12
  ADMIN_USERNAME, ADMIN_PASSWORD
13
  )
14
  from .database import get_db
 
15
 
16
  # Password hashing
17
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@@ -22,12 +22,12 @@ api_key_header = APIKeyHeader(name="api-key")
22
 
23
  router = APIRouter()
24
 
25
- def verify_api_key(api_key: str = Security(api_key_header)) -> models.Customer:
26
  """Verify API key and return customer"""
27
  db = next(get_db())
28
- customer = db.query(models.Customer).filter(
29
- models.Customer.api_key == api_key,
30
- models.Customer.is_active == True
31
  ).first()
32
 
33
  if not customer:
@@ -93,14 +93,14 @@ async def login(form_data: OAuth2PasswordRequestForm = Depends()):
93
  @router.post("/customers/", response_model=dict)
94
  async def create_customer(
95
  customer_data: dict,
96
- db: Session = Depends(models.get_db),
97
  current_admin: str = Depends(get_current_admin)
98
  ):
99
  # Generate API key
100
  api_key = secrets.token_urlsafe(32)
101
 
102
  # Create new customer
103
- customer = models.Customer(
104
  name=customer_data["name"],
105
  company_name=customer_data["company_name"],
106
  email=customer_data["email"],
@@ -140,19 +140,19 @@ async def create_customer(
140
 
141
  @router.get("/customers/", response_model=list)
142
  async def list_customers(
143
- db: Session = Depends(models.get_db),
144
  current_admin: str = Depends(get_current_admin)
145
  ):
146
- customers = db.query(models.Customer).all()
147
  return customers
148
 
149
  @router.get("/customers/{customer_id}", response_model=dict)
150
  async def get_customer(
151
  customer_id: int,
152
- db: Session = Depends(models.get_db),
153
  current_admin: str = Depends(get_current_admin)
154
  ):
155
- customer = db.query(models.Customer).filter(models.Customer.id == customer_id).first()
156
  if not customer:
157
  raise HTTPException(status_code=404, detail="Customer not found")
158
  return customer
@@ -160,10 +160,10 @@ async def get_customer(
160
  @router.delete("/customers/{customer_id}")
161
  async def delete_customer(
162
  customer_id: int,
163
- db: Session = Depends(models.get_db),
164
  current_admin: str = Depends(get_current_admin)
165
  ):
166
- customer = db.query(models.Customer).filter(models.Customer.id == customer_id).first()
167
  if not customer:
168
  raise HTTPException(status_code=404, detail="Customer not found")
169
  db.delete(customer)
 
6
  from passlib.context import CryptContext
7
  from typing import Optional
8
  import secrets
 
9
  from .settings import (
10
  JWT_SECRET, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES,
11
  ADMIN_USERNAME, ADMIN_PASSWORD
12
  )
13
  from .database import get_db
14
+ from .models import Customer
15
 
16
  # Password hashing
17
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
 
22
 
23
  router = APIRouter()
24
 
25
+ def verify_api_key(api_key: str = Security(api_key_header)) -> Customer:
26
  """Verify API key and return customer"""
27
  db = next(get_db())
28
+ customer = db.query(Customer).filter(
29
+ Customer.api_key == api_key,
30
+ Customer.is_active == True
31
  ).first()
32
 
33
  if not customer:
 
93
  @router.post("/customers/", response_model=dict)
94
  async def create_customer(
95
  customer_data: dict,
96
+ db: Session = Depends(Customer.get_db),
97
  current_admin: str = Depends(get_current_admin)
98
  ):
99
  # Generate API key
100
  api_key = secrets.token_urlsafe(32)
101
 
102
  # Create new customer
103
+ customer = Customer(
104
  name=customer_data["name"],
105
  company_name=customer_data["company_name"],
106
  email=customer_data["email"],
 
140
 
141
  @router.get("/customers/", response_model=list)
142
  async def list_customers(
143
+ db: Session = Depends(Customer.get_db),
144
  current_admin: str = Depends(get_current_admin)
145
  ):
146
+ customers = db.query(Customer).all()
147
  return customers
148
 
149
  @router.get("/customers/{customer_id}", response_model=dict)
150
  async def get_customer(
151
  customer_id: int,
152
+ db: Session = Depends(Customer.get_db),
153
  current_admin: str = Depends(get_current_admin)
154
  ):
155
+ customer = db.query(Customer).filter(Customer.id == customer_id).first()
156
  if not customer:
157
  raise HTTPException(status_code=404, detail="Customer not found")
158
  return customer
 
160
  @router.delete("/customers/{customer_id}")
161
  async def delete_customer(
162
  customer_id: int,
163
+ db: Session = Depends(Customer.get_db),
164
  current_admin: str = Depends(get_current_admin)
165
  ):
166
+ customer = db.query(Customer).filter(Customer.id == customer_id).first()
167
  if not customer:
168
  raise HTTPException(status_code=404, detail="Customer not found")
169
  db.delete(customer)
main.py CHANGED
@@ -10,11 +10,12 @@ import tempfile
10
  from transformers import pipeline
11
  from sqlalchemy.orm import Session
12
  import asyncio
13
- from app import models, auth
14
  from app.settings import (
15
  ADMIN_USERNAME, ADMIN_PASSWORD, WHISPER_MODEL,
16
  SUMMARIZER_MODEL, SENTIMENT_MODEL
17
  )
 
 
18
  from sqlalchemy.orm import sessionmaker
19
  from fastapi.security import OAuth2PasswordRequestForm
20
 
@@ -45,10 +46,10 @@ sentiment_analyzer = pipeline("sentiment-analysis", model=SENTIMENT_MODEL)
45
  # Include auth router
46
  app.include_router(auth.router, prefix="/api/v1", tags=["auth"])
47
 
48
- async def get_customer_by_api_key(api_key: str = Header(...), db: Session = Depends(models.get_db)):
49
- customer = db.query(models.Customer).filter(
50
- models.Customer.api_key == api_key,
51
- models.Customer.is_active == True
52
  ).first()
53
  if not customer:
54
  raise HTTPException(
@@ -62,8 +63,8 @@ async def process_call(
62
  file: UploadFile = File(...),
63
  caller_number: str = Form(...),
64
  called_number: str = Form(...),
65
- customer: models.Customer = Depends(auth.verify_api_key),
66
- db: Session = Depends(models.get_db)
67
  ):
68
  """
69
  Process a voice call recording file.
@@ -101,7 +102,7 @@ async def process_call(
101
 
102
  try:
103
  # Create call record
104
- call_record = models.CallRecord(
105
  id=process_id,
106
  customer_id=customer.id,
107
  caller_number=caller_number,
@@ -135,13 +136,13 @@ async def process_call(
135
  @app.get("/api/v1/calls/{customer_id}")
136
  async def list_calls(
137
  customer_id: int,
138
- db: Session = Depends(models.get_db),
139
- current_admin: str = Depends(auth.get_current_admin)
140
  ):
141
  """
142
  List all calls for a specific customer.
143
  """
144
- customer = db.query(models.Customer).filter(models.Customer.id == customer_id).first()
145
  if not customer:
146
  raise HTTPException(status_code=404, detail="Customer not found")
147
 
@@ -157,8 +158,8 @@ async def list_calls(
157
  customer_db = CustomerSession()
158
 
159
  try:
160
- calls = customer_db.query(models.CallRecord).filter(
161
- models.CallRecord.customer_id == customer_id
162
  ).all()
163
  return calls
164
  finally:
@@ -167,23 +168,23 @@ async def list_calls(
167
  @app.post("/api/v1/token")
168
  async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
169
  """Admin login endpoint"""
170
- if form_data.username != settings.ADMIN_USERNAME or form_data.password != settings.ADMIN_PASSWORD:
171
  raise HTTPException(
172
  status_code=status.HTTP_401_UNAUTHORIZED,
173
  detail="Incorrect username or password",
174
  headers={"WWW-Authenticate": "Bearer"},
175
  )
176
- access_token = auth.create_access_token(data={"sub": form_data.username})
177
  return {"access_token": access_token, "token_type": "bearer"}
178
 
179
- @app.post("/api/v1/customers/", response_model=models.Customer)
180
  async def create_customer(
181
- customer: models.CustomerCreate,
182
- db: Session = Depends(models.get_db),
183
- current_admin: str = Depends(auth.get_current_admin)
184
  ):
185
  """Create new customer"""
186
- db_customer = models.Customer(
187
  name=customer.name,
188
  company_name=customer.company_name,
189
  email=customer.email,
@@ -194,19 +195,19 @@ async def create_customer(
194
  db.refresh(db_customer)
195
  return db_customer
196
 
197
- @app.get("/api/v1/calls", response_model=List[models.CallRecord])
198
  async def get_calls(
199
  start_date: Optional[str] = None,
200
  end_date: Optional[str] = None,
201
- customer: models.Customer = Depends(auth.verify_api_key)
202
  ):
203
  """Get customer's call records"""
204
  return customer.get_call_records(start_date, end_date)
205
 
206
- @app.get("/api/v1/calls/{call_id}", response_model=models.CallRecord)
207
  async def get_call(
208
  call_id: str,
209
- customer: models.Customer = Depends(auth.verify_api_key)
210
  ):
211
  """Get specific call details"""
212
  return customer.get_call_details(call_id)
@@ -214,7 +215,7 @@ async def get_call(
214
  @app.get("/api/v1/calls/search")
215
  async def search_calls(
216
  query: dict,
217
- customer: models.Customer = Depends(auth.verify_api_key)
218
  ):
219
  """Search calls"""
220
  return customer.search_calls(query)
 
10
  from transformers import pipeline
11
  from sqlalchemy.orm import Session
12
  import asyncio
 
13
  from app.settings import (
14
  ADMIN_USERNAME, ADMIN_PASSWORD, WHISPER_MODEL,
15
  SUMMARIZER_MODEL, SENTIMENT_MODEL
16
  )
17
+ from app.models import Customer, CallRecord
18
+ from app.auth import verify_api_key, get_current_admin, create_access_token
19
  from sqlalchemy.orm import sessionmaker
20
  from fastapi.security import OAuth2PasswordRequestForm
21
 
 
46
  # Include auth router
47
  app.include_router(auth.router, prefix="/api/v1", tags=["auth"])
48
 
49
+ async def get_customer_by_api_key(api_key: str = Header(...), db: Session = Depends(Customer.get_db)):
50
+ customer = db.query(Customer).filter(
51
+ Customer.api_key == api_key,
52
+ Customer.is_active == True
53
  ).first()
54
  if not customer:
55
  raise HTTPException(
 
63
  file: UploadFile = File(...),
64
  caller_number: str = Form(...),
65
  called_number: str = Form(...),
66
+ customer: Customer = Depends(verify_api_key),
67
+ db: Session = Depends(Customer.get_db)
68
  ):
69
  """
70
  Process a voice call recording file.
 
102
 
103
  try:
104
  # Create call record
105
+ call_record = CallRecord(
106
  id=process_id,
107
  customer_id=customer.id,
108
  caller_number=caller_number,
 
136
  @app.get("/api/v1/calls/{customer_id}")
137
  async def list_calls(
138
  customer_id: int,
139
+ db: Session = Depends(Customer.get_db),
140
+ current_admin: str = Depends(get_current_admin)
141
  ):
142
  """
143
  List all calls for a specific customer.
144
  """
145
+ customer = db.query(Customer).filter(Customer.id == customer_id).first()
146
  if not customer:
147
  raise HTTPException(status_code=404, detail="Customer not found")
148
 
 
158
  customer_db = CustomerSession()
159
 
160
  try:
161
+ calls = customer_db.query(CallRecord).filter(
162
+ CallRecord.customer_id == customer_id
163
  ).all()
164
  return calls
165
  finally:
 
168
  @app.post("/api/v1/token")
169
  async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
170
  """Admin login endpoint"""
171
+ if form_data.username != ADMIN_USERNAME or form_data.password != ADMIN_PASSWORD:
172
  raise HTTPException(
173
  status_code=status.HTTP_401_UNAUTHORIZED,
174
  detail="Incorrect username or password",
175
  headers={"WWW-Authenticate": "Bearer"},
176
  )
177
+ access_token = create_access_token(data={"sub": form_data.username})
178
  return {"access_token": access_token, "token_type": "bearer"}
179
 
180
+ @app.post("/api/v1/customers/", response_model=Customer)
181
  async def create_customer(
182
+ customer: Customer,
183
+ db: Session = Depends(Customer.get_db),
184
+ current_admin: str = Depends(get_current_admin)
185
  ):
186
  """Create new customer"""
187
+ db_customer = Customer(
188
  name=customer.name,
189
  company_name=customer.company_name,
190
  email=customer.email,
 
195
  db.refresh(db_customer)
196
  return db_customer
197
 
198
+ @app.get("/api/v1/calls", response_model=List[CallRecord])
199
  async def get_calls(
200
  start_date: Optional[str] = None,
201
  end_date: Optional[str] = None,
202
+ customer: Customer = Depends(verify_api_key)
203
  ):
204
  """Get customer's call records"""
205
  return customer.get_call_records(start_date, end_date)
206
 
207
+ @app.get("/api/v1/calls/{call_id}", response_model=CallRecord)
208
  async def get_call(
209
  call_id: str,
210
+ customer: Customer = Depends(verify_api_key)
211
  ):
212
  """Get specific call details"""
213
  return customer.get_call_details(call_id)
 
215
  @app.get("/api/v1/calls/search")
216
  async def search_calls(
217
  query: dict,
218
+ customer: Customer = Depends(verify_api_key)
219
  ):
220
  """Search calls"""
221
  return customer.search_calls(query)