jps-controlled-vocabularies-rest-api
A lightweight REST service that exposes controlled vocabularies and terms over HTTP for programmatic retrieval and validation.
🚀 Overview
jps-controlled-vocabularies-rest-api is a FastAPI-based REST service designed to provide programmatic access to controlled vocabularies and terminology. It serves as a stable API layer for consuming vocabulary data from various backend sources including YAML files and PostgreSQL databases.
Key Features
- RESTful API - Clean, well-documented endpoints for vocabulary and term operations
- Pluggable Backends - Support for YAML files (built-in) and PostgreSQL (via plugin)
- Search & Validation - Full-text search across terms and value validation capabilities
- OpenAPI Documentation - Automatic Swagger UI and ReDoc documentation
- Container-Ready - Docker and docker-compose configurations included
- Type-Safe - Full type hints with Pydantic models
- Production-Ready - Health checks, structured logging, and graceful error handling
Use Cases
- Frontend Integration - Provide drop-down values and definitions for UI components
- Service Integration - Enable backend services to validate terminology consistently
- Data Validation - ETL pipelines can validate data against controlled vocabularies
- CI/CD Validation - Ensure vocabulary definitions are valid before deployment
Architecture
┌─────────────────┐
│ FastAPI App │
│ (Routers) │
└────────┬────────┘
│
▼
┌────────────────────┐
│ VocabularyStore │
│ (Abstraction) │
└────────┬───────────┘
│
┌────┴─────┐
▼ ▼
┌─────────┐ ┌──────────────┐
│ YAML │ │ PostgreSQL │
│ Store │ │ Store │
│ (Built) │ │ (Plugin) │
└─────────┘ └──────────────┘
📦 Installation
Option 1: Install from PyPI (coming soon)
pip install jps-controlled-vocabularies-rest-api
Option 2: Install from Source
git clone https://github.com/jai-python3/jps-controlled-vocabularies-rest-api.git
cd jps-controlled-vocabularies-rest-api
pip install -e .
Option 3: Using Docker
docker-compose up -d
🚀 Quick Start
1. Configure Environment
cp .env.example .env
# Edit .env with your configuration
Minimal configuration for YAML backend:
VOCAB_BACKEND=yaml
VOCAB_YAML_PATH=./vocabularies
2. Prepare Vocabulary Files
Place your YAML vocabulary files in the vocabularies/ directory:
# vocabularies/my_vocab.yaml
vocabulary_id: my_vocabulary
schema_version: "1.0"
title: My Vocabulary
description: Example vocabulary
terms:
- key: term1
name: Term One
description: First term
metadata:
allowed_values: ["value1", "value2", "value3"]
3. Run the Service
Using Python directly:
python -m jps_controlled_vocabularies_rest_api.main
Using Uvicorn:
uvicorn jps_controlled_vocabularies_rest_api.main:app --host 0.0.0.0 --port 8000
Using Docker:
docker-compose up
4. Access the API
- API Base: http://localhost:8000
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI Spec: http://localhost:8000/openapi.json
📚 API Endpoints
Health & Readiness
GET /healthz- Simple health checkGET /readyz- Detailed readiness check with backend status
Vocabularies
GET /v1/vocabularies- List all vocabulariesGET /v1/vocabularies/{vocabulary_id}- Get vocabulary detailsGET /v1/vocabularies/{vocabulary_id}/terms- List terms (with pagination)GET /v1/vocabularies/{vocabulary_id}/terms/{term_key}- Get specific term
Search
GET /v1/search?q={query}- Search terms across vocabularies- Optional:
vocabulary_id- Filter by vocabulary - Optional:
limit,offset- Pagination
- Optional:
Validation
POST /v1/validate/value- Validate a value against a termPOST /v1/validate/registry- Validate the entire registry
💡 Example Usage
List Vocabularies
curl http://localhost:8000/v1/vocabularies
Response:
[
{
"vocabulary_id": "workflow.system_terminology",
"schema_version": "1.0",
"title": "Workflow and System Terminology",
"description": "Core terms used across JPSHealth EHR workflow services",
"term_count": 4
}
]
Get Vocabulary Details
curl http://localhost:8000/v1/vocabularies/workflow.system_terminology
Search Terms
curl "http://localhost:8000/v1/search?q=ready"
Validate a Value
curl -X POST http://localhost:8000/v1/validate/value \
-H "Content-Type: application/json" \
-d '{
"vocabulary_id": "workflow.system_terminology",
"term_key": "readiness_status",
"value": "Almost Ready"
}'
Response:
{
"is_valid": true,
"normalized_value": "Almost Ready",
"reasons": ["Value is in the list of allowed values"],
"allowed_values": ["Ready", "Almost Ready", "Not Ready"],
"pattern": null
}
⚙️ Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
VOCAB_BACKEND |
yaml |
Backend type: yaml or postgres |
VOCAB_YAML_PATH |
- | Path to YAML file or directory (required for yaml backend) |
VOCAB_YAML_RELOAD |
false |
Enable hot-reload of YAML vocabularies |
VOCAB_SEARCH_CASE_SENSITIVE |
false |
Case-sensitive search |
UVICORN_HOST |
0.0.0.0 |
Server host |
UVICORN_PORT |
8000 |
Server port |
POSTGRES_DSN |
- | PostgreSQL connection string (for postgres backend) |
CORS_ALLOW_ORIGINS |
- | Comma-separated list of allowed CORS origins |
LOG_REQUEST_BODIES |
false |
Enable request body logging |
PostgreSQL Backend
To use PostgreSQL backend (requires plugin):
- Install the plugin:
pip install jps-controlled-vocabularies-postgresql
- Configure environment:
VOCAB_BACKEND=postgres
POSTGRES_DSN=postgresql://user:pass@localhost:5432/dbname
🧪 Development
Setup Development Environment
# Install with dev dependencies
make install
# Or manually
pip install -e ".[dev]"
Run Tests
# Run all tests
make test
# Run with coverage
pytest --cov=src --cov-report=html
# Run specific test file
pytest tests/test_health.py
Code Quality
# Format code
make format
# Run linters
make lint
# Fix auto-fixable issues
make fix
# Type checking
mypy src/
Pre-commit Hooks
pre-commit install
pre-commit run --all-files
🐳 Docker Deployment
Build Image
docker build -t jps-vocab-api:latest .
Run Container
docker run -d \
-p 8000:8000 \
-e VOCAB_BACKEND=yaml \
-e VOCAB_YAML_PATH=/app/vocabularies \
-v $(pwd)/vocabularies:/app/vocabularies:ro \
--name jps-vocab-api \
jps-vocab-api:latest
Using Docker Compose
docker-compose up -d
docker-compose logs -f
docker-compose down
📖 Documentation
🤝 Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and linters (
make test && make lint) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 Changelog
See CHANGELOG.md for release history.
📜 License
MIT License © Jaideep Sundaram
See LICENSE for details.
🔗 Related Projects
jps-controlled-vocabularies-utils- Core vocabulary utilitiesjps-controlled-vocabularies-postgresql- PostgreSQL backend plugin
📧 Contact
Jaideep Sundaram - jai.python3@gmail.com
Project Link: https://github.com/jai-python3/jps-controlled-vocabularies-rest-api
Metadata
Release files for jps-controlled-vocabularies-rest-api 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jps_controlled_vocabularies_rest_api-0.1.0.tar.gz | 23.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jps_controlled_vocabularies_rest_api-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.5 kB
Release files / jps_controlled_vocabularies_rest_api-0.1.0.tar.gz
| Download URL | jps_controlled_vocabularies_rest_api-0.1.0.tar.gz |
|---|---|
| Size | 23.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f033a14b1571f6015dbf6d41ab64b170e7de9c6b8ab7cc4878ea9b70e47b89f4
|
|
BLAKE2b-256 checksum How to use checksums |
b3d169d1a5d440c88f69fe960c8c262bf618f890633623acbb2a9142d243f534
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / jps_controlled_vocabularies_rest_api-0.1.0-py3-none-any.whl
| Download URL | jps_controlled_vocabularies_rest_api-0.1.0-py3-none-any.whl |
|---|---|
| Size | 23.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
437432ffb92209b5f780d34ffad4f55d90ce7659a3d2223dd5fa7afbd6fff196
|
|
BLAKE2b-256 checksum How to use checksums |
0d106d40157e9fedffdc8eb36ce661f21a081feabd02f40281bc0edcae72e12d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|