jampuramprem commited on
Commit
d17b1dd
·
1 Parent(s): 74e7a0b

Add homepage to FastAPI server with endpoint overview

Browse files
Files changed (1) hide show
  1. server/app.py +201 -0
server/app.py CHANGED
@@ -28,6 +28,9 @@ Usage:
28
  python -m server.app
29
  """
30
 
 
 
 
31
  try:
32
  from openenv.core.env_server.http_server import create_app
33
  except Exception as e: # pragma: no cover
@@ -52,6 +55,204 @@ app = create_app(
52
  max_concurrent_envs=1, # increase this number to allow more concurrent WebSocket sessions
53
  )
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  def main(host: str = "0.0.0.0", port: int = 8000):
57
  """
 
28
  python -m server.app
29
  """
30
 
31
+ from fastapi import Request
32
+ from fastapi.responses import HTMLResponse
33
+
34
  try:
35
  from openenv.core.env_server.http_server import create_app
36
  except Exception as e: # pragma: no cover
 
55
  max_concurrent_envs=1, # increase this number to allow more concurrent WebSocket sessions
56
  )
57
 
58
+ _HOMEPAGE_HTML = """<!DOCTYPE html>
59
+ <html lang="en">
60
+ <head>
61
+ <meta charset="UTF-8" />
62
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
63
+ <title>AxiomForgeAI — Math RL Environment</title>
64
+ <style>
65
+ * { box-sizing: border-box; margin: 0; padding: 0; }
66
+ body {
67
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
68
+ background: #0f0f1a;
69
+ color: #e2e8f0;
70
+ min-height: 100vh;
71
+ display: flex;
72
+ flex-direction: column;
73
+ align-items: center;
74
+ padding: 3rem 1.5rem;
75
+ }
76
+ .hero {
77
+ text-align: center;
78
+ margin-bottom: 3rem;
79
+ }
80
+ .badge {
81
+ display: inline-block;
82
+ background: linear-gradient(135deg, #6366f1, #ec4899);
83
+ color: white;
84
+ font-size: 0.75rem;
85
+ font-weight: 600;
86
+ letter-spacing: 0.08em;
87
+ text-transform: uppercase;
88
+ padding: 0.3rem 0.8rem;
89
+ border-radius: 999px;
90
+ margin-bottom: 1.2rem;
91
+ }
92
+ h1 {
93
+ font-size: 2.8rem;
94
+ font-weight: 800;
95
+ background: linear-gradient(135deg, #818cf8, #f472b6);
96
+ -webkit-background-clip: text;
97
+ -webkit-text-fill-color: transparent;
98
+ background-clip: text;
99
+ margin-bottom: 1rem;
100
+ }
101
+ .subtitle {
102
+ color: #94a3b8;
103
+ font-size: 1.1rem;
104
+ max-width: 600px;
105
+ line-height: 1.7;
106
+ margin: 0 auto;
107
+ }
108
+ .grid {
109
+ display: grid;
110
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
111
+ gap: 1.25rem;
112
+ width: 100%;
113
+ max-width: 900px;
114
+ margin-bottom: 2.5rem;
115
+ }
116
+ .card {
117
+ background: #1e1e2e;
118
+ border: 1px solid #2d2d44;
119
+ border-radius: 12px;
120
+ padding: 1.5rem;
121
+ transition: border-color 0.2s, transform 0.2s;
122
+ }
123
+ .card:hover {
124
+ border-color: #6366f1;
125
+ transform: translateY(-2px);
126
+ }
127
+ .card-header {
128
+ display: flex;
129
+ align-items: center;
130
+ gap: 0.75rem;
131
+ margin-bottom: 0.75rem;
132
+ }
133
+ .method {
134
+ font-size: 0.7rem;
135
+ font-weight: 700;
136
+ padding: 0.2rem 0.5rem;
137
+ border-radius: 4px;
138
+ text-transform: uppercase;
139
+ letter-spacing: 0.05em;
140
+ }
141
+ .post { background: #1a3a2a; color: #4ade80; border: 1px solid #4ade8040; }
142
+ .get { background: #1a2a4a; color: #60a5fa; border: 1px solid #60a5fa40; }
143
+ .ws { background: #2a1a3a; color: #c084fc; border: 1px solid #c084fc40; }
144
+ .endpoint {
145
+ font-family: "Fira Code", "Cascadia Code", monospace;
146
+ font-size: 1rem;
147
+ font-weight: 600;
148
+ color: #e2e8f0;
149
+ }
150
+ .card p {
151
+ color: #94a3b8;
152
+ font-size: 0.9rem;
153
+ line-height: 1.6;
154
+ }
155
+ .links {
156
+ display: flex;
157
+ gap: 1rem;
158
+ flex-wrap: wrap;
159
+ justify-content: center;
160
+ }
161
+ .btn {
162
+ display: inline-flex;
163
+ align-items: center;
164
+ gap: 0.5rem;
165
+ padding: 0.65rem 1.4rem;
166
+ border-radius: 8px;
167
+ font-size: 0.9rem;
168
+ font-weight: 600;
169
+ text-decoration: none;
170
+ transition: opacity 0.2s;
171
+ }
172
+ .btn:hover { opacity: 0.85; }
173
+ .btn-primary { background: linear-gradient(135deg, #6366f1, #ec4899); color: white; }
174
+ .btn-outline { border: 1px solid #2d2d44; color: #94a3b8; background: #1e1e2e; }
175
+ footer {
176
+ margin-top: 3rem;
177
+ color: #475569;
178
+ font-size: 0.8rem;
179
+ text-align: center;
180
+ }
181
+ </style>
182
+ </head>
183
+ <body>
184
+ <div class="hero">
185
+ <div class="badge">OpenEnv Hackathon India 2026</div>
186
+ <h1>AxiomForgeAI</h1>
187
+ <p class="subtitle">
188
+ A self-improving math RL environment. The model practices on verified problems,
189
+ generates new challenges when ready, and learns from solution attempts whose
190
+ reasoning steps and final answers agree.
191
+ </p>
192
+ </div>
193
+
194
+ <div class="grid">
195
+ <div class="card">
196
+ <div class="card-header">
197
+ <span class="method post">POST</span>
198
+ <span class="endpoint">/reset</span>
199
+ </div>
200
+ <p>Start a new episode. Returns a math question with topic and difficulty metadata.</p>
201
+ </div>
202
+ <div class="card">
203
+ <div class="card-header">
204
+ <span class="method post">POST</span>
205
+ <span class="endpoint">/step</span>
206
+ </div>
207
+ <p>Submit a solution for the current question. Returns reward, feedback, and scoring breakdown.</p>
208
+ </div>
209
+ <div class="card">
210
+ <div class="card-header">
211
+ <span class="method get">GET</span>
212
+ <span class="endpoint">/state</span>
213
+ </div>
214
+ <p>Get the current episode state including episode ID and step count.</p>
215
+ </div>
216
+ <div class="card">
217
+ <div class="card-header">
218
+ <span class="method get">GET</span>
219
+ <span class="endpoint">/schema</span>
220
+ </div>
221
+ <p>Returns JSON schemas for action and observation types.</p>
222
+ </div>
223
+ <div class="card">
224
+ <div class="card-header">
225
+ <span class="method get">GET</span>
226
+ <span class="endpoint">/health</span>
227
+ </div>
228
+ <p>Health check endpoint. Returns server status and environment availability.</p>
229
+ </div>
230
+ <div class="card">
231
+ <div class="card-header">
232
+ <span class="method ws">WS</span>
233
+ <span class="endpoint">/ws</span>
234
+ </div>
235
+ <p>WebSocket endpoint for persistent sessions. Supports concurrent multi-agent connections.</p>
236
+ </div>
237
+ </div>
238
+
239
+ <div class="links">
240
+ <a class="btn btn-primary" href="/docs">Swagger UI</a>
241
+ <a class="btn btn-outline" href="/redoc">ReDoc</a>
242
+ <a class="btn btn-outline" href="https://github.com/Prem01-cyber/AxiomForgeAI" target="_blank">GitHub</a>
243
+ <a class="btn btn-outline" href="https://huggingface.co/spaces/jampuramprem/AxiomForgeAI" target="_blank">HF Space</a>
244
+ </div>
245
+
246
+ <footer>Engineered for the OpenEnv Hackathon India 2026 &mdash; Powered by OpenEnv</footer>
247
+ </body>
248
+ </html>
249
+ """
250
+
251
+
252
+ @app.get("/", response_class=HTMLResponse, include_in_schema=False)
253
+ async def homepage(_request: Request) -> HTMLResponse:
254
+ return HTMLResponse(content=_HOMEPAGE_HTML)
255
+
256
 
257
  def main(host: str = "0.0.0.0", port: int = 8000):
258
  """