from typing import Optional, Sequence from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy import select, delete from sqlalchemy.ext.asyncio import AsyncSession from app.schemas.posts import PostCreate, PostRead from app.db_engine import get_async_session from app.models.posts import Post router = APIRouter( prefix="/posts", tags=["posts"], responses={404: {"description": "Not found"}}, ) @router.get("/") async def get_posts( page: int = Query(1, ge=1), page_size: int = Query(10, ge=1, le=100), db: AsyncSession = Depends(get_async_session), ): offset = (page - 1) * page_size stmt = select(Post).order_by(Post.id).offset(offset).limit(page_size) result = await db.execute(stmt) posts: Sequence[Post] = result.scalars().all() return posts @router.get("/{id}", response_model=PostRead) async def get_post(id: int, db: AsyncSession = Depends(get_async_session)): post = await db.get(Post, id) if post is None: raise HTTPException(status_code=404, detail="Post not found") else: return post @router.post("/", response_model=PostRead) async def create_post( title: str, content: str, images: Optional[str] = None, db: AsyncSession = Depends(get_async_session), ) -> Post: try: post = PostCreate(title=title, content=content, images=images) except ValueError as e: raise HTTPException(status_code=422, detail=str(e)) new_post = Post(title=post.title, content=post.content, images=post.images) db.add(new_post) await db.commit() await db.refresh(new_post) return new_post @router.put("/{id}") async def update_post( id: int, db: AsyncSession = Depends(get_async_session), title: Optional[str] = None, content: Optional[str] = None, images: Optional[str] = None, ): s = select(Post).where(Post.id == id) result = await db.execute(s) post = result.scalars().first() if post is None: raise HTTPException(status_code=404, detail="Post not found") if title is not None: post.title = title # type: ignore if content is not None: post.content = content # type: ignore if images is not None: post.images = images # type: ignore await db.commit() return post @router.delete("/{id}") async def delete_post(id: int, db: AsyncSession = Depends(get_async_session)): s = delete(Post).where(Post.id == id) await db.execute(s) await db.commit() return {"message": "Post deleted"}