Docs/SDKs/Python

Diaphora Python SDK

Python client library for the Diaphora API.

Supported Python versions: 3.11, 3.12, 3.13

Installation

Shell
pip install diaphora-python

Authentication

The Diaphora client needs your Diaphora credentials. Pass them directly, or set the DIAPHORA_USERNAME and DIAPHORA_PASSWORD environment variables and call the constructor with no arguments.

Direct credentials:

Python
from diaphora.auth.basic_authenticator import BasicAuthenticator

auth = BasicAuthenticator("user@example.com", "your-password")

Environment variables:

Python
# export DIAPHORA_USERNAME=user@example.com
# export DIAPHORA_PASSWORD=your-password
auth = BasicAuthenticator()

To use a custom auth scheme, implement DiaphoraAuthenticator:

Python
from diaphora.auth.authenticator_interface import DiaphoraAuthenticator

class MyAuthenticator(DiaphoraAuthenticator):
    def token(self) -> str:
        return "my-session-token"

Diaphora

Python
from diaphora import Diaphora

sdk = Diaphora(authenticator)
AttributeDescription
sdk.storePlan and result management
sdk.routerPlan execution and MCP tools

Quickstart

Search for plans

Python
from diaphora.models import SearchPlansNamespace

# Namespace is one of ALL, DIAPHORA, BARNDOOR, NONE
plans = sdk.store.search_plans(namespace=SearchPlansNamespace.DIAPHORA)

Showing Plan

Python
plan = sdk.store.show_plan(str(plans[0].id))
print(plan.name, plan.description)

Create a plan

Python
from diaphora.models import PlanRequest, PlanRequestVisibility

new_plan = sdk.store.create_plan(PlanRequest(
    name="Daily Summary",
    description="Summarises activity from the past 24 hours",
    visibility=PlanRequestVisibility.ORGANIZATION,
    labels=["summary", "daily"],
    text="<plan definition>",
))

Search results for a plan

Python
from diaphora.models import SearchResultsStatus

results = sdk.store.search_results(
    plan_id=str(plan.id),
    status=SearchResultsStatus.SUCCESS,
)

Run a plan

Python
response = sdk.router.run_plan(
    plan_id=str(plan.id),
    parameters={"animal_type": "feline"},
)

Stream a plan execution

handle_event is a function that can be defined with a custom implementation. The function here is just an example function for printing the contents of the streamed data

Python
from diaphora.events import START_PHASE, END_PHASE, RESULT_PHASE, StreamEvent


def handle_event(event: StreamEvent):
    if event.event == START_PHASE:
        print(f"[{event.component}] starting {event.session}...")
    elif event.event == END_PHASE:
        print(f"[{event.component}] done")
    elif event.event == RESULT_PHASE:
        print(event.content["document"])

sdk.router.stream_plan(
    plan_id=str(plan.id),
    on_event=handle_event,
    parameters={"animal_type": "feline"},
)

sdk.store

Plans

MethodDescription
search_plans(label, search, namespace, limit, offset)Search plans. namespace is one of ALL, DIAPHORA, BARNDOOR, NONE
show_plan(plan_id)Get plan details
create_plan(body: PlanRequest)Create a plan
update_plan(plan_id, body: PlanRequest)Update a plan
delete_plan(plan_id)Delete a plan
list_plan_labels()List all labels used across plans

search_plans

Search plans visible to your organisation. All filters are optional and combinable.

Parameters

ParameterTypeRequiredDescription
labellist[str]NoFilter to plans that have all of the given labels
searchstrNoFull-text search across plan names and descriptions
namespaceSearchPlansNamespaceNoFilter by namespace — ALL, DIAPHORA, BARNDOOR, or NONE. Defaults to ALL
limitintNoMaximum number of results to return
offsetintNoNumber of results to skip (for pagination)

Returns list[PlanSummary] | None — each item has .id, .name, .description, .namespace, .labels, .visibility, .parameters, .created_at, .updated_at.

Example

Python
from diaphora.models import SearchPlansNamespace

# All plans
plans = sdk.store.search_plans()

