"""OpenAPI 3.0 description and a /docs page (Swagger UI loaded from a CDN in the visitor's browser; the server itself needs no extra packages).""" from .routes import API_VERSION _unit = {"type": "number", "minimum": 0, "maximum": 1} _C = {"type": "integer", "enum": [1, 2, 3, 4, 5], "description": "Consequence index (Table 2): 1=0.10 Insignificant, 2=0.30 Minor, " "3=0.50 Moderate, 4=0.75 Major, 5=1.00 Severe. Default 5."} _N = {"type": "number", "minimum": 1, "maximum": 10_000_000_000, "description": "Population / cohort size (drives the advisory E_log and the per-capita rate)."} _disaster_input = { "type": "object", "required": ["N", "L", "E_sel", "V", "rho_now"], "additionalProperties": False, "properties": { "N": _N, "L": {**_unit, "description": "Hazard likelihood"}, "E_sel": {**_unit, "description": "Selected exposure ('E' is accepted as an alias)"}, "V": {**_unit, "description": "Vulnerability"}, "rho_now": {**_unit, "description": "Current resilience (must be < 1 if rho_after is given)"}, "rho_after": {**_unit, "description": "Post-investment resilience (optional)"}, "C": _C}, "example": {"N": 1100000, "L": 0.875, "E_sel": 0.8, "V": 0.8, "rho_now": 0.25, "rho_after": 0.48, "C": 4}} _onc_input = { "type": "object", "required": ["N", "L", "rho_now"], "additionalProperties": False, "description": "Provide exactly one of V, albi_grade, albi_grade_counts. E is optional " "(defaults to the log-normalised helper from N). Provide C or bclc_stage, not both.", "properties": { "N": _N, "L": {**_unit, "description": "Annual HCC incidence-derived likelihood"}, "E": _unit, "V": _unit, "albi_grade": {"type": "integer", "enum": [1, 2, 3]}, "albi_grade_counts": {"type": "object", "example": {"1": 10, "2": 18, "3": 1}}, "rho_now": _unit, "rho_after": _unit, "C": _C, "bclc_stage": {"type": "string", "enum": ["BCLC0", "BCLC_A", "EARLY_INT", "BCLC_B", "BCLC_CD"]}}, "example": {"N": 100000, "L": 0.30, "E": 0.65, "albi_grade": 2, "rho_now": 0.20, "rho_after": 0.50, "bclc_stage": "BCLC_CD"}} def _rank_body(item_schema, desc): item = {"allOf": [item_schema, {"type": "object", "required": ["label"], "properties": {"label": {"type": "string", "maxLength": 60}}}]} return {"type": "object", "required": ["items"], "additionalProperties": False, "properties": {"items": {"type": "array", "minItems": 1, "maxItems": 100, "items": item, "description": desc}}} _ok = {"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}, "400": {"description": "Validation error: {error:{code,message}}"}, "429": {"description": "Rate limited; see Retry-After header"}} def _post(summary, schema, tag): return {"post": {"summary": summary, "tags": [tag], "responses": _ok, "requestBody": {"required": True, "content": {"application/json": {"schema": schema}}}}} def _get(summary, tag, params=None): g = {"summary": summary, "tags": [tag], "responses": _ok} if params: g["parameters"] = params return {"get": g} def spec(): return { "openapi": "3.0.3", "info": { "title": "RMTI API", "version": API_VERSION, "description": ( "Risk Mechanism Theory Index scoring for **disaster / urban risk** and **oncology (HCC) " "surveillance triage**.\n\nR = L·E·V·(1−ρ); EAL = L·C·(1−ρ); five fixed tiers.\n\n" "Stateless: request bodies are never stored or logged.\n\n" "**Educational and research use only.** Not a forecast, engineering assessment or " "actuarial figure. The oncology endpoints are not a medical device, are not clinically " "validated, and must not be sent patient-identifiable information."), "license": {"name": "Apache-2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0"}}, "tags": [{"name": "framework"}, {"name": "disaster"}, {"name": "oncology"}], "paths": { "/health": _get("Liveness check", "framework"), "/v1/framework": _get("Fixed tier table, consequence scale and anchors", "framework"), "/v1/exposure": _get("Advisory log-normalised exposure E_log", "framework", [ {"name": "N", "in": "query", "required": True, "schema": {"type": "number"}}, {"name": "domain", "in": "query", "schema": {"type": "string", "enum": ["disaster", "oncology"]}}]), "/v1/disaster/assess": _post("Score one asset or city", _disaster_input, "disaster"), "/v1/disaster/rank": _post("Score and rank a portfolio (max 100)", _rank_body(_disaster_input, "Assets to rank"), "disaster"), "/v1/disaster/cohort": _get("Published eight-asset validation cohort, ranked", "disaster"), "/v1/multi": _post("Multi-hazard, multi-category form (Eq. 3/5) — not field-validated", { "type": "object", "required": ["hazards", "weights"], "additionalProperties": False, "properties": { "N": _N, "weights": {"type": "object", "description": "social, economic, environmental; must sum to 1", "example": {"social": 0.4, "economic": 0.3, "environmental": 0.3}}, "hazards": {"type": "array", "maxItems": 10, "items": {"type": "object"}}}}, "disaster"), "/v1/oncology/assess": _post("Score one HCC cohort/stratum", _onc_input, "oncology"), "/v1/oncology/rank": _post("Score and rank strata (max 100)", _rank_body(_onc_input, "Strata to rank; use non-identifying labels"), "oncology"), "/v1/oncology/cohorts": _get("Published HCC cohorts and Pearl-protocol aetiologies", "oncology"), }, } DOCS_HTML = """