A FastAPI-based microservice that exposes an HTTP API for retrieving nucleic acid sequence lengths from the Protein Data Bank (PDB).
This service provides a simple REST API to query the total length of nucleic acid sequences for any PDB structure. It automatically syncs with PDB's weekly updates and maintains a local cache for fast responses.
- REST API: Simple endpoint to query nucleic acid lengths by PDB ID
- Health Check: Built-in health endpoint for monitoring and Docker healthchecks
- New PDB ID Format: Supports both classic (
1abc) and new (pdb_00001abc) PDB ID formats - Automatic Updates: Checks for new PDB data every 6 hours with conditional GET (respects ETag/Last-Modified headers)
- Efficient Caching: Maintains local cache in
/datavolume that survives container restarts - Docker Support: Easy deployment with Docker Compose, including tini init for proper signal handling
- Streaming Download: Memory-efficient parsing of large PDB sequence files
- Atomic Updates: Ensures data consistency during updates
- CI/CD: GitHub Actions for automated testing and Docker image publishing
- Test Suite: Comprehensive pytest-based test suite
# Build and run
docker-compose up --build
# Run in detached mode
docker-compose up -d --buildThe API will be available at http://localhost:8000
# Install dependencies
pip install -r requirements.txt
# Run the application
uvicorn main:app --host 0.0.0.0 --port 8000 --reloadGET /api/{pdbid}
Returns the total length of all nucleic acid sequences for the specified PDB structure.
Parameters:
pdbid(path): PDB ID (case-insensitive, e.g.,1abcor1ABC)
Response (200 OK):
{
"pdbid": "1abc",
"total_na_length": 42
}Error (404 Not Found):
{
"detail": "PDB ID not found or contains no nucleic acids"
}Example:
# Classic PDB ID format
curl http://localhost:8000/api/1abc
# New PDB ID format (automatically converted)
curl http://localhost:8000/api/pdb_00001abcGET /health
Returns the service health status and current data statistics.
Response (200 OK):
{
"status": "healthy",
"entries": 12345,
"total_pdb_ids": 98765
}Response (503 Service Unavailable):
Returned when data is still loading on startup.
Example:
curl http://localhost:8000/healthInteractive API documentation is available at:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
The service automatically:
- On startup: Checks for updates and downloads data if needed
- Every 6 hours: Polls PDB for new data (4x daily to catch Wednesday updates)
- Conditional GET: Uses ETag and If-Modified-Since to avoid unnecessary downloads
- Atomic writes: Updates are performed atomically to prevent data corruption
Data is sourced from: https://files.wwpdb.org/pub/pdb/derived_data/pdb_seqres.txt
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │────▶│ FastAPI │────▶│ In-Memory │
│ │◄────│ (main.py) │◄────│ Cache │
└─────────────┘ └──────────────┘ └─────────────┘
│ │
▼ │
┌──────────────┐ │
│ Periodic │ │
│ Updater │ │
└──────────────┘ │
│ │
▼ ▼
┌──────────────┐ ┌─────────────┐
│ PDB FTP │ │ /data │
│ Server │ │ (Volume) │
└──────────────┘ └─────────────┘
.
├── main.py # FastAPI application
├── Dockerfile # Docker image definition
├── docker-compose.yml # Docker Compose configuration
├── requirements.in # High-level dependencies (for Docker)
├── requirements.txt # Pinned dependencies (auto-generated)
├── requirements-dev.in # Development dependencies
├── requirements-dev.txt # Pinned dev dependencies (auto-generated)
├── tests/ # Test suite
│ ├── __init__.py
│ ├── conftest.py
│ └── test_api.py
└── data/ # Persisted data (Docker volume)
├── na_lengths.json # Cached nucleic acid lengths
└── metadata.json # ETag and Last-Modified headers
# Install development dependencies
pip install -r requirements-dev.in
# Run all tests
pytest tests/ -v
# Run specific test file
pytest tests/test_api.py -v# Check for issues
ruff check .
# Auto-fix issues
ruff check --fix .
# Format code
ruff format .Production dependencies (included in Docker image):
Edit requirements.in and run:
pip-compile requirements.inDevelopment dependencies (not included in Docker image):
Edit requirements-dev.in and run:
pip-compile requirements-dev.inThe service can be configured via environment variables:
| Variable | Default | Description |
|---|---|---|
DATA_FILE |
/data/na_lengths.json |
Path to cache file |
METADATA_FILE |
/data/metadata.json |
Path to metadata file |
PDB_SEQRES_URL |
https://files.wwpdb.org/pub/pdb/derived_data/pdb_seqres.txt |
PDB data source |
- Framework: FastAPI - Modern, fast web framework
- HTTP Client: httpx - Async HTTP client with streaming support
- Server: Uvicorn - Lightning-fast ASGI server
- Python: 3.13+
- Docker: Multi-stage build with Python 3.14-slim
The project uses GitHub Actions for continuous integration and deployment:
Runs on every push and pull request to main:
- Installs production and development dependencies
- Executes the full test suite with pytest
Automatically builds and publishes Docker images to GitHub Container Registry:
- Triggers on pushes to
mainbranch - Triggers on new tags
- Builds but does not push on pull requests (for validation)
- Uses Docker Buildx with layer caching for faster builds
Images are available at: ghcr.io/${{ github.repository }}
MIT License
Data Source: Worldwide Protein Data Bank (wwPDB)