| 1 | from typing import Any |
| 2 | from typing import Dict |
| 3 | from typing import List |
| 4 | from typing import Optional |
| 5 | |
| 6 | from fastapi import HTTPException |
| 7 | from pydantic import BaseModel |
| 8 | from pydantic import Field |
| 9 | from pydantic import model_validator |
| 10 | |
| 11 | |
| 12 | class ShuffleConnectorCredentialsResponse(BaseModel): |
| 13 | """Minimal Shuffle connector creds for the frontend's `<ShuffleMCP>` / |
| 14 | `<TryMcpSection>` embeds. We only expose URL + API key — not the full |
| 15 | connector row — to keep the frontend surface narrow.""" |
| 16 | |
| 17 | success: bool |
| 18 | message: str |
| 19 | base_url: str = Field(..., description="The Shuffle backend base URL (e.g. https://shuffler.io).") |
| 20 | api_key: str = Field(..., description="The deployment-wide Shuffle API key from the connectors table.") |
| 21 | |
| 22 | |
| 23 | class IntegrationRequest(BaseModel): |
| 24 | app_name: str = Field(..., description="The name of the application", examples=["PagerDuty"]) |
| 25 | category: str = Field(..., description="The category of the application", examples=["cases"]) |
| 26 | label: str = Field(..., description="The label of the application", examples=["create_ticket"]) |
| 27 | fields: Optional[List[Dict[str, Any]]] = Field( |
| 28 | [], |
| 29 | description="The fields of the application", |
| 30 | examples=[ |
| 31 | [ |
| 32 | {"key": "title", "value": "This is the title"}, |
| 33 | {"key": "description", "value": "This is the description"}, |
| 34 | {"key": "source", "value": "Shuffle"}, |
| 35 | ], |
| 36 | ], |
| 37 | ) |
| 38 | skip_workflow: Optional[bool] = Field( |
| 39 | False, |
| 40 | description="Skip the workflow", |
| 41 | examples=[True], |
| 42 | ) |
| 43 | |
| 44 | |
| 45 | class ExecuteWorkflowRequest(BaseModel): |
| 46 | workflow_id: str = Field(..., description="The ID of the workflow", examples=["workflow_id"]) |
| 47 | execution_arguments: Optional[Dict[str, Any]] = Field( |
| 48 | {}, |
| 49 | description="The execution arguments", |
| 50 | examples=[{"key": "value"}], |
| 51 | ) |
| 52 | start: str = Field("", description="The start of the workflow", examples=["start"]) |
| 53 | |
| 54 | @model_validator(mode="after") |
| 55 | def check_customer_code(self): |
| 56 | execution_arguments = self.execution_arguments or {} |
| 57 | if "customer_code" not in execution_arguments or not execution_arguments["customer_code"]: |
| 58 | raise HTTPException(status_code=400, detail="customer_code is required") |
| 59 | return self |