mirror of
https://github.com/langgenius/dify.git
synced 2026-09-24 23:22:26 +08:00
feat(cli): adopt generated oRPC contract for unary endpoints (#37090)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
autofix-ci[bot]
parent
d0b376d31a
commit
a15ecf6bec
@@ -87,8 +87,12 @@ class AppDescribeInfo(AppInfoResponse):
|
||||
|
||||
class AppDescribeResponse(BaseModel):
|
||||
info: AppDescribeInfo | None = None
|
||||
parameters: dict[str, Any] | None = None
|
||||
input_schema: dict[str, Any] | None = None
|
||||
# `parameters` (the app-config blob) and `input_schema` (a Draft 2020-12 JSON Schema derived
|
||||
# per-app) are deliberately open JSON, not under-annotated. The `x-dify-opaque` marker tells the
|
||||
# contract generator's readiness detector to treat them as intentional, so the route is not
|
||||
# flagged "annotations incomplete". CLI/web consume them as opaque objects either way.
|
||||
parameters: dict[str, Any] | None = Field(default=None, json_schema_extra={"x-dify-opaque": True})
|
||||
input_schema: dict[str, Any] | None = Field(default=None, json_schema_extra={"x-dify-opaque": True})
|
||||
|
||||
|
||||
class ChatMessageResponse(BaseModel):
|
||||
@@ -173,6 +177,15 @@ class SessionListResponse(BaseModel):
|
||||
data: list[SessionRow]
|
||||
|
||||
|
||||
class SessionListQuery(BaseModel):
|
||||
"""Pagination for GET /account/sessions. Strict (extra='forbid')."""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
page: int = Field(1, ge=1)
|
||||
limit: int = Field(100, ge=1, le=MAX_PAGE_LIMIT)
|
||||
|
||||
|
||||
class RevokeResponse(BaseModel):
|
||||
status: str
|
||||
|
||||
@@ -223,6 +236,23 @@ class ServerVersionResponse(BaseModel):
|
||||
edition: Literal["SELF_HOSTED", "CLOUD"]
|
||||
|
||||
|
||||
class HealthResponse(BaseModel):
|
||||
"""Liveness payload for `GET /openapi/v1/_health` — no auth required."""
|
||||
|
||||
ok: bool
|
||||
|
||||
|
||||
def _csv_string_query_schema(schema: dict[str, Any]) -> None:
|
||||
"""Re-shape a set/list field's query schema to a comma-separated string — the wire form the
|
||||
handler actually accepts (`request.args` is flat + the validator splits on ','). Without this
|
||||
the generated contract would type it as an array and serialize `fields[0]=…&fields[1]=…`,
|
||||
which `extra='forbid'` rejects. Runtime `set[str]` validation is unaffected."""
|
||||
schema.pop("anyOf", None)
|
||||
schema.pop("items", None)
|
||||
schema.pop("uniqueItems", None)
|
||||
schema["type"] = "string"
|
||||
|
||||
|
||||
class AppDescribeQuery(BaseModel):
|
||||
"""`?fields=` allow-list for GET /apps/<id>/describe.
|
||||
|
||||
@@ -231,7 +261,7 @@ class AppDescribeQuery(BaseModel):
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
fields: set[str] | None = None
|
||||
fields: set[str] | None = Field(default=None, json_schema_extra=_csv_string_query_schema)
|
||||
workspace_id: str | None = None
|
||||
|
||||
@field_validator("workspace_id", mode="before")
|
||||
@@ -400,3 +430,19 @@ class MemberInviteResponse(BaseModel):
|
||||
|
||||
class MemberActionResponse(BaseModel):
|
||||
result: Literal["success"] = "success"
|
||||
|
||||
|
||||
class TaskStopResponse(BaseModel):
|
||||
"""200 body for POST /apps/<id>/tasks/<task_id>/stop. The handler always returns
|
||||
{"result": "success"}, so `result` is required (no default) — the generated contract
|
||||
types it as a required `'success'` rather than an optional field."""
|
||||
|
||||
result: Literal["success"]
|
||||
|
||||
|
||||
class FormSubmitResponse(BaseModel):
|
||||
"""Empty 200 body for POST /apps/<id>/form/human_input/<token>. `extra='forbid'`
|
||||
pins `additionalProperties: false` so the generated contract is an exact `{}` rather
|
||||
than an under-annotated open object."""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
Reference in New Issue
Block a user