from fastapi import FastAPI, __version__ from pydantic import BaseModel from typing import Set, List, Optional, Dict app = FastAPI() class MetaData(BaseModel): key: str value: str field_id: Optional[int] option_id: Optional[int] class Item(BaseModel): id: int metadata: List[MetaData] class Constraint(BaseModel): key: str value: str field_id: Optional[int] option_id: Optional[int] minimum: int maximum: int class IRTModel(BaseModel): a_param: float b_param: float c_param: float model: str class Targets(BaseModel): neg_2_5: int neg_1_5: int neg_0_5: int _0_5: int _1: int class ObjectiveFunction(BaseModel): # minimizing tif/tcc target value is only option currently # as we add more we can build this out to be more dynamic # likely with models representing each objective function type tif_targets: Targets tcc_targets: Targets weight: Dict = {'tif': 1, 'tcc': 1} class AdvancedOptions(BaseModel): # will supported currently linearity_check: bool show_progress: bool max_solution_time: Optional[int] brand_bound_tolerance: Optional[float] max_forms: Optional[int] precision: Optional[float] extra_param_range: Optional[List[Dict]] class SolverContent(BaseModel): items: List[Item] constraints: List[Constraint] irt_model: IRTModel objective_fuction: ObjectiveFunction total_form_items: int advanced_options: Optional[List[AdvancedOptions]] engine: str @app.get("/") async def root(): return {"message": "Welcome to Measures LOFT solver service. v0.1"} @app.get("/healthcheck") async def health(): content = { "maintainer": "Meazure Horizon Team", "git_repo": "https://github.com/yardstick/measure-solver", "server": "OK", "fastapi version": __version__, "app version": "0.1.1" } return content @app.get('/readycheck') async def ready(): return 'OK' # just means we're on air @app.post('/solve/') async def solve(solver_content: SolverContent): return solver_content