AutomationFlowsWeb Scraping › MLOps Pipeline for Hand Talk

MLOps Pipeline for Hand Talk

Original n8n title: Mlops Pipeline - Hand Talk

MLOps Pipeline - Hand Talk. Uses executeCommand, httpRequest. Webhook trigger; 15 nodes.

Webhook trigger★★★★☆ complexity15 nodesExecute CommandHTTP Request
Web Scraping Trigger: Webhook Nodes: 15 Complexity: ★★★★☆ Added:

This workflow follows the Executecommand → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "MLOps Pipeline - Hand Talk",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "mlops-pipeline",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "p1",
              "name": "dataset_name",
              "value": "={{ (() => { const value = $json.body?.dataset_name; return value === undefined || value === null || value === '' || value === 'undefined' ? 'para_crawl/enpt' : String(value); })() }}",
              "type": "string"
            },
            {
              "id": "p2",
              "name": "max_tokens",
              "value": "={{ (() => { const value = $json.body?.max_tokens; return value === undefined || value === null || value === '' || value === 'undefined' ? 64 : Number(value); })() }}",
              "type": "number"
            },
            {
              "id": "p3",
              "name": "epochs",
              "value": "={{ (() => { const value = $json.body?.epochs; return value === undefined || value === null || value === '' || value === 'undefined' ? 2 : Number(value); })() }}",
              "type": "number"
            },
            {
              "id": "p4",
              "name": "threshold",
              "value": "={{ (() => { const value = $json.body?.threshold; return value === undefined || value === null || value === '' || value === 'undefined' ? 0.0 : Number(value); })() }}",
              "type": "number"
            },
            {
              "id": "p5",
              "name": "git_sha",
              "value": "={{ (() => { const value = $json.body?.git_sha; return value === undefined || value === null || value === '' || value === 'undefined' ? 'unknown' : String(value); })() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "name": "Par\u00e2metros",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "command": "=docker run --rm --network mlops-challenge_mlops -v {{ $env.HOST_WORKSPACE_PATH }}:/workspace -e WRAPT_DISABLE_EXTENSIONS=1 -e PYTHONUNBUFFERED=1 mlops-challenge-ml:local python -m ml.prepare_dataset --output_dir data/processed --dataset_name {{ $json.dataset_name }} --max_tokens {{ $json.max_tokens }} --train_records 500 --val_records 100 --seed 42"
      },
      "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "name": "Preparar Dados",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "command": "=docker run --rm --network mlops-challenge_mlops -v {{ $env.HOST_WORKSPACE_PATH }}:/workspace -e WRAPT_DISABLE_EXTENSIONS=1 -e PYTHONUNBUFFERED=1 mlops-challenge-ml:local python -m ml.train --data_dir data/processed --artifacts_dir artifacts --epochs {{ $('Par\u00e2metros').item.json.epochs }} --batch_size 32 --threshold {{ $('Par\u00e2metros').item.json.threshold }} --max_tokens {{ $('Par\u00e2metros').item.json.max_tokens }} --git_sha {{ $('Par\u00e2metros').item.json.git_sha }}"
      },
      "id": "d4e5f6a7-b8c9-0123-defa-234567890123",
      "name": "Treinar",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const output = $input.item.json.stdout;\nconst lines = output.trim().split('\\n');\nconst lastLine = lines[lines.length - 1];\nconst summary = JSON.parse(lastLine);\nreturn { json: summary };"
      },
      "id": "e5f6a7b8-c9d0-1234-efab-345678901234",
      "name": "Parsear Resultado",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "check-approved",
              "leftValue": "={{ $json.status }}",
              "rightValue": "approved",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "f6a7b8c9-d0e1-2345-fabc-456789012345",
      "name": "Aprovado?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1340,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "http://api:8000/model",
        "options": {}
      },
      "id": "a0b1c2d3-e4f5-6789-abcd-000000000001",
      "name": "Modelo Atual",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1560,
        180
      ]
    },
    {
      "parameters": {
        "command": "=docker run --rm --network mlops-challenge_mlops -v {{ $env.HOST_WORKSPACE_PATH }}:/workspace -e WRAPT_DISABLE_EXTENSIONS=1 -e PYTHONUNBUFFERED=1 mlops-challenge-ml:local python automation/publish_artifact.py --artifacts_dir artifacts --run_id {{ $('Parsear Resultado').item.json.run_id }}"
      },
      "id": "11223344-5566-7788-99aa-bbccddeeff00",
      "name": "Publicar Artefatos",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        1560,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://api:8000/reload",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ run_id: $('Parsear Resultado').item.json.run_id, artifacts_dir: 'artifacts' }) }}",
        "options": {}
      },
      "onError": "continueErrorOutput",
      "id": "a7b8c9d0-e1f2-3456-abcd-567890123456",
      "name": "Deploy",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1780,
        180
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: true, run_id: $('Parsear Resultado').item.json.run_id, status: 'deployed', metric_value: $('Parsear Resultado').item.json.metric_value }) }}",
        "options": {}
      },
      "id": "b8c9d0e1-f2a3-4567-bcde-678901234567",
      "name": "Sucesso",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        2000,
        120
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://api:8000/reload",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ run_id: $('Modelo Atual').item.json.run_id || null, artifacts_dir: 'artifacts' }) }}",
        "options": {}
      },
      "id": "a0b1c2d3-e4f5-6789-abcd-000000000002",
      "name": "Rollback",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2000,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: false, run_id: $('Parsear Resultado').item.json.run_id, status: 'deploy_failed_rollback', reason: 'Falha no deploy \u2014 modelo anterior restaurado', previous_run_id: $('Modelo Atual').item.json.run_id }) }}",
        "options": {
          "responseCode": 500
        }
      },
      "id": "a0b1c2d3-e4f5-6789-abcd-000000000003",
      "name": "Falha no Deploy",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        2220,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: false, run_id: $('Parsear Resultado').item.json.run_id, status: 'rejected', reason: 'Modelo abaixo do threshold', metric_value: $('Parsear Resultado').item.json.metric_value, threshold: $('Parsear Resultado').item.json.threshold }) }}",
        "options": {
          "responseCode": 422
        }
      },
      "id": "c9d0e1f2-a3b4-5678-cdef-789012345678",
      "name": "Rejeitado",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1560,
        420
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "mlops-alerts",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "00112233-4455-6677-8899-aabbccddeeff",
      "name": "Webhook Alertas",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        560
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ received: true, source: 'grafana', status: 'acknowledged', alert: $json.body?.title || $json.body?.message || 'unknown' }) }}",
        "options": {}
      },
      "id": "ffeeddcc-bbaa-9988-7766-554433221100",
      "name": "Alerta Recebido",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        460,
        560
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Par\u00e2metros",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Par\u00e2metros": {
      "main": [
        [
          {
            "node": "Preparar Dados",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preparar Dados": {
      "main": [
        [
          {
            "node": "Treinar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Treinar": {
      "main": [
        [
          {
            "node": "Parsear Resultado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parsear Resultado": {
      "main": [
        [
          {
            "node": "Aprovado?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aprovado?": {
      "main": [
        [
          {
            "node": "Publicar Artefatos",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Rejeitado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Publicar Artefatos": {
      "main": [
        [
          {
            "node": "Modelo Atual",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Modelo Atual": {
      "main": [
        [
          {
            "node": "Deploy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Deploy": {
      "main": [
        [
          {
            "node": "Sucesso",
            "type": "main",
            "index": 0
          }
        ]
      ],
      "error": [
        [
          {
            "node": "Rollback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rollback": {
      "main": [
        [
          {
            "node": "Falha no Deploy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Alertas": {
      "main": [
        [
          {
            "node": "Alerta Recebido",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d0e1f2a3-b4c5-6789-defa-890123456790",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "f2a3b4c5-d6e7-8901-fabc-012345678901",
  "tags": []
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

MLOps Pipeline - Hand Talk. Uses executeCommand, httpRequest. Webhook trigger; 15 nodes.

Source: https://github.com/saviorgomes/mlops-challenge-handtalk/blob/52c3dfbaaa663a25f3840a84379d412355049005/n8n/workflow.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

Sign PDF documents with legally-compliant digital signatures using X.509 certificates. Supports multiple PAdES signature levels (B, T, LT, LTA) with optional visible stamps.

Execute Command, HTTP Request, Read Write File +1
Web Scraping

AIDP - Main Workflow v2. Uses executeCommand, httpRequest. Webhook trigger; 13 nodes.

Execute Command, HTTP Request
Web Scraping

JFCandia_Flujo. Uses executeCommand, emailSend, readWriteFile, httpRequest. Webhook trigger; 8 nodes.

Execute Command, Email Send, Read Write File +1
Web Scraping

SmarterOS - Update Button. Uses executeCommand, httpRequest. Webhook trigger; 5 nodes.

Execute Command, HTTP Request
Web Scraping

This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di

n8n, Execute Workflow Trigger, HTTP Request +1