# Filter by namespace and label
plans = sdk.store.search_plans(
    namespace=SearchPlansNamespace.DIAPHORA,
    label=["daily"],
    limit=10,
)
for plan in plans:
    print(plan.name, plan.namespace)

show_plan

Retrieve full details for a single plan, including its definition text and parameter schema.

Parameters

ParameterTypeRequiredDescription
plan_idstrYesID of the plan to retrieve

Returns PlanDetails | None — all fields from PlanSummary plus .text (plan definition), .document_template, and .resources.

Example

Python
plan = sdk.store.show_plan(str(plans[0].id))
print(plan.name, plan.description)
print("Parameters:", [p.name for p in plan.parameters])

create_plan

Create a new plan.

Parameters

ParameterTypeRequiredDescription
bodyPlanRequestYesPlan definition — see fields below

PlanRequest fields

FieldTypeRequiredDescription
namestrYesDisplay name for the plan
descriptionstrYesHuman-readable summary
visibilityPlanRequestVisibilityYesNAMESPACE, ORGANIZATION, or USER
labelslist[str]YesTags for grouping and filtering
textstrYesPlan definition body
namespacestrNoNamespace to assign the plan to
document_templatestrNoTemplate string for rendering the result document

Returns PlanDetails | None — the newly created plan.

Example

Python
from diaphora.models import PlanRequest, PlanRequestVisibility

new_plan = sdk.store.create_plan(PlanRequest(
    name="Daily Summary",
    description="Summarises activity from the past 24 hours",
    visibility=PlanRequestVisibility.ORGANIZATION,
    labels=["summary", "daily"],
    text="<plan definition>",
))
print(new_plan.id)

update_plan

Overwrite an existing plan's metadata and definition text.

Parameters

ParameterTypeRequiredDescription
plan_idstrYesID of the plan to update
bodyPlanRequestYesUpdated plan definition — same fields as create_plan

Returns PlanDetails | None — the updated plan.

Example

Python
from diaphora.models import PlanRequest, PlanRequestVisibility

updated = sdk.store.update_plan(
    plan_id=str(plan.id),
    body=PlanRequest(
        name="Daily Summary v2",
        description="Updated summary plan",
        visibility=PlanRequestVisibility.ORGANIZATION,
        labels=["summary", "daily", "v2"],
        text="<updated plan definition>",
    ),
)
print(updated.name)

delete_plan

Permanently delete a plan. This action cannot be undone.

Parameters

ParameterTypeRequiredDescription
plan_idstrYesID of the plan to delete

Returns Response — HTTP 204 on success.

Example

Python
sdk.store.delete_plan(str(plan.id))

list_plan_labels

Return every unique label used across plans in the organisation.

Returns list[str] | None — alphabetically sorted list of label strings.

Example

Python
labels = sdk.store.list_plan_labels()
print(labels)  # ["daily", "reports", "summary"]

Results

MethodDescription
search_results(search, status, limit, offset, start, end, plan_id)Search results. status is SUCCESS or ERROR
show_results(results_id)Get result details
delete_results(results_id)Delete a result
list_results_stats(start, end)Get result statistics

search_results

Search execution results with optional filters. All parameters are optional and combinable.

Parameters

ParameterTypeRequiredDescription
searchstrNoFull-text search across result data
statusSearchResultsStatusNoFilter by outcome — SUCCESS or ERROR
limitintNoMaximum number of results to return
offsetintNoNumber of results to skip (for pagination)
startdatetimeNoReturn only results created at or after this time
enddatetimeNoReturn only results created at or before this time
plan_idstrNoFilter to results from a specific plan

Returns list[ResultSummary] | None — each item has .id, .plan_id, .plan_name, .created_at.

Example

Python
from diaphora.models import SearchResultsStatus

# All results for a plan
results = sdk.store.search_results(plan_id=str(plan.id))

# Successful results only, newest 20
recent = sdk.store.search_results(
    plan_id=str(plan.id),
    status=SearchResultsStatus.SUCCESS,
    limit=20,
)

show_results

Retrieve full details for a single result, including the execution output.

Parameters

ParameterTypeRequiredDescription
results_idstrYesID of the result to retrieve

