Skip to content

Commit

Permalink
added endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
jamestitus299 committed Jul 11, 2024
1 parent 7743d99 commit 1786dc4
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 40 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/venv
__pycache__
__pycache__
.env
38 changes: 25 additions & 13 deletions api/courses.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
from typing import List

import fastapi
from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session

from db.dbsetup import get_db
from pydantic_schemas.course import Course, CourseCreate
from api.utils.courses import get_course, get_courses, create_course

router = fastapi.APIRouter()


@router.get("/courses")
async def read_courses():
return {"courses": []}
@router.get("/courses", response_model=List[Course])
async def read_courses(db: Session = Depends(get_db)):
courses = get_courses(db=db)
return courses


@router.post("/courses")
async def create_course_api():
return {"courses": []}
@router.post("/courses", response_model=Course)
async def create_new_course(course: CourseCreate, db: Session = Depends(get_db)):
return create_course(db=db, course=course)


@router.get("/courses/{id}")
async def read_course():
return {"courses": []}
@router.get("/courses/{course_id}")
async def read_course(course_id: int, db: Session = Depends(get_db)):
db_course = get_course(db=db, course_id=course_id)
if db_course is None:
raise HTTPException(status_code=404, detail="Course not found")
return db_course


@router.patch("/courses/{id}")
@router.patch("/courses/{course_id}")
async def update_course():
return {"courses": []}


@router.delete("/courses/{id}")
@router.delete("/courses/{course_id}")
async def delete_course():
return {"courses": []}


@router.get("/courses/{id}/sections")
@router.get("/courses/{course_id}/sections")
async def read_course_sections():
return {"courses": []}
return {"courses": []}
8 changes: 0 additions & 8 deletions api/models.py

This file was deleted.

46 changes: 33 additions & 13 deletions api/users.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
from fastapi import FastAPI, Path, APIRouter
from typing import List, Optional
from .models import User
from os import stat
from typing import Optional, List

router = APIRouter()
import fastapi
from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session

from db.dbsetup import get_db
from pydantic_schemas.user import UserCreate, User
from pydantic_schemas.course import Course
from api.utils.users import get_user, get_user_by_email, get_users, create_user
from api.utils.courses import get_user_courses

router = fastapi.APIRouter()

users = []

@router.get("/users", response_model=List[User])
async def get_users():
async def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = get_users(db, skip=skip, limit=limit)
return users


@router.post("/users")
async def post_users(user : User):
users.append(user)
return {"message": "added"}
@router.post("/users", response_model=User, status_code=201)
async def create_new_user(user: UserCreate, db: Session = Depends(get_db)):
db_user = get_user_by_email(db=db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email is already registered")
return create_user(db=db, user=user)


@router.get("/users/{user_id}", response_model=User)
async def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = get_user(db=db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user


@router.get("/users/{id}")
def get_user_by_id(id : int = Path(..., description="The id of the User you want to query.", gt=-1)):
return users[id]
@router.get("/users/{user_id}/courses", response_model=List[Course])
async def read_user_courses(user_id: int, db: Session = Depends(get_db)):
courses = get_user_courses(user_id=user_id, db=db)
return courses
29 changes: 29 additions & 0 deletions api/utils/courses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from sqlalchemy.orm import Session

from db.models.courses import Course
from pydantic_schemas.course import CourseCreate


def get_course(db: Session, course_id: int):
return db.query(Course).filter(Course.id == course_id).first()


def get_courses(db: Session):
return db.query(Course).all()


def get_user_courses(db: Session, user_id: int):
courses = db.query(Course).filter(Course.user_id == user_id).all()
return courses


def create_course(db: Session, course: CourseCreate):
db_course = Course(
title=course.title,
description=course.description,
user_id=course.user_id
)
db.add(db_course)
db.commit()
db.refresh(db_course)
return db_course
24 changes: 24 additions & 0 deletions api/utils/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from sqlalchemy.orm import Session

from db.models.users import User
from pydantic_schemas.user import UserCreate


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


def get_user_by_email(db: Session, email: str):
return db.query(User).filter(User.email == email).first()


def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(User).offset(skip).limit(limit).all()


def create_user(db: Session, user: UserCreate):
db_user = User(email=user.email, role=user.role)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
7 changes: 6 additions & 1 deletion db/dbsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

import os
from dotenv import load_dotenv

load_dotenv()

# Enter your connecton string
SQLALCHEMY_DATABASE_URL = "postgresql://user:password@host:port/database"
SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URL")

engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={}, future=True
Expand Down
6 changes: 5 additions & 1 deletion db/models/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ class CompletedContentBlock(Timestamp, Base):
grade = Column(Integer, default=0)

student = relationship(User, back_populates="student_content_blocks")
content_block = relationship(ContentBlock, back_populates="completed_content_blocks")
content_block = relationship(ContentBlock, back_populates="completed_content_blocks")




10 changes: 9 additions & 1 deletion db/models/users.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import enum

from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Enum, Text
from sqlalchemy.orm import relationship
Expand All @@ -7,6 +6,7 @@
from ..dbsetup import Base
from .mixins import Timestamp

import enum

class Role(enum.Enum):
teacher = 1
Expand All @@ -19,7 +19,12 @@ class User(Timestamp, Base):
id = Column(Integer, primary_key=True, index=True)
email = Column(String(100), unique=True, index=True, nullable=False)
role = Column(Enum(Role))
is_active = Column(Boolean, default=False)

profile = relationship("Profile", back_populates="owner", uselist=False)
student_courses = relationship("StudentCourse", back_populates="student")
student_content_blocks = relationship(
"CompletedContentBlock", back_populates="student")


class Profile(Timestamp, Base):
Expand All @@ -32,4 +37,7 @@ class Profile(Timestamp, Base):
is_active = Column(Boolean, default=False)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
owner = relationship("User", back_populates="profile")




2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

@app.get("/")
async def home():
return "Hello World"
return "Hello College"

app.include_router(users.router)
app.include_router(sections.router)
Expand Down
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions pydantic_schemas/course.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from typing import Optional

from pydantic import BaseModel


class CourseBase(BaseModel):
title: str
description: Optional[str] = None
user_id: int


class CourseCreate(CourseBase):
...


class Course(CourseBase):
id: int

class Config:
orm_mode = True
22 changes: 22 additions & 0 deletions pydantic_schemas/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from datetime import datetime

from pydantic import BaseModel


class UserBase(BaseModel):
email: str
role: int


class UserCreate(UserBase):
...


class User(UserBase):
id: int
is_active: bool
created_at: datetime
updated_at: datetime

class Config:
orm_mode = True
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pydantic = "^2.8.2"
psycopg2-binary = "^2.9.9"
sqlalchemy = "^2.0.31"
alembic = "^1.13.2"
python-dotenv = "^1.0.1"


[build-system]
Expand Down
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@

# Basic CRUD Api using FastAPI

(In work ...)

0 comments on commit 1786dc4

Please sign in to comment.