Keble db
Project description
Keble-DB
Lightweight database toolkit for MongoDB (PyMongo/Motor), SQL (SQLModel/SQLAlchemy), Qdrant, and Neo4j.
Includes sync + async CRUD base classes, a shared QueryBase, a Db session manager, FastAPI deps (ApiDbDeps), and Redis namespace wrappers.
Installation
pip install keble-db
Core API (import from keble_db)
- Queries/types:
DbSettingsABC,QueryBase,ObjectId,Uuid - CRUD:
MongoCRUDBase[Model]SqlCRUDBase[Model]QdrantCRUDBase[Payload, Vector](+Record)Neo4jCRUDBase[Model]
- Connections/DI:
Db(settings: DbSettingsABC),ApiDbDeps(db) - Redis:
ExtendedRedis,ExtendedAsyncRedis - Mongo helpers:
build_mongo_find_query,merge_mongo_and_queries,merge_mongo_or_queries
Async methods are prefixed with a (e.g. afirst, aget_multi, adelete).
QueryBase expectations
QueryBase fields: filters, order_by, offset, limit, id, ids.
- Mongo:
filtersis a Mongo querydict;order_byis[(field, ASCENDING|DESCENDING)];offset/limitareint. - SQL:
filtersis alistof SQLAlchemy expressions;order_byis an expression or list;offset/limitareint. - Qdrant:
search():filtersis a Qdrant filterdict,offsetisint|None,limitdefaults to 100.scroll():offsetisPointId|None(point id) andlimitis required; ordering usesorder_by(str or QdrantOrderBy) or falls back toQueryBase.order_by. Qdrant requires a payload range index for the ordered key. Example:from qdrant_client.models import PayloadSchemaType;crud.ensure_payload_indexes(client, payload_indexes={"id": PayloadSchemaType.INTEGER}).
- Neo4j:
filtersis adictof property predicates (operators:$gt,$gte,$lt,$lte,$in,$contains,$startswith,$endswith);order_byis[(field, "asc"|"desc")];offset/limitareint.
Examples
MongoDB
from pydantic import BaseModel
from pymongo import MongoClient, DESCENDING
from keble_db import MongoCRUDBase, QueryBase
class User(BaseModel):
name: str
age: int
crud = MongoCRUDBase(User, collection="users", database="app")
m = MongoClient("mongodb://localhost:27017")
crud.create(m, obj_in=User(name="Alice", age=30))
users = crud.get_multi(
m,
query=QueryBase(filters={"age": {"$gte": 18}}, order_by=[("age", DESCENDING)]),
)
SQL (SQLModel)
import uuid
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine
from keble_db import QueryBase, SqlCRUDBase
class User(SQLModel, table=True):
id: Optional[str] = Field(
default_factory=lambda: str(uuid.uuid4()), primary_key=True
)
name: str
age: int
engine = create_engine("sqlite:///db.sqlite")
SQLModel.metadata.create_all(engine)
crud = SqlCRUDBase(User, table_name="users")
with Session(engine) as s:
created = crud.create(s, obj_in=User(name="Alice", age=30))
found = crud.first(s, query=QueryBase(id=created.id))
Qdrant
Requires qdrant-client>=1.16.0 (uses query_points).
from pydantic import BaseModel
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, PayloadSchemaType, VectorParams
from keble_db import QdrantCRUDBase, QueryBase
class Payload(BaseModel):
id: int
name: str
class Vector(BaseModel):
vector: list[float]
client = QdrantClient(host="localhost", port=6333)
client.recreate_collection(
collection_name="items",
vectors_config={"vector": VectorParams(size=3, distance=Distance.COSINE)},
)
crud = QdrantCRUDBase(Payload, Vector, collection="items")
crud.ensure_payload_indexes(
client,
payload_indexes={"id": PayloadSchemaType.INTEGER},
)
crud.create(client, Vector(vector=[0.1, 0.2, 0.3]), Payload(id=1, name="a"), "p1")
hits = crud.search(
client,
vector=[0.1, 0.2, 0.3],
vector_key="vector",
query=QueryBase(filters={"must": [{"key": "id", "match": {"value": 1}}]}, limit=5),
)
If you have per-embedder collections (common in RAG), use deterministic naming:
collection = QdrantCRUDBase.derive_collection_name(
base="items",
embedder_id="text-embedding-3-small",
)
crud = QdrantCRUDBase(Payload, Vector, collection=collection)
Neo4j
from pydantic import BaseModel
from neo4j import GraphDatabase
from keble_db import Neo4jCRUDBase, QueryBase
class Person(BaseModel):
id: int
name: str
driver = GraphDatabase.driver("neo4j://localhost:7687", auth=("neo4j", "password"))
crud = Neo4jCRUDBase(Person, label="Person", id_field="id")
with driver.session() as s:
crud.create(s, obj_in=Person(id=1, name="Alice"))
people = crud.get_multi(s, query=QueryBase(filters={"id": 1}))
Db + FastAPI
Db(settings) builds clients from a DbSettingsABC implementation (see keble_db/schemas.py or tests/config.py).
ApiDbDeps(db) exposes FastAPI-friendly generator dependencies such as get_mongo, get_amongo, get_read_sql, get_write_asql, get_qdrant, get_neo4j_session, plus Redis equivalents.
More runnable examples
See tests/test_crud/ and tests/test_api_deps.py.
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 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 keble_db-1.4.1.tar.gz.
File metadata
- Download URL: keble_db-1.4.1.tar.gz
- Upload date:
- Size: 30.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.2 CPython/3.12.2 Darwin/25.1.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dde41fbb26bcd73fe2da26cc8e48a64af468ad65963bb26c0b81aad8e1145077
|
|
| MD5 |
04c6db13ccd87be651c955d40e57095f
|
|
| BLAKE2b-256 |
f605d8d34e0f602cf7b2a8dae712c983dc287444427af9cb8e436b19b7e91a59
|
File details
Details for the file keble_db-1.4.1-py3-none-any.whl.
File metadata
- Download URL: keble_db-1.4.1-py3-none-any.whl
- Upload date:
- Size: 34.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.2 CPython/3.12.2 Darwin/25.1.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cb29433767382b82812d7717b051a56fc713068605fc429f3126fd26010d038
|
|
| MD5 |
e0d1e363d0b7bd267926dcdc5f4e3e55
|
|
| BLAKE2b-256 |
631915a718d7f648e6b95c01e338eb314ae2b4b131e64cdabb8748694e1cfabc
|