Returns Response[ResultDetails] — access the parsed object via .parsed. ResultDetails has .id, .plan_id, .plan_name, .created_at, .data (ExecuteResponseBody), and .error.

Example

Python
response = sdk.store.show_results(str(results[0].id))
result = response.parsed
print(result.plan_name, result.created_at)
print(result.data.document)

delete_results

Permanently delete a result record. This action cannot be undone.

Parameters

ParameterTypeRequiredDescription
results_idstrYesID of the result to delete

Returns Response — HTTP 204 on success.

Example

Python
sdk.store.delete_results(str(result.id))

list_results_stats

Return a time-ordered list of result metadata records, optionally bounded by a date range. Useful for building audit logs or activity dashboards.

Parameters

ParameterTypeRequiredDescription
startdatetimeNoReturn only stats at or after this time
enddatetimeNoReturn only stats at or before this time

Returns list[Stat] | None — each item has .result_id, .plan_id, .plan_name, .created_at.

Example

Python
from datetime import datetime, timezone

stats = sdk.store.list_results_stats()
for stat in stats:
    print(f"{stat.plan_name}{stat.created_at}")

# Last 7 days only
from datetime import timedelta
week_ago = datetime.now(timezone.utc) - timedelta(days=7)
recent_stats = sdk.store.list_results_stats(start=week_ago)
MethodDescription
list_public_links(results_id)List public links for a result
create_public_link(results_id, body: PublicLinkRequest)Create a public link. expires_in accepts values like "7d" or "24h"
delete_public_link(results_id, public_link_id)Delete a public link
show_result_public_link(public_link_id)Fetch a result via public link (no auth required)

List all public share links associated with a result.

Parameters

ParameterTypeRequiredDescription
results_idstrYesID of the result whose links to list

Returns list[PublicLinkSummary] | None — each item has .id, .label, .created_at, .expires_at, .ref_id, .ref_type.

Example

Python
links = sdk.store.list_public_links(str(result.id))
for link in links:
    print(link.label, "expires:", link.expires_at)

Create a time-limited, unauthenticated share link for a result. Anyone with the link ID can fetch the result via show_result_public_link without credentials.

Parameters

ParameterTypeRequiredDescription
results_idstrYesID of the result to share
bodyPublicLinkRequestYesLink configuration — see fields below

PublicLinkRequest fields

FieldTypeRequiredDescription
expires_instrYesHow long until the link expires, e.g. "7d", "24h", "30m"
labelstrYesHuman-readable name for the link

Returns PublicLinkSummary | None — the created link, including its .id and .expires_at.

Example

Python
from diaphora.models import PublicLinkRequest

link = sdk.store.create_public_link(
    results_id=str(result.id),
    body=PublicLinkRequest(expires_in="7d", label="Weekly Report"),
)
print(f"Share link ID: {link.id}, expires: {link.expires_at}")

Revoke a public share link immediately. Any subsequent requests using this link ID will fail.

Parameters

ParameterTypeRequiredDescription
results_idstrYesID of the result the link belongs to
public_link_idstrYesID of the link to revoke

Returns Response — HTTP 204 on success.

Example

Python
sdk.store.delete_public_link(str(result.id), str(link.id))

Fetch a result via its public share link. Does not require authentication — useful for embedding results in external applications.

Parameters

ParameterTypeRequiredDescription
public_link_idstrYesID of the public link

Returns Response[ResultDetails] — access the parsed object via .parsed.

Example

Python
response = sdk.store.show_result_public_link(str(link.id))
result = response.parsed
print(result.data.document)

Tools & Schema

MethodDescription
list_tools()List available tools
show_tools(tool_id)Get tool details
show_default_tools()Get default tools
get_frags_schema()Get the Frags JSON schema

list_tools

List all tool sets available in the organisation.

Returns list[ToolsSummary] | None — each item has .id, .name, .default.

Example

Python
tools = sdk.store.list_tools()
for t in tools:
    print(t.name, "(default)" if t.default else "")

show_tools

Get full details of a tool set, including its MCP servers, API CP servers, and collections.

Parameters

