From d5ceeb9d5cbe28660b712c4cd2cfe38fbb41c2b5 Mon Sep 17 00:00:00 2001
From: Navin Chandra <nc01009@surrey.ac.uk>
Date: Fri, 19 Apr 2024 15:07:14 +0530
Subject: [PATCH] API code

---
 README.md                       |   4 +++
 __init__.py                     |   0
 __pycache__/main.cpython-39.pyc | Bin 0 -> 2001 bytes
 crud.py                         |  36 ++++++++++++++++++++++
 database.py                     |  13 ++++++++
 main.py                         |  53 ++++++++++++++++++++++++++++++++
 models.py                       |  26 ++++++++++++++++
 schemas.py                      |  37 ++++++++++++++++++++++
 sql_app.db                      |   0
 9 files changed, 169 insertions(+)
 create mode 100644 __init__.py
 create mode 100644 __pycache__/main.cpython-39.pyc
 create mode 100644 crud.py
 create mode 100644 database.py
 create mode 100644 main.py
 create mode 100644 models.py
 create mode 100644 schemas.py
 create mode 100644 sql_app.db

diff --git a/README.md b/README.md
index f1630c9..e57a6e9 100644
--- a/README.md
+++ b/README.md
@@ -91,3 +91,7 @@ For open source projects, say how it is licensed.
 
 ## Project status
 If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
