Files
ds_scp_task_solution/app/api/standards_routes.py
T
Aherobo Ovie Victor 0e3e22e8cb Initial commit
2025-07-17 22:20:25 +01:00

114 lines
3.9 KiB
Python

# Standards API routes
from fastapi import APIRouter, UploadFile, File, HTTPException, Query
from typing import List, Optional
from loguru import logger
from app.core.models import Standard, StandardUploadResponse
from app.services.standards import StandardsService
# Create services
standards_service = StandardsService()
# Create router
router = APIRouter(prefix="/standards", tags=["standards"])
@router.get("/", response_model=List[Standard])
async def get_all_standards():
"""
Get all available compliance standards.
Returns:
List of all standards
"""
try:
standards = await standards_service.get_all_standards()
return standards
except Exception as e:
logger.error(f"Error retrieving standards: {str(e)}")
raise HTTPException(status_code=500, detail=f"Error retrieving standards: {str(e)}")
@router.get("/{standard_id}", response_model=Standard)
async def get_standard(standard_id: str):
"""
Get a specific standard by ID.
Args:
standard_id: The standard ID
Returns:
Standard details
"""
try:
standard = await standards_service.get_standard(standard_id)
if not standard:
raise HTTPException(status_code=404, detail=f"Standard with ID {standard_id} not found")
return standard
except HTTPException:
raise
except Exception as e:
logger.error(f"Error retrieving standard: {str(e)}")
raise HTTPException(status_code=500, detail=f"Error retrieving standard: {str(e)}")
@router.post("/upload", response_model=StandardUploadResponse)
async def upload_standard(file: UploadFile = File(...)):
"""
Upload a new compliance standard definition.
Args:
file: JSON file containing standard definition
Returns:
StandardUploadResponse with standard ID
"""
try:
# Check file extension
if not file.filename:
raise HTTPException(status_code=400, detail="Filename is required")
if not file.filename.lower().endswith('.json'):
raise HTTPException(status_code=400, detail="Standard definition must be a JSON file")
# Log the standards service instance ID to verify singleton pattern
logger.info(f"Standards API - Using StandardsService instance: {id(standards_service)}")
logger.info(f"Standards API - Standards count before upload: {len(standards_service.standards)}")
# Process standard
standard = await standards_service.upload_standard(file.file, file.filename)
# Log the updated standards count
logger.info(f"Standards API - Standards count after upload: {len(standards_service.standards)}")
logger.info(f"Standards API - Uploaded standard: {standard.name} (ID: {standard.id})")
return StandardUploadResponse(
standard_id=standard.id,
name=standard.name,
requirement_count=len(standard.requirements),
message="Standard uploaded successfully."
)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Error processing standard: {str(e)}")
raise HTTPException(status_code=500, detail=f"Error processing standard: {str(e)}")
@router.get("/search/", response_model=List[Standard])
async def search_standards(name: Optional[str] = Query(None, description="Standard name to search for")):
"""
Search for standards by name.
Args:
name: Standard name to search for (optional)
Returns:
List of matching standards
"""
try:
if name:
standard = await standards_service.get_standard_by_name(name)
return [standard] if standard else []
else:
return await standards_service.get_all_standards()
except Exception as e:
logger.error(f"Error searching standards: {str(e)}")
raise HTTPException(status_code=500, detail=f"Error searching standards: {str(e)}")