ParameterTypeRequiredDescription
tool_idstrYesID of the tool set to retrieve

Returns Response[ToolsDetails] — access via .parsed. ToolsDetails has .id, .name, .default, .mcp_servers, .api_cps, .collections.

Example

Python
response = sdk.store.show_tools(str(tools[0].id))
details = response.parsed
print(f"{details.name}{len(details.mcp_servers)} MCP servers")

show_default_tools

Get the organisation's default tool set.

Returns Response[ToolsDetails] — access via .parsed.

Example

Python
response = sdk.store.show_default_tools()
default = response.parsed
if default:
    print(f"Default tool set: {default.name}")

get_frags_schema

Retrieve the Frags JSON schema that describes the plan definition format. Useful for validating plan text before submission.

Returns Response — the raw JSON schema is in .content.

Example

Python
import json

response = sdk.store.get_frags_schema()
schema = json.loads(response.content)

sdk.router

Plan Execution

MethodDescription
run_plan(plan_id, parameters)Execute a plan synchronously
stream_plan(plan_id, on_event, parameters)Execute a plan and receive SSE events via callback

stream_plan delivers StreamEvent objects to the callback:

event.eventAdditional fieldsDescription
START_PHASEcomponent, sessionA component started
END_PHASEcomponentA component finished
RESULT_PHASEcontentResult payload — content["document"] holds the output text

run_plan

Execute a plan synchronously and block until the result is ready.

Parameters

ParameterTypeRequiredDescription
plan_idstrYesID of the plan to execute
parametersdictNoKey/value pairs matching the plan's parameter definitions

Returns ExecuteResponseBody with fields:

FieldTypeDescription
.resultExecuteResponseBodyResultStructured output produced by the plan — call .to_dict() for a plain dict
.documentstr | NoneRendered document string, if the plan has a document template
.warningslist[str]Non-fatal warnings emitted during execution

Example

Python
response = sdk.router.run_plan(
    plan_id=str(plan.id),
    parameters={"animal_type": "feline"},
)
print(response.result)
if response.document:
    print(response.document)
if response.warnings:
    print("Warnings:", response.warnings)

stream_plan

Execute a plan and receive progress events in real time via Server-Sent Events. The optional on_event callback is invoked for each event as it arrives. Returns the final result content when the stream ends.

Parameters

ParameterTypeRequiredDescription
plan_idstrYesID of the plan to execute
on_eventCallable[[StreamEvent], None]NoCallback invoked for each SSE event
parametersdictNoKey/value pairs matching the plan's parameter definitions

Returns dict | None — the content dict from the RESULT_PHASE event, or None if the stream ended without a result. content["document"] holds the rendered output text.

Example

Python
from diaphora.events import START_PHASE, END_PHASE, RESULT_PHASE, StreamEvent

def handle_event(event: StreamEvent):
    if event.event == START_PHASE:
        print(f"[{event.component}] starting {event.session}...")
    elif event.event == END_PHASE:
        print(f"[{event.component}] done")
    elif event.event == RESULT_PHASE:
        print(event.content["document"])

content = sdk.router.stream_plan(
    plan_id=str(plan.id),
    on_event=handle_event,
    parameters={"animal_type": "feline"},
)

MCP Tools

MethodDescription
check_plan_mcp_requirements(plan_id)Check which MCP servers a plan needs and their auth status
refresh_plan_mcp_requirements(plan_id)Force-refresh MCP requirement status
check_tool_mcp_requirements()Check global MCP requirements
list_tool_commands(tools_id, server_id)List commands on an MCP server
call_tool_command(tools_id, server_id, command_name)Execute an MCP command
list_mcp_auth_cache()List cached MCP OAuth tokens
delete_mcp_auth_cache(cache_id)Revoke a cached MCP token
mcp_callback(state, code)Handle an OAuth redirect callback
render_template(body: RenderTemplate)Render a template

check_plan_mcp_requirements

List the MCP servers required by a plan and whether each one is currently authenticated.

Parameters

ParameterTypeRequiredDescription
plan_idstrYesID of the plan to inspect

Returns list[McpRequirement] | None — each item has .name, .status (ready or not_ready), .url (the authentication URL when not_ready), .authentication_method.

