Automated Action 90c1cdef34 Setup News Aggregation Service
- Fix code linting issues
- Update README with detailed documentation
- Configure database paths for the current environment
- Create necessary directory structure

The News Aggregation Service is now ready to use with FastAPI and SQLite.
2025-05-27 18:50:11 +00:00

172 lines
4.7 KiB
Python

from typing import Any, List
from datetime import timedelta
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from app.api import deps
from app.core.config import settings
from app.core.security import create_access_token
from app.models.user import User
from app.schemas.user import User as UserSchema, UserCreate, UserUpdate
from app.schemas.news import UserPreference as UserPreferenceSchema, UserPreferenceUpdate
from app.schemas.token import Token
from app.services.user import (
authenticate_user,
create_user,
update_user,
get_user_by_email,
get_user,
get_user_preference,
update_user_preference,
)
router = APIRouter()
@router.post("/token", response_model=Token)
async def login_for_access_token(
db: Session = Depends(deps.get_db),
form_data: OAuth2PasswordRequestForm = Depends(),
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests.
"""
user = authenticate_user(db, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}
@router.post("/register", response_model=UserSchema)
async def register_user(
*,
db: Session = Depends(deps.get_db),
user_in: UserCreate,
) -> Any:
"""
Register a new user.
"""
try:
user = create_user(db, user_in)
return user
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
@router.get("/me", response_model=UserSchema)
async def read_users_me(
current_user: User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user
@router.put("/me", response_model=UserSchema)
async def update_user_me(
*,
db: Session = Depends(deps.get_db),
user_in: UserUpdate,
current_user: User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update current user.
"""
if user_in.email and user_in.email != current_user.email:
if get_user_by_email(db, user_in.email):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email already registered",
)
user = update_user(db, current_user, user_in)
return user
@router.get("/me/preferences", response_model=UserPreferenceSchema)
async def read_user_preferences(
db: Session = Depends(deps.get_db),
current_user: User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user's preferences.
"""
preferences = get_user_preference(db, current_user.id)
if not preferences:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User preferences not found",
)
return preferences
@router.put("/me/preferences", response_model=UserPreferenceSchema)
async def update_user_preferences(
*,
db: Session = Depends(deps.get_db),
preferences_in: UserPreferenceUpdate,
current_user: User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update current user's preferences.
"""
preferences = update_user_preference(
db,
current_user.id,
keywords=preferences_in.keywords,
sources=preferences_in.sources,
categories=preferences_in.categories,
countries=preferences_in.countries,
languages=preferences_in.languages,
)
return preferences
# Admin endpoints
@router.get("/", response_model=List[UserSchema])
async def read_users(
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users. Only for superusers.
"""
users = db.query(User).offset(skip).limit(limit).all()
return users
@router.get("/{user_id}", response_model=UserSchema)
async def read_user(
user_id: int,
db: Session = Depends(deps.get_db),
current_user: User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Get a specific user by id. Only for superusers.
"""
user = get_user(db, user_id=user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found",
)
return user