sheerid-verify / web /api /schools.py
phonglanvq002's picture
Upload folder using huggingface_hub
4ac818f verified
"""School Search API for K12 verification"""
import logging
from typing import List, Optional
from fastapi import APIRouter, Query
from pydantic import BaseModel
import httpx
logger = logging.getLogger(__name__)
router = APIRouter()
# SheerID organization search endpoint
SHEERID_ORG_SEARCH_URL = "https://orgsearch.sheerid.net/rest/organization/search"
# K12 program account ID (from the API you shared)
K12_ACCOUNT_ID = "67d1dd27d7732a41eb64d141"
class SchoolResult(BaseModel):
"""School search result"""
id: int
idExtended: str
name: str
city: Optional[str] = None
state: Optional[str] = None
country: str = "US"
type: str # K12 or HIGH_SCHOOL
class SchoolSearchResponse(BaseModel):
"""School search response"""
success: bool
results: List[SchoolResult]
count: int
@router.get("/search")
async def search_schools(
q: str = Query(..., min_length=1, description="Search query"),
limit: int = Query(25, ge=1, le=50, description="Max results")
) -> SchoolSearchResponse:
"""Search for K12 schools by name
Args:
q: Search query (school name)
limit: Maximum number of results (default 25, max 50)
"""
try:
async with httpx.AsyncClient(timeout=15.0) as client:
response = await client.get(
SHEERID_ORG_SEARCH_URL,
params={
"accountId": K12_ACCOUNT_ID,
"country": "US",
"format": "detailed",
"name": q,
"tags": "qualifying_hs,qualifying_k12",
"type": "K12,HIGH_SCHOOL"
}
)
if response.status_code != 200:
logger.error(f"SheerID search failed: {response.status_code}")
return SchoolSearchResponse(success=False, results=[], count=0)
data = response.json()
# Limit results
results = data[:limit] if len(data) > limit else data
return SchoolSearchResponse(
success=True,
results=[SchoolResult(**school) for school in results],
count=len(results)
)
except Exception as e:
logger.error(f"School search error: {e}")
return SchoolSearchResponse(success=False, results=[], count=0)