Initial Commit
This commit is contained in:
0
app/routers/__init__.py
Normal file
0
app/routers/__init__.py
Normal file
93
app/routers/authors.py
Normal file
93
app/routers/authors.py
Normal file
@ -0,0 +1,93 @@
|
||||
from datetime import date
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import text
|
||||
from app.database import get_db
|
||||
|
||||
router = APIRouter(prefix="/authors", tags=["Authors"])
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_all_authors(db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(text("SELECT * FROM authors ORDER BY name"))
|
||||
return result.mappings().all()
|
||||
|
||||
|
||||
@router.get("/{author_id}")
|
||||
async def get_author(author_id: int, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(
|
||||
text("SELECT * FROM authors WHERE id = :id"),
|
||||
{"id": author_id}
|
||||
)
|
||||
author = result.mappings().one_or_none()
|
||||
if not author:
|
||||
raise HTTPException(status_code=404, detail="Author not found")
|
||||
return author
|
||||
|
||||
|
||||
@router.get("/{author_id}/books")
|
||||
async def get_books_by_author(author_id: int, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(
|
||||
text("""
|
||||
SELECT b.id, b.title, b.published, b.genre
|
||||
FROM books b
|
||||
WHERE b.author_id = :author_id
|
||||
ORDER BY b.published DESC
|
||||
"""),
|
||||
{"author_id": author_id}
|
||||
)
|
||||
return result.mappings().all()
|
||||
|
||||
|
||||
@router.post("/", status_code=201)
|
||||
async def create_author(
|
||||
name: str, bio: str = None, born_date: date = None,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
await db.execute(
|
||||
text("""
|
||||
INSERT INTO authors (name, bio, born_date)
|
||||
VALUES (:name, :bio, :born_date)
|
||||
"""),
|
||||
{"name": name, "bio": bio, "born_date": born_date}
|
||||
)
|
||||
await db.commit()
|
||||
return {"message": f"Author '{name}' created"}
|
||||
|
||||
|
||||
@router.put("/{author_id}")
|
||||
async def update_author(
|
||||
author_id: int, name: str = None, bio: str = None,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
result = await db.execute(
|
||||
text("SELECT id FROM authors WHERE id = :id"), {"id": author_id}
|
||||
)
|
||||
if not result.one_or_none():
|
||||
raise HTTPException(status_code=404, detail="Author not found")
|
||||
|
||||
await db.execute(
|
||||
text("""
|
||||
UPDATE authors
|
||||
SET name = COALESCE(:name, name),
|
||||
bio = COALESCE(:bio, bio)
|
||||
WHERE id = :id
|
||||
"""),
|
||||
{"id": author_id, "name": name, "bio": bio}
|
||||
)
|
||||
await db.commit()
|
||||
return {"message": "Author updated"}
|
||||
|
||||
|
||||
@router.delete("/{author_id}", status_code=204)
|
||||
async def delete_author(author_id: int, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(
|
||||
text("SELECT id FROM authors WHERE id = :id"), {"id": author_id}
|
||||
)
|
||||
if not result.one_or_none():
|
||||
raise HTTPException(status_code=404, detail="Author not found")
|
||||
|
||||
await db.execute(
|
||||
text("DELETE FROM authors WHERE id = :id"), {"id": author_id}
|
||||
)
|
||||
await db.commit()
|
||||
99
app/routers/books.py
Normal file
99
app/routers/books.py
Normal file
@ -0,0 +1,99 @@
|
||||
from datetime import date
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import text
|
||||
from app.database import get_db
|
||||
|
||||
router = APIRouter(prefix="/books", tags=["Books"])
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_all_books(db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(text("""
|
||||
SELECT b.id, b.title, b.genre, b.published, a.name AS author
|
||||
FROM books b
|
||||
JOIN authors a ON a.id = b.author_id
|
||||
ORDER BY b.title
|
||||
"""))
|
||||
return result.mappings().all()
|
||||
|
||||
|
||||
@router.get("/{book_id}")
|
||||
async def get_book(book_id: int, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(
|
||||
text("""
|
||||
SELECT b.*, a.name AS author_name
|
||||
FROM books b
|
||||
JOIN authors a ON a.id = b.author_id
|
||||
WHERE b.id = :id
|
||||
"""),
|
||||
{"id": book_id}
|
||||
)
|
||||
book = result.mappings().one_or_none()
|
||||
if not book:
|
||||
raise HTTPException(status_code=404, detail="Book not found")
|
||||
return book
|
||||
|
||||
|
||||
@router.post("/", status_code=201)
|
||||
async def create_book(
|
||||
title: str, author_id: int, genre: str = None,
|
||||
published: date = None, description: str = None,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
# Check author exists
|
||||
result = await db.execute(
|
||||
text("SELECT id FROM authors WHERE id = :id"), {"id": author_id}
|
||||
)
|
||||
if not result.one_or_none():
|
||||
raise HTTPException(status_code=404, detail="Author not found")
|
||||
|
||||
await db.execute(
|
||||
text("""
|
||||
INSERT INTO books (title, author_id, genre, published, description)
|
||||
VALUES (:title, :author_id, :genre, :published, :description)
|
||||
"""),
|
||||
{"title": title, "author_id": author_id, "genre": genre,
|
||||
"published": published, "description": description}
|
||||
)
|
||||
await db.commit()
|
||||
return {"message": f"Book '{title}' created"}
|
||||
|
||||
|
||||
@router.put("/{book_id}")
|
||||
async def update_book(
|
||||
book_id: int, title: str = None, genre: str = None,
|
||||
description: str = None, db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
result = await db.execute(
|
||||
text("SELECT id FROM books WHERE id = :id"), {"id": book_id}
|
||||
)
|
||||
if not result.one_or_none():
|
||||
raise HTTPException(status_code=404, detail="Book not found")
|
||||
|
||||
await db.execute(
|
||||
text("""
|
||||
UPDATE books
|
||||
SET title = COALESCE(:title, title),
|
||||
genre = COALESCE(:genre, genre),
|
||||
description = COALESCE(:description, description)
|
||||
WHERE id = :id
|
||||
"""),
|
||||
{"id": book_id, "title": title, "genre": genre, "description": description}
|
||||
)
|
||||
await db.commit()
|
||||
return {"message": "Book updated"}
|
||||
|
||||
|
||||
@router.delete("/{book_id}", status_code=204)
|
||||
async def delete_book(book_id: int, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(
|
||||
text("SELECT id FROM books WHERE id = :id"), {"id": book_id}
|
||||
)
|
||||
if not result.one_or_none():
|
||||
raise HTTPException(status_code=404, detail="Book not found")
|
||||
|
||||
await db.execute(
|
||||
text("DELETE FROM books WHERE id = :id"), {"id": book_id}
|
||||
)
|
||||
await db.commit()
|
||||
Reference in New Issue
Block a user