Upload routes.py
Browse files- app/api/routes.py +72 -13
app/api/routes.py
CHANGED
|
@@ -6,7 +6,8 @@ from fastapi import APIRouter, Depends, HTTPException, Query
|
|
| 6 |
|
| 7 |
from app.core.config import Settings, get_settings
|
| 8 |
from app.core.security import CurrentUser, get_current_user
|
| 9 |
-
from app.
|
|
|
|
| 10 |
from app.models.workflow import (
|
| 11 |
ChatRequest,
|
| 12 |
ChatResponse,
|
|
@@ -62,7 +63,7 @@ from app.models.workflow import (
|
|
| 62 |
WebhookInspectResponse,
|
| 63 |
)
|
| 64 |
from app.services.adapters import adapters
|
| 65 |
-
from app.services.catalog import NODE_CATALOG
|
| 66 |
from app.services.chat import chat_service
|
| 67 |
from app.services.collaboration import CollaborationRepository
|
| 68 |
from app.services.deployment import deploy_to_n8n
|
|
@@ -104,8 +105,13 @@ async def generate_workflow(
|
|
| 104 |
user: User,
|
| 105 |
settings: AppSettings,
|
| 106 |
) -> GenerateWorkflowResponse:
|
| 107 |
-
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
|
| 111 |
@router.post("/validate", response_model=ValidationResult)
|
|
@@ -291,19 +297,35 @@ async def export_workflow(request: ExportRequest, user: User):
|
|
| 291 |
@router.get("/templates")
|
| 292 |
async def list_templates(
|
| 293 |
user: User,
|
|
|
|
| 294 |
q: str = Query(default="", max_length=200),
|
| 295 |
category: str | None = Query(default=None, max_length=80),
|
| 296 |
limit: int = Query(default=24, ge=1, le=100),
|
| 297 |
offset: int = Query(default=0, ge=0),
|
| 298 |
) -> dict[str, list[TemplateSummary] | int]:
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
|
| 308 |
|
| 309 |
@router.get("/nodes")
|
|
@@ -329,7 +351,30 @@ async def list_nodes(
|
|
| 329 |
|
| 330 |
@router.get("/projects", response_model=list[ProjectSummary])
|
| 331 |
async def list_projects(user: User, settings: AppSettings) -> list[ProjectSummary]:
|
| 332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
|
| 334 |
|
| 335 |
@router.post("/save", response_model=SaveResponse)
|
|
@@ -340,6 +385,8 @@ async def save_workflow(
|
|
| 340 |
) -> SaveResponse:
|
| 341 |
try:
|
| 342 |
return await WorkflowRepository(settings).save(request, user.id)
|
|
|
|
|
|
|
| 343 |
except ValueError as exc:
|
| 344 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 345 |
|
|
@@ -350,6 +397,8 @@ async def create_share(
|
|
| 350 |
) -> ShareResponse:
|
| 351 |
try:
|
| 352 |
return await CollaborationRepository(settings).create_share(request, user.id)
|
|
|
|
|
|
|
| 353 |
except ValueError as exc:
|
| 354 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 355 |
|
|
@@ -360,6 +409,8 @@ async def get_shared_workflow(token: str, settings: AppSettings) -> SharedWorkfl
|
|
| 360 |
raise HTTPException(status_code=404, detail="Share link was not found")
|
| 361 |
try:
|
| 362 |
return await CollaborationRepository(settings).shared_workflow(token)
|
|
|
|
|
|
|
| 363 |
except ValueError as exc:
|
| 364 |
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
| 365 |
|
|
@@ -370,6 +421,8 @@ async def list_versions(
|
|
| 370 |
) -> list[VersionSummary]:
|
| 371 |
try:
|
| 372 |
return await CollaborationRepository(settings).versions(workflow_id, user.id)
|
|
|
|
|
|
|
| 373 |
except ValueError as exc:
|
| 374 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 375 |
|
|
@@ -380,6 +433,8 @@ async def restore_version(
|
|
| 380 |
) -> WorkflowDocument:
|
| 381 |
try:
|
| 382 |
return await CollaborationRepository(settings).restore(workflow_id, version, user.id)
|
|
|
|
|
|
|
| 383 |
except ValueError as exc:
|
| 384 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 385 |
|
|
@@ -390,6 +445,8 @@ async def list_comments(
|
|
| 390 |
) -> list[WorkflowComment]:
|
| 391 |
try:
|
| 392 |
return await CollaborationRepository(settings).comments(workflow_id, user.id)
|
|
|
|
|
|
|
| 393 |
except ValueError as exc:
|
| 394 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 395 |
|
|
@@ -402,6 +459,8 @@ async def add_comment(
|
|
| 402 |
return await CollaborationRepository(settings).add_comment(
|
| 403 |
request.workflow_id, request.body, request.node_id, user.id
|
| 404 |
)
|
|
|
|
|
|
|
| 405 |
except ValueError as exc:
|
| 406 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 407 |
|
|
|
|
| 6 |
|
| 7 |
from app.core.config import Settings, get_settings
|
| 8 |
from app.core.security import CurrentUser, get_current_user
|
| 9 |
+
from app.core.errors import ServiceConfigurationError
|
| 10 |
+
from app.models.catalog import DashboardSummary, NodeDefinition, ProjectSummary, TemplateSummary
|
| 11 |
from app.models.workflow import (
|
| 12 |
ChatRequest,
|
| 13 |
ChatResponse,
|
|
|
|
| 63 |
WebhookInspectResponse,
|
| 64 |
)
|
| 65 |
from app.services.adapters import adapters
|
| 66 |
+
from app.services.catalog import NODE_CATALOG
|
| 67 |
from app.services.chat import chat_service
|
| 68 |
from app.services.collaboration import CollaborationRepository
|
| 69 |
from app.services.deployment import deploy_to_n8n
|
|
|
|
| 105 |
user: User,
|
| 106 |
settings: AppSettings,
|
| 107 |
) -> GenerateWorkflowResponse:
|
| 108 |
+
try:
|
| 109 |
+
provider = providers.get(request.provider or settings.ai_provider)
|
| 110 |
+
return await provider.generate(request.prompt, request.model)
|
| 111 |
+
except ValueError as exc:
|
| 112 |
+
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
| 113 |
+
except (RuntimeError, httpx.HTTPError) as exc:
|
| 114 |
+
raise HTTPException(status_code=502, detail=f"Workflow generation failed: {exc}") from exc
|
| 115 |
|
| 116 |
|
| 117 |
@router.post("/validate", response_model=ValidationResult)
|
|
|
|
| 297 |
@router.get("/templates")
|
| 298 |
async def list_templates(
|
| 299 |
user: User,
|
| 300 |
+
settings: AppSettings,
|
| 301 |
q: str = Query(default="", max_length=200),
|
| 302 |
category: str | None = Query(default=None, max_length=80),
|
| 303 |
limit: int = Query(default=24, ge=1, le=100),
|
| 304 |
offset: int = Query(default=0, ge=0),
|
| 305 |
) -> dict[str, list[TemplateSummary] | int]:
|
| 306 |
+
try:
|
| 307 |
+
items, total = await WorkflowRepository(settings).templates(
|
| 308 |
+
user.id,
|
| 309 |
+
query=q.strip(),
|
| 310 |
+
category=category,
|
| 311 |
+
limit=limit,
|
| 312 |
+
offset=offset,
|
| 313 |
+
)
|
| 314 |
+
return {"items": items, "total": total}
|
| 315 |
+
except ServiceConfigurationError as exc:
|
| 316 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
@router.get("/templates/{template_id}", response_model=WorkflowDocument)
|
| 320 |
+
async def get_template(
|
| 321 |
+
template_id: str, user: User, settings: AppSettings
|
| 322 |
+
) -> WorkflowDocument:
|
| 323 |
+
try:
|
| 324 |
+
return await WorkflowRepository(settings).template(template_id, user.id)
|
| 325 |
+
except ServiceConfigurationError as exc:
|
| 326 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 327 |
+
except ValueError as exc:
|
| 328 |
+
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
| 329 |
|
| 330 |
|
| 331 |
@router.get("/nodes")
|
|
|
|
| 351 |
|
| 352 |
@router.get("/projects", response_model=list[ProjectSummary])
|
| 353 |
async def list_projects(user: User, settings: AppSettings) -> list[ProjectSummary]:
|
| 354 |
+
try:
|
| 355 |
+
return await WorkflowRepository(settings).projects(user.id)
|
| 356 |
+
except ServiceConfigurationError as exc:
|
| 357 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
@router.get("/dashboard", response_model=DashboardSummary)
|
| 361 |
+
async def dashboard(user: User, settings: AppSettings) -> DashboardSummary:
|
| 362 |
+
try:
|
| 363 |
+
return await WorkflowRepository(settings).dashboard(user.id, user.email)
|
| 364 |
+
except ServiceConfigurationError as exc:
|
| 365 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
@router.get("/workflows/{workflow_id}", response_model=WorkflowDocument)
|
| 369 |
+
async def get_workflow(
|
| 370 |
+
workflow_id: str, user: User, settings: AppSettings
|
| 371 |
+
) -> WorkflowDocument:
|
| 372 |
+
try:
|
| 373 |
+
return await WorkflowRepository(settings).workflow(workflow_id, user.id)
|
| 374 |
+
except ServiceConfigurationError as exc:
|
| 375 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 376 |
+
except ValueError as exc:
|
| 377 |
+
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
| 378 |
|
| 379 |
|
| 380 |
@router.post("/save", response_model=SaveResponse)
|
|
|
|
| 385 |
) -> SaveResponse:
|
| 386 |
try:
|
| 387 |
return await WorkflowRepository(settings).save(request, user.id)
|
| 388 |
+
except ServiceConfigurationError as exc:
|
| 389 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 390 |
except ValueError as exc:
|
| 391 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 392 |
|
|
|
|
| 397 |
) -> ShareResponse:
|
| 398 |
try:
|
| 399 |
return await CollaborationRepository(settings).create_share(request, user.id)
|
| 400 |
+
except ServiceConfigurationError as exc:
|
| 401 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 402 |
except ValueError as exc:
|
| 403 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 404 |
|
|
|
|
| 409 |
raise HTTPException(status_code=404, detail="Share link was not found")
|
| 410 |
try:
|
| 411 |
return await CollaborationRepository(settings).shared_workflow(token)
|
| 412 |
+
except ServiceConfigurationError as exc:
|
| 413 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 414 |
except ValueError as exc:
|
| 415 |
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
| 416 |
|
|
|
|
| 421 |
) -> list[VersionSummary]:
|
| 422 |
try:
|
| 423 |
return await CollaborationRepository(settings).versions(workflow_id, user.id)
|
| 424 |
+
except ServiceConfigurationError as exc:
|
| 425 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 426 |
except ValueError as exc:
|
| 427 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 428 |
|
|
|
|
| 433 |
) -> WorkflowDocument:
|
| 434 |
try:
|
| 435 |
return await CollaborationRepository(settings).restore(workflow_id, version, user.id)
|
| 436 |
+
except ServiceConfigurationError as exc:
|
| 437 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 438 |
except ValueError as exc:
|
| 439 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 440 |
|
|
|
|
| 445 |
) -> list[WorkflowComment]:
|
| 446 |
try:
|
| 447 |
return await CollaborationRepository(settings).comments(workflow_id, user.id)
|
| 448 |
+
except ServiceConfigurationError as exc:
|
| 449 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 450 |
except ValueError as exc:
|
| 451 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 452 |
|
|
|
|
| 459 |
return await CollaborationRepository(settings).add_comment(
|
| 460 |
request.workflow_id, request.body, request.node_id, user.id
|
| 461 |
)
|
| 462 |
+
except ServiceConfigurationError as exc:
|
| 463 |
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
| 464 |
except ValueError as exc:
|
| 465 |
raise HTTPException(status_code=403, detail=str(exc)) from exc
|
| 466 |
|