Skip to main content

Python client for the SyncTeams Workflow API

Project description

SyncTeams Workflow SDK (Python)

A Python client for the SyncTeams Workflow API. Mirrors the capabilities of the JavaScript SDK, offering convenient helpers to execute workflows, monitor task status, and manage approval flows.


Installation

pip install syncteams-sdk

Requirements: Python 3.9 or newer


Quick Start

from syncteams_sdk import WorkflowClient, WorkflowStatus

client = WorkflowClient(api_key="YOUR_API_KEY")

# Execute a workflow
result = client.execute_workflow(
    workflow_id="your_workflow_id",
    input={"email": "user@example.com"},
    unique_id="customer-123",
)

task_id = result["taskId"]

# Wait for completion
final_status = client.wait_for_completion(
    task_id,
    poll_interval_ms=2_000,
    on_update=lambda status: print(f"Status: {status['status']}")
)

if final_status["status"] == WorkflowStatus.COMPLETED:
    print("Workflow completed successfully!")

Configuration

Option Required Default Description
api_key Your SyncTeams API key
base_url https://develop.api.syncteams.studio API base URL
timeout_ms 30000 Request timeout in milliseconds
retry See below Retry configuration for failed requests
default_headers {} Extra headers merged into every request
user_agent_suffix Extra token appended to the default User-Agent

Retry Configuration

By default, the SDK retries transient failures with exponential backoff:

  • Maximum attempts: 3
  • Initial delay: 1 second
  • Backoff factor: 2x
  • Maximum delay: 30 seconds
  • Retries on: 408, 425, 429, and all 5xx responses

You can override any subset of these values when constructing the client.


API overview

execute_workflow(workflow_id, input, unique_id=None)

Starts a workflow execution.

response = client.execute_workflow(
    workflow_id="your_workflow_id",
    input={"customer_id": "cust-123"},
)

print(response["taskId"], response["status"])

Returns the taskId and initial status.

get_task_status(task_id)

Fetches the latest status and the filtered event log for a task.

status = client.get_task_status(task_id)
print(status["status"], len(status.get("eventLogs", [])))

continue_task(task_id, decision, message=None)

Resumes a waiting workflow after an approval decision.

from syncteams_sdk import ApprovalDecision

client.continue_task(task_id=task_id, decision=ApprovalDecision.APPROVE)

client.continue_task(
    task_id=task_id,
    decision=ApprovalDecision.REJECT,
    message="Missing documentation",
)

When decision is ApprovalDecision.REJECT, message is required.

wait_for_completion(task_id, *, poll_interval_ms=2000, max_wait_time_ms=600000, on_update=None, exit_on_waiting=False, terminal_statuses=None, stop_event=None)

Polls a task until it reaches a terminal status (COMPLETED, FAILED, or CANCELED).

final_status = client.wait_for_completion(
    task_id,
    poll_interval_ms=1000,
    on_update=lambda payload: print("Status:", payload["status"]),
)

execute_and_wait(workflow_id, input, **options)

Convenience method that starts a workflow and optionally handles approvals via on_waiting.

from syncteams_sdk import ApprovalDecision

def handle_waiting(status):
    # Perform approval logic
    client.continue_task(task_id=status["taskId"], decision=ApprovalDecision.APPROVE)
    return True

result = client.execute_and_wait(
    workflow_id="wf-123",
    input={"amount": 500},
    on_waiting=handle_waiting,
)

If on_waiting returns False, polling stops and the SDK returns the current status (even if still waiting).


Error Handling

The SDK raises WorkflowAPIError for API failures. It exposes the HTTP status, headers, response payload, and request metadata to simplify debugging.

from syncteams_sdk import WorkflowAPIError

try:
    client.execute_workflow(workflow_id="invalid", input={})
except WorkflowAPIError as error:
    print("API error:", error.status, error.data)

Transient errors (timeouts, rate limits, server errors) are automatically retried according to the configured policy.


Webhooks

You can receive workflow updates via webhooks instead of polling:

from flask import Flask, request
from syncteams_sdk import WebhookEventPayload

app = Flask(__name__)

@app.post("/webhooks/syncteams")
def handle_webhook():
    payload: WebhookEventPayload = request.get_json(force=True)
    print("Task", payload["taskId"], "status:", payload["status"])
    return ("", 200)

Validate webhook signatures with the SDK helper:

from flask import Flask, request
from syncteams_sdk import (
    WEBHOOK_SIGNATURE_HEADER,
    WEBHOOK_TIMESTAMP_HEADER,
    verify_webhook_signature,
)

app = Flask(__name__)

@app.post("/webhooks/syncteams")
def handle_webhook():
    raw_body = request.get_data(as_text=True)
    signature_header = request.headers.get(WEBHOOK_SIGNATURE_HEADER, "")
    timestamp_header = request.headers.get(WEBHOOK_TIMESTAMP_HEADER, "")

    is_valid = verify_webhook_signature(
        payload=raw_body,
        signature_header=signature_header,
        timestamp_header=timestamp_header,
        signing_secret="YOUR_WEBHOOK_SECRET",
    )

    if not is_valid:
        return ("invalid signature", 400)

    return ("", 200)

Use the raw request body for verification; re-serializing parsed JSON can invalidate signatures.


Type Safety with Enums

The SDK provides enums for better type safety and IDE autocomplete:

from syncteams_sdk import WorkflowStatus, ApprovalDecision, WorkflowEventType

# Use enums for type-safe comparisons
if status["status"] == WorkflowStatus.COMPLETED:
    # Handle completion
    pass

# All available workflow statuses
WorkflowStatus.QUEUED
WorkflowStatus.PENDING
WorkflowStatus.RUNNING
WorkflowStatus.WAITING
WorkflowStatus.CANCELED
WorkflowStatus.FAILED
WorkflowStatus.COMPLETED

# Approval decisions
ApprovalDecision.APPROVE
ApprovalDecision.REJECT

# Enums work seamlessly with the API
client.continue_task(
    task_id=task_id,
    decision=ApprovalDecision.APPROVE  # Type-safe!
)

Development

Install dependencies and run tests:

pip install -e .[dev]
pytest

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

syncteams_sdk-0.5.0.tar.gz (17.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

syncteams_sdk-0.5.0-py3-none-any.whl (4.6 kB view details)

Uploaded Python 3

File details

Details for the file syncteams_sdk-0.5.0.tar.gz.

File metadata

  • Download URL: syncteams_sdk-0.5.0.tar.gz
  • Upload date:
  • Size: 17.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.10

File hashes

Hashes for syncteams_sdk-0.5.0.tar.gz
Algorithm Hash digest
SHA256 7d68c4532ab9a848721b15333c8120cbb76373a920822ef0006e9e696695ce0d
MD5 e82fa43aa84b363a254c877889da0733
BLAKE2b-256 e68d28d105ba95c45176f13e892c1468d65a91318fd871069425fa40b0681ffc

See more details on using hashes here.

File details

Details for the file syncteams_sdk-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: syncteams_sdk-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 4.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.10

File hashes

Hashes for syncteams_sdk-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 47f5deb89e3d7ead619ea6c88f9e3e07cd28a75b6be996c091ffa68d2fe06943
MD5 50724a80d824b5c8b4f0f9afdcf2b708
BLAKE2b-256 26df673259d110e27467670889dc38f292f22c0bfd631f3683f9342bf675c5ea

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page