Example

Python
requirements = sdk.router.check_plan_mcp_requirements(str(plan.id))
for req in requirements:
    print(f"{req.name}: {req.status}")
    if req.status == "not_ready":
        print(f"  Authenticate at: {req.url}")

refresh_plan_mcp_requirements

Force re-evaluation of which MCP servers a plan needs and refresh their authentication status. Call this after completing an OAuth flow to confirm that requirements are now satisfied.

Parameters

ParameterTypeRequiredDescription
plan_idstrYesID of the plan whose requirements to refresh

Returns list[McpServer] | None — the updated list of MCP servers for the plan, each with .id, .name, .url, .authentication_method.

Example

Python
servers = sdk.router.refresh_plan_mcp_requirements(str(plan.id))
for server in servers:
    print(f"{server.name}: {server.url}")

check_tool_mcp_requirements

List MCP authentication requirements across all tool sets in the organisation. Equivalent to check_plan_mcp_requirements but not scoped to a single plan.

Returns list[McpRequirement] | None

Example

Python
reqs = sdk.router.check_tool_mcp_requirements()
if reqs:
    not_ready = [r for r in reqs if r.status == "not_ready"]
    print(f"{len(not_ready)} servers need authentication")

list_tool_commands

List the commands exposed by a specific MCP server within a tool set.

Parameters

ParameterTypeRequiredDescription
tools_idstrYesID of the tool set
server_idstrYesID of the MCP server within that tool set

Returns list[McpCommand] | None — each item describes a callable command on the MCP server.

Example

Python
commands = sdk.router.list_tool_commands(
    tools_id=str(tools[0].id),
    server_id=str(server.id),
)
for cmd in commands:
    print(cmd.name)

call_tool_command

Execute a single command on an MCP server.

Parameters

ParameterTypeRequiredDescription
tools_idstrYesID of the tool set
server_idstrYesID of the MCP server
command_namestrYesName of the command to execute

Returns CallToolCommandResponse200 | None

Example

Python
result = sdk.router.call_tool_command(
    tools_id=str(tools[0].id),
    server_id=str(server.id),
    command_name="list_files",
)

list_mcp_auth_cache

List all cached MCP OAuth tokens for the current user.

Returns list[AuthCache] | None — each item has .id, .domain, .created_at, .expiry, and optionally .client_id.

Example

Python
cache = sdk.router.list_mcp_auth_cache()
for entry in cache:
    print(f"{entry.domain} — expires {entry.expiry}")

delete_mcp_auth_cache

Revoke a cached MCP OAuth token. The next request to that MCP server will require re-authentication.

Parameters

ParameterTypeRequiredDescription
cache_idstrYesID of the cache entry to revoke

Returns None

Example

Python
cache = sdk.router.list_mcp_auth_cache()
sdk.router.delete_mcp_auth_cache(str(cache[0].id))

mcp_callback

Handle an OAuth redirect callback from an MCP server after the user completes authentication. Typically called from a redirect endpoint in your web application.

Parameters

ParameterTypeRequiredDescription
statestrYesThe state query parameter from the OAuth redirect
codestrYesThe code query parameter from the OAuth redirect

Returns Response

Example

Python
# In a web framework route handler:
# GET /mcp/callback?state=...&code=...
sdk.router.mcp_callback(state=request.args["state"], code=request.args["code"])

render_template

Render a Diaphora template string against a given scope.

Parameters

ParameterTypeRequiredDescription
bodyRenderTemplateYesTemplate and scope — see fields below

RenderTemplate fields

FieldTypeRequiredDescription
templatestrYesThe template string to render
scopeRenderTemplateScopeYesScope context — construct with RenderTemplateScope() and set attributes via dictionary access

Returns Response — the rendered output is in .content.

Example

Python
from diaphora.models import RenderTemplate
from diaphora.services.frags_router_open_api_client.models import RenderTemplateScope

scope = RenderTemplateScope()
scope["name"] = "Rayna"
response = sdk.router.render_template(
    RenderTemplate(template="Hello {{name}}", scope=scope)
)
print(response.content)