From 1839606582f26e9ab6666c57666a7be6614f0c48 Mon Sep 17 00:00:00 2001 From: viktor Date: Sun, 14 May 2023 23:25:14 +0300 Subject: [PATCH 1/2] Add updating a book by ID, deleting a book, and searching for a book by ID --- Pipfile | 5 ++- .../d9b85eefcd0e_added_new_table_books.py | 29 ++++++++++++ app/dependencies/users.py | 2 +- app/routers/books.py | 45 ++++++++++++++++--- 4 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 alembic/versions/d9b85eefcd0e_added_new_table_books.py diff --git a/Pipfile b/Pipfile index 200f9eb..dbb6ed8 100644 --- a/Pipfile +++ b/Pipfile @@ -8,9 +8,12 @@ fastapi = "*" pydantic = "*" requests = "*" pymysql = "*" -sqlalchemy = "2.0.12" +sqlalchemy = "2.0.13" alembic = "1.10.4" python-dotenv = "*" +unicorn ="*" +python-multipart = "*" +cryptography = "*" [dev-packages] diff --git a/alembic/versions/d9b85eefcd0e_added_new_table_books.py b/alembic/versions/d9b85eefcd0e_added_new_table_books.py new file mode 100644 index 0000000..28ff431 --- /dev/null +++ b/alembic/versions/d9b85eefcd0e_added_new_table_books.py @@ -0,0 +1,29 @@ +"""Added new table books + +Revision ID: d9b85eefcd0e +Revises: b8a484e6683d +Create Date: 2023-05-14 20:21:45.567433 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'd9b85eefcd0e' +down_revision = 'b8a484e6683d' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.create_table("books", + sa.Column("id", sa.Integer, primary_key=True), + sa.Column("title", sa.String(255), nullable=False), + sa.Column("author", sa.String(255), nullable=False), + sa.Column("pages_count", sa.Integer, nullable=True), + ) + + +def downgrade() -> None: + op.drop_table("books") diff --git a/app/dependencies/users.py b/app/dependencies/users.py index 305f092..e51badb 100644 --- a/app/dependencies/users.py +++ b/app/dependencies/users.py @@ -4,7 +4,7 @@ security = HTTPBasic() users = { - "vitalii": "123", + "nic": "7788", } diff --git a/app/routers/books.py b/app/routers/books.py index 6a1b9c3..ef4063b 100644 --- a/app/routers/books.py +++ b/app/routers/books.py @@ -1,11 +1,13 @@ import json -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from app.dependencies.db import get_session from app.models import Book +from sqlalchemy.future import select + router = APIRouter(prefix="/books") # books = [ @@ -29,14 +31,17 @@ class BookCreateModel(BaseModel): author: str +class BookUpdate(BaseModel): + title: str + author: str + pages_count: int = None + + @router.get("", response_model=list[BookModel]) async def get_books(title: str = None, session=Depends(get_session)): books = session.query(Book).all() - books_models = [] - for book in books: - books_models.append(BookModel.from_orm(book)) - return books_models + return [BookModel.from_orm(book) for book in books] # @router.get("/{book_id}", response_model=BookModel) @@ -57,3 +62,33 @@ async def create_book(book: BookCreateModel, session=Depends(get_session)): return BookModel.from_orm(book) + +@router.put("/update/{book_id}") +async def update_book(book_id: int, book_update: BookUpdate, session=Depends(get_session)): + book = session.query(Book).filter(Book.id == book_id).first() + for variant, sense in variants(book_update).items(): + if value is not None: + setattr(book, variant, sense) + session.commit() + return BookModel.from_orm(book) + + +@router.delete("/delete/{book_id}") +async def delete_book(book_id: int, session=Depends(get_session)): + book = session.query(Book).filter(Book.id == book_id).first() + if not book: + raise HTTPException(status_code=404, detail="Book not found") + else: + session.delete(book) + session.commit() + return {"message": "Book deleted"} + + +@router.get("/get/{book_id}", response_model=BookModel) +async def get_book(book_id: int, session=Depends(get_session)): + if book := session.query(Book).filter(Book.id == book_id).first(): + book_data = {k: v for k, v in book.__dict__.items() + if k != '_sa_instance_state'} + return Book(**book_data) + else: + raise HTTPException(status_code=404, detail="Book not found") From fa003e5027f3da9d2219047f940c68c502a9f150 Mon Sep 17 00:00:00 2001 From: viktor Date: Mon, 15 May 2023 14:26:25 +0300 Subject: [PATCH 2/2] Add fix bug --- app/routers/books.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/routers/books.py b/app/routers/books.py index ef4063b..8079135 100644 --- a/app/routers/books.py +++ b/app/routers/books.py @@ -66,6 +66,10 @@ async def create_book(book: BookCreateModel, session=Depends(get_session)): @router.put("/update/{book_id}") async def update_book(book_id: int, book_update: BookUpdate, session=Depends(get_session)): book = session.query(Book).filter(Book.id == book_id).first() + + if not book: + raise HTTPException(status_code=404, detail="Book not found") + for variant, sense in variants(book_update).items(): if value is not None: setattr(book, variant, sense) @@ -76,6 +80,7 @@ async def update_book(book_id: int, book_update: BookUpdate, session=Depends(get @router.delete("/delete/{book_id}") async def delete_book(book_id: int, session=Depends(get_session)): book = session.query(Book).filter(Book.id == book_id).first() + if not book: raise HTTPException(status_code=404, detail="Book not found") else: