Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

16 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“Έ WXO – Asynchronous Image Processing with OpenAI & IBM Cloud Object Storage

FastAPI Python OpenAI IBM Cloud

πŸ“š Related Documentation: API.md Β· CONFIGURATION.md Β· ARCHITECTURE.md Β· tools Orchestrate/README.md

🧭 Where to start?


πŸ“Œ Overview

Asynchronous image processing tools for IBM watsonx Orchestrate (WXO) with AI-powered transformations via OpenAI and persistent storage in IBM Cloud Object Storage.

πŸ’‘ Design Philosophy: This project is production-ready by design (async patterns, error handling, observability), but intentionally simplified (in-process background tasks) for demo and enablement purposes. See ARCHITECTURE.md for production scaling options.

Key Features

βœ… Single image processing with AI (OpenAI image editing) βœ… Batch image processing from IBM Cloud Object Storage βœ… Asynchronous execution with callback mechanism βœ… Fallback local processing when OpenAI is unavailable βœ… Enterprise-ready for demos, prototyping, and production workflows


πŸš€ Quick Start

Prerequisites

  • Python 3.10+ (3.9+ supported, 3.10+ recommended)
  • IBM Cloud Object Storage account with HMAC credentials
  • OpenAI API key from https://platform.openai.com/api-keys
  • For local development on Mac: Lima VM with watsonX Orchestrate ADK

Installation

  1. Clone and setup:
git clone https://github.com/Estepa-F/wxo-fastapi-callback.git
cd wxo-fastapi-callback
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install -r requirements.txt
  1. Configure environment:
cp .env.example .env
# Edit .env with your credentials (see CONFIGURATION.md for details)
  1. Load environment variables:

⚠️ CRITICAL: You MUST load .env before running the server!

set -a
source .env
set +a

Verify variables are loaded:

echo $COS_ENDPOINT
# Should print: https://s3.eu-de.cloud-object-storage.appdomain.cloud

echo $OPENAI_API_KEY | wc -c
# Should print a number > 10 (without exposing the key)
  1. Run the server:
uvicorn main:app --host 0.0.0.0 --port 8000 --log-level debug

⚠️ Important: Use --host 0.0.0.0 (not 127.0.0.1) to make the server accessible from Lima VM.

Troubleshooting: If curl http://host.lima.internal:8000/health fails from inside the VM, it's almost always because FastAPI was started with 127.0.0.1 instead of 0.0.0.0.

  1. Verify it's running:
curl http://localhost:8000/health
# Expected: {"ok": true}

πŸ§ͺ Quick Test

Option 1: Automated Test Script (Recommended)

The easiest way to verify your setup:

# 1. Make the script executable
chmod +x scripts/test_local.sh

# 2. Load environment variables
set -a
source .env
set +a

# 3. Start FastAPI (in a separate terminal)
uvicorn main:app --host 0.0.0.0 --port 8000

# 4. Run the test script
./scripts/test_local.sh

What it does:

  • βœ… Verifies all required environment variables
  • βœ… Checks FastAPI server health
  • βœ… Validates COS configuration
  • βœ… Starts a local callback server automatically
  • βœ… Tests single image processing (Base64)
  • βœ… Tests batch image processing
  • βœ… Cleans up resources on exit

Prerequisites:

  • Test image burger.jpeg in project root (for single image test)
  • Input bucket with test images (for batch test)

Option 2: Manual Testing

Prerequisites for Batch Processing

Before testing batch operations, ensure:

βœ… Input bucket exists and contains test images (JPEG, PNG) βœ… Output bucket exists (can be the same as input) βœ… HMAC credentials have permissions: list, get, put βœ… Configuration is valid:

curl http://localhost:8000/cos/config
# Verify: endpoint, input_bucket, output_bucket match your setup

1. Start a Callback Server

In a new terminal:

python - <<'PY'
from fastapi import FastAPI
import uvicorn
from datetime import datetime, timezone

app = FastAPI()

@app.post("/callback")
def cb(data: dict):
    print(f"\n--- {datetime.now(timezone.utc).isoformat()} ---")
    print(data)
    return {"ok": True}

uvicorn.run(app, host="127.0.0.1", port=9999)
PY

2. Process an Image

export B64=$(base64 -i your-image.jpg | tr -d '\n')

curl -X POST http://localhost:8000/process-image-async-b64 \
  -H "Content-Type: application/json" \
  -H "callbackUrl: http://localhost:9999/callback" \
  -d "{
    \"prompt\": \"add a sunset background\",
    \"filename\": \"test.jpg\",
    \"image_base64\": \"$B64\"
  }"

