component_framework.adapters.fastapi
FastAPI adapter for component endpoints.
1"""FastAPI adapter for component endpoints.""" 2 3import logging 4 5try: 6 from fastapi import HTTPException, Request 7 from fastapi.responses import JSONResponse 8except ImportError as e: 9 from . import _require_extra 10 11 raise _require_extra("fastapi", "fastapi") from e 12 13from ..core import StateSerializer, registry 14 15logger = logging.getLogger(__name__) 16 17 18async def component_endpoint(name: str, request: Request) -> JSONResponse: 19 """ 20 Generic component endpoint for FastAPI. 21 22 POST /components/{name} 23 Body: { 24 "event": "event_name", 25 "payload": {...}, 26 "state": "serialized_state" 27 } 28 29 Returns: { 30 "html": "rendered_html", 31 "state": "serialized_state", 32 "component_id": "component-id" 33 } 34 """ 35 try: 36 # Get component class 37 component_cls = registry.get(name) 38 if not component_cls: 39 raise HTTPException(status_code=404, detail=f"Component '{name}' not found") 40 41 # Parse request data 42 try: 43 data = await request.json() 44 except Exception as e: 45 raise HTTPException(status_code=400, detail=f"Invalid JSON: {e}") 46 47 # Extract parameters 48 params = data.get("params", {}) 49 event = data.get("event") 50 payload = data.get("payload", {}) 51 state_str = data.get("state") 52 53 # Deserialize state if provided 54 state = None 55 if state_str: 56 try: 57 state = StateSerializer.deserialize(state_str) 58 except Exception as e: 59 raise HTTPException(status_code=400, detail=f"Invalid state: {e}") 60 61 # Create and dispatch component 62 component = component_cls(**params) 63 result = component.dispatch(event=event, payload=payload, state=state) 64 65 # Serialize state for response 66 result["state"] = StateSerializer.serialize(result["state"]) 67 68 return JSONResponse(content=result) 69 70 except HTTPException: 71 raise 72 except Exception: 73 logger.exception(f"Error processing component '{name}'") 74 raise HTTPException(status_code=500, detail="Internal server error") 75 76 77def create_component_routes(app): 78 """ 79 Add component endpoint to FastAPI app. 80 81 Usage: 82 from fastapi import FastAPI 83 app = FastAPI() 84 create_component_routes(app) 85 """ 86 app.add_api_route( 87 "/components/{name}", 88 component_endpoint, 89 methods=["POST"], 90 name="component_endpoint", 91 )
logger =
<Logger component_framework.adapters.fastapi (WARNING)>
async def
component_endpoint( name: str, request: starlette.requests.Request) -> starlette.responses.JSONResponse:
19async def component_endpoint(name: str, request: Request) -> JSONResponse: 20 """ 21 Generic component endpoint for FastAPI. 22 23 POST /components/{name} 24 Body: { 25 "event": "event_name", 26 "payload": {...}, 27 "state": "serialized_state" 28 } 29 30 Returns: { 31 "html": "rendered_html", 32 "state": "serialized_state", 33 "component_id": "component-id" 34 } 35 """ 36 try: 37 # Get component class 38 component_cls = registry.get(name) 39 if not component_cls: 40 raise HTTPException(status_code=404, detail=f"Component '{name}' not found") 41 42 # Parse request data 43 try: 44 data = await request.json() 45 except Exception as e: 46 raise HTTPException(status_code=400, detail=f"Invalid JSON: {e}") 47 48 # Extract parameters 49 params = data.get("params", {}) 50 event = data.get("event") 51 payload = data.get("payload", {}) 52 state_str = data.get("state") 53 54 # Deserialize state if provided 55 state = None 56 if state_str: 57 try: 58 state = StateSerializer.deserialize(state_str) 59 except Exception as e: 60 raise HTTPException(status_code=400, detail=f"Invalid state: {e}") 61 62 # Create and dispatch component 63 component = component_cls(**params) 64 result = component.dispatch(event=event, payload=payload, state=state) 65 66 # Serialize state for response 67 result["state"] = StateSerializer.serialize(result["state"]) 68 69 return JSONResponse(content=result) 70 71 except HTTPException: 72 raise 73 except Exception: 74 logger.exception(f"Error processing component '{name}'") 75 raise HTTPException(status_code=500, detail="Internal server error")
Generic component endpoint for FastAPI.
POST /components/{name} Body: { "event": "event_name", "payload": {...}, "state": "serialized_state" }
Returns: { "html": "rendered_html", "state": "serialized_state", "component_id": "component-id" }
def
create_component_routes(app):
78def create_component_routes(app): 79 """ 80 Add component endpoint to FastAPI app. 81 82 Usage: 83 from fastapi import FastAPI 84 app = FastAPI() 85 create_component_routes(app) 86 """ 87 app.add_api_route( 88 "/components/{name}", 89 component_endpoint, 90 methods=["POST"], 91 name="component_endpoint", 92 )
Add component endpoint to FastAPI app.
Usage:
from fastapi import FastAPI app = FastAPI() create_component_routes(app)