Skip to main content

htsget protocol server implementation in Rust with Python bindings

Project description

htsgetr

A Rust implementation of the htsget protocol (v1.3) for serving genomic data over HTTP. Built with noodles for bioinformatics I/O and axum for the web server.

Features

  • htsget 1.3 compliant - GET/POST endpoints for reads and variants
  • Multiple formats - BAM, CRAM, VCF, BCF via noodles
  • Extensions - FASTA/FASTQ support beyond the spec
  • Multiple storage backends - Local filesystem, S3, and HTTP/HTTPS
  • JWT authentication - Optional Bearer token auth with JWKS/static keys
  • Python bindings - PyO3 integration via maturin
  • Async - Built on tokio for high concurrency

Installation

From source (Rust)

git clone https://github.com/bolu-atx/htsgetr.git
cd htsgetr
cargo install --path .

Python

pip install maturin
maturin develop --features python

Quick Start

# Create a data directory with some BAM/VCF files
mkdir -p data
cp /path/to/sample.bam data/
cp /path/to/sample.bam.bai data/

# Start the server
htsgetr --data-dir ./data

# Query reads
curl http://localhost:8080/reads/sample

Usage

Server

# Start server with default settings
htsgetr --data-dir /path/to/data

# Custom host/port
htsgetr --host 0.0.0.0 --port 8080 --data-dir /path/to/data

# With explicit base URL (for proxied setups)
htsgetr --data-dir /path/to/data --base-url https://example.com/htsget

Configuration

Environment Variable CLI Flag Default Description
HTSGET_HOST --host 0.0.0.0 Bind address
HTSGET_PORT --port 8080 Listen port
HTSGET_DATA_DIR --data-dir ./data Directory containing genomic files
HTSGET_BASE_URL --base-url auto Base URL for ticket URLs
HTSGET_CORS --cors true Enable CORS
HTSGET_STORAGE --storage local Storage backend: local, s3, or http
RUST_LOG --log-level info Log level

S3 Storage

cargo build --features s3

HTSGET_STORAGE=s3 \
HTSGET_S3_BUCKET=my-genomics-bucket \
HTSGET_S3_PREFIX=samples/ \
htsgetr
Environment Variable Default Description
HTSGET_S3_BUCKET required S3 bucket name
HTSGET_S3_REGION auto AWS region (uses AWS_REGION if not set)
HTSGET_S3_PREFIX "" Key prefix for files
HTSGET_S3_ENDPOINT - Custom endpoint (for MinIO, LocalStack)
HTSGET_PRESIGNED_URL_EXPIRY 3600 Presigned URL TTL in seconds
HTSGET_CACHE_DIR /tmp/htsgetr-cache Local cache for index files

HTTP Storage

cargo build --features http

HTSGET_STORAGE=http \
HTSGET_HTTP_BASE_URL=https://files.example.com/genomics/ \
htsgetr
Environment Variable Default Description
HTSGET_HTTP_BASE_URL required Base URL for data files
HTSGET_HTTP_INDEX_BASE_URL - Base URL for index files (defaults to data URL)

Authentication

Enable JWT/Bearer token authentication by building with the auth feature:

cargo build --features auth

HTSGET_AUTH_ENABLED=true \
HTSGET_AUTH_ISSUER=https://auth.example.com \
htsgetr --features auth
Environment Variable Default Description
HTSGET_AUTH_ENABLED false Enable authentication
HTSGET_AUTH_ISSUER - JWT issuer URL (JWKS fetched from {issuer}/.well-known/jwks.json)
HTSGET_AUTH_AUDIENCE - Expected aud claim
HTSGET_AUTH_JWKS_URL auto Explicit JWKS URL (overrides issuer-derived URL)
HTSGET_AUTH_PUBLIC_KEY - Static RSA/EC PEM public key (alternative to JWKS)
HTSGET_AUTH_PUBLIC_ENDPOINTS /,/service-info Comma-separated paths that don't require auth
HTSGET_DATA_URL_SECRET generated HMAC secret for signing data URLs
HTSGET_DATA_URL_EXPIRY 3600 Signed data URL TTL in seconds

When auth is enabled:

  • Public endpoints (root, service-info) don't require authentication
  • All other endpoints require a valid Authorization: Bearer <token> header
  • Data URLs in tickets are HMAC-signed with expiry to prevent unauthorized access

Data Directory Structure

Place files in the data directory with standard extensions:

data/
├── sample1.bam
├── sample1.bam.bai
├── sample2.vcf.gz
├── sample2.vcf.gz.tbi
├── reference.fa
└── reference.fa.fai

API Reference

Reads Endpoint

# Get all reads
curl http://localhost:8080/reads/sample1

# Get reads for a region
curl "http://localhost:8080/reads/sample1?referenceName=chr1&start=0&end=1000000"

# Header only
curl "http://localhost:8080/reads/sample1?class=header"

