# Orchestra: human-in-the-loop project teams on Django and Postgres

> Orchestra is B12's open source framework for workflows that mix human experts with automated steps, such as a crawler feeding an analyst or a classifier filtering noise before review. It ships as a Python package on top of Django, with a job queue, an admin interface and a signed REST API, and it has had no tagged release since 2021.

**b12io/orchestra** — Orchestra is a human-in-the-loop AI system for orchestrating project teams of experts and machines.

- Repository: https://github.com/b12io/orchestra
- Website: https://orchestra.b12.io/
- Stars: 717 · Forks: 72
- Language: Python
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/b12io-orchestra

## A framework for workflows where a person stays in the loop

Orchestra is described as a human-in-the-loop AI system for orchestrating project teams of experts and machines. The examples in the documentation are editorial rather than industrial: a design team working on a client project, or a newsroom bringing together reporters, photographers and editors for one story.

The distinguishing feature is that experts can be assigned to review other experts. The workflow model therefore treats human judgment as a scheduled step rather than as an exception path, and the iteration happens inside the tool instead of over email. On the machine side, the same workflow can call in a crawler that collects content from the web before an expert combs through it, or a classifier that filters out bad data so an analyst spends less time in the noise.

The practical audience is a team that already has a Django application and wants to add a review pipeline to it. Orchestra does not try to be a general workflow engine you connect to arbitrary services. New workflows are added with python glue and an html interface, which is a small but important constraint: extending it means writing Django code, not declaring a graph in yaml.

## Django, Postgres, a job queue and an AngularJS front end

The architecture is visible in the dependency list. Django 5.2.7 is the core, with psycopg2 2.9.9 pointing at Postgres as the database, and djangorestframework 3.15.1 plus djangorestframework-httpsignature 1.0.0 and httpsig 1.3.0 providing a REST API whose requests are signed. django-registration-redux handles accounts, django-money 3.5.4 and py-moneyed 3.0 cover money fields, and django-hijack 3.7.4 allows an administrator to impersonate a user, which is a common need in a review workflow where you need to see what a contributor sees.

Background work goes through beanstalk-dispatch 0.1.5, so the job queue is a separate service rather than a thread pool inside the web process. The front end is a different story from the Python side: package.json lists angular-smart-table 2.1.11, angular-ui-tree 2.22.6, d3 3.5.17, dragula 3.7.2, quill 0.20.0 and pikaday 1.4.0, built with webpack 3.3.0, babel 6 and gulp 4, with sass for styling. django-gulp 4.1.0 ties asset building into Django, and style assets are served through Django.

Integration with outside services is broad but narrow at once: boto3 1.35.46 with moto 4.2.8 for AWS and its test doubles, slacker 0.13.0 for Slack, djrill 2.1.0 for email, google-api-python-client 1.7.12 for Google, and lxml 5.2.2 with beautifulsoup4 4.11.1 for HTML scraping. jsl 0.2.4 and jsonschema 4.26.0 bring JSON Schema validation, and ipython 7.23.1 is available for a shell inside the environment.

## Installing from a checkout rather than from a release

The project is packaged with setup.py, which reads its version through release.py and pulls in the packages found by find_packages. The pinned dependency set is long, and the pins are exact, so the supported environment is the one the maintainers recorded:

```bash
setuptools==81.0.0
Django==5.2.7
psycopg2==2.9.9
djangorestframework==3.15.1
beanstalk-dispatch==0.1.5
```

The README does not give a pip install line, and the repository has no Docker Compose file or container recipe, so a working environment means creating a virtualenv, installing requirements.txt and pointing the Django settings at a Postgres instance. The rest of the pins, including factory_boy 2.10.0, moto 4.2.8, coverage 7.10.2, flake8 7.3.0 and twine 4.0.2, cover testing and packaging rather than runtime.

The setup.py metadata is sparse, and the package description field says only that it is a framework for building complex expert workflows, with keywords crowdsourcing and workflows and an Apache 2 licence line. The top level of the repository also carries docs/, a Makefile, tox.ini and a release.py script, which tells you the project expects a documented, test-backed development process even if the README itself stays brief.

## The Makefile is the entry point for building and testing

Most of the practical instructions live in the Makefile rather than in the README, and the targets assume a checked out repository with a local Postgres and a node toolchain:

```bash
test: lint
	cd example_project && python3 $(TEST_CMD)
```

The test target depends on lint, so a run of make test also runs flake8, the gulp linter and a migration check. The lint target is unusually strict about database changes, failing when a migration contains a field removal, a model deletion, a model or table rename, a unique-together change, a raw SQL statement or a RunPython operation, unless the line carries a manually-reviewed marker. It also runs makemigrations in dry-run mode against example_project and fails if new migrations are missing, so schema changes cannot drift silently.

Front end assets are a separate chain. npm_install installs gulp globally when the binary is missing and then runs npm install, and gulp_build produces a production bundle:

```bash
gulp_build: npm_install
	npx gulp build --production
```

Documentation has its own target, build_docs, which runs make html inside docs. Coverage runs the same test command under coverage with the repository .coveragerc, and coveralls ships the result onward.

## Two example projects to read before writing your own

The repository ships example_project/, which is the Django project the Makefile drives, along with simple_workflow/ and journalism_workflow/ at the top level. The last one is the clearest statement of intent: a newsroom workflow that matches the description of reporters, photographers and editors working on a story, with a machinery step doing collection or filtering before a person reads the results.

