Craft ML Features
Project description
Fabra
The Context Store for LLMs & ML Features
Unify RAG pipelines and ML features in a single Python decorator.
From notebook prototype to production in 30 seconds. No Kubernetes. No Spark. No YAML.
The Problem
You're building an AI app. You need:
- Structured features (user tier, purchase history) for personalization
- Unstructured context (relevant docs, chat history) for your LLM
- Vector search for semantic retrieval
- Token budgets to fit your context window
Today, this means stitching together LangChain, Pinecone, a feature store, Redis, and prayer.
Fabra unifies all of this in one Python decorator.
The 30-Second Quickstart
pip install "fabra[ui]"
from fabra.core import FeatureStore, entity, feature
from fabra.context import context, ContextItem
from fabra.retrieval import retriever
store = FeatureStore()
@entity(store)
class User:
user_id: str
@feature(entity=User, refresh="daily")
def user_tier(user_id: str) -> str:
return "premium" if hash(user_id) % 2 == 0 else "free"
@retriever(index="docs", top_k=3)
async def find_docs(query: str):
pass # Automatic vector search via pgvector
@context(store, max_tokens=4000)
async def build_prompt(user_id: str, query: str):
tier = await store.get_feature("user_tier", user_id)
docs = await find_docs(query)
return [
ContextItem(content=f"User is {tier}.", priority=0),
ContextItem(content=str(docs), priority=1),
]
fabra serve features.py
# Server running on http://localhost:8000
That's it. No infrastructure. No config files. Just Python.
Context Accountability (v1.4+): Every context assembly is tracked with full lineage:
ctx = await build_prompt("user_123", "How do I upgrade?")
print(ctx.id) # UUIDv7 identifier for replay
print(ctx.lineage) # Full audit trail: features, retrievers, freshness
Freshness SLAs (v1.5+): Ensure your AI decisions are based on fresh data:
@context(store, max_tokens=4000, freshness_sla="5m") # Features must be <5m old
async def build_prompt(user_id: str, query: str):
tier = await store.get_feature("user_tier", user_id)
return [ContextItem(content=f"User is {tier}.", priority=0)]
ctx = await build_prompt("user_123", "query")
print(ctx.is_fresh) # True if all features within SLA
print(ctx.meta["freshness_violations"]) # Details on any stale features
Why Fabra?
| Traditional Stack | Fabra | |
|---|---|---|
| Config | 500 lines of YAML | Python decorators |
| Infrastructure | Kubernetes + Spark + Pinecone | Your laptop (DuckDB) |
| RAG Pipeline | LangChain spaghetti | @retriever + @context |
| Feature Serving | Separate feature store | Same @feature decorator |
| Time to Production | Weeks | 30 seconds |
What Makes Fabra Different
1. One Decorator for Everything
Other tools make you choose: LangChain for RAG, Feast for features, separate vector DB. Fabra gives you @feature, @retriever, and @context — all wired together, all in Python.
2. Local-First, Production-Ready
# Development (default): DuckDB + In-Memory
MERIDIAN_ENV=development
# Production: Postgres + Redis + pgvector
MERIDIAN_ENV=production
Same code. Zero changes. Just flip an environment variable.
3. Point-in-Time Correctness
Training ML models? We use ASOF JOIN (DuckDB) and LATERAL JOIN (Postgres) to ensure your training data reflects the world exactly as it was — no data leakage, ever.
4. Token Budget Management
@context(store, max_tokens=4000)
async def build_prompt(user_id: str, query: str):
return [
ContextItem(content=critical_info, priority=0, required=True),
ContextItem(content=nice_to_have, priority=2), # Dropped if over budget
]
Automatically assembles context that fits your LLM's window. Priority-based truncation. No more "context too long" errors.
Key Capabilities
For AI Engineers
- Vector Search: Built-in pgvector with automatic chunking and embedding
- Magic Retrievers:
@retrieverauto-wires to your vector index - Context Assembly: Token budgets, priority truncation, explainability API
- Semantic Cache: Cache expensive LLM calls and retrieval results
- Context Accountability: Full lineage tracking, context replay, and audit trails for AI decisions
- Freshness SLAs: Ensure data freshness with configurable SLAs and degraded mode handling
For ML Engineers
- Hybrid Features: Mix Python logic and SQL in the same pipeline
- Event-Driven: Trigger updates via Redis Streams
- Observability: Prometheus metrics, OpenTelemetry tracing
- Self-Healing: Circuit breakers, fallback chains,
fabra doctor
For Everyone
- One-Command Deploy:
fabra deploy fly|cloudrun|ecs|railway|render - Visual UI: Dependency graphs, live metrics, context debugging
- Shell Completion:
fabra --install-completion
Architecture
Fabra scales from laptop to production without code changes.
graph TD
subgraph Dev [Development]
A[Your Code] -->|Uses| B(DuckDB)
A -->|Uses| C(In-Memory Cache)
end
subgraph Prod [Production]
D[Your Code] -->|Async| E[(Postgres + pgvector)]
D -->|Async| F[(Redis)]
end
Switch{MERIDIAN_ENV} -->|development| Dev
Switch -->|production| Prod
Production in 60 Seconds
# Set environment variables
export MERIDIAN_ENV=production
export MERIDIAN_POSTGRES_URL=postgresql+asyncpg://...
export MERIDIAN_REDIS_URL=redis://...
# Deploy
fabra deploy fly --name my-app
Roadmap
- v1.0: Core Feature Store (DuckDB, Postgres, Redis, FastAPI)
- v1.2: Context Store (pgvector, retrievers, token budgets)
- v1.3: UI, Magic Retrievers, One-Command Deploy
- v1.4: Context Accountability (lineage tracking, context replay, audit trails)
- v1.5: Freshness SLAs (data freshness guarantees, degraded mode, strict mode)
- v1.6: Drift detection, RBAC, multi-region
Get Started
pip install "fabra[ui]"
Try in Browser · Quickstart Guide · Full Documentation
Contributing
We love contributions! See CONTRIBUTING.md to get started.
Fabra · Apache 2.0 · 2025
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 fabra_ai-2.0.1.tar.gz.
File metadata
- Download URL: fabra_ai-2.0.1.tar.gz
- Upload date:
- Size: 677.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8dc9cf2d8f7a9cf619b31e619605cfc615634cc7edcb0c921061369b5c1620d7
|
|
| MD5 |
6e2e125bf5d8ace97ee9615bbcab103e
|
|
| BLAKE2b-256 |
0b564171ae79396e20a66cbaeeb9d3386d9dc0e9e3431126f50f9bdea01c4c7e
|
Provenance
The following attestation bundles were made for fabra_ai-2.0.1.tar.gz:
Publisher:
release.yml on davidahmann/fabra
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fabra_ai-2.0.1.tar.gz -
Subject digest:
8dc9cf2d8f7a9cf619b31e619605cfc615634cc7edcb0c921061369b5c1620d7 - Sigstore transparency entry: 755685896
- Sigstore integration time:
-
Permalink:
davidahmann/fabra@3f2304e1b4573cf8367a8a9c11253a5a5ce8c576 -
Branch / Tag:
refs/tags/v2.0.1 - Owner: https://github.com/davidahmann
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3f2304e1b4573cf8367a8a9c11253a5a5ce8c576 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fabra_ai-2.0.1-py3-none-any.whl.
File metadata
- Download URL: fabra_ai-2.0.1-py3-none-any.whl
- Upload date:
- Size: 160.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bff46c1724f2f148bb54c983dbed5692de84c019ee10f2947d49de051a193f94
|
|
| MD5 |
1e1fb0f5b3ea4916b15fb1f72416c105
|
|
| BLAKE2b-256 |
0e84c6f90743442a21fc4a8468415e2a720408d6f3e0753c3c13ff3b25434f9b
|
Provenance
The following attestation bundles were made for fabra_ai-2.0.1-py3-none-any.whl:
Publisher:
release.yml on davidahmann/fabra
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fabra_ai-2.0.1-py3-none-any.whl -
Subject digest:
bff46c1724f2f148bb54c983dbed5692de84c019ee10f2947d49de051a193f94 - Sigstore transparency entry: 755685901
- Sigstore integration time:
-
Permalink:
davidahmann/fabra@3f2304e1b4573cf8367a8a9c11253a5a5ce8c576 -
Branch / Tag:
refs/tags/v2.0.1 - Owner: https://github.com/davidahmann
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3f2304e1b4573cf8367a8a9c11253a5a5ce8c576 -
Trigger Event:
push
-
Statement type: