Installation Guide¶
This guide will help you install the software on your system. Note that only Linux distributions are officially supported, due to the usage of multiprocessing libraries and torch.
Contents¶
Prerequisites¶
The following software must be installed on your system before proceeding with the installation:
A document database for storing and retrieving biomedical terminology text data. MongoDB is recommended and used throughout this guide. PostgreSQL, MySQL/MariaDB, or SQLite are also supported as alternatives via SQLAlchemy.
A graph database for storing relationships between terminology concepts. Neo4j is recommended and used throughout this guide. PostgreSQL is also supported as an alternative (plain relational tables plus recursive CTEs, not a graph extension), and can share the same PostgreSQL instance as the document/vector databases above.
A cache for hot data and inter-process communication. Only Redis is supported.
A vector database for storing and searching vector embeddings. Qdrant is recommended and used throughout this guide. MongoDB (with Atlas Search / mongot support) and PostgreSQL (with the pgvector extension) are also supported as alternatives - the latter can share the same PostgreSQL instance as the document database, avoiding a separate vector store entirely.
Resource requirements:
Disk space depends on the terminologies you plan to load: a few gigabytes to over 100 GB.
At least 2 CPU cores and 4 GB of RAM for queries to work. For moderate workloads, 4 cores and 8 GB of RAM is recommended.
It is not recommended to build the database directly on the serving server because it consumes significant CPU and memory. Build it on a separate machine (preferably an HPC with CPU and GPU) and transfer the built database to the server. Refer to Constructing Database for details.
If installing on bare metal, ensure:
Python 3.11 or higher
Active internet connection for downloading dependencies
Ability to install pip packages, or use virtualenv/conda
Using Docker (Recommended)¶
The recommended way to install and run the software is using Docker. This method simplifies the installation process by encapsulating all dependencies within a container, providing an isolated environment that avoids conflicts with other software on the system.
Available Images¶
There are different tags available for different use cases:
latest- tracks the latest stable release. May include breaking changes; update carefully.A specific version tag (e.g.,
v1.2.3) - corresponds to a specific release. Recommended for production where stability is crucial.-cpusuffix - CPU-only installation. Suitable for systems without a compatible GPU. GPU is only needed for embedding and GNN training, not for serving queries.Default image (no
-cpusuffix) - includes GPU support (CUDA torch). Recommended if you have an NVIDIA GPU for faster embedding and training. These images are significantly larger (10 GB or more) due to CUDA libraries.
Choose the appropriate tag based on your system capabilities and requirements.
Docker Compose¶
The repository provides two compose files:
docker-compose.yamlDeploys the bioterms service alongside its dependencies (Neo4j, MongoDB, Redis, Qdrant). Environment variable values are embedded directly.
scripts/docker-compose.dependencies.yamlA standalone dependencies file that publishes ports to the host, for local development or standalone database access. Combine it with the main
docker-compose.yamlvia:docker compose -f docker-compose.yaml -f scripts/docker-compose.dependencies.yaml up
Both compose files also define two further opt-in Compose profiles, neither started by a plain
docker compose up:
mongodb-search- MongoDB Community Server plus MongoDB Community Search (mongot), a self-hosted, SSPL-licensed alternative to Qdrant forBTS_VECTOR_DATABASE_DRIVER=mongodb.postgres- a PostgreSQL+pgvector container, usable as the document database (BTS_DOC_DATABASE_DRIVER=sql), the vector database (BTS_VECTOR_DATABASE_DRIVER=postgresql), the graph database (BTS_GRAPH_DATABASE_DRIVER=postgresql), or all three at once - the document and vector stores share the same tables, and the graph store’s owngraph_*-named tables live alongside them, so one PostgreSQL instance can replace MongoDB/SQL, Qdrant/MongoDB, and Neo4j simultaneously.
Pass --profile <name> to include one. See Constructing Database for details.
### Example Compose
The docker-compose.yaml file from the repository contains the full production-ready configuration,
including both the bioterms web service and an optional bioterms-worker Celery worker process.
The compose files reference the images published on Docker Hub at
firefox2100/biomedical-terminology-service.
Note
BTS_SECRET_KEY (used for session cookies) is auto-generated if omitted.
BTS_SERVER_HMAC_KEY must be set; generate it with:
docker compose exec bioterms bioterms-cli generate-hmac-key
After the containers are up, create an administrator account:
docker compose exec bioterms bioterms-cli user create <username>
From Source Code¶
First install the project with the all extra, which includes every optional dependency
(SQLAlchemy drivers, GNN support, etc.):
pip install .[all]
Then configure environment variables (read from BTS_* env vars first, then from a .env file
at the path specified by BTS_ENV_FILE, or conf/.env by default), build the database
(see Constructing Database), create an admin user, and start the service:
export BTS_SERVER_HMAC_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
bioterms-cli user create admin
uvicorn bioterms.asgi:application --host 127.0.0.1 --port 5000
# (Optional) celery -A bioterms.task.app.celery_app worker --loglevel=info
After loading or deleting a vocabulary or annotation through the CLI or the web UI, the GraphQL
schema must be refreshed. Either send an authenticated POST /reload-graphql request or restart the
web service. A full restart is not required.
Configuration Setup¶
The service is entirely controlled by BTS_* environment variables. The variable is resolved
in the following order (first match wins):
OS environment variables - the OS
os.environnamespace.``.env`` file - at the path specified by the
BTS_ENV_FILEenvironment variable. Default path isconf/.envrelative to the application directory.Docker secrets - if the
/run/secretsdirectory exists, individual environment variable files (e.g.,/run/secrets/BTS_SERVER_HMAC_KEY) are read.
Any variable that has a non-... sentinel value in the Settings class (i.e., any field
declared with Field(default_value)) has a built-in default. Variables declared as ...
(the Ellipsis sentinel, such as server_hmac_key) are required; the service will raise a
ValidationError at startup if no value is provided.
A complete example.env file is available in the repository root with every environment variable
listed, commented, and grouped into logical sections. Copy it and fill in the values needed for
your deployment:
cp example.env conf/.env
Configuration Reference¶
The following tables document every BTS_* configuration variable.
Note
The Sec column indicates if the variable is secret (yes) or public (no).
Secret variables are often used in cookies, signatures, or API keys.
General Settings¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
no |
Maximum worker process count for CLI data handling. Not used by the running web service. |
|
|
no |
Minimum query-string length for auto-complete searches |
|
|
no |
Logging level ( |
|
auto-generated |
yes |
Secret key for session cookies. A different key is generated on each start if not set. |
|
required |
yes |
HMAC key for hashing API keys. No default value. Generate with: |
|
|
no |
Whether the application is behind an HTTPS proxy. Affects cookie settings, redirect URLs, and security headers. |
|
|
no |
Enable Prometheus metrics endpoint at |
|
|
no |
Enable error reporting to Sentry or compatible services |
|
|
no |
Enable performance profiling using Sentry SDK |
|
(empty) |
yes |
Sentry DSN for error reporting |
|
(empty) |
no |
Google site verification ID for webmaster tools. Injects the |
|
|
no |
Directory path inside the container for storing data files |
|
(empty) |
no |
Root path prefix for reverse-proxy setups (e.g. |
|
|
no |
URL path for the OpenAPI schema |
|
|
no |
URL path for the Swagger UI documentation |
|
|
no |
URL path for the ReDoc documentation |
|
|
no |
Canonical base URL for FHIR resources (CodeSystem URLs). Change to your deployment domain. |
|
|
no |
Runtime environment ( |
Celery (Worker Only)¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
yes |
Redis URL for Celery message broker (task input) |
|
|
yes |
Redis URL for Celery result backend (task output) |
Document Database¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
no |
|
|
|
no |
MongoDB host |
|
|
no |
MongoDB port |
|
|
no |
MongoDB database name |
|
(empty) |
yes |
MongoDB username |
|
(empty) |
yes |
MongoDB password |
|
|
no |
MongoDB authentication source database |
|
|
no |
SQLAlchemy async connection URL. Example: |
|
|
no |
Batch size for SQL database write operations |
Graph Database¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
no |
|
|
|
no |
Neo4j Bolt connection URI |
|
|
no |
Neo4j database name |
|
|
yes |
Neo4j username |
|
|
yes |
Neo4j password |
|
|
no |
Number of rows (relationships/nodes) committed per transaction when batch-deleting from Neo4j. Lower values reduce peak transaction memory usage at the cost of speed; important for large vocabularies on memory-constrained Neo4j instances. |
|
|
no |
SQLAlchemy async URL for the PostgreSQL graph database. Only used when |
|
|
no |
Safety bound on recursion depth when (re)building a vocabulary’s ancestor/descendant closure table. Guards against runaway recursion on a malformed/cyclic hierarchy; real ontologies are far shallower than this. Only used when |
Cache¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
no |
Currently only |
|
|
no |
Redis host |
|
|
no |
Redis port |
|
|
no |
Redis database index |
|
|
no |
Multiplier applied to cache item TTLs for Redis hard expiration. The item TTL is the stale-after time; Redis expiration is only a safety limit. |
|
|
no |
Seconds to hold the cache-rebuild single-flight lock, preventing concurrent rebuilds. |
Vector Database¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
no |
|
|
|
no |
Qdrant API endpoint URL |
|
|
no |
Name of the |
|
|
no |
Multiplier applied to the requested result limit to compute |
|
|
no |
SQLAlchemy async URL for the PostgreSQL/pgvector vector database. Only used when
|
External API Keys (Optional)¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
None |
yes |
BioPortal API key. Needed for downloading OMIM and ORDO. |
|
None |
yes |
NHS TRUD API key. Needed for downloading CTV3 and SNOMED CT. |
|
None |
yes |
NIH UMLS API key. Needed for SNOMED-ORDO mappings. |
Embedding & GNN Settings¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
no |
HuggingFace model name for concept embedding generation |
|
|
no |
Worker-process count for embedding generation. Set to 1 to disable multiprocessing. |
|
|
no |
Number of concepts to embed per batch |
|
|
no |
PyTorch device ( |
|
|
no |
Number of training epochs for the GNN model |
|
|
no |
Hidden dimension size for the GNN model |
|
|
no |
Output (embedding) dimension of the GNN model |
|
|
no |
Learning rate for GNN training |
CLI Output Settings¶
Variable |
Default |
Sec |
Description |
|---|---|---|---|
|
|
no |
Show verbose output during CLI operations |
|
|
no |
Disable progress bars for long-running CLI commands |