"""HTTP service for roomtsc 0.1. POST /api/predict body: {"structure": ""} returns the estimate as JSON GET /api/health returns the model version and what it was trained on Run: uvicorn serve:app --app-dir model --host 0.0.0.0 --port 8000 """ import pathlib import sys from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field from pymatgen.core import Structure sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent)) import predict as P app = FastAPI(title='roomtsc', docs_url=None, redoc_url=None, openapi_url=None) class Query(BaseModel): structure: str = Field(max_length=200_000) def parse(text): """A CIF if it looks like one, otherwise a POSCAR.""" fmt = 'cif' if ('_cell_length_a' in text or text.lstrip().startswith('data_')) else 'poscar' try: return Structure.from_str(text, fmt=fmt) except Exception as err: raise HTTPException(422, f'could not read the structure as {fmt.upper()}: {str(err)[:200]}') @app.get('/api/health') def health(): meta = P.models()['meta'] return dict(model=meta['name'], version=meta['version'], trained_on=meta['trained_on'], graph_members=len(meta['graph_seeds'])) @app.post('/api/predict') def predict(q: Query): st = parse(q.structure) try: return P.predict(st) except ValueError as err: raise HTTPException(422, str(err))