Files
smart-support/backend/app/openapi/models.py
Yaojia Wang a54eb224e0 feat: complete phase 3 -- OpenAPI auto-discovery, SSRF protection, tool generation
- SSRF protection: private IP blocking, DNS rebinding defense, redirect validation
- OpenAPI fetcher with SSRF guard, JSON/YAML auto-detection, 10MB limit
- Structural spec validator (3.0.x/3.1.x)
- Endpoint parser with $ref resolution, auto-generated operation IDs
- Heuristic + LLM endpoint classifier with Protocol interface
- Review API at /api/openapi (import, job status, classification CRUD, approve)
- @tool code generator + Agent YAML generator
- Import orchestrator (fetch -> validate -> parse -> classify pipeline)
- 125 new tests, 322 total passing, 93.23% coverage
2026-03-31 00:10:44 +02:00

68 lines
1.8 KiB
Python

"""Data models for OpenAPI auto-discovery module.
Frozen dataclasses for all value objects to ensure immutability.
"""
from __future__ import annotations
from dataclasses import dataclass, field
@dataclass(frozen=True)
class ParameterInfo:
"""Describes a single endpoint parameter."""
name: str
location: str # "path", "query", "header", "cookie"
required: bool
schema_type: str # "string", "integer", "boolean", etc.
description: str = ""
@dataclass(frozen=True)
class EndpointInfo:
"""Describes a single API endpoint."""
path: str
method: str # uppercase: GET, POST, PUT, DELETE, PATCH
operation_id: str
summary: str
description: str
parameters: tuple[ParameterInfo, ...] = field(default_factory=tuple)
request_body_schema: dict | None = None
response_schema: dict | None = None
@dataclass(frozen=True)
class ClassificationResult:
"""Result of classifying an endpoint for agent routing."""
endpoint: EndpointInfo
access_type: str # "read" or "write"
customer_params: tuple[str, ...] # param names that identify the customer
agent_group: str # which agent group handles this endpoint
confidence: float # 0.0 to 1.0
needs_interrupt: bool # requires human approval before execution
@dataclass(frozen=True)
class ImportJob:
"""Tracks the state of an OpenAPI import job."""
job_id: str
status: str # "pending", "fetching", "validating", "parsing", "classifying", "done", "failed"
spec_url: str
total_endpoints: int = 0
classified_count: int = 0
error_message: str | None = None
@dataclass(frozen=True)
class GeneratedTool:
"""A generated LangChain tool from a classified endpoint."""
function_name: str
endpoint: EndpointInfo
classification: ClassificationResult
code: str