# Request CRAM format
curl "http://localhost:8080/reads/sample1?format=CRAM"

# POST with multiple regions
curl -X POST http://localhost:8080/reads/sample1 \
  -H "Content-Type: application/json" \
  -d '{
    "format": "BAM",
    "regions": [
      {"referenceName": "chr1", "start": 0, "end": 1000000},
      {"referenceName": "chr2", "start": 0, "end": 500000}
    ]
  }'

Variants Endpoint

# Get all variants
curl http://localhost:8080/variants/sample2

# Get variants for a region
curl "http://localhost:8080/variants/sample2?referenceName=chr1&start=0&end=1000000"

Sequences Endpoint (Extension)

# Get FASTA sequence
curl http://localhost:8080/sequences/reference

Service Info

curl http://localhost:8080/service-info

Response Format

Successful responses return a JSON ticket per the htsget spec:

{
  "htsget": {
    "format": "BAM",
    "urls": [
      {
        "url": "http://localhost:8080/data/reads/sample1",
        "class": "body"
      }
    ]
  }
}

Error responses:

{
  "htsget": {
    "error": "NotFound",
    "message": "not found: sample1"
  }
}

Python Bindings

from htsgetr import HtsgetServer, HtsgetClient

# Start a server
server = HtsgetServer("/path/to/data", port=8080)
server.run()  # Blocking

# Use the client
client = HtsgetClient("http://localhost:8080")
ticket = client.reads("sample1", reference_name="chr1", start=0, end=1000000)

Roadmap

  • Server scaffold with axum
  • htsget 1.3 types and error handling
  • Local filesystem storage backend
  • Reads endpoint (BAM/CRAM)
  • Variants endpoint (VCF/BCF)
  • Sequences endpoint (FASTA/FASTQ extension)
  • Index-based byte range queries (BAI, TBI, CSI)
  • S3 storage backend with pre-signed URLs
  • HTTP/HTTPS storage backend
  • JWT/Bearer token authentication
  • CRAM reference resolution
  • GCS storage backend
  • Python bindings (full implementation)
  • Docker image

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Related Projects

  • htsget-rs - Another Rust htsget implementation
  • noodles - Bioinformatics I/O libraries in Rust
  • htslib - C library for HTS formats

License

MIT License - see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htsgetr-0.1.0.tar.gz (955.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

htsgetr-0.1.0-cp311-cp311-win_amd64.whl (8.1 MB view details)

Uploaded CPython 3.11Windows x86-64

htsgetr-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl (10.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

htsgetr-0.1.0-cp311-cp311-manylinux_2_28_aarch64.whl (10.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

htsgetr-0.1.0-cp311-cp311-macosx_11_0_arm64.whl (9.1 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file htsgetr-0.1.0.tar.gz.

File metadata

  • Download URL: htsgetr-0.1.0.tar.gz
  • Upload date:
  • Size: 955.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for htsgetr-0.1.0.tar.gz
Algorithm Hash digest
SHA256 af996b6291491a03b26a279a8d98dee9c99474c616ef3e18ed2d380d4016df02
MD5 ba63a6b8560a175a8a576a7e76bb515f
BLAKE2b-256 93412df6b60ddbf3143382cb90ee972652ab4c6087074c0191af6808e7bb42a1

See more details on using hashes here.

File details

Details for the file htsgetr-0.1.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: htsgetr-0.1.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 8.1 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for htsgetr-0.1.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 e874220488e72eaaf4d2db6a4434d5fb5bd3052eb370ed4880dfaceee9618ce9
MD5 c3eb6f71b3df0cbb08de7be9c0617431
BLAKE2b-256 efe0015012afd8205dc58d9524b42c25f71b1a8674c92930340c0e2c5d7c98e8

See more details on using hashes here.

File details

Details for the file htsgetr-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for htsgetr-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2286e2705288566c44233475356312b1dc6b8e57677d04636d8c5a1418efeba4
MD5 5150d7867f468950e90db3fddf0d8f03
BLAKE2b-256 2faf87b12f8df13a2a8c4dc1129736cef493e4c4f6ccc54bcf50b36bf2cb2941

See more details on using hashes here.

File details

Details for the file htsgetr-0.1.0-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for htsgetr-0.1.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 646d2d7a6ce450206b6d6355f4e78892226715a2c5dc1ec9e444bd4496590fe9
MD5 ce40fd7417b70c8aaff50b1eef310dd4
BLAKE2b-256 4ea0e838351f50d612e6f18f94bb7f2a7c8272073e385b55500acc9d09a9577b

See more details on using hashes here.

File details

Details for the file htsgetr-0.1.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for htsgetr-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4cdf2319abf77a77856f261b9d180d56ec4c56764d5675cfb0ddfba85407da6d
MD5 077db0bbb3a58e7736b3388ef500f71e
BLAKE2b-256 e80975b448ec5708110878e561826065f0a72d36341f64ff1624de00f0363311

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page