Reading these directories is the fastest way to understand the extension points, because the documentation for a workflow system is usually the code. The published pipeline for a machine step is short: a crawler collects content from the web, a classifier filters out bad data, and an expert then works through what remains. That sequence is the same whether the workflow is a simple one or the newsroom case, which suggests the framework treats a machine step as another kind of task rather than as a special case.

The README points to the project website, a blog post introducing Orchestra v0.1.0, a GitHub Discussions forum and a ReadTheDocs build for the documentation status. For a project whose last tagged release is v1.0.46 from July 2021, that documentation is the closest thing to a specification, so read it before assuming how a review assignment is modelled.

## Where the age of the project shows up

The most obvious limitation is release cadence. The tagged releases stop at v1.0.46 on 2021-07-28, with v1.0.45 and v1.0.44 in the days before it, and the last push to the repository was on 2026-04-28. The dependency pins, Django 5.2.7 and webpack 3.3.0 among them, describe a working configuration that was assembled recently, but the packaging around it has not been cut into a release, and there is no changelog to tell you what changed since 2021. A team that needs a supported version pin will have to vendor the code or build its own wheel.

The front end is the second pressure point. AngularJS with babel-preset-es2015 6.14.0, webpack 3.3.0, node-sass 8.0.0 and eslint 3.8.1 is a 2017-era toolchain, and the webpack 3 line in particular does not run on current node without friction. The package.json test script is a placeholder that echoes an error and exits 1, so the JavaScript side has no real test command, and the Python side is where the checking lives.

There is a third limit worth naming. The Apache 2 licence covers the code, and the system stores expert judgement and client material in Postgres, which means the operational work of backups, access control and audit trails stays with whoever deploys it. The framework does not remove that obligation, it relocates it into a database you now maintain.

## Orchestra against writing the workflow yourself

The realistic alternative is to skip the framework and build the review pipeline inside an existing Django project with a Celery or database-backed queue. The difference in approach is specific. Writing it yourself gives you full control over the task model, the permission scheme and the data model, and it costs you the parts Orchestra already supplies: expert-to-expert assignment, the impersonation path that lets a reviewer see a contributor's view through django-hijack, signed API requests through djangorestframework-httpsignature, and the admin interface that django-registration-redux and the admin styling package make usable without custom work.

Orchestra is also not a service orchestrator. It does not schedule containerised jobs or fan out to third party APIs the way a pipeline tool would; the machine steps are Python functions inside a Django project, and the queue is beanstalk-dispatch, a background work dispatcher that is convenient for light jobs and light for anything with serious throughput needs.

The deciding factor is therefore the review workflow rather than the automation. If the hard part of your problem is who reviews what and how that decision is recorded, the framework saves real work. If the hard part is moving data between many systems reliably, a purpose-built pipeline tool fits the shape of the problem better, and you can borrow the idea of a human approval step without importing the whole framework.

## Conclusion

Orchestra fits teams that already run Django and Postgres and need review workflows with a human decision inside the loop, and it is the shortest route to the example_project and journalism_workflow code that B12 published. It is the wrong choice for a new automation project that needs a released, versioned package, since the last tagged release was v1.0.46 on 2021-07-28 and the last push was on 2026-04-28, so a fork with your own dependency pins is likely. Before adopting it, run make lint on the example_project, confirm that your Postgres version is acceptable to psycopg2 2.9.9, and check that the angular-smart-table and webpack 3 front end still builds with the node version you have.

## FAQ

### What is Orchestra used for?

Orchestra is a framework for expert workflows that combine human review with automated steps, such as a crawler collecting web content before an expert reads it, or a classifier filtering out bad data so an analyst spends less time in the noise. Senior experts can be assigned to review other experts so the work is refined inside the workflow.

### How do I install and run Orchestra?

The README does not give a pip install line, so you install from a checkout by creating a virtualenv and installing the exact pins in requirements.txt, which include Django 5.2.7 and psycopg2 2.9.9, then run the Django project in example_project. The Makefile drives the rest, with make test running the tests and gulp_build producing the front end bundle.

### What database and job queue does Orchestra use?

The dependency list points at Postgres through psycopg2 2.9.9, and background work is dispatched through beanstalk-dispatch 0.1.5, so the queue is a separate service rather than an in-process thread pool. The REST layer is djangorestframework with request signing via httpsig.

### Is Orchestra still maintained?

The last push to the repository was on 2026-04-28, but the most recent tagged release is v1.0.46 from 2021-07-28, and there is no changelog covering what changed since then. The dependency pins are recent even though the packaged releases are not, so most adopters end up pinning or vendoring the code themselves.

### Can I add a new workflow to Orchestra?

New workflows are added with python glue and an html interface, and the repository ships simple_workflow/ and journalism_workflow/ as examples. A machine step is written as a Python function inside the Django project, and the documentation site plus the GitHub Discussions forum are the places to look for the current model of an expert review assignment.

## Sources

- [b12io/orchestra on GitHub](https://github.com/b12io/orchestra)
- [License: Apache-2.0](https://github.com/b12io/orchestra/blob/main/LICENSE)
- [Project website](https://orchestra.b12.io/)
- [README](https://github.com/b12io/orchestra/blob/main/README.md)
- [Releases](https://github.com/b12io/orchestra/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/b12io-orchestra