You should see:

  1. Immediate response: {"accepted": true, "job_id": "..."}
  2. Callback in terminal 1 with the processed image (base64)

πŸ–₯️ Local Development with watsonX Orchestrate (Mac + Lima VM)

Architecture

Mac (Host)
β”œβ”€β”€ FastAPI Server (port 8000)
β”‚   └── http://0.0.0.0:8000
β”‚
└── Lima VM (ibm-watsonx-orchestrate)
    β”œβ”€β”€ watsonX Orchestrate ADK (port 4321)
    β”‚   └── Accessible via SSH tunnel: localhost:14321
    β”‚
    └── Access to Mac host via: host.lima.internal:8000

Why host.lima.internal:8000?

Lima VM uses an isolated network. The special DNS alias host.lima.internal resolves to the Mac host's IP from within the VM, allowing Orchestrate to communicate with your FastAPI server.

Setup Steps

1. Start FastAPI on Mac:

cd wxo-fastapi-callback
source .venv/bin/activate
uvicorn main:app --host 0.0.0.0 --port 8000 --log-level debug

2. Start Lima VM:

limactl start ibm-watsonx-orchestrate

3. Create SSH Tunnel:

ssh -o 'IdentityFile="/Users/YOUR_USERNAME/.lima/_config/user"' \
  -o StrictHostKeyChecking=no \
  -o Hostname=127.0.0.1 \
  -o Port=YOUR_LIMA_SSH_PORT \
  -N \
  -L 14321:127.0.0.1:4321 \
  lima-ibm-watsonx-orchestrate

πŸ“ Replace YOUR_USERNAME and YOUR_LIMA_SSH_PORT (check with limactl list)

4. Access Orchestrate:

http://localhost:14321

5. Test Connectivity:

limactl shell ibm-watsonx-orchestrate
curl http://host.lima.internal:8000/health
# Expected: {"ok": true}

6. Import Tools:

Import these files from tools Orchestrate/ into watsonX Orchestrate:

  • YAML files as API tools
  • Python file as Python tool
  • JSON files as workflows

See tools Orchestrate/README.md for detailed instructions.


⚠️ Known Pitfalls

  • callbackUrl header is case-sensitive - Use exactly callbackUrl, not callbackurl or callback_url
  • No data: prefix in Base64 - Send raw Base64 string without data:image/...;base64, prefix
  • Use --host 0.0.0.0 - Required for Lima VM access, 127.0.0.1 won't work
  • Source .env before running - Run set -a && source .env && set +a or server will fail
  • COS buckets must exist - Create input/output buckets in IBM Cloud before testing batch

🧰 Available Tools

1️⃣ Single Image (Base64 Output)

Endpoint: POST /process-image-async-b64
Use case: Process one image, return result directly in chat/workflow
Best for: Quick demos, visual preview, lightweight interactions

2️⃣ Single Image (COS URL Output)

Endpoint: POST /process-image-async
Use case: Process one image, store in COS, return presigned URL
Best for: Persistent storage, sharing, integration with other systems

3️⃣ Batch Processing (COS β†’ COS)

Endpoint: POST /batch-process-images
Use case: Apply same instruction to all images in a COS folder
Best for: Mass content updates, e-commerce catalogs, marketing assets


πŸ“š Documentation

Document Purpose
API.md Complete API reference with endpoints, schemas, and examples
CONFIGURATION.md Environment variables and setup guide
ARCHITECTURE.md Technical architecture, patterns, and design decisions
tools Orchestrate/README.md watsonX Orchestrate integration guide

🎯 Use Cases

  • 🎨 Product demos – Showcase AI capabilities
  • 🏒 Client workshops – Hands-on training
  • πŸš€ Internal accelerators – Rapid prototyping
  • πŸ“š watsonx Orchestrate best practices – Reference implementation

πŸ”’ Security Notes

  • Never commit .env to version control
  • Use environment variables for all credentials
  • Rotate API keys regularly
  • Use presigned URLs with appropriate expiration
  • See CONFIGURATION.md for production security recommendations

🀝 Contributing

This is a demo project for IBM watsonx Orchestrate. For questions or suggestions, please contact the maintainer.


πŸ“ License

This project is for demonstration and educational purposes.

About

WXO Async Image Processing with OpenAI & IBM Cloud Object Storage

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages