|
| 1 | +import json |
1 | 2 | import logging |
2 | 3 | import urllib.parse |
3 | 4 | from collections.abc import Awaitable, Callable |
|
11 | 12 | Body, |
12 | 13 | Depends, |
13 | 14 | FastAPI, |
| 15 | + Form, |
14 | 16 | HTTPException, |
15 | 17 | Request, |
16 | 18 | Response, |
17 | 19 | status, |
18 | 20 | ) |
19 | 21 | from fastapi.datastructures import Address |
20 | 22 | from fastapi.middleware.cors import CORSMiddleware |
21 | | -from fastapi.responses import RedirectResponse, StreamingResponse |
| 23 | +from fastapi.responses import HTMLResponse, RedirectResponse, StreamingResponse |
22 | 24 | from fastapi.security import OAuth2AuthorizationCodeBearer |
| 25 | +from fastapi.templating import Jinja2Templates |
23 | 26 | from observability_utils.tracing import ( |
24 | 27 | add_span_attributes, |
25 | 28 | get_tracer, |
@@ -179,15 +182,6 @@ async def on_token_error_401(_: Request, __: Exception): |
179 | 182 | ) |
180 | 183 |
|
181 | 184 |
|
182 | | -@secure_router.get("/", include_in_schema=False) |
183 | | -def root_redirect() -> RedirectResponse: |
184 | | - """Redirect to docs url""" |
185 | | - return RedirectResponse( |
186 | | - status_code=status.HTTP_307_TEMPORARY_REDIRECT, |
187 | | - url=ApplicationConfig.DOCS_ENDPOINT, |
188 | | - ) |
189 | | - |
190 | | - |
191 | 185 | @secure_router.get("/environment", tags=[Tag.ENV]) |
192 | 186 | @start_as_current_span(TRACER, "runner") |
193 | 187 | def get_environment( |
@@ -621,3 +615,67 @@ async def inject_propagated_observability_context( |
621 | 615 | attach(ctx) |
622 | 616 | response = await call_next(request) |
623 | 617 | return response |
| 618 | + |
| 619 | + |
| 620 | +templates = Jinja2Templates(directory="templates") |
| 621 | + |
| 622 | + |
| 623 | +@secure_router.get("/", include_in_schema=False, response_class=HTMLResponse) |
| 624 | +def root_landing( |
| 625 | + request: Request, |
| 626 | + runner: Annotated[WorkerDispatcher, Depends(_runner)], |
| 627 | +) -> HTMLResponse: |
| 628 | + |
| 629 | + if runner._config.env.metadata: |
| 630 | + instrument = runner._config.env.metadata.instrument |
| 631 | + else: |
| 632 | + instrument = "<ixx>" |
| 633 | + |
| 634 | + devices = runner.run(interface.get_devices) |
| 635 | + devices = [ |
| 636 | + {"device": device.name, "protocols": [p.name for p in device.protocols]} |
| 637 | + for device in devices |
| 638 | + ] |
| 639 | + |
| 640 | + plans = runner.run(interface.get_plans) |
| 641 | + task_list = get_tasks(runner) |
| 642 | + |
| 643 | + context = { |
| 644 | + "instrument": instrument, |
| 645 | + "devices": devices, |
| 646 | + "plans": plans, |
| 647 | + "tasks": task_list.tasks, |
| 648 | + } |
| 649 | + |
| 650 | + return templates.TemplateResponse( |
| 651 | + request=request, name="index.html", context=context |
| 652 | + ) |
| 653 | + |
| 654 | + |
| 655 | +@secure_router.post("/run", include_in_schema=True, tags=[Tag.TASK]) |
| 656 | +@start_as_current_span(TRACER) |
| 657 | +def run( |
| 658 | + name: Annotated[str, Form()], |
| 659 | + params: Annotated[str, Form()], |
| 660 | + instrument_session: Annotated[str, Form()], |
| 661 | + request: Request, |
| 662 | + response: Response, |
| 663 | + runner: Annotated[WorkerDispatcher, Depends(_runner)], |
| 664 | +) -> RedirectResponse: |
| 665 | + |
| 666 | + task_request = TaskRequest( |
| 667 | + name=name, |
| 668 | + params=json.loads(params), # do this validator in the model? |
| 669 | + instrument_session=instrument_session, |
| 670 | + ) |
| 671 | + res = submit_task(request, response, task_request, runner) |
| 672 | + |
| 673 | + tid = res.task_id |
| 674 | + req_task = WorkerTask(task_id=tid) |
| 675 | + |
| 676 | + try: |
| 677 | + set_active_task(request, req_task, runner) |
| 678 | + except HTTPException: |
| 679 | + delete_submitted_task(tid, runner) |
| 680 | + |
| 681 | + return RedirectResponse(status_code=status.HTTP_204_NO_CONTENT, url="/") |
0 commit comments