Files
optovia/temporal

Temporal prototype: team-created workflow

Purpose: replace Prefect team_created_flow with Temporal workflow + HTTP gateway so Django/Odoo can start runs without gRPC.

Components

  • workflows.py: TeamCreatedWorkflow — runs create_kyc_in_odoo activity.
  • activities.py: calls Odoo FastAPI /fastapi/kyc/order with auth/timeouts from env.
  • worker.py: Temporal worker for task queue teams-team-created (configurable).
  • gateway.py: FastAPI gateway to start the workflow via POST.

Env vars

  • TEMPORAL_ADDRESS (default localhost:7233)
  • TEMPORAL_NAMESPACE (default default)
  • TEMPORAL_TASK_QUEUE (default teams-team-created)
  • ODOO_KYC_URL (default http://odoo:8069/fastapi/kyc/order)
  • ODOO_KYC_AUTH_USER / ODOO_KYC_AUTH_PASS (default kyc_api / kyc_api_pass)
  • ODOO_KYC_TIMEOUT (seconds, default 30)

Run locally

pip install temporalio requests

# Start worker
python -m temporal.worker

Docker

Build once:

docker build -t temporal-team-created -f temporal/Dockerfile .

Run worker:

docker run --rm \
  -e TEMPORAL_ADDRESS=host.docker.internal:7233 \
  -e TEMPORAL_NAMESPACE=default \
  -e TEMPORAL_TASK_QUEUE=teams-team-created \
  -e ODOO_KYC_URL=http://odoo:8069/fastapi/kyc/order \
  -e ODOO_KYC_AUTH_USER=kyc_api \
  -e ODOO_KYC_AUTH_PASS=kyc_api_pass \
  temporal-team-created

Run gateway:

docker run --rm -p 8008:8008 \
  -e SERVICE=gateway \
  -e TEMPORAL_ADDRESS=host.docker.internal:7233 \
  -e TEMPORAL_NAMESPACE=default \
  -e TEMPORAL_TASK_QUEUE=teams-team-created \
  temporal-team-created

Docker Compose (Temporal dev stack + worker):

cd temporal
docker compose up --build

Temporal UI: http://localhost:8233

Trigger from services (SDK, без gateway)

Install dependency in caller: pip install temporalio

Async:

from temporal.types import TeamCreatedInput
from temporal.client import start_team_created_async

ids = await start_team_created_async(
    TeamCreatedInput(
        team_id="team-123",
        team_name="Test Team",
        owner_id="user-456",
        logto_org_id="org-789",
    ),
    address="temporal:7233",
    namespace="default",
)

Sync wrapper (для Django/Odoo sync-кода):

from temporal.types import TeamCreatedInput
from temporal.client import start_team_created

workflow_id, run_id = start_team_created(
    TeamCreatedInput(
        team_id="team-123",
        team_name="Test Team",
        owner_id="user-456",
    ),
    address="temporal:7233",
    namespace="default",
)