feat: expose source admin over rpc and cli

This commit is contained in:
lda
2026-06-03 21:49:13 +07:00 Verified
parent 24ca91afb1
commit f0d0cffa17
15 changed files with 246 additions and 22 deletions
+4
View File
@@ -14,10 +14,12 @@ from .models import (
InspectCapabilityParams,
InspectDeploymentParams,
InspectRunParams,
InspectSourceParams,
ListArtifactsParams,
ListCapabilitiesParams,
ListDeploymentsParams,
ListDraftWorkspacesParams,
ListSourcesParams,
PatchDraftParams,
PatchDraftWorkspaceParams,
ReadRunTraceParams,
@@ -42,10 +44,12 @@ __all__ = [
"InspectCapabilityParams",
"InspectDeploymentParams",
"InspectRunParams",
"InspectSourceParams",
"ListArtifactsParams",
"ListCapabilitiesParams",
"ListDeploymentsParams",
"ListDraftWorkspacesParams",
"ListSourcesParams",
"PatchDraftParams",
"PatchDraftWorkspaceParams",
"ReadRunTraceParams",
+2
View File
@@ -12,6 +12,7 @@ from .methods_capabilities import register_methods as register_capability_method
from .methods_deployments import register_methods as register_deployment_methods
from .methods_drafts import register_methods as register_draft_methods
from .methods_runs import register_methods as register_run_methods
from .methods_sources import register_methods as register_source_methods
def create_rpc_app(server: WorkflowServer, *, rpc_path: str = "/rpc") -> jsonrpc.API:
@@ -43,6 +44,7 @@ def create_rpc_app(server: WorkflowServer, *, rpc_path: str = "/rpc") -> jsonrpc
register_artifact_methods(entrypoint, server)
register_deployment_methods(entrypoint, server)
register_run_methods(entrypoint, server)
register_source_methods(entrypoint, server)
app.bind_entrypoint(entrypoint)
return app
+2
View File
@@ -10,6 +10,7 @@ from .client_capabilities import RpcCapabilityClientMixin
from .client_deployments import RpcDeploymentClientMixin
from .client_drafts import RpcDraftClientMixin
from .client_runs import RpcRunClientMixin
from .client_sources import RpcSourceAdminClientMixin
@dataclass(slots=True)
@@ -20,6 +21,7 @@ class RpcWorkflowApiClient(
RpcArtifactClientMixin,
RpcDeploymentClientMixin,
RpcRunClientMixin,
RpcSourceAdminClientMixin,
):
"""WorkflowApiSurface implementation backed by JSON-RPC HTTP calls.
@@ -0,0 +1,29 @@
from __future__ import annotations
from typing import Any
class RpcSourceAdminClientMixin:
"""JSON-RPC implementation of read-only source admin surface methods."""
async def _call(self, method: str, params: dict[str, Any]) -> dict[str, Any]: ...
async def list_sources(
self,
*,
cursor: str | None = None,
limit: int = 50,
) -> dict[str, Any]:
return await self._call(
"workflow.sources.list",
{
"cursor": cursor,
"limit": limit,
},
)
async def inspect_source(self, *, source_id: str) -> dict[str, Any]:
return await self._call(
"workflow.sources.inspect",
{"source_id": source_id},
)
@@ -0,0 +1,40 @@
from __future__ import annotations
from typing import Any
from fastapi import Body
import fastapi_jsonrpc as jsonrpc
from fastapi_jsonrpc import Params
from wf_server import WorkflowServer
from .errors import WorkflowRpcError, raise_workflow_rpc_error
from .models import InspectSourceParams, ListSourcesParams
def register_methods(
entrypoint: jsonrpc.Entrypoint,
server: WorkflowServer,
) -> None:
"""Register read-only source/admin JSON-RPC methods."""
@entrypoint.method(name="workflow.sources.list", errors=[WorkflowRpcError])
async def workflow_sources_list(
params: ListSourcesParams = Body(default_factory=ListSourcesParams),
) -> dict[str, Any]:
try:
return await server.source_admin.list_sources(
cursor=params.cursor,
limit=params.limit,
)
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
@entrypoint.method(name="workflow.sources.inspect", errors=[WorkflowRpcError])
async def workflow_sources_inspect(
params: InspectSourceParams = Params(...), # type: ignore[reportArgumentType]
) -> dict[str, Any]:
try:
return await server.source_admin.inspect_source(source_id=params.source_id)
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
+9
View File
@@ -37,6 +37,15 @@ class ListCapabilitiesParams(RpcParamsModel):
limit: int = Field(default=50, ge=1, le=200)
class ListSourcesParams(RpcParamsModel):
cursor: str | None = Field(default=None)
limit: int = Field(default=50, ge=1, le=100)
class InspectSourceParams(RpcParamsModel):
source_id: str = Field(min_length=1)
class InspectCapabilityParams(RpcParamsModel):
qualified_name: str = Field(min_length=1)