Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added backend/app/db/__init__.py
Empty file.
28 changes: 28 additions & 0 deletions backend/app/db/crud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from sqlalchemy.orm import Session

from . import models, schemas

# We declare functions that the endpoints in app/routers/*.py
# use to interact with the tables in the database


def create_user(db: Session, user: schemas.UserCreate):
db_user = models.User(
email=user.email,
first_name= "",
last_name="",
location="",
profile_picture="",
)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user


def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.user_id == user_id).first()


def get_user_by_email(db: Session, email: str):
return db.query(models.User).filter(models.User.email == email).first()
11 changes: 11 additions & 0 deletions backend/app/db/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# TODO: Parameterize this
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://user:password@localhost:3306/db"

engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_pre_ping=True, echo=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()
17 changes: 17 additions & 0 deletions backend/app/db/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from sqlalchemy import Boolean, Column, Integer, VARCHAR, BLOB

from .database import Base

# Creating the User class as a subclass of Base
# will let us create the users table in
# app/routers/users.py
class User(Base):
__tablename__ = "users"

user_id = Column(Integer, primary_key=True, index=True)
first_name = Column(VARCHAR(50))
last_name = Column(VARCHAR(50))
email = Column(VARCHAR(50), unique=True, index=True)
location = Column(VARCHAR(50))
profile_picture = Column(BLOB)
recipe_driven = Column(Boolean, default=True)
21 changes: 21 additions & 0 deletions backend/app/db/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from pydantic import BaseModel
from typing import Union

# This defines the type Schema for classes like User
# For the database schema/models, see ./models.py
class UserBase(BaseModel):
email: str

class UserCreate(UserBase):
password: str

class User(UserBase):
user_id: int
first_name: Union[str, None]
last_name: Union[str, None]
location: Union[str, None]
profile_picture: Union[str, None]
recipe_driven: bool

class Config:
orm_mode = True
8 changes: 8 additions & 0 deletions backend/app/deps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from app.db.database import SessionLocal

def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
3 changes: 2 additions & 1 deletion backend/app/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from fastapi import FastAPI
from .routers import users

app = FastAPI()

app.include_router(users.router)

@app.get("/")
async def root():
Expand Down
Empty file added backend/app/routers/__init__.py
Empty file.
34 changes: 34 additions & 0 deletions backend/app/routers/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from fastapi import APIRouter, Depends, HTTPException

from sqlalchemy.orm import Session

from ..db import crud, models, schemas, database
from ..deps import get_db

# This line creates the tables based on the subclasses of
# of Base we created in app/db/models.py
models.Base.metadata.create_all(bind=database.engine)

# We can delegate all calls to the /users route
# to be handled by this router. We can give the
# APIRouter arguments for the prefix /users for
# brevity and the users tag for the local docs info
router = APIRouter(
prefix="/users",
tags=["users"]
)


@router.post("/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)

@router.get("/{user_id}", response_model=schemas.User)
async def get_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
5 changes: 4 additions & 1 deletion backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
fastapi
uvicorn
uvicorn
sqlalchemy
pymysql
pymysql[rsa]
4 changes: 2 additions & 2 deletions database/tables/users.sql
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ CREATE TABLE `users_table` (
`user_id` INT NOT NULL auto_increment,
`first_name` VARCHAR(50),
`last_name` VARCHAR(50),
`email` VARCHAR(50),
`email` VARCHAR(50) NOT NULL,
`location` VARCHAR(50),
`profile_picture` MEDIUMBLOB,
`recipe_driven` BOOLEAN,
`recipe_driven` BOOLEAN DEFAULT 1,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Expand Down