upload
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, computed_field
|
||||
|
||||
from app.models import ActionIngestStatus, HttpMethod
|
||||
|
||||
|
||||
class ActionListItemResponse(BaseModel):
|
||||
id: UUID
|
||||
user_id: UUID | None = None
|
||||
operation_id: str | None = None
|
||||
method: HttpMethod
|
||||
path: str
|
||||
base_url: str | None = None
|
||||
summary: str | None = None
|
||||
description: str | None = None
|
||||
tags: list[str] | None = None
|
||||
source_filename: str | None = None
|
||||
ingest_status: ActionIngestStatus
|
||||
ingest_error: str | None = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ActionIngestItemResponse(BaseModel):
|
||||
id: UUID
|
||||
user_id: UUID | None = None
|
||||
operation_id: str | None = None
|
||||
method: HttpMethod
|
||||
path: str
|
||||
summary: str | None = None
|
||||
source_filename: str | None = None
|
||||
ingest_status: ActionIngestStatus
|
||||
ingest_error: str | None = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ActionDetailResponse(ActionListItemResponse):
|
||||
parameters_schema: dict[str, Any] | None = None
|
||||
request_body_schema: dict[str, Any] | None = None
|
||||
response_schema: dict[str, Any] | None = None
|
||||
raw_spec: dict[str, Any] | None = None
|
||||
|
||||
@computed_field(return_type=dict[str, Any] | None)
|
||||
@property
|
||||
def json_schema(self) -> dict[str, Any] | None:
|
||||
if not any((self.parameters_schema, self.request_body_schema, self.response_schema, self.raw_spec)):
|
||||
return None
|
||||
|
||||
return {
|
||||
"parameters": self.parameters_schema,
|
||||
"request_body": self.request_body_schema,
|
||||
"response": self.response_schema,
|
||||
"raw_spec": self.raw_spec,
|
||||
}
|
||||
|
||||
|
||||
class ActionIngestResponse(BaseModel):
|
||||
succeeded_count: int
|
||||
failed_count: int
|
||||
succeeded_actions: list[ActionDetailResponse]
|
||||
failed_actions: list[ActionDetailResponse]
|
||||
@@ -0,0 +1,19 @@
|
||||
from pydantic import AliasChoices, BaseModel, ConfigDict, EmailStr, Field
|
||||
|
||||
|
||||
class RegisterIn(BaseModel):
|
||||
email: EmailStr = Field(max_length=254)
|
||||
password: str = Field(min_length=1, max_length=72)
|
||||
full_name: str = Field(
|
||||
min_length=2,
|
||||
max_length=200,
|
||||
validation_alias=AliasChoices("full_name", "fullName"),
|
||||
serialization_alias="fullName",
|
||||
)
|
||||
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
|
||||
class LoginIn(BaseModel):
|
||||
email: EmailStr = Field(max_length=254)
|
||||
password: str = Field(min_length=1, max_length=72)
|
||||
@@ -0,0 +1,73 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from app.schemas.action_sch import ActionIngestItemResponse
|
||||
|
||||
|
||||
class CapabilityDataFormat(BaseModel):
|
||||
parameter_locations: list[str] = []
|
||||
request_content_types: list[str] = []
|
||||
request_schema_type: str | None = None
|
||||
response_content_types: list[str] = []
|
||||
response_schema_types: list[str] = []
|
||||
|
||||
|
||||
class CapabilityResponse(BaseModel):
|
||||
id: UUID
|
||||
user_id: UUID | None = None
|
||||
action_id: UUID | None = None
|
||||
type: str = "ATOMIC"
|
||||
name: str
|
||||
description: str | None = None
|
||||
input_schema: dict[str, Any] | None = None
|
||||
output_schema: dict[str, Any] | None = None
|
||||
recipe: dict[str, Any] | None = None
|
||||
data_format: CapabilityDataFormat | None = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class CapabilityIngestItemResponse(BaseModel):
|
||||
id: UUID
|
||||
user_id: UUID | None = None
|
||||
action_id: UUID | None = None
|
||||
type: str = "ATOMIC"
|
||||
name: str
|
||||
description: str | None = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ActionIngestWithCapabilitiesResponse(BaseModel):
|
||||
succeeded_count: int
|
||||
failed_count: int
|
||||
created_capabilities_count: int
|
||||
succeeded_actions: list[ActionIngestItemResponse]
|
||||
failed_actions: list[ActionIngestItemResponse]
|
||||
capabilities: list[CapabilityIngestItemResponse]
|
||||
|
||||
|
||||
class CompositeCapabilityRecipeStepCreate(BaseModel):
|
||||
step: int = Field(ge=1)
|
||||
capability_id: UUID
|
||||
inputs: dict[str, str] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class CompositeCapabilityRecipeCreate(BaseModel):
|
||||
version: int = 1
|
||||
steps: list[CompositeCapabilityRecipeStepCreate] = Field(default_factory=list)
|
||||
|
||||
|
||||
class CreateCompositeCapabilityRequest(BaseModel):
|
||||
name: str = Field(min_length=1, max_length=255)
|
||||
description: str | None = None
|
||||
input_schema: dict[str, Any] | None = None
|
||||
output_schema: dict[str, Any] | None = None
|
||||
recipe: CompositeCapabilityRecipeCreate
|
||||
@@ -0,0 +1,67 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Literal
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
class RunPipelineRequest(BaseModel):
|
||||
inputs: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class RunPipelineResponse(BaseModel):
|
||||
run_id: UUID
|
||||
pipeline_id: UUID
|
||||
status: Literal["QUEUED", "RUNNING"]
|
||||
|
||||
|
||||
class ExecutionRunListItemResponse(BaseModel):
|
||||
id: UUID
|
||||
pipeline_id: UUID
|
||||
status: Literal["QUEUED", "RUNNING", "SUCCEEDED", "FAILED", "PARTIAL_FAILED"]
|
||||
error: str | None = None
|
||||
started_at: datetime | None = None
|
||||
finished_at: datetime | None = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ExecutionStepRunResponse(BaseModel):
|
||||
step: int
|
||||
name: str | None = None
|
||||
capability_id: UUID | None = None
|
||||
action_id: UUID | None = None
|
||||
method: Literal["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"] | None = None
|
||||
status_code: int | None = None
|
||||
status: Literal["PENDING", "RUNNING", "SUCCEEDED", "FAILED", "SKIPPED"]
|
||||
resolved_inputs: dict[str, Any] | None = None
|
||||
accepted_payload: Any = None
|
||||
output_payload: Any = None
|
||||
request_snapshot: dict[str, Any] | None = None
|
||||
response_snapshot: dict[str, Any] | None = None
|
||||
error: str | None = None
|
||||
started_at: datetime | None = None
|
||||
finished_at: datetime | None = None
|
||||
duration_ms: int | None = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ExecutionRunDetailResponse(BaseModel):
|
||||
id: UUID
|
||||
pipeline_id: UUID
|
||||
status: Literal["QUEUED", "RUNNING", "SUCCEEDED", "FAILED", "PARTIAL_FAILED"]
|
||||
inputs: dict[str, Any] = Field(default_factory=dict)
|
||||
summary: dict[str, Any] | None = None
|
||||
error: str | None = None
|
||||
started_at: datetime | None = None
|
||||
finished_at: datetime | None = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
steps: list[ExecutionStepRunResponse] = Field(default_factory=list)
|
||||
@@ -0,0 +1,104 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Literal
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
class PipelineInputTypeFromPrevious(BaseModel):
|
||||
from_step: int
|
||||
type: str
|
||||
|
||||
|
||||
class PipelineStepEndpoint(BaseModel):
|
||||
name: str
|
||||
capability_id: UUID
|
||||
action_id: UUID | None = None
|
||||
type: str | None = None
|
||||
input_type: str | dict[str, Any] | None = None
|
||||
output_type: str | dict[str, Any] | None = None
|
||||
|
||||
|
||||
class PipelineGraphNode(BaseModel):
|
||||
step: int
|
||||
name: str
|
||||
description: str | None = None
|
||||
input_connected_from: list[int] = Field(default_factory=list)
|
||||
output_connected_to: list[int] = Field(default_factory=list)
|
||||
input_data_type_from_previous: list[PipelineInputTypeFromPrevious] = Field(default_factory=list)
|
||||
external_inputs: list[str] = Field(default_factory=list)
|
||||
endpoints: list[PipelineStepEndpoint] = Field(default_factory=list)
|
||||
|
||||
|
||||
class PipelineGraphEdge(BaseModel):
|
||||
from_step: int
|
||||
to_step: int
|
||||
type: str
|
||||
|
||||
|
||||
class PipelineGenerateRequest(BaseModel):
|
||||
dialog_id: UUID
|
||||
message: str = Field(min_length=1)
|
||||
capability_ids: list[UUID] | None = None
|
||||
|
||||
|
||||
class PipelineGenerateResponse(BaseModel):
|
||||
status: Literal["ready", "needs_input", "cannot_build"]
|
||||
message_ru: str
|
||||
chat_reply_ru: str
|
||||
pipeline_id: UUID | None = None
|
||||
nodes: list[PipelineGraphNode] = Field(default_factory=list)
|
||||
edges: list[PipelineGraphEdge] = Field(default_factory=list)
|
||||
missing_requirements: list[str] = Field(default_factory=list)
|
||||
context_summary: str | None = None
|
||||
|
||||
|
||||
class PipelineGraphUpdateRequest(BaseModel):
|
||||
nodes: list[PipelineGraphNode] = Field(default_factory=list)
|
||||
edges: list[PipelineGraphEdge] = Field(default_factory=list)
|
||||
|
||||
|
||||
class PipelineGraphUpdateResponse(BaseModel):
|
||||
pipeline_id: UUID
|
||||
nodes: list[PipelineGraphNode] = Field(default_factory=list)
|
||||
edges: list[PipelineGraphEdge] = Field(default_factory=list)
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class DialogResetRequest(BaseModel):
|
||||
dialog_id: UUID
|
||||
|
||||
|
||||
class DialogResetResponse(BaseModel):
|
||||
status: Literal["ok"]
|
||||
message_ru: str
|
||||
|
||||
|
||||
class PipelineDialogListItemResponse(BaseModel):
|
||||
dialog_id: UUID
|
||||
title: str | None = None
|
||||
last_status: str | None = None
|
||||
last_pipeline_id: UUID | None = None
|
||||
last_message_preview: str | None = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class PipelineDialogMessageResponse(BaseModel):
|
||||
id: UUID
|
||||
role: Literal["user", "assistant"]
|
||||
content: str
|
||||
assistant_payload: dict[str, Any] | None = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class PipelineDialogHistoryResponse(BaseModel):
|
||||
dialog_id: UUID
|
||||
title: str | None = None
|
||||
messages: list[PipelineDialogMessageResponse] = Field(default_factory=list)
|
||||
@@ -0,0 +1,33 @@
|
||||
from pydantic import BaseModel, EmailStr, ConfigDict
|
||||
from uuid import UUID
|
||||
from datetime import datetime
|
||||
from app.models import UserRole
|
||||
from typing import Optional
|
||||
|
||||
class UserBase(BaseModel):
|
||||
email: EmailStr
|
||||
full_name: str
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
email: Optional[EmailStr] = None
|
||||
full_name: Optional[str] = None
|
||||
role: Optional[UserRole] = None
|
||||
is_active: Optional[bool] = None
|
||||
min_approvals_required: Optional[int] = None
|
||||
|
||||
class UserResponse(UserBase):
|
||||
id: UUID
|
||||
role: UserRole
|
||||
is_active: bool
|
||||
min_approvals_required: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class UserUpdateMe(BaseModel):
|
||||
email: Optional[EmailStr] = None
|
||||
full_name: Optional[str] = None
|
||||
|
||||
class PasswordUpdate(BaseModel):
|
||||
old_password: str
|
||||
new_password: str
|
||||
@@ -0,0 +1,45 @@
|
||||
from typing import Annotated, Optional
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, EmailStr, Field, ConfigDict, field_validator
|
||||
from app.models import UserRole
|
||||
|
||||
|
||||
class UserBase(BaseModel):
|
||||
email: EmailStr
|
||||
full_name: Annotated[str | None, Field(max_length=255)] = None
|
||||
|
||||
|
||||
class UserResponse(UserBase):
|
||||
id: uuid.UUID
|
||||
role: UserRole
|
||||
is_active: bool
|
||||
created_at: datetime
|
||||
updated_at: datetime | None = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
email: Optional[EmailStr] = None
|
||||
full_name: Optional[str] = Field(None, min_length=2, max_length=255)
|
||||
role: Optional[UserRole] = None
|
||||
is_active: Optional[bool] = None
|
||||
|
||||
|
||||
class UserUpdateMe(BaseModel):
|
||||
email: Optional[EmailStr] = None
|
||||
full_name: Optional[str] = Field(None, min_length=2, max_length=255)
|
||||
|
||||
|
||||
class PasswordUpdate(BaseModel):
|
||||
old_password: str = Field(min_length=8)
|
||||
new_password: str = Field(min_length=8)
|
||||
|
||||
@field_validator("new_password")
|
||||
@classmethod
|
||||
def validate_password_complexity(cls, v: str) -> str:
|
||||
if not any(c.isalpha() for c in v) or not any(c.isdigit() for c in v):
|
||||
raise ValueError("must contain at least one letter and one digit")
|
||||
return v
|
||||
Reference in New Issue
Block a user