-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
130 lines (106 loc) · 4.98 KB
/
Copy pathmain.py
File metadata and controls
130 lines (106 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from datetime import timedelta
from typing import List
import jwt
import models
import schemas
import auth
from database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI(title="Polyglot Notes API (Python)")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allows all origins (change to "http://127.0.0.1:5500" in production)
allow_credentials=True,
allow_methods=["*"], # Allows all methods (GET, POST, OPTIONS, etc.)
allow_headers=["*"], # Allows all headers (Authorization, Content-Type, etc.)
)
oauth_scheme = OAuth2PasswordBearer(tokenUrl="login")
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def get_current_user(token: str = Depends(oauth_scheme), db: Session = Depends(get_db)) -> models.User:
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, auth.SECRET_KEY, algorithms=[auth.ALGORITH])
username: str = payload.get("sub")
if username is None:
raise credentials_exception
except jwt.PyJWTError:
raise credentials_exception
user = db.query(models.User).filter(models.User.username == username).first()
if user is None:
raise credentials_exception
return user
# AUTH ENDPOINTS
# Register
@app.post("/register", response_model=schemas.UserResponse, status_code=status.HTTP_201_CREATED)
def register_user(user_in: schemas.UserCreate, db: Session = Depends(get_db)):
existing_user = db.query(models.User).filter(models.User.username == user_in.username).first()
if existing_user:
raise HTTPException(status_code=400, detail="Username is already registered")
hashed_pass = auth.hash_password(user_in.password)
db_user = models.User(username=user_in.username, hashed_password=hashed_pass)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
# Login
@app.post("/login", response_model=schemas.Token)
def login(user_in: schemas.UserCreate, db: Session = Depends(get_db)):
user = db.query(models.User).filter(models.User.username == user_in.username).first()
if not user or not auth.verify_password(user_in.password, user.hashed_password):
raise HTTPException(status_code=400, detail="Incorrect username or password")
access_token = auth.create_access_token(data={"sub": user.username})
return {"access_token": access_token, "token_type": "bearer"}
# ENDPOINTS
# CREATE
@app.post("/notes", response_model=schemas.NoteResponse, status_code=status.HTTP_201_CREATED)
def create_note(note: schemas.NoteCreate, current_user: models.User = Depends(get_current_user) ,db: Session = Depends(get_db)):
db_note = models.Note(title=note.title, content=note.content, user_id=current_user.id)
db.add(db_note)
db.commit()
db.refresh(db_note)
return db_note
# READ ALL
@app.get("/notes", response_model=List[schemas.NoteResponse])
def read_all_notes(current_user: models.User = Depends(get_current_user), db: Session = Depends(get_db)):
return db.query(models.Note).filter(models.Note.user_id == current_user.id).all()
# READ ONE
@app.get("/notes/{note_id}", response_model=schemas.NoteResponse)
def read_single_note(note_id: int, current_user: models.User = Depends(get_current_user) ,db: Session = Depends(get_db)):
db_note = db.query(models.Note).filter(models.Note.id == note_id, models.Note.user_id == current_user.id).first()
if not db_note:
raise HTTPException(status_code=404, detail="Note not found or unauthorized")
return db_note
# UPDATE
@app.patch("/notes/{note_id}", response_model=schemas.NoteResponse)
def update_note(note_id: int, note_update: schemas.NoteUpdate, current_user: models.User = Depends(get_current_user), db: Session = Depends(get_db)):
db_note = db.query(models.Note).filter(models.Note.id == note_id, models.Note.user_id == current_user.id).first()
if not db_note:
raise HTTPException(status_code=404, detail="Note not found or unauthorized")
update_data = note_update.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(db_note, key, value)
db.commit()
db.refresh(db_note)
return db_note
# DELETE
@app.delete("/notes/{note_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_note(note_id: int, current_user: models.User = Depends(get_current_user), db: Session = Depends(get_db)):
db_note = db.query(models.Note).filter(models.Note.id == note_id, models.Note.user_id == current_user.id).first()
if not db_note:
raise HTTPException(status_code=404, detail="Note not found or unauthorized")
db.delete(db_note)
db.commit()
return