Skip to content
Snippets Groups Projects
Commit 802efc48 authored by duyanhehe's avatar duyanhehe
Browse files

CRUD for shop

parent 95876917
No related branches found
No related tags found
No related merge requests found
......@@ -4,4 +4,5 @@ DATABASE_PASSWORD="your_mysql_password"
DATABASE_HOST="127.0.0.1"
DATABASE_NAME="shopping"
SECRET_KEY="your_secret_key"
ALGORITHM=HS256
DEBUG=True
......@@ -4,7 +4,7 @@ import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from fastapi import FastAPI
from backend.routes import auth
from backend.routes import auth, shop
from backend.database import init_db
from core.config import settings
......@@ -15,6 +15,7 @@ init_db()
# Include API routes
app.include_router(auth.router, prefix="/auth", tags=["auth"])
app.include_router(shop.router, prefix="/shops", tags=["shops"])
@app.get("/")
......
from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from backend.models.models import User
from backend.schemas.user import UserCreate, UserLogin
from backend.database import get_session
from sqlmodel import Session, select
from backend.utils.hashing import hash_password, verify_password
from app.core.security import decode_token, create_access_token
router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login")
def get_current_user(
token: str = Depends(oauth2_scheme), session: Session = Depends(get_session)
) -> User:
user_id = decode_token(token)
user = session.get(User, user_id)
if not user:
raise HTTPException(
status_code=401, detail="Invalid authentication credentials"
)
return user
@router.post("/signup")
def signup(user_data: UserCreate, session: Session = Depends(get_session)):
......@@ -29,9 +45,28 @@ def signup(user_data: UserCreate, session: Session = Depends(get_session)):
return {"message": "User created successfully"}
# @router.post("/login")
# def login(user_data: UserLogin, session: Session = Depends(get_session)):
# user = session.exec(select(User).where(User.email == user_data.email)).first()
# if not user or not verify_password(user_data.password, user.password):
# raise HTTPException(status_code=401, detail="Invalid credentials")
# access_token = create_access_token(data={"sub": str(user.id)})
# return {
# "message": "Login successful",
# "user_id": user.id,
# "access_token": access_token,
# }
@router.post("/login")
def login(user_data: UserLogin, session: Session = Depends(get_session)):
user = session.exec(select(User).where(User.email == user_data.email)).first()
if not user or not verify_password(user_data.password, user.password):
def login(
form_data: OAuth2PasswordRequestForm = Depends(),
session: Session = Depends(get_session),
):
user = session.exec(select(User).where(User.email == form_data.username)).first()
if not user or not verify_password(form_data.password, user.password):
raise HTTPException(status_code=401, detail="Invalid credentials")
return {"message": "Login successful", "user_id": user.id}
access_token = create_access_token(data={"sub": str(user.id)})
return {"access_token": access_token, "token_type": "bearer"}
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form
from sqlmodel import Session
from backend.models.models import Shop, User
from backend.schemas.shop import ShopCreate, ShopRead
from backend.database import get_session
from backend.routes.auth import get_current_user
import shutil
import os
router = APIRouter()
static_dir = os.path.join("app", "static")
os.makedirs(static_dir, exist_ok=True)
@router.post("/", response_model=ShopRead)
def create_shop(
name: str = Form(...),
description: str = Form(None),
file: UploadFile = File(None),
session: Session = Depends(get_session),
current_user: User = Depends(get_current_user),
):
shop = ShopCreate(name=name, description=description, owner_id=current_user.id)
db_shop = Shop.from_orm(shop)
if file and file.filename:
# Save the image to the static directory
file_location = os.path.join(static_dir, f"{db_shop.name}_{file.filename}")
with open(file_location, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
db_shop.image_url = file_location
else:
# Set a default image URL if no file is uploaded
db_shop.image_url = os.path.join(static_dir, "default_shop_image.png")
session.add(db_shop)
session.commit()
session.refresh(db_shop)
if file:
# Delete the image file after session commit
os.remove(file_location)
return db_shop
@router.get("/{shop_id}", response_model=ShopRead)
def read_shop(shop_id: int, session: Session = Depends(get_session)):
shop = session.get(Shop, shop_id)
if not shop:
raise HTTPException(status_code=404, detail="Shop not found")
return shop
@router.put("/{shop_id}", response_model=ShopRead)
def update_shop(
shop_id: int,
name: str = Form(None),
description: str = Form(None),
file: UploadFile = File(None),
session: Session = Depends(get_session),
):
db_shop = session.get(Shop, shop_id)
if not db_shop:
raise HTTPException(status_code=404, detail="Shop not found")
if name:
db_shop.name = name
if description:
db_shop.description = description
if file and file.filename:
# Save the image to the static directory
file_location = os.path.join(static_dir, f"{db_shop.name}_{file.filename}")
with open(file_location, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
db_shop.image_url = file_location
else:
# Set a default image URL if no file is uploaded
db_shop.image_url = os.path.join(static_dir, "default_shop_image.png")
session.add(db_shop)
session.commit()
session.refresh(db_shop)
if file:
# Delete the image file after session commit
os.remove(file_location)
return db_shop
@router.delete("/{shop_id}")
def delete_shop(shop_id: int, session: Session = Depends(get_session)):
shop = session.get(Shop, shop_id)
if not shop:
raise HTTPException(status_code=404, detail="Shop not found")
session.delete(shop)
session.commit()
return {"message": "Shop deleted successfully"}
from pydantic import BaseModel
from typing import Optional
class ShopBase(BaseModel):
name: str
description: Optional[str] = None
class ShopCreate(ShopBase):
owner_id: int
class ShopRead(ShopBase):
id: int
owner_id: int
image_url: Optional[str] = None
class Config:
orm_mode = True
class ShopUpdate(ShopBase):
name: Optional[str] = None
description: Optional[str] = None
......@@ -9,6 +9,7 @@ class Settings(BaseSettings):
database_host: str
database_name: str
secret_key: str
algorithm: str
debug: bool = True
@property
......
import jwt
from datetime import datetime, timedelta
from fastapi import HTTPException
from jwt import PyJWTError
from core.config import settings
SECRET_KEY = settings.secret_key
ALGORITHM = settings.algorithm
ACCESS_TOKEN_EXPIRE_MINUTES = 30
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
def decode_token(token: str) -> int:
try:
token = token.replace("Bearer ", "") # Remove "Bearer " prefix
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id: int = payload.get("sub")
if user_id is None:
raise HTTPException(
status_code=401, detail="Invalid authentication credentials"
)
return user_id
except PyJWTError:
raise HTTPException(
status_code=401, detail="Invalid authentication credentials"
)
app/static/default_shop_image.png

16.4 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment