{"id":37083975,"url":"https://github.com/scionoftech/tinyworkflow","last_synced_at":"2026-01-14T10:15:25.773Z","repository":{"id":329091265,"uuid":"1101863037","full_name":"scionoftech/tinyworkflow","owner":"scionoftech","description":"Lightweight Workflow Orchestration for AI and Python","archived":false,"fork":false,"pushed_at":"2025-12-17T08:19:16.000Z","size":1114,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-20T21:43:36.975Z","etag":null,"topics":["ai","aiworkflow","workflow","workflow-automation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scionoftech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-22T11:33:09.000Z","updated_at":"2025-12-17T08:19:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/scionoftech/tinyworkflow","commit_stats":null,"previous_names":["scionoftech/tinyworkflow"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/scionoftech/tinyworkflow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scionoftech%2Ftinyworkflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scionoftech%2Ftinyworkflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scionoftech%2Ftinyworkflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scionoftech%2Ftinyworkflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scionoftech","download_url":"https://codeload.github.com/scionoftech/tinyworkflow/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scionoftech%2Ftinyworkflow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28416748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:38:59.149Z","status":"ssl_error","status_checked_at":"2026-01-14T08:38:43.588Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","aiworkflow","workflow","workflow-automation"],"created_at":"2026-01-14T10:15:25.196Z","updated_at":"2026-01-14T10:15:25.768Z","avatar_url":"https://github.com/scionoftech.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Tinyworkflow](https://github.com/scionoftech/tinyworkflow/blob/main/tinyworkflow.png?width=200\u0026height=150)\n\n[![PyPI version](https://badge.fury.io/py/tinyworkflow.svg)](https://pypi.org/project/tinyworkflow/)\n[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n**Lightweight Workflow Library for Learning and Experimentation**\n\nTinyWorkflow is a simple, Python-first workflow library designed for **learning workflow concepts**, **prototyping**, and **lightweight task orchestration**. Perfect for AI experimentation, small projects, and understanding workflow patterns before moving to production systems.\n\n\u003e **⚠️ Important**: TinyWorkflow is designed for learning and lightweight use cases. For production-grade durable workflows with full fault tolerance, use [Temporal](https://temporal.io/), [Azure Durable Functions](https://learn.microsoft.com/en-us/azure/azure-functions/durable/), or [DBOS](https://www.dbos.dev/).\n\n## 🌟 Key Features\n\n**Perfect for learning and lightweight workflows:**\n\n- **🎯 Pure Python** - Simple decorator-based API, no DSL to learn\n- **💾 State Persistence** - SQLite, PostgreSQL, or MySQL (basic state tracking)\n- **🔄 Retry Logic** - Exponential backoff with jitter for failed activities\n- **⚡ Async/Await** - Modern Python async for high-performance\n- **🔀 Parallel Execution** - Run activities concurrently (fan-out/fan-in)\n- **👥 Human-in-the-Loop** - Basic approval workflows\n- **📅 Scheduling** - Cron expressions and delayed execution\n- **📊 Event Sourcing** - Audit trail for observability\n- **🖥️ Web UI** - Simple workflow monitoring interface\n- **🛠️ CLI Tool** - Command-line interface for operations\n- **🚀 Zero Setup** - No external services required (SQLite default)\n- **📚 Easy to Learn** - Small codebase (~2000 LOC), great for education\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\n# Install from PyPI (once published)\n# Includes support for SQLite, PostgreSQL, and MySQL\npip install tinyworkflow\n\n# Or install from source\ngit clone https://github.com/scionoftech/tinyworkflow\ncd tinyworkflow\npip install -e .\n```\n\n### Basic Example\n\n```python\nimport asyncio\nfrom tinyworkflow import workflow, activity, WorkflowContext, TinyWorkflowClient\n\n# Define activities\n@activity(name=\"fetch_data\")\nasync def fetch_data(url: str):\n    # Your code here\n    return {\"data\": \"...\"}\n\n@activity(name=\"process_data\")\nasync def process_data(data: dict):\n    # Your code here\n    return {\"result\": \"...\"}\n\n# Define workflow\n@workflow(name=\"etl_pipeline\")\nasync def etl_workflow(ctx: WorkflowContext):\n    url = ctx.get_input(\"url\")\n\n    # Execute activities\n    data = await ctx.execute_activity(fetch_data, url)\n    result = await ctx.execute_activity(process_data, data)\n\n    return result\n\n# Run workflow\nasync def main():\n    async with TinyWorkflowClient() as client:\n        run_id = await client.start_workflow(\n            \"etl_pipeline\",\n            input_data={\"url\": \"https://api.example.com\"}\n        )\n        print(f\"Workflow started: {run_id}\")\n\nasyncio.run(main())\n```\n\n### Try the Web UI\n\n```bash\n# IMPORTANT: Run from project root directory\ncd /path/to/tinyworkflow\n\n# Start server with example workflows\ntinyworkflow server --import-workflows examples.workflows\n\n# Open browser to http://localhost:8080\n# You'll see all 20 example workflows ready to run!\n```\n\n**Common Error:** If you see \"No module named 'examples'\", make sure you're running from the project root directory (the directory containing the `examples/` folder).\n\n## 📖 Core Concepts\n\n### Activities\n\nActivities are reusable tasks that perform a single unit of work. They support automatic retries and timeouts.\n\n```python\nfrom tinyworkflow import activity, RetryPolicy\n\n@activity(\n    name=\"fetch_user\",\n    retry_policy=RetryPolicy(max_retries=5, initial_delay=1.0),\n    timeout=30.0\n)\nasync def fetch_user(user_id: str):\n    # Activity code\n    return {\"id\": user_id, \"name\": \"John\"}\n```\n\n### Workflows\n\nWorkflows orchestrate multiple activities and define the business logic. They are automatically persisted and can recover from failures.\n\n```python\nfrom tinyworkflow import workflow, WorkflowContext, RetryPolicy\n\n@workflow(\n    name=\"user_onboarding\",\n    retry_policy=RetryPolicy(max_retries=3)\n)\nasync def user_onboarding_workflow(ctx: WorkflowContext):\n    user_id = ctx.get_input(\"user_id\")\n\n    # Sequential execution\n    user = await ctx.execute_activity(fetch_user, user_id)\n    await ctx.execute_activity(send_welcome_email, user)\n\n    return {\"status\": \"completed\"}\n```\n\n### Parallel Execution\n\nExecute multiple activities concurrently for better performance:\n\n```python\n@workflow(name=\"parallel_example\")\nasync def parallel_workflow(ctx: WorkflowContext):\n    user_id = ctx.get_input(\"user_id\")\n\n    # Run activities in parallel\n    user, orders, preferences = await ctx.execute_parallel(\n        (fetch_user, (user_id,), {}),\n        (fetch_orders, (user_id,), {}),\n        (fetch_preferences, (user_id,), {})\n    )\n\n    return {\"user\": user, \"orders\": orders, \"preferences\": preferences}\n```\n\n### Human-in-the-Loop\n\nPause workflows for manual approval:\n\n```python\n@workflow(name=\"expense_approval\")\nasync def expense_workflow(ctx: WorkflowContext):\n    amount = ctx.get_input(\"amount\")\n\n    if amount \u003e 1000:\n        # Wait for manager approval\n        approved = await ctx.wait_for_approval(\"manager_approval\", timeout=3600)\n\n        if not approved:\n            return {\"status\": \"rejected\"}\n\n    # Process payment\n    result = await ctx.execute_activity(process_payment, amount)\n    return result\n```\n\n## 🛠️ CLI Usage\n\nTinyWorkflow includes a powerful CLI for workflow management:\n\n```bash\n# Start the web UI server (with workflow imports)\ntinyworkflow server --import-workflows examples.workflows --port 8080\n\n# Start a background worker (with workflow imports)\ntinyworkflow worker --import-workflows examples.workflows\n\n# Start a workflow\ntinyworkflow start my_workflow --input '{\"key\": \"value\"}'\n\n# Check workflow status\ntinyworkflow status \u003crun_id\u003e\n\n# List all workflows\ntinyworkflow list --status running\n\n# View workflow events (audit trail)\ntinyworkflow events \u003crun_id\u003e\n\n# Schedule a workflow (cron)\ntinyworkflow schedule my_workflow \"0 9 * * *\"\n\n# List pending approvals\ntinyworkflow approvals\n\n# Approve a workflow\ntinyworkflow approve \u003crun_id\u003e --approve\n\n# List registered workflows\ntinyworkflow workflows\n\n# Cancel a workflow\ntinyworkflow cancel \u003crun_id\u003e\n```\n\n## 🖥️ Web UI\n\nStart the web interface to manage workflows visually:\n\n```bash\n# IMPORTANT: Run from project root directory\ncd /path/to/tinyworkflow\n\n# Start server with workflow imports\ntinyworkflow server --import-workflows examples.workflows --port 8080\n```\n\nThen open http://localhost:8080 in your browser. Features include:\n\n- 📊 Dashboard with workflow statistics\n- ▶️ Start new workflows with custom input\n- 📋 List and filter workflow executions\n- 🔍 View detailed workflow status and events\n- ⏰ Schedule workflows with cron expressions\n- ✅ Approve/reject pending workflows\n- 📚 Browse registered workflows and activities\n\n**⚠️ Requirements:**\n- Must use `--import-workflows` to make workflows available\n- Must run from project root directory\n- See [Workflow Registration](#-workflow-registration) for troubleshooting\n\n## 📅 Scheduling\n\n### Cron-based Scheduling\n\n```python\nasync with TinyWorkflowClient() as client:\n    # Run daily at 9am\n    await client.schedule_workflow(\"daily_report\", \"0 9 * * *\")\n\n    # Run every 5 minutes\n    await client.schedule_workflow(\"health_check\", \"*/5 * * * *\")\n```\n\n### Delayed Execution\n\n```python\nasync with TinyWorkflowClient() as client:\n    # Run after 5 minutes\n    await client.schedule_delayed_workflow(\n        \"cleanup_job\",\n        delay_seconds=300,\n        input_data={\"resource_id\": \"abc123\"}\n    )\n```\n\n## 🎯 Use Cases\n\n### AI/ML Workflows\n\nPerfect for multi-step AI pipelines with automatic retries and state management:\n\n```python\n@workflow(name=\"ai_content_pipeline\")\nasync def ai_content_pipeline(ctx: WorkflowContext):\n    prompt = ctx.get_input(\"prompt\")\n\n    # Generate content with retry logic\n    content = await ctx.execute_activity(generate_ai_content, prompt)\n\n    # Parallel analysis: sentiment, moderation, keywords\n    sentiment, moderation, keywords = await ctx.execute_parallel(\n        (analyze_sentiment, (content,), {}),\n        (moderate_content, (content,), {}),\n        (extract_keywords, (content,), {})\n    )\n\n    # Check moderation\n    if moderation[\"flagged\"]:\n        return {\"status\": \"rejected\", \"reason\": \"content_moderation\"}\n\n    # Translate to multiple languages\n    translations = await ctx.execute_parallel(\n        (translate, (content, \"es\"), {}),\n        (translate, (content, \"fr\"), {}),\n        (translate, (content, \"de\"), {})\n    )\n\n    # Save results with full audit trail\n    await ctx.execute_activity(save_results, {\n        \"content\": content,\n        \"sentiment\": sentiment,\n        \"translations\": translations\n    })\n\n    return {\"status\": \"completed\", \"content\": content}\n```\n\n**Real-world AI use cases:**\n- Content generation and moderation pipelines\n- Document processing and extraction\n- Sentiment analysis workflows\n- Multi-language translation pipelines\n- Image/video processing workflows\n- ML model inference pipelines\n- Data labeling and annotation workflows\n\n### Data Processing\n\nETL and data pipelines:\n\n```python\n@workflow(name=\"etl\")\nasync def etl_workflow(ctx: WorkflowContext):\n    # Extract\n    data = await ctx.execute_activity(extract_from_source)\n\n    # Transform\n    transformed = await ctx.execute_activity(transform_data, data)\n\n    # Load\n    await ctx.execute_activity(load_to_destination, transformed)\n\n    return {\"status\": \"success\"}\n```\n\n### Approval Workflows\n\nBusiness processes requiring human approval:\n\n```python\n@workflow(name=\"purchase_order\")\nasync def purchase_order_workflow(ctx: WorkflowContext):\n    order = await ctx.execute_activity(create_order, ctx.get_input(\"items\"))\n\n    # Require approval for large orders\n    if order[\"total\"] \u003e 10000:\n        approved = await ctx.wait_for_approval(\"purchase_approval\")\n        if not approved:\n            return {\"status\": \"rejected\"}\n\n    await ctx.execute_activity(process_order, order)\n    return {\"status\": \"completed\", \"order_id\": order[\"id\"]}\n```\n\n## 🏗️ Architecture\n\nTinyWorkflow is designed as a **simple workflow library** with these components:\n\n- **State Manager** - SQLAlchemy-based persistence (SQLite/PostgreSQL/MySQL)\n- **Workflow Engine** - Executes workflows with state tracking\n- **Activity Executor** - Runs activities with retry logic\n- **Scheduler** - Cron and delayed jobs (APScheduler)\n- **Worker** - Background processor for async execution\n- **Client API** - Python API for workflow management\n- **CLI** - Command-line interface (Click)\n- **Web UI** - FastAPI-based web interface\n\n### ⚠️ Current Limitations\n\n**What TinyWorkflow does NOT provide (by design):**\n\n1. **No Workflow Replay** - Failed workflows retry from scratch, not from the failure point\n2. **No Deterministic Execution** - Can use `datetime.now()`, `uuid.uuid4()`, `random()` freely\n3. **No Durable Timers** - Using `asyncio.sleep()` loses timer state on crash\n4. **No Signal System** - Cannot send external events to running workflows\n5. **No Saga/Compensation** - No automatic rollback on failures\n6. **No Workflow Versioning** - Changing code may break in-flight workflows\n\n**These limitations are intentional** - implementing them would significantly increase complexity. For workflows requiring these features, use production systems like Temporal or DBOS.\n\n**What TinyWorkflow DOES provide:**\n\n✅ State persistence (workflows/activities stored in database)\n✅ Retry policies (exponential backoff with jitter)\n✅ Parallel execution (fan-out/fan-in patterns)\n✅ Event sourcing (audit trail)\n✅ Human-in-the-loop (basic approval workflows)\n✅ Scheduling (cron expressions)\n✅ Web UI (workflow monitoring)\n✅ Multi-database support (SQLite/PostgreSQL/MySQL)\n\n## 🔧 Configuration\n\n### Database Configuration\n\nTinyWorkflow supports SQLite (default), PostgreSQL, and MySQL for state persistence.\n\n#### SQLite (Default)\n\nNo additional setup required. Perfect for development and small deployments:\n\n```python\nfrom tinyworkflow import TinyWorkflowClient\n\n# Use default SQLite database (tinyworkflow.db in current directory)\nasync with TinyWorkflowClient() as client:\n    pass\n\n# Or specify custom SQLite path\nasync with TinyWorkflowClient(\n    database_url=\"sqlite+aiosqlite:///path/to/custom.db\"\n) as client:\n    pass\n```\n\n#### PostgreSQL\n\nConfigure PostgreSQL connection (driver included by default):\n\n```python\nfrom tinyworkflow import TinyWorkflowClient\n\n# Connect to PostgreSQL\nasync with TinyWorkflowClient(\n    database_url=\"postgresql+asyncpg://user:password@localhost:5432/tinyworkflow\"\n) as client:\n    pass\n\n```\n\n**Setup PostgreSQL database:**\n\n```bash\n# Create database\ncreatedb tinyworkflow\n\n# Or using psql\npsql -c \"CREATE DATABASE tinyworkflow;\"\n```\n\n#### MySQL\n\nConfigure MySQL connection (driver included by default):\n\n```python\nfrom tinyworkflow import TinyWorkflowClient\n\n# Connect to MySQL\nasync with TinyWorkflowClient(\n    database_url=\"mysql+asyncmy://user:password@localhost:3306/tinyworkflow\"\n) as client:\n    pass\n\n# With charset specification\nasync with TinyWorkflowClient(\n    database_url=\"mysql+asyncmy://user:password@localhost:3306/tinyworkflow?charset=utf8mb4\"\n) as client:\n    pass\n```\n\n**Setup MySQL database:**\n\n```bash\n# Create database\nmysql -u root -p -e \"CREATE DATABASE tinyworkflow CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\"\n```\n\n#### CLI with Custom Database\n\nYou can specify the database URL when using the CLI:\n\n```bash\n# PostgreSQL\ntinyworkflow --db \"postgresql+asyncpg://user:pass@localhost/tinyworkflow\" server\n\n# MySQL\ntinyworkflow --db \"mysql+asyncmy://user:pass@localhost/tinyworkflow\" worker\n\n# Custom SQLite path\ntinyworkflow --db \"sqlite+aiosqlite:///custom/path/db.sqlite\" server\n```\n\n#### Environment Variables\n\nSet database URL via environment variable:\n\n```bash\nexport TINYWORKFLOW_DATABASE_URL=\"postgresql+asyncpg://user:pass@localhost/tinyworkflow\"\ntinyworkflow server\n```\n\n#### Connection Pooling\n\nPostgreSQL and MySQL use connection pooling by default:\n\n- **Pool Size**: 10 connections\n- **Max Overflow**: 20 additional connections\n- **Pool Pre-Ping**: Enabled (verifies connections before use)\n- **Pool Recycle**: 3600 seconds (1 hour)\n\nThese settings are optimized for most use cases and applied automatically.\n\n### Retry Policies\n\nCustomize retry behavior:\n\n```python\nfrom tinyworkflow import RetryPolicy\n\nretry_policy = RetryPolicy(\n    max_retries=5,\n    initial_delay=1.0,      # seconds\n    max_delay=60.0,         # seconds\n    backoff_multiplier=2.0,  # exponential backoff\n    jitter=True,            # add randomness\n    jitter_factor=0.1       # 10% jitter\n)\n\n@activity(name=\"flaky_task\", retry_policy=retry_policy)\nasync def flaky_task():\n    # May fail and will be retried\n    pass\n```\n\n### Worker Configuration\n\n```python\nclient = TinyWorkflowClient(auto_start_worker=True)\n\n# Or manually configure\nworker = WorkflowWorker(\n    state_manager=state_manager,\n    workflow_engine=engine,\n    poll_interval=1.0,\n    max_concurrent_workflows=10\n)\n```\n\n## 📊 Monitoring \u0026 Observability\n\n### Event Sourcing\n\nEvery state change is recorded:\n\n```python\nevents = await client.get_workflow_events(run_id)\nfor event in events:\n    print(f\"{event.timestamp}: {event.event_type}\")\n```\n\n### Workflow Status\n\n```python\nworkflow = await client.get_workflow_status(run_id)\nprint(f\"Status: {workflow.status}\")\nprint(f\"Created: {workflow.created_at}\")\nprint(f\"Retries: {workflow.retry_count}/{workflow.max_retries}\")\n```\n\n## 📦 Workflow Registration\n\n**Important:** Workflows must be explicitly imported to be available in the CLI and web UI.\n\n### Quick Start\n\n```bash\n# IMPORTANT: Run from project root directory\ncd /path/to/tinyworkflow\n\n# Start server with example workflows\ntinyworkflow server --import-workflows examples.workflows\n\n# Start worker with your project workflows\ntinyworkflow worker --import-workflows myproject.workflows\n```\n\n**Troubleshooting:** If you get \"No module named 'examples'\" error:\n1. Verify you're in the project root directory: `pwd` or `cd`\n2. Check that `examples/__init__.py` exists\n3. Try: `python -c \"import examples.workflows\"` to test imports\n\n### Create a Workflow Registry\n\n```python\n# myproject/workflows.py\n\"\"\"Workflow registry - imports all workflow modules\"\"\"\n\nfrom myproject.orders import order_workflow\nfrom myproject.payments import payment_workflow\nfrom myproject.notifications import notification_workflow\n```\n\nThen start the server:\n\n```bash\ntinyworkflow server --import-workflows myproject.workflows\n```\n\n### Why This Is Needed\n\nWorkflows are registered when their Python modules are imported via the `@workflow` decorator. Without explicit imports:\n- ❌ Web UI shows \"No workflows registered\"\n- ❌ Cannot start or schedule workflows\n- ❌ Registry appears empty\n\n**📖 See [WORKFLOW_REGISTRATION.md](WORKFLOW_REGISTRATION.md) for detailed guide**\n\n## 🧪 Testing\n\nRun the test suite:\n\n```bash\npytest tests/ -v\n```\n\n## 📝 Examples\n\nCheck the `examples/` directory for complete examples:\n\n- `simple_workflow.py` - Basic ETL workflow\n- `parallel_workflow.py` - Parallel activity execution\n- `approval_workflow.py` - Human-in-the-loop approval\n- `retry_workflow.py` - **Retry policies and failure handling**\n- `scheduling_workflow.py` - **Cron scheduling and delayed execution**\n- `ai_content_pipeline.py` - **AI content generation with sentiment analysis and moderation**\n- `ai_document_processor.py` - **AI document processing with parallel analysis**\n- `database_configuration.py` - Multi-database configuration examples\n\n### Core Workflow Examples\n\nRun the core examples to understand TinyWorkflow's features:\n\n```bash\n# Retry Policies - Handle failures with automatic retries\npython examples/retry_workflow.py\n\n# Scheduling - Cron expressions and delayed execution\npython examples/scheduling_workflow.py\n\n# Approval Workflows - Human-in-the-loop patterns\npython examples/approval_workflow.py\n```\n\n### AI Workflow Examples\n\nRun the AI examples to see TinyWorkflow in action with AI workloads:\n\n```bash\n# AI Content Pipeline - Generate, analyze, and moderate content\npython examples/ai_content_pipeline.py\n\n# AI Document Processor - Extract, classify, and analyze documents\npython examples/ai_document_processor.py\n```\n\n**Core features demonstrated:**\n- ✅ Retry policies with exponential backoff\n- ✅ Activity-level and workflow-level retries\n- ✅ Cron-based scheduling (daily, weekly, monthly jobs)\n- ✅ Delayed workflow execution\n- ✅ Human-in-the-loop approval workflows\n- ✅ Parallel execution patterns\n\n**AI/ML features demonstrated:**\n- ✅ AI/ML task orchestration\n- ✅ Content generation and moderation pipelines\n- ✅ Document processing with parallel analysis\n- ✅ Sentiment analysis workflows\n- ✅ State persistence and recovery\n- ✅ Event sourcing for audit trails\n- ✅ Batch processing of multiple documents\n\n## ✅ When to Use TinyWorkflow\n\n**Perfect for:**\n- 📚 **Learning** workflow orchestration concepts\n- 🧪 **Prototyping** and experimenting with workflow patterns\n- 🎓 **Educational** projects and tutorials\n- 🚀 **Quick demos** and POCs\n- 📊 **Simple data pipelines** (\u003c 1 hour execution)\n- 🤖 **AI experimentation** with LLM chains\n- 🛠️ **Small internal tools** and automation scripts\n- 📅 **Lightweight scheduled jobs**\n\n**Key advantages:**\n- Zero infrastructure setup (SQLite by default)\n- Simple decorator-based API\n- Easy to understand codebase (~2000 LOC)\n- Great for learning before Temporal\n\n## ⚠️ When NOT to Use TinyWorkflow\n\n**Use production systems instead for:**\n- ❌ **Critical business processes** requiring guaranteed execution\n- ❌ **Long-running workflows** (hours/days) with crash recovery\n- ❌ **High-scale production** workloads (1000s of workflows/sec)\n- ❌ **Distributed transactions** requiring saga patterns\n- ❌ **Complex compensations** and rollback logic\n- ❌ **Mission-critical** systems where downtime costs money\n\n**For production, use:**\n- [**Temporal**](https://temporal.io/) - Full-featured durable execution\n- [**Azure Durable Functions**](https://learn.microsoft.com/en-us/azure/azure-functions/durable/) - Serverless workflows\n- [**DBOS**](https://www.dbos.dev/) - Database-backed workflows\n- [**Prefect**](https://www.prefect.io/) - Data engineering workflows\n- [**Airflow**](https://airflow.apache.org/) - Batch data pipelines\n\n## 🆚 Comparison\n\n| Feature | TinyWorkflow | Temporal | Azure Durable | DBOS |\n|---------|-------------|----------|---------------|------|\n| **Setup Complexity** | ⭐ Very Simple | ⭐⭐⭐ Complex | ⭐⭐ Moderate | ⭐⭐ Moderate |\n| **Target Use Case** | Learning/Small | Production | Production | Production |\n| **Workflow Replay** | ❌ | ✅ | ✅ | ✅ |\n| **Deterministic Execution** | ❌ | ✅ | ✅ | ✅ |\n| **Fault Tolerance** | ⚠️ Basic | ✅ Full | ✅ Full | ✅ Full |\n| **Durable Timers** | ❌ | ✅ | ✅ | ✅ |\n| **Signals/Events** | ❌ | ✅ | ✅ | ✅ |\n| **State Persistence** | ✅ SQLite/Postgres/MySQL | ✅ | ✅ | ✅ |\n| **Retry Policies** | ✅ | ✅ | ✅ | ✅ |\n| **Parallel Execution** | ✅ | ✅ | ✅ | ✅ |\n| **Learning Curve** | Low | High | Medium | Medium |\n| **Best For** | Learning \u0026 Prototypes | Production Scale | Azure Ecosystem | DB-Centric Apps |\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## 📄 License\n\nMIT License - see LICENSE file for details.\n\n## 🙏 Acknowledgments\n\nInspired by:\n- [Temporal](https://temporal.io/) - Durable execution primitives\n- [Prefect](https://www.prefect.io/) - Modern workflow orchestration\n- [DBOS](https://www.dbos.dev/) - Durable execution with databases\n\n## 📚 Documentation\n\n- [Quick Start Guide](QUICKSTART.md) - Get started in 5 minutes\n- [Workflow Registration](WORKFLOW_REGISTRATION.md) - How to register workflows\n- [Limitations](LIMITATIONS.md) - What TinyWorkflow does and doesn't provide\n\n## 💬 Support\n\n- GitHub Issues: [Report bugs](https://github.com/scionoftech/tinyworkflow/issues)\n- Discussions: [Ask questions](https://github.com/scionoftech/tinyworkflow/discussions)\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscionoftech%2Ftinyworkflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscionoftech%2Ftinyworkflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscionoftech%2Ftinyworkflow/lists"}