Spaces:
Running
Running
| # 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") | |
| 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", | |
| } | |
| def healthz(): | |
| return {"status": "ok", "service": "graphql-gateway", "doctrine": DOCTRINE, | |
| "flagships": len(FLAGSHIPS)} | |
| def sdl(): | |
| return PlainTextResponse(schema.as_str()) | |
| 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))) | |