Files
YG-Datasets/backend/app/api/v1/projects/__init__.py

112 lines
3.5 KiB
Python
Raw Normal View History

2026-03-17 14:36:31 +08:00
"""
Projects API Router
"""
import logging
from typing import List, Optional
2026-03-17 14:36:31 +08:00
from uuid import UUID
from fastapi import APIRouter, Depends, Query
2026-03-17 14:36:31 +08:00
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.response import ApiResponse, PaginatedResponse
2026-03-17 14:36:31 +08:00
from app.core.database import get_db
from app.core.exceptions import NotFoundException
from app.core.crud import CRUDBase
2026-03-17 14:36:31 +08:00
from app.models.models import Project
from app.schemas.project import (
2026-03-17 14:36:31 +08:00
ProjectCreate,
ProjectUpdate,
ProjectResponse,
ProjectCreateSchema,
ProjectUpdateSchema
2026-03-17 14:36:31 +08:00
)
router = APIRouter()
logger = logging.getLogger("yg_dataset.projects")
# Initialize CRUD
project_crud = CRUDBase(Project)
2026-03-17 14:36:31 +08:00
@router.get("", response_model=PaginatedResponse)
async def list_projects(
page: int = Query(1, ge=1, description="Page number"),
page_size: int = Query(20, ge=1, le=100, description="Page size"),
db: AsyncSession = Depends(get_db)
):
"""List all projects with pagination"""
logger.info(f"Listing projects - page: {page}, page_size: {page_size}")
skip = (page - 1) * page_size
projects, total = await project_crud.get_multi(
db,
skip=skip,
limit=page_size,
order_by="created_at",
descending=True
)
2026-03-17 14:36:31 +08:00
logger.info(f"Found {total} projects, returning {len(projects)} items")
project_responses = [ProjectResponse.model_validate(p) for p in projects]
return PaginatedResponse.ok(
items=project_responses,
page=page,
page_size=page_size,
total=total
)
2026-03-17 14:36:31 +08:00
@router.post("", response_model=ApiResponse)
async def create_project(
project: ProjectCreateSchema,
db: AsyncSession = Depends(get_db)
):
2026-03-17 14:36:31 +08:00
"""Create a new project"""
logger.info(f"Creating project: name={project.name}, description={project.description}")
db_project = await project_crud.create(db, project)
logger.info(f"Project created successfully: id={db_project.id}")
return ApiResponse.ok(
data={"id": str(db_project.id)},
message="Project created successfully"
)
2026-03-17 14:36:31 +08:00
@router.get("/{project_id}", response_model=ApiResponse)
async def get_project(
project_id: UUID,
db: AsyncSession = Depends(get_db)
):
2026-03-17 14:36:31 +08:00
"""Get project by ID"""
logger.info(f"Getting project: id={project_id}")
project = await project_crud.get_or_raise(db, project_id, "Project")
logger.info(f"Found project: name={project.name}")
return ApiResponse.ok(data=ProjectResponse.model_validate(project))
2026-03-17 14:36:31 +08:00
@router.put("/{project_id}", response_model=ApiResponse)
async def update_project(
project_id: UUID,
project: ProjectUpdateSchema,
db: AsyncSession = Depends(get_db)
):
2026-03-17 14:36:31 +08:00
"""Update project"""
logger.info(f"Updating project: id={project_id}")
db_project = await project_crud.get_or_raise(db, project_id, "Project")
updated_project = await project_crud.update(db, db_project, project)
logger.info(f"Project updated: name={updated_project.name}")
return ApiResponse.ok(
data=ProjectResponse.model_validate(updated_project),
message="Project updated successfully"
)
2026-03-17 14:36:31 +08:00
@router.delete("/{project_id}", response_model=ApiResponse)
async def delete_project(
project_id: UUID,
db: AsyncSession = Depends(get_db)
):
2026-03-17 14:36:31 +08:00
"""Delete project"""
logger.info(f"Deleting project: id={project_id}")
await project_crud.get_or_raise(db, project_id, "Project")
await project_crud.delete(db, project_id)
logger.info(f"Project deleted: id={project_id}")
return ApiResponse.ok(message="Project deleted successfully")