graphql-gateway / app.py
betterwithage's picture
feat(graphql): SZL GraphQL gateway — app.py
62616b4 verified
# SPDX-License-Identifier: Apache-2.0
# Copyright 2026 SZL Holdings. Licensed under the Apache License, Version 2.0.
"""SZL GraphQL Gateway — FastAPI + Strawberry.
Serves a unified GraphQL surface over the 5 flagships:
POST /graphql — GraphQL endpoint
GET /graphiql — mobile-friendly interactive explorer
GET /graphql/sdl — full SDL
GET /healthz — health + Doctrine v11
GET / — service info
Doctrine v11 — LOCKED, verbatim: 749/14/163 · locked_at c7c0ba17.
Signed: Yachay <yachay@szlholdings.dev>
Co-Authored-By: Perplexity Computer Agent
"""
from __future__ import annotations
import os
from fastapi import FastAPI
from fastapi.responses import HTMLResponse, PlainTextResponse
from strawberry.fastapi import GraphQLRouter
from szl_graphql_schema import DOCTRINE_LOCKED_AT, FLAGSHIPS, schema
app = FastAPI(title="szl-graphql-gateway", version="1.0.0")
DOCTRINE = {"version": "v11", "declarations": 749, "axioms": 14, "sorries": 163,
"locked_at": DOCTRINE_LOCKED_AT}
# GraphiQL is served by our own mobile-friendly route below; disable the
# built-in one so we control the viewport meta.
graphql_app = GraphQLRouter(schema, graphql_ide=None)
app.include_router(graphql_app, prefix="/graphql")
@app.get("/")
def root():
return {
"service": "szl-graphql-gateway",
"version": "1.0.0",
"doctrine": DOCTRINE,
"flagships": list(FLAGSHIPS),
"endpoints": ["/graphql", "/graphiql", "/graphql/sdl", "/healthz"],
"license": "Apache-2.0",
}
@app.get("/healthz")
def healthz():
return {"status": "ok", "service": "graphql-gateway", "doctrine": DOCTRINE,
"flagships": len(FLAGSHIPS)}
@app.get("/graphql/sdl", response_class=PlainTextResponse)
def sdl():
return PlainTextResponse(schema.as_str())
@app.get("/graphiql", response_class=HTMLResponse)
def graphiql():
return HTMLResponse(_GRAPHIQL_HTML)
_GRAPHIQL_HTML = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="theme-color" content="#0a0e14">
<title>SZL GraphQL — Explorer</title>
<link rel="stylesheet" href="https://unpkg.com/graphiql@3.0.6/graphiql.min.css" />
<style>
* { -webkit-tap-highlight-color: transparent; box-sizing: border-box; }
html, body { margin:0; height:100%; background:#0a0e14; max-width:100vw; overflow-x:hidden; }
#graphiql { height: 100dvh; height: calc(var(--vh, 1vh) * 100); }
.szl-bar { background:#0a0e14; color:#7ee787; font-family:ui-monospace,monospace;
padding: env(safe-area-inset-top) 12px 8px; font-size:14px; display:flex;
flex-wrap:wrap; gap:8px; align-items:center; border-bottom:1px solid #21262d; }
.szl-bar b { color:#58a6ff; }
.szl-bar a { color:#58a6ff; min-height:44px; line-height:44px; }
/* Mobile: stack the GraphiQL editor/result panes vertically */
@media (max-width: 760px) {
.graphiql-container .graphiql-sessions { flex-direction: column; }
}
</style>
</head>
<body>
<div class="szl-bar">
<span>SZL GraphQL Gateway</span>
<b>Doctrine v11 · 749/14/163</b>
<a href="/graphql/sdl">SDL</a>
<a href="/healthz">healthz</a>
</div>
<div id="graphiql">Loading…</div>
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://unpkg.com/graphiql@3.0.6/graphiql.min.js"></script>
<script>
function setVH(){ document.documentElement.style.setProperty('--vh', (window.innerHeight*0.01)+'px'); }
setVH(); addEventListener('resize', setVH); addEventListener('orientationchange', setVH);
const fetcher = GraphiQL.createFetcher({ url: '/graphql' });
const root = ReactDOM.createRoot(document.getElementById('graphiql'));
root.render(React.createElement(GraphiQL, {
fetcher,
defaultQuery: `# SZL GraphQL Gateway — try me\\nquery Mesh {\\n mesh {\\n totalReceipts\\n chainIntegrity\\n flagships { id name healthz { ok } doctrine { version declarations } }\\n slos { flagship objective current }\\n }\\n}`
}));
</script>
</body>
</html>"""
if __name__ == "__main__": # pragma: no cover
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))