+
+
+## run the project
+uvicorn main:app --reload
\ No newline at end of file
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/__pycache__/main.cpython-39.pyc b/__pycache__/main.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f0f2a2fb2d661836ec6fda3ef3fd2071009e6eed
GIT binary patch
literal 2001
zcmb7F&2M8h5V!q4lP0fe`u(*VEfOL^Y7jRhgn->eT?thybpgqj=;hgMUw9wEeqm`z
zFLbY!IB?tp9Q!Z%iiEU(0TP#G#!1@J3M5?F8INb?{bqh+H*PlT1je6#L`VBRA;071
z_5dCE6sF#%ga{&NMsmt&&N#~*?oiaR%*{RSS=q__Jm5hd@-VOQn$@{kJzwApd4o47
zk>Rj8jE0M{A-qcpdv-y1OZXyqMfj3z4cj7=wc)a;T{21K(gi)DuwRj$sJ~`nK{Q@@
z7nHAp<r-M7qwOX^Ye3SRc{p+d{yY)AcEqA+S&vQYv2-ss+O;9_vRJWpTNcAA*lqs<
z!v<(}z;+E{u8R$8yK7@^S`^#=iDFA^TaO1~=a6)F-(ZcqjtQQ~kt~EZ!56WvK70Pm
zH1}V;c>eT<M2@PoEV|SLhf-@49pffyER3I*LT2EilM|W8y30&sX7gp4#F_DBahw(s
zeBD7>hy=eiAHX6BVWLvM2TMgR$T>M{PsrDVl5fa_{7QcVsi@DT4}fF9Ob@zD)xg7e
zNmgnM&&1%0s0eg_^?D~|E_+4%eOmOMl*u@kMWuT$<)D(uN$*&d<IzX`<Yh09(_(LQ
zYW!na^~IoxI1mt_K4mmyss-{{&>L&1bgxT!q@*5|g_eDrH)QMLnL^Kmq33Kk@aw{S
z3{&sHQjsB@&<PnbK`+@kn=sX>9KnPm+)MTog>x6rp%ED*=pR5z9#k~V(x0JDXB$sZ
z?!=jru{iB0d7SD>Dk-j*S<qEnjdec(F1Rmb1(r}B1f`Z>>3RyU4qw7F5pRER+PAS)
z8*LD%Sx6vqCGC0Fv3@p!3B<rEZEdH^B6_XDf^%9i)}k(LP^*0-K#eV;zfDKR%hEip
zrX|9%%m;qegK0~&0)j0On~({G5;^D2#5p8a44K}5Q?&^T$TpMOJQLk@Z%*wuxM$hA
zgVxlsZZ;3S3xPC#od9UH4Zmlt8O1-^>ZIZvm<?v~6#2iB`!4v;$(>Ux$e5@{6}zE#
zf~0yts@ehj^cSQw`U<G%6lK*pD#wLT%Wwjfw+V*x1T8tBMK_B?t)YZ{e#3>SU1#?W
z9LyMrXo!qpx@YTm6YQmx%ysW-8ritGz0VQyb<Gi8h8aiLsK62A1pGKtTo2*c!km-T
zy46vA8~*{C+=0F_vqFRZQK>9P?}MSXC3jT^WVnM<yvhIWAhiYlb4a#tY@~aAV?3+B
z3vb#t_UJ<db=^0QV0X}c$b%zzEaOqC5UxUamNFjc@3J_<SMhYORJp=3ayJ<(VHs8d
zTH<5FLlIZ;AckhZ7fs>+K<<7HdlTkxm+_R>XH|-`%sBCAWM3xZj!Io|7yF3UaeZv>
zu)T!Fffh1u2G4|X(xS4BZkvI-&!E=4j_b^!gCE9>Zl!N|!kccwkKwf&XYvz#ur)UP
i3T?0z+F~u{yI~m7ouExSUPQNoi1}~f>3kdcZTdIBuDIm@

literal 0
HcmV?d00001

diff --git a/crud.py b/crud.py
new file mode 100644
index 0000000..7f64109
--- /dev/null
+++ b/crud.py
@@ -0,0 +1,36 @@
+from sqlalchemy.orm import Session
+
+from . import models, schemas
+
+
+def get_user(db: Session, user_id: int):
+    return db.query(models.User).filter(models.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()
+
+
+def get_users(db: Session, skip: int = 0, limit: int = 100):
+    return db.query(models.User).offset(skip).limit(limit).all()
+
+
+def create_user(db: Session, user: schemas.UserCreate):
+    fake_hashed_password = user.password + "notreallyhashed"
+    db_user = models.User(email=user.email, hashed_password=fake_hashed_password)
+    db.add(db_user)
+    db.commit()
+    db.refresh(db_user)
+    return db_user
+
+
+def get_items(db: Session, skip: int = 0, limit: int = 100):
+    return db.query(models.Item).offset(skip).limit(limit).all()
+
+
+def create_user_item(db: Session, item: schemas.ItemCreate, user_id: int):
+    db_item = models.Item(**item.dict(), owner_id=user_id)
+    db.add(db_item)
+    db.commit()
+    db.refresh(db_item)
+    return db_item
\ No newline at end of file
diff --git a/database.py b/database.py
new file mode 100644
index 0000000..62838e6
--- /dev/null
+++ b/database.py
@@ -0,0 +1,13 @@
+from sqlalchemy import create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+
+SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
+# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
+
+engine = create_engine(
+    SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
+)
+SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
+
+Base = declarative_base()
\ No newline at end of file
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..8a2b9eb
--- /dev/null
+++ b/main.py
@@ -0,0 +1,53 @@
+from fastapi import Depends, FastAPI, HTTPException
+from sqlalchemy.orm import Session
+
+from curd import crud, models, schemas
+from database import SessionLocal, engine
+
+models.Base.metadata.create_all(bind=engine)
+
+app = FastAPI()
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@app.post("/users/", 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)
+
+
+@app.get("/users/", response_model=list[schemas.User])
+def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+    users = crud.get_users(db, skip=skip, limit=limit)
+    return users
+
+
+@app.get("/users/{user_id}", response_model=schemas.User)
+def read_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
+
+
+@app.post("/users/{user_id}/items/", response_model=schemas.Item)
+def create_item_for_user(
+    user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
+):
+    return crud.create_user_item(db=db, item=item, user_id=user_id)
+
+
+@app.get("/items/", response_model=list[schemas.Item])
+def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+    items = crud.get_items(db, skip=skip, limit=limit)
+    return items
\ No newline at end of file
diff --git a/models.py b/models.py
new file mode 100644
index 0000000..3041a3d
--- /dev/null
+++ b/models.py
@@ -0,0 +1,26 @@
+from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
+from sqlalchemy.orm import relationship
+
+from .database import Base
+
+
+class User(Base):
+    __tablename__ = "users"
+
+    id = Column(Integer, primary_key=True)
+    email = Column(String, unique=True, index=True)
+    hashed_password = Column(String)
+    is_active = Column(Boolean, default=True)
+
+    items = relationship("Item", back_populates="owner")
+
+
+class Item(Base):
+    __tablename__ = "items"
+
+    id = Column(Integer, primary_key=True)
+    title = Column(String, index=True)
+    description = Column(String, index=True)
+    owner_id = Column(Integer, ForeignKey("users.id"))
+
+    owner = relationship("User", back_populates="items")
\ No newline at end of file
diff --git a/schemas.py b/schemas.py
new file mode 100644
index 0000000..cf51ac2
--- /dev/null
+++ b/schemas.py
@@ -0,0 +1,37 @@
+from typing import Union
+
+from pydantic import BaseModel
+
+
+class ItemBase(BaseModel):
+    title: str
+    description: Union[str, None] = None
+
+
+class ItemCreate(ItemBase):
+    pass
+
+
+class Item(ItemBase):
+    id: int
+    owner_id: int
+
+    class Config:
+        orm_mode = True
+
+
+class UserBase(BaseModel):
+    email: str
+
+
+class UserCreate(UserBase):
+    password: str
+
+
+class User(UserBase):
+    id: int
+    is_active: bool
+    items: list[Item] = []
+
+    class Config:
+        orm_mode = True
\ No newline at end of file
diff --git a/sql_app.db b/sql_app.db
new file mode 100644
index 0000000..e69de29
-- 
GitLab