Skip to main content

The n8n alternative, written in Python.

Where n8n gives you a canvas, a Task is a program. Hosted and run on secure cloud infrastructure.

triage.py
since = qbash.run.last_run_at.date().isoformat() tickets = qbash.integrations.jira.get_tickets_by_time_span( query_type="date_range", start_date=since, ) for ticket in tickets: triage = qbash.ai.run_prompt( slug="triage-ticket", variables={"body": ticket["description"]}, ) qbash.integrations.jira.update_ticket( ticket["key"], field_id="labels", tag_name=triage["team"], )

Model and provider agnostic.

  • Anthropic
  • OpenAI
  • Gemini
  • xAI
  • OpenRouter
  • Amazon
  • Perplexity
  • MoonshotAI
  • Meta
  • Qwen

qbash vs n8n

n8n has a large node catalogue and a good visual debugger. These rows are about what happens to an automation after it ships, when it has to be changed, reviewed and trusted.

Featureqbashn8n
What you buildA Python programA node graph with expressions
Change historyA revision on every save, with a line-level diffWorkflow JSON you export
RollbackRestore any revision in one clickRe-import an older export
TestsA tests.py rides with the task, in the same revisionNot included
Model outputAn output schema constrains the model to your JSONThe AI Agent node does not constrain it
PromptsVersioned in a prompt platform, called by slugPrompt text sits in the node
Swapping modelsThe model is a field on the promptConfigured per node
CredentialsBrokered server-side, and selectable per callChosen per node, copied with the workflow
Retrying a partial runCheckpoints skip the items that finishedThe workflow runs again
Deploying a changeSaving puts the revision liven8n Cloud, or a server you run
Control flowLoops, branches and functions in codeWired on the canvas
Watching a runRun logs, per stepThe canvas shows execution as it moves
Integrations45+ integrations, 390+ operations, plus raw HTTPSeveral hundred nodes, plus community nodes
Self-hostingNot available. The runtime is proprietary.Yes, and the source is available
What you build
qbashA Python program
n8nA node graph with expressions
Change history
qbashA revision on every save, with a line-level diff
n8nWorkflow JSON you export
Rollback
qbashRestore any revision in one click
n8nRe-import an older export
Tests
qbashA tests.py rides with the task, in the same revision
n8nNot included
Model output
qbashAn output schema constrains the model to your JSON
n8nThe AI Agent node does not constrain it
Prompts
qbashVersioned in a prompt platform, called by slug
n8nPrompt text sits in the node
Swapping models
qbashThe model is a field on the prompt
n8nConfigured per node
Credentials
qbashBrokered server-side, and selectable per call
n8nChosen per node, copied with the workflow
Retrying a partial run
qbashCheckpoints skip the items that finished
n8nThe workflow runs again
Deploying a change
qbashSaving puts the revision live
n8nn8n Cloud, or a server you run
Control flow
qbashLoops, branches and functions in code
n8nWired on the canvas
Watching a run
qbashRun logs, per step
n8nThe canvas shows execution as it moves
Integrations
qbash45+ integrations, 390+ operations, plus raw HTTP
n8nSeveral hundred nodes, plus community nodes
Self-hosting
qbashNot available. The runtime is proprietary.
n8nYes, and the source is available

Easier to maintain than a node graph.

A canvas is hard to manage. Changes are onerous and tough to follow. A task moves the problem into code, where logic is easier to reason about, faster to modify, and version tracking is fast and simple.

Revisions and rollback

Every save writes a revision with a line-level diff and a changelog note, and any revision restores in one click. The tests.py is versioned in the same revision, so the diff shows whether the tests moved with the code. No repo, CI or deploy target to set up first.

Structured outputs

Pass an output_schema and the model is constrained to JSON matching it, so the next step reads fields instead of parsing prose. A malformed answer fails at the schema boundary rather than three steps downstream. A saved prompt carries its own schema, so a run_prompt call returns a dict the same way.

triage.py
TRIAGE = {
    "type": "object",
    "properties": {
        "team": {"enum": ["billing", "technical", "sales"]},
        "priority": {"enum": ["low", "normal", "urgent"]},
    },
}

triage = qbash.ai.raw(
    f"Triage this ticket:\n\n{body}",
    output_schema=TRIAGE,
)

Credentials are brokered outside your code

Connect an account once for the org. Credentials are brokered server-side, never in your code, logs, or a model’s context, and any call can name which account to use, including from a run-form input. One task and a client list, instead of fifteen copied workflows that drift.

clients.py
account = qbash.inputs.get("account")

rows = qbash.integrations.postgres.execute_query(
    "select * from invoices where paid is false",
    credential=account,
)

Checkpoints

qbash.parallel records the items that finished. A retry resumes at the failure, so it does not pay again for model calls that already returned, and does not re-fire the side effects that already happened.

backfill.py
result = qbash.parallel(
    triage, tickets,
    concurrency=8, max_per_minute=120,
    checkpoint="triage-backfill", retry=3,
)

Moving a workflow across.

There is no importer. Porting is real work, so start with an automation whose failure would be cheap rather than the one carrying the most volume.

  1. Describe the workflow to the builder and it drafts the task as code your developer edits.
  2. Connect the accounts once at the org level, rather than per node.
  3. Run the n8n workflow and the task side by side and compare the output.
  4. Move the trigger over once they agree.

Where n8n fits better.

Some of these matter more than anything above. If one of them is your constraint, stay where you are.

  • You need to self-host, for data residency, air-gapped operation, or cost at volume.
  • You need a community node for something niche with no usable API.
  • The people maintaining the automations do not write code.
  • You want to watch execution move through a graph while you debug.

Questions

Is qbash an open-source n8n alternative?

No. The runtime is proprietary and there is no self-hosted edition. Your logic, prompts and memories are portable, but the runtime is not. If self-hosting is a requirement, n8n, Activepieces and Windmill are the realistic options.

What does n8n not do for AI work?

Three things come up. Prompts live inside nodes, so there is no version history and no rollback on a prompt edit. The AI Agent node does not constrain what the model returns. And a retry re-runs the workflow, which re-fires side effects that already succeeded.

Can I import my n8n workflows?

There is no importer. Describe the workflow to the builder and it drafts the task as code you then edit, and run both side by side until the output agrees. Budget time for it and start small.

Do I need to write Python to use qbash?

To build or change a task, yes, though the builder drafts the first version from a description. To run one, no. Typed inputs render a form, so the person who asked for the automation runs it without seeing the code.

Does a task run the same way every time?

The steps are fixed, because they are lines in your code rather than a path a model chooses. A model’s answer can send a run down a different branch, but it cannot change the shape of the process or add a step you did not write.

How does the cost compare to n8n Cloud?

The units differ, so compare on your own volume. n8n Cloud bills per workflow execution and self-hosting trades that for server and maintenance time. In a task a prompt is only used when you call it, so the model spend sits at points you chose in the code and can be worked out before you deploy.

Competitor details reviewed . Vendors change plans and features without notice, so check theirs before deciding.

Ship your first task.

Open the editor, write a script against your connected accounts, and put it on a trigger. Or describe it, and the builder drafts the task as code you edit.