Skip to content
Open
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
36 changes: 36 additions & 0 deletions crud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from sqlalchemy.orm import Session
import models
import schemas


def get_author(db: Session, author_id: int):
return (db.query(models.Author).
filter(models.Author.id == author_id).first())


def get_authors(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.Author).offset(skip).limit(limit).all()


def create_author(db: Session, author: schemas.AuthorCreate):
db_author = models.Author(name=author.name, bio=author.bio)
db.add(db_author)
db.commit()
db.refresh(db_author)
return db_author


def get_books(db: Session, skip: int = 0, limit: int = 100,
author_id: int = None):
query = db.query(models.Book)
if author_id:
query = query.filter(models.Book.author_id == author_id)
return query.offset(skip).limit(limit).all()


def create_book(db: Session, book: schemas.BookCreate, author_id: int):
db_book = models.Book(**book.model_dump(), author_id=author_id)
db.add(db_book)
db.commit()
db.refresh(db_book)
return db_book
14 changes: 14 additions & 0 deletions database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base


SQL_ALCHEMY_DATABASE_URL = "sqlite:///./library.db"

engine = create_engine(
SQL_ALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()
Binary file added library.db
Binary file not shown.
54 changes: 54 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List


import crud
import models
import schemas
from database import SessionLocal, engine


models.Base.metadata.create_all(bind=engine)


app = FastAPI(title="Library")


def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()


@app.post("/authors/", response_model=schemas.Author)
def create_author(author: schemas.AuthorCreate, db: Session = Depends(get_db)):
return crud.create_author(db=db, author=author)


@app.get("/authors/", response_model=List[schemas.Author])
def read_authors(skip: int = 0, limit: int = 100,
db: Session = Depends(get_db)):
return crud.get_authors(db=db, skip=skip, limit=limit)


@app.get("/authors/{author_id}", response_model=schemas.Author)
def get_author(author_id: int, db: Session = Depends(get_db)):
db_author = crud.get_author(db=db, author_id=author_id)
if db_author is None:
raise HTTPException(status_code=404, detail="Author not found")
return db_author


@app.post("/books/", response_model=schemas.Book)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter name 'author' should be 'author_id' to match REST conventions and clearly indicate it expects an author ID value, not just a generic identifier.

def create_book_for_author(author: int, book: schemas.BookCreate,
db: Session = Depends(get_db)):
return crud.create_book(db=db, book=book, author_id=author)


@app.get("/books/", response_model=List[schemas.Book])
def read_books(skip: int = 0, limit: int = 10, author_id: int = None,
db: Session = Depends(get_db)):
return crud.get_books(db, skip=skip, limit=limit, author_id=author_id)
27 changes: 27 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from sqlalchemy import Column, Integer, String, Date, ForeignKey
from sqlalchemy.orm import relationship


from database import Base


class Author(Base):
__tablename__ = "authors"

id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, index=True)
bio = Column(String)

books = relationship("Book", back_populates="author")


class Book(Base):
__tablename__ = "books"

id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
summary = Column(String)
publication_date = Column(Date)
author_id = Column(Integer, ForeignKey("authors.id"))

author = relationship("Author", back_populates="books")
37 changes: 37 additions & 0 deletions schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from pydantic import BaseModel, ConfigDict
from typing import List, Optional
from datetime import date


class BookBase(BaseModel):
title: str
summary: str
publication_date: date


class BookCreate(BookBase):
pass


class Book(BookBase):
id: int
author_id: int

model_config = ConfigDict(from_attributes=True)


class AuthorBase(BaseModel):
name: str
bio: Optional[str] = None


class AuthorCreate(AuthorBase):
pass


class Author(AuthorBase):
id: int

books: List[Book] = []

model_config = ConfigDict(from_attributes=True)