sheerid-verify / web /api /config.py
phonglanvq002's picture
Upload folder using huggingface_hub
4ac818f verified
"""Configuration Management API"""
import json
import os
from pathlib import Path
from typing import Dict, Any, Optional
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
router = APIRouter()
# Config directory
DATA_DIR = Path(__file__).parent.parent / "data"
# Module names mapping
MODULES = {
"gemini": "one",
"k12": "k12",
"spotify": "spotify",
"youtube": "youtube",
"boltnew": "Boltnew"
}
# Default configs (from original config.py files)
DEFAULT_CONFIGS = {
"gemini": {
"program_id": "67c8c14f5f17a83b745e3f82",
"sheerid_base_url": "https://services.sheerid.com",
"my_sheerid_url": "https://my.sheerid.com",
"default_school_id": "2565",
"max_file_size": 1048576,
"utm_params": {
"utm_source": "gemini",
"utm_medium": "paid_media",
"utm_campaign": "students_pmax_bts-slap"
},
"schools": {
"2565": {
"id": 2565,
"idExtended": "2565",
"name": "Pennsylvania State University-Main Campus",
"city": "University Park",
"state": "PA",
"country": "US",
"type": "UNIVERSITY",
"domain": "PSU.EDU"
},
"651379": {
"id": 651379,
"idExtended": "651379",
"name": "Pennsylvania State University-World Campus",
"city": "University Park",
"state": "PA",
"country": "US",
"type": "UNIVERSITY",
"domain": "PSU.EDU"
}
}
},
"k12": {
"program_id": "68d47554aa292d20b9bec8f7",
"sheerid_base_url": "https://services.sheerid.com",
"my_sheerid_url": "https://my.sheerid.com",
"default_school_id": "3995910",
"max_file_size": 1048576,
"schools": {
"3995910": {
"id": 3995910,
"idExtended": "3995910",
"name": "Springfield High School (Springfield, OR)",
"country": "US",
"type": "HIGH_SCHOOL"
},
"3995271": {
"id": 3995271,
"idExtended": "3995271",
"name": "Springfield High School (Springfield, OH)",
"country": "US",
"type": "HIGH_SCHOOL"
}
}
},
"spotify": {
"program_id": "67c8c14f5f17a83b745e3f82",
"sheerid_base_url": "https://services.sheerid.com",
"my_sheerid_url": "https://my.sheerid.com",
"default_school_id": "2565",
"max_file_size": 1048576,
"schools": {
"2565": {
"id": 2565,
"idExtended": "2565",
"name": "Pennsylvania State University-Main Campus",
"city": "University Park",
"state": "PA",
"country": "US",
"type": "UNIVERSITY",
"domain": "PSU.EDU"
}
}
},
"youtube": {
"program_id": "67c8c14f5f17a83b745e3f82",
"sheerid_base_url": "https://services.sheerid.com",
"my_sheerid_url": "https://my.sheerid.com",
"default_school_id": "2565",
"max_file_size": 1048576,
"schools": {
"2565": {
"id": 2565,
"idExtended": "2565",
"name": "Pennsylvania State University-Main Campus",
"city": "University Park",
"state": "PA",
"country": "US",
"type": "UNIVERSITY",
"domain": "PSU.EDU"
}
}
},
"boltnew": {
"program_id": "68cc6a2e64f55220de204448",
"sheerid_base_url": "https://services.sheerid.com",
"my_sheerid_url": "https://my.sheerid.com",
"default_school_id": "2565",
"max_file_size": 1048576,
"utm_params": {
"utm_source": "gemini",
"utm_medium": "paid_media",
"utm_campaign": "students_pmax_bts-slap"
},
"schools": {
"2565": {
"id": 2565,
"idExtended": "2565",
"name": "Pennsylvania State University-Main Campus",
"city": "University Park",
"state": "PA",
"country": "US",
"type": "UNIVERSITY",
"domain": "PSU.EDU"
}
}
}
}
def initialize_configs():
"""Initialize config files from defaults if they don't exist"""
DATA_DIR.mkdir(parents=True, exist_ok=True)
for module_key, default_config in DEFAULT_CONFIGS.items():
config_file = DATA_DIR / f"config_{module_key}.json"
if not config_file.exists():
with open(config_file, "w") as f:
json.dump(default_config, f, indent=2)
def get_config(module: str) -> Dict[str, Any]:
"""Load config for a module"""
if module not in MODULES and module not in DEFAULT_CONFIGS:
raise HTTPException(status_code=404, detail=f"Unknown module: {module}")
config_file = DATA_DIR / f"config_{module}.json"
if config_file.exists():
with open(config_file, "r") as f:
return json.load(f)
return DEFAULT_CONFIGS.get(module, {})
def save_config(module: str, config: Dict[str, Any]):
"""Save config for a module"""
DATA_DIR.mkdir(parents=True, exist_ok=True)
config_file = DATA_DIR / f"config_{module}.json"
with open(config_file, "w") as f:
json.dump(config, f, indent=2)
# Pydantic models
class ConfigUpdate(BaseModel):
program_id: Optional[str] = None
default_school_id: Optional[str] = None
utm_params: Optional[Dict[str, str]] = None
class SchoolCreate(BaseModel):
id: int
idExtended: str
name: str
country: str
type: str
city: Optional[str] = None
state: Optional[str] = None
domain: Optional[str] = None
@router.get("/modules")
async def list_modules():
"""List all available verification modules"""
return {
"modules": [
{"key": "gemini", "name": "Gemini One Pro", "description": "Student verification for Gemini"},
{"key": "k12", "name": "ChatGPT Teacher K12", "description": "Teacher verification for ChatGPT"},
{"key": "spotify", "name": "Spotify Student", "description": "Student verification for Spotify"},
{"key": "youtube", "name": "YouTube Student Premium", "description": "Student verification for YouTube"},
{"key": "boltnew", "name": "Bolt.new Teacher", "description": "Teacher verification for Bolt.new"}
]
}
@router.get("/{module}")
async def get_module_config(module: str):
"""Get configuration for a specific module"""
return get_config(module)
@router.put("/{module}")
async def update_module_config(module: str, update: ConfigUpdate):
"""Update configuration for a specific module"""
config = get_config(module)
if update.program_id is not None:
config["program_id"] = update.program_id
if update.default_school_id is not None:
if update.default_school_id not in config.get("schools", {}):
raise HTTPException(status_code=400, detail="School ID not found in schools list")
config["default_school_id"] = update.default_school_id
if update.utm_params is not None:
config["utm_params"] = update.utm_params
save_config(module, config)
return {"message": "Config updated successfully", "config": config}
@router.get("/{module}/schools")
async def get_schools(module: str):
"""Get list of schools for a module"""
config = get_config(module)
return {"schools": config.get("schools", {})}
@router.post("/{module}/schools")
async def add_school(module: str, school: SchoolCreate):
"""Add a new school to a module"""
config = get_config(module)
school_id = str(school.id)
if school_id in config.get("schools", {}):
raise HTTPException(status_code=400, detail="School already exists")
if "schools" not in config:
config["schools"] = {}
config["schools"][school_id] = school.model_dump()
save_config(module, config)
return {"message": "School added successfully", "school": config["schools"][school_id]}
@router.delete("/{module}/schools/{school_id}")
async def delete_school(module: str, school_id: str):
"""Delete a school from a module"""
config = get_config(module)
if school_id not in config.get("schools", {}):
raise HTTPException(status_code=404, detail="School not found")
if config.get("default_school_id") == school_id:
raise HTTPException(status_code=400, detail="Cannot delete default school")
del config["schools"][school_id]
save_config(module, config)
return {"message": "School deleted successfully"}