Locutus is the backend for a web-based terminology mapping tool. It gives researchers a collaborative environment to harmonize dataset terms — the column values in a data dictionary — against public ontologies such as MeSH and HPO, so that datasets from different studies can be compared and combined using shared vocabulary.
It's a REST API (Flask + MongoDB) that manages terminologies, tables/data dictionaries, code mappings, provenance history, and per-user voting/discussion on proposed mappings. It's the API layer for the companion frontend, Map Dragon.
- Flask app exposing a resource-oriented REST API (
flask-restful) - MongoDB for storage
- Session-based auth for interactive editing, with editor/service-account fallback for scripted access
- Provenance tracking on every change to a terminology, table, or mapping
- Deployed as a container (see
Dockerfile/cloudbuild.yaml) to Google Cloud Run
docker compose up --buildThis builds the image and serves the API on http://localhost:5000.
Requires Python 3.13+ and a running MongoDB instance.
pip install ".[dev]"For a cloud deployment, install with the cloud extra instead (adds structured JSON logging):
pip install ".[cloud]"By default the log level is WARNING; set LOCUTUS_LOGLEVEL to any standard Python log level (INFO, DEBUG, etc.) to change it.
Unit tests use PyTest and expect a reachable MongoDB instance.
LOCUTUS_DB_TYPE=mongodb LOCUTUS_LOGLEVEL=DEBUG pytestRun a single test file:
pytest src/locutus/tests/test_terminology.pyStop on the first failure:
pytest -x src/locutus/tests/test_terminology.pyThe project lints and formats with Ruff and type-checks with basedpyright, both left at their stock/default settings — no project-specific rule overrides.
pip install ".[dev]"
ruff check .
ruff format .
basedpyrightZed users get this for free: Zed's built-in Python support already runs Ruff and basedpyright with their default settings, so no extra editor config is needed.
VS Code users: this repo ships .vscode/settings.json and .vscode/extensions.json, so opening the folder will prompt you to install the Ruff and basedpyright extensions, with format-on-save and Ruff's fixAll/organize-imports code actions already wired up. Pylance is disabled in favor of basedpyright to avoid two language servers fighting over the same diagnostics.
The full REST API reference — every resource, request/response payloads, and error behavior — lives in the docs site.