Add Reddit monitoring bot — backend, frontend, and Docker config
Python/FastAPI backend with PostgreSQL for collecting Reddit data via public .json endpoints. React/Vite dashboard for analytics. Docker Compose setup with API and worker services connecting to shared PostgreSQL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
64
backend/routers/posts.py
Normal file
64
backend/routers/posts.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from datetime import datetime
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from backend.database import get_db
|
||||
from backend.schemas.post import PostResponse, PostDetailResponse
|
||||
from backend.services import post_service
|
||||
from backend.models.metric_snapshot import MetricSnapshot
|
||||
from sqlalchemy import select
|
||||
|
||||
router = APIRouter(prefix="/posts", tags=["posts"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def list_posts(
|
||||
subreddit_id: int | None = None,
|
||||
author: str | None = None,
|
||||
flair: str | None = None,
|
||||
sort_by: str = Query("created_utc", pattern="^(created_utc|score|num_comments)$"),
|
||||
sort_order: str = Query("desc", pattern="^(asc|desc)$"),
|
||||
since: datetime | None = None,
|
||||
until: datetime | None = None,
|
||||
page: int = Query(1, ge=1),
|
||||
per_page: int = Query(25, ge=1, le=100),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
posts, total = await post_service.list_posts(
|
||||
db, subreddit_id, author, flair, sort_by, sort_order, since, until, page, per_page
|
||||
)
|
||||
return {
|
||||
"data": posts,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"per_page": per_page,
|
||||
"pages": (total + per_page - 1) // per_page if per_page else 0,
|
||||
}
|
||||
|
||||
|
||||
@router.get("/{post_id}")
|
||||
async def get_post(post_id: int, db: AsyncSession = Depends(get_db)):
|
||||
post = await post_service.get_post(db, post_id)
|
||||
if not post:
|
||||
raise HTTPException(status_code=404, detail="Post not found")
|
||||
return post
|
||||
|
||||
|
||||
@router.get("/{post_id}/snapshots")
|
||||
async def get_post_snapshots(post_id: int, db: AsyncSession = Depends(get_db)):
|
||||
stmt = (
|
||||
select(MetricSnapshot)
|
||||
.where(MetricSnapshot.post_id == post_id)
|
||||
.order_by(MetricSnapshot.snapshot_at.asc())
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
snapshots = result.scalars().all()
|
||||
return [
|
||||
{
|
||||
"score": s.score,
|
||||
"num_comments": s.num_comments,
|
||||
"upvote_ratio": s.upvote_ratio,
|
||||
"snapshot_at": s.snapshot_at,
|
||||
}
|
||||
for s in snapshots
|
||||
]
|
||||
Reference in New Issue
Block a user