OpenFrame Microservice Suite - adapter meta-package. Install adapters by name or group.
Project description
openframe-adapters
A metadata-only package that provides named install shortcuts for the entire
openframe-adapters ecosystem. Install one adapter, a category, or everything
— all with a single pip install command.
Install surface
Individual adapters
# Relational
pip install openframe-adapters[postgres] # PostgreSQL via asyncpg
pip install openframe-adapters[mysql] # MySQL via aiomysql
# Key-value
pip install openframe-adapters[redis] # Redis via redis-py
pip install openframe-adapters[dynamodb] # DynamoDB via aiobotocore
# Document
pip install openframe-adapters[mongo] # MongoDB via Motor
# Columnar
pip install openframe-adapters[cassandra] # Cassandra via cassandra-driver
# Time-series
pip install openframe-adapters[influxdb] # InfluxDB via influxdb-client
# Vector
pip install openframe-adapters[milvus] # Milvus via pymilvus
pip install openframe-adapters[chromadb] # Chroma via chromadb
pip install openframe-adapters[qdrant] # Qdrant via qdrant-client
pip install openframe-adapters[faiss] # FAISS via faiss-cpu
pip install openframe-adapters[falkordb] # FalkorDB via falkordb
# Queues
pip install openframe-adapters[kafka] # Kafka via aiokafka
pip install openframe-adapters[nats] # NATS via nats-py
pip install openframe-adapters[rabbitmq] # RabbitMQ via aio-pika
Groups — one category
pip install openframe-adapters[db] # all 7 DB adapters (relational + document + specialist)
pip install openframe-adapters[vector] # all 5 vector DB adapters
pip install openframe-adapters[queue] # all 3 queue adapters
Everything
pip install openframe-adapters[all] # all 15 individual adapter packages
Convenience combinations
pip install openframe-adapters[rest-min] # postgres + redis (REST API minimum)
pip install openframe-adapters[rag-stack] # milvus + falkordb + redis (RAG / inference)
pip install openframe-adapters[research-min] # mongo + redis (Research Vault Phase 1)
Import paths
The import path is identical regardless of how you installed:
# Whether you ran:
# pip install openframe-adapters[postgres]
# or:
# pip install openframe-adapters[all]
# the import is always the same:
from openframe.adapters.db.postgres import PostgresRepository
from openframe.adapters.db.mongo import MongoRepository
Each individual adapter package uses Python namespace packages under
openframe.adapters.*, so all adapters share the same top-level namespace
without any conflicts.
Wiring adapters into your service
Every adapter wires into your service through a single file — deps.py or
bootstrap/dependencies.py. This file is the only place in your codebase
that knows which adapter is active. Routes and services never import adapters
directly.
The rule is simple:
One adapter — wire directly with
lru_cache. Two or more adapters — usePluginRegistry. The trigger to upgrade is adding a second adapter.
Stage 1 — One adapter
Install one adapter and wire it directly. Four lines. No registry needed.
# bootstrap/dependencies.py
from functools import lru_cache
from openframe.adapters.db.postgres import PostgresRepository, PostgresSettings
from openframe.core.tracing import TracingProxy
from src.adapters.item_repository import ItemPostgresRepository
from src.application.services.item_service import ItemService
@lru_cache(maxsize=1)
def _get_repository() -> ItemPostgresRepository:
return ItemPostgresRepository(PostgresSettings())
def get_item_service() -> ItemService:
return ItemService(TracingProxy(_get_repository(), prefix="repository.item"))
PostgresSettings() reads DATABASE_URL from env at startup.
lru_cache(maxsize=1) constructs the repository once per process.
TracingProxy wraps it for automatic OTel spans on every call.
Stage 2 — Two or more adapters
When a second adapter is needed, replace lru_cache with PluginRegistry.
The registry handles startup ordering, health aggregation, and graceful
shutdown across all adapters.
# bootstrap/dependencies.py
from openframe.adapters.db.postgres import PostgresPlugin, PostgresSettings
from openframe.adapters.db.redis import RedisPlugin, RedisSettings
from openframe.core.plugins import PluginRegistry
from openframe.core.tracing import TracingProxy
from src.application.services.item_service import ItemService
from src.application.services.session_service import SessionService
_registry: PluginRegistry | None = None
async def initialise() -> None:
global _registry
_registry = PluginRegistry()
_registry.register(PostgresPlugin(PostgresSettings())) # capability: "persistence"
_registry.register(RedisPlugin(RedisSettings())) # capability: "cache"
await _registry.initialize_all() # fails fast if any backend unreachable
async def shutdown() -> None:
if _registry:
await _registry.shutdown_all() # never raises
def get_item_service() -> ItemService:
repo = TracingProxy(
_registry.get("persistence").get_repository(),
prefix="repository.item",
)
return ItemService(repo)
def get_session_service() -> SessionService:
cache = TracingProxy(
_registry.get("cache").get_repository(),
prefix="cache.session",
)
return SessionService(cache)
Wire initialise() and shutdown() in your FastAPI lifespan:
from contextlib import asynccontextmanager
from fastapi import FastAPI
from openframe.core.middleware import TelemetryMiddleware
from openframe.core.telemetry import setup_telemetry
from src.bootstrap import dependencies
@asynccontextmanager
async def lifespan(app: FastAPI):
setup_telemetry()
await dependencies.initialise()
yield
await dependencies.shutdown()
app = FastAPI(lifespan=lifespan)
app.add_middleware(TelemetryMiddleware)
Plugin capabilities
Every *Plugin class declares a capability string. This is the key used
by registry.get(). The capability taxonomy is a convention across the entire
OpenFrame ecosystem — use these exact strings:
| Capability | Adapters | Use for |
|---|---|---|
"persistence" |
Postgres, Mongo, MySQL, DynamoDB, Cassandra | Primary data store |
"cache" |
Redis | Fast ephemeral store, sessions, rate limits |
"queue" |
Kafka, NATS, RabbitMQ | Message publishing and consumption |
"vector" |
Milvus, Qdrant, ChromaDB, FAISS, FalkorDB | Vector similarity search |
"timeseries" |
InfluxDB | Time-series metrics and events |
Using a different string for the same category breaks registry.get() across
services. Always use the strings from this table.
The env-var swap exception
Switching between adapters via an environment variable (PERSISTENCE_BACKEND=postgres
vs PERSISTENCE_BACKEND=mongo) is still Stage 1 — because only one adapter
is active at any moment. Use lru_cache direct wiring with a conditional:
@lru_cache(maxsize=1)
def _get_repository():
backend = os.environ.get("PERSISTENCE_BACKEND", "postgres")
if backend == "postgres":
return ItemPostgresRepository(PostgresSettings())
elif backend == "mongo":
return ItemMongoRepository(MongoSettings())
raise ValueError(f"Unknown PERSISTENCE_BACKEND: {backend!r}")
PluginRegistry is for services that need multiple adapters simultaneously,
not for services that swap between adapters via configuration.
Full wiring reference
For the complete guide — upgrade path from Stage 1 to Stage 2, lifespan
wiring, and architecture diagrams — see the
Composition Root
page in the openframe-core documentation.
Package inventory
| Extra | pip install |
Package installed | Async driver |
|---|---|---|---|
postgres |
openframe-adapters[postgres] |
openframe-adapters-db-postgres |
asyncpg |
mysql |
openframe-adapters[mysql] |
openframe-adapters-db-mysql |
aiomysql |
redis |
openframe-adapters[redis] |
openframe-adapters-db-redis |
redis-py (asyncio) |
dynamodb |
openframe-adapters[dynamodb] |
openframe-adapters-db-dynamodb |
aiobotocore |
mongo |
openframe-adapters[mongo] |
openframe-adapters-db-mongo |
Motor |
cassandra |
openframe-adapters[cassandra] |
openframe-adapters-db-cassandra |
cassandra-driver |
influxdb |
openframe-adapters[influxdb] |
openframe-adapters-db-influxdb |
influxdb-client |
milvus |
openframe-adapters[milvus] |
openframe-adapters-db-milvus |
pymilvus |
chromadb |
openframe-adapters[chromadb] |
openframe-adapters-db-chromadb |
chromadb |
qdrant |
openframe-adapters[qdrant] |
openframe-adapters-db-qdrant |
qdrant-client |
faiss |
openframe-adapters[faiss] |
openframe-adapters-db-faiss |
faiss-cpu |
falkordb |
openframe-adapters[falkordb] |
openframe-adapters-db-falkordb |
falkordb |
kafka |
openframe-adapters[kafka] |
openframe-adapters-queue-kafka |
aiokafka |
nats |
openframe-adapters[nats] |
openframe-adapters-queue-nats |
nats-py |
rabbitmq |
openframe-adapters[rabbitmq] |
openframe-adapters-queue-rabbitmq |
aio-pika |
db |
openframe-adapters[db] |
all 7 DB adapters above | — |
vector |
openframe-adapters[vector] |
all 5 vector adapters above | — |
queue |
openframe-adapters[queue] |
all 3 queue adapters above | — |
all |
openframe-adapters[all] |
all 15 adapter packages | — |
Core dependency
openframe-core is installed
automatically as a transitive dependency — you never need to declare it
separately. Every individual adapter package pins openframe-core>=1.0,<2,
so installing any extra brings core in as part of the resolution.
Versioning
Each adapter package is versioned independently and published to PyPI under
its own name (e.g. openframe-adapters-db-postgres). This meta-package pins
all of them at >=1.0,<2, so patch and minor releases are picked up
automatically the next time you run pip install --upgrade. Only a major
version bump in an individual adapter requires a meta-package update.
When a new adapter is added to the ecosystem, only this pyproject.toml
changes — one new line in [project.optional-dependencies] and an update to
the relevant group. No other file in the monorepo is touched.
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
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 openframe_adapters-1.2.0.tar.gz.
File metadata
- Download URL: openframe_adapters-1.2.0.tar.gz
- Upload date:
- Size: 6.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2a557fe842552b35500507c77ee0fb4b5c070c3b4b6869148baafacc737f7ba
|
|
| MD5 |
8f7c16a8db1f19d2c55b037c9bb6ac28
|
|
| BLAKE2b-256 |
3a0e7b25de9427f018ce68ea7a6a1a76e11b7a3eee67032e9d02b42f33a49ec3
|
File details
Details for the file openframe_adapters-1.2.0-py3-none-any.whl.
File metadata
- Download URL: openframe_adapters-1.2.0-py3-none-any.whl
- Upload date:
- Size: 5.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1834ae5b977ccb1d021476565452ec1f46f314334c723fcd368534c96ed513fd
|
|
| MD5 |
404d54973b9fd0d47cb13e6904c5eb97
|
|
| BLAKE2b-256 |
60fa411080f9f608f629e7312b9e456a03442b81c48f5c5380e89a5ca9c77002
|