Python SDK for QBench LIMS API
Project description
QBench Python SDK
A modern, production-ready Python SDK for the QBench LIMS API that provides a simple and intuitive interface for interacting with your QBench laboratory information management system.
Features
- Async-first design with seamless sync compatibility
- Comprehensive API coverage with 200+ endpoints (v1 and v2)
- Automatic pagination with configurable limits and concurrent page fetching
- Robust authentication with JWT token management and automatic refresh
- Basic error handling with custom exceptions and retry logic
- Type hints throughout for excellent IDE support and development experience
- Concurrent request handling with rate limiting and connection pooling
- Dynamic method generation based on available endpoints
- Trivial to include new endpoints simply add to the dict in endpoints.py
- Production-ready packaging with modern Python tooling
Installation
As a Package
pip install qbench
For Development
git clone https://github.com/nwilliams-cts/qbench.git
cd qbench
pip install -e .[dev]
Quick Start
import qbench
# Connect to your QBench instance
qb = qbench.connect(
base_url="https://your-qbench-instance.qbench.net",
api_key="your_api_key",
api_secret="your_api_secret"
)
# Check connection health
health = qb.health_check()
print(f"API Status: {health['status']}")
# Get a specific sample
sample = qb.get_sample(1234)
print(f"Sample: {sample}")
# Get all customers (automatically paginated)
customers = qb.get_customers()
print(f"Total customers: {len(customers)}")
# Search with filters
filtered_samples = qb.get_samples(status="Completed", page_limit=2)
# Use v1 API when needed. Required for some endpoints such as kvstores.
kvstore = qb.get_kvstore("xxxxx-xxxxxxxx-xxxxxxxxxx", use_v1=True)
# Create new records
new_customer = qb.create_customers(data={
"name": "ACME Corp",
"email": "contact@acme.com"
})
# Clean up connection when done
qb.close()
Available Methods
The SDK dynamically generates methods based on the QBench API once added to endpoints.py. Common patterns:
# GET single entity
sample = qb.get_sample(123)
customer = qb.get_customer(456)
# GET collections (with automatic pagination)
all_samples = qb.get_samples()
active_orders = qb.get_orders(status="Placed")
# CREATE entities
new_sample = qb.create_samples(data={...})
new_customer = qb.create_customers(data={...})
# UPDATE entities
updated = qb.update_samples(entity_id=123, data={...})
modified = qb.update_customers(entity_id=456, data={...})
# DELETE entities. Note: Some QBench modules prevent deletion operations.
qb.delete_sample(123)
qb.delete_customer(456)
See the full endpoint documentation for all 200+ available methods.
Configuration
Authentication
QBench uses JWT-based authentication with automatic token management. You'll need:
- API Key: Your unique API identifier
- API Secret: Your secret key for signing JWTs
- Base URL: Your QBench instance URL
# Basic connection
qb = qbench.connect(
base_url="https://your-instance.qbench.net",
api_key="your_api_key_here",
api_secret="your_secret_here"
)
# Advanced configuration
qb = qbench.connect(
base_url="https://your-instance.qbench.net",
api_key="your_api_key_here",
api_secret="your_secret_here",
timeout=30, # Request timeout in seconds
retry_attempts=3, # Number of retry attempts
concurrency_limit=10 # Max concurrent requests for pagination
)
Additional Usage
# Connection health monitoring
health = qb.health_check()
is_connected = health.get('api_accessible', False)
# Explore available endpoints
endpoints = qb.list_available_endpoints()
print(f"Available endpoints: {len(endpoints)}")
# Get endpoint information
info = qb.get_endpoint_info("get_samples")
print(f"Method: {info['method']}, Paginated: {info.get('paginated', False)}")
# Control pagination behavior
all_samples = qb.get_samples(page_limit=None) # Get all pages
limited = qb.get_samples(page_limit=5) # First 5 pages only
single_page = qb.get_samples(page_limit=1) # Just first page
# Concurrent processing with rate limiting
qb = qbench.connect(..., concurrency_limit=5) # Max 5 concurrent requests
Error Handling
The SDK provides error handling with custom exceptions:
from qbench.exceptions import (
QBenchAPIError,
QBenchAuthError,
QBenchConnectionError,
QBenchTimeoutError,
QBenchValidationError
)
try:
sample = qb.get_sample(entity_id=999999)
except QBenchAPIError as e:
print(f"API Error: {e}")
print(f"Status Code: {e.status_code}")
print(f"Response Data: {e.response_data}")
except QBenchAuthError as e:
print(f"Authentication Error: {e}")
except QBenchConnectionError as e:
print(f"Connection Error: {e}")
except QBenchTimeoutError as e:
print(f"Timeout Error: {e}")
except QBenchValidationError as e:
print(f"Validation Error: {e}")
Automatic Retry Logic
The SDK includes intelligent retry logic for connection issues:
# Retries are automatic for:
# - Connection timeouts
# - Network errors
# - Rate limiting (429 errors)
# HTTP errors (4xx, 5xx) are NOT retried automatically
# Authentication errors trigger token refresh attempts
Async Usage
The SDK is built async-first with seamless sync compatibility:
import asyncio
import qbench
async def main():
qb = qbench.connect(
base_url="https://your-instance.qbench.net",
api_key="your_api_key",
api_secret="your_secret"
)
# These calls are naturally async when called from async context
sample = await qb.get_sample(1234)
customers = await qb.get_customers()
# Concurrent operations
tasks = [
qb.get_sample(i)
for i in range(1000, 1010)
]
results = await asyncio.gather(*tasks)
qb.close()
# Run async function
asyncio.run(main())
# Or use sync mode (automatically detected)
qb = qbench.connect(...)
sample = qb.get_sample(1234) # Sync call
customers = qb.get_customers() # Sync call
qb.close()
Setup
# Clone repository
git clone https://github.com/nwilliams-cts/qbench.git
cd qbench
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in development mode
pip install -e .[dev]
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=qbench --cov-report=html
# Run specific test file
pytest tests/test_api.py
# Run with verbose output
pytest -v
# Run integration tests (requires QBench instance)
pytest tests/test_integration.py
Current Test Coverage: 91% (265 statements, 86 tests)
Code Quality
# Format code with black
black qbench/ tests/
# Sort imports
isort qbench/ tests/
# Lint with flake8
flake8 qbench/ tests/
# Type checking with mypy
mypy qbench/
# Run pre-commit hooks
pre-commit run --all-files
Project Structure
qbench/
├── qbench/ # Main package
│ ├── __init__.py # Package entry point
│ ├── api.py # Main API client
│ ├── auth.py # Authentication handling
│ ├── endpoints.py # API endpoint definitions
│ └── exceptions.py # Custom exceptions
├── tests/ # Test suite
│ ├── test_api.py # API client tests
│ ├── test_auth.py # Authentication tests
│ ├── test_exceptions.py # Exception tests
│ ├── test_init.py # Package tests
│ ├── test_integration.py # Integration tests
│ └── conftest.py # Test fixtures
├── examples/ # Usage examples
├── setup.py # Package setup
├── pyproject.toml # Modern Python configuration
└── README.md # This file
Examples
See the examples/ directory for complete usage examples:
- basic_usage.py - Getting started with common operations
- advanced_usage.py - Advanced features and async usage
API Documentation
- QBench REST API v1 Documentation
- API v2 Swagger Definition (included in repository)
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Ensure code quality (
black,flake8,mypy) - Run the test suite (
pytest --cov=qbench) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Guidelines
- Write tests for all new functionality
- Maintain code coverage above 90%
- Follow PEP 8 style guidelines
- Add type hints to all public APIs
- Update documentation for new features
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- SDK Issues: Open an issue on GitHub
- QBench API Support: Contact Junction Concepts support
- Documentation: See examples and API docs above
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qbench-1.0.2-py3-none-any.whl.
File metadata
- Download URL: qbench-1.0.2-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8308c56a734187506722b91b4f3e44145ad7df25250c0dc1857fa85003652285
|
|
| MD5 |
139d1553e803f77e0eb027129f45fab8
|
|
| BLAKE2b-256 |
50850a212629e959ad82f1986b2716bd9d5bba3d73a110e7f4ea0d46b80ce0ea
|
Provenance
The following attestation bundles were made for qbench-1.0.2-py3-none-any.whl:
Publisher:
publish.yml on nwilliams-cts/qbench
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qbench-1.0.2-py3-none-any.whl -
Subject digest:
8308c56a734187506722b91b4f3e44145ad7df25250c0dc1857fa85003652285 - Sigstore transparency entry: 349136207
- Sigstore integration time:
-
Permalink:
nwilliams-cts/qbench@6c74fb56ebe9783b8bfd986e4548e6bb6fab19de -
Branch / Tag:
refs/tags/v1.0.2 - Owner: https://github.com/nwilliams-cts
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6c74fb56ebe9783b8bfd986e4548e6bb6fab19de -
Trigger Event:
release
-
Statement type: