Skip to main content

iil-aifw — Django AI Services Framework

DB-driven LLM provider, model & usage management for Django projects.

PyPI Python License: MIT

Installation

pip install iil-aifw
# With NL2SQL support:
pip install "iil-aifw[nl2sql]"

Extras / Optional Dependencies

Extra Additional deps Purpose
nl2sql (none — activation-only) Activates aifw.nl2sql INSTALLED_APPS entry + migrations; no additional download weight
rag pgvector>=0.3 Schema-RAG via pgvector (ADR-009 Phase 1, planned)
dev pytest, hatch, ruff, iil-promptfw Development toolchain

Quick Start

# settings.py
INSTALLED_APPS = [
    ...
    "aifw",
]

# Run migrations
python manage.py migrate aifw
python manage.py init_aifw_config   # seed default providers & models
from aifw.service import sync_completion

result = sync_completion(
    action_code="story_writing",
    messages=[{"role": "user", "content": "Write a short story about a dragon."}],
)

if result.success:
    print(result.content)
else:
    print(result.error)

Features

  • DB-driven model routing — swap LLM providers/models via Django Admin, zero code changes
  • Multi-provider — OpenAI, Anthropic, Google, Ollama, any LiteLLM-compatible provider
  • Quality-level routing — map subscription tiers to model quality (economy/balanced/premium)
  • Async & sync — completion() async, sync_completion() sync, completion_with_fallback()
  • Streaming — sync_completion_stream() for Django StreamingHttpResponse
  • Usage logging — automatic token & latency tracking per action, per tenant
  • Fallback models — configure primary + fallback model per action type
  • NL2SQL — natural language → SQL engine with few-shot examples and self-healing retry
  • Hybrid cache — process-local (30s) + Django cache framework (600s, Redis-aware)

Core API

from aifw.service import (
    completion,  # async
    sync_completion,  # sync wrapper
    completion_with_fallback,  # async, tries fallback model on error
    sync_completion_with_fallback,
    sync_completion_stream,  # streaming generator
    get_quality_level_for_tier,  # tier name → QualityLevel int
    check_action_code,  # bool — action code exists in DB
)

Quality-Level Routing (v0.10.2)

Each AIActionType row can be scoped to a quality_level (1–9) and/or priority ('fast'|'balanced'|'quality'). A NULL in either dimension acts as catch-all. Lookup uses a deterministic 4-step cascade: exact → ql-only → prio-only → catch-all.

from aifw.constants import QualityLevel
from aifw.service import get_quality_level_for_tier, sync_completion

# Map a subscription tier to a quality level (DB-driven via TierQualityMapping)
ql = get_quality_level_for_tier("pro")  # → QualityLevel.BALANCED (5)
ql = get_quality_level_for_tier("premium")  # → QualityLevel.PREMIUM  (8)
ql = get_quality_level_for_tier("freemium")  # → QualityLevel.ECONOMY  (2)

result = sync_completion(
    "story_writing",
    messages,
    quality_level=ql,
    priority="quality",
)

Multi-Tenant Usage Tracking (v0.5.0)

result = sync_completion(
    "story_writing",
    messages,
    tenant_id=user.organization_id,
    object_id=f"story-{story.pk}",
    metadata={"source": "web", "plan": "pro"},
)

Privacy-by-Design Logging (issue #8)

AIUsageLog can pseudonymise or anonymise itself at write time — PII never reaches the database. Select the policy with one Django setting (DSGVO Art. 25 / Art. 5 Abs. 1 lit. c):

# settings.py
from aifw.constants import PrivacyMode

AIFW_PRIVACY_MODE = PrivacyMode.PSEUDONYMOUS  # "full" (default) | "pseudonymous" | "anonymous"
AIFW_PRIVACY_HMAC_SECRET = env("AIFW_PRIVACY_HMAC_SECRET")  # optional; falls back to SECRET_KEY
# Call site stays the same — the hook transforms the row before it is written:
sync_completion(
    "nl2sql",
    messages,
    user=request.user,
    tenant_id=user.organization_id,
    metadata={"nl_question": question},
)
Mode user metadata
full (default) stored raw (FK) stored raw
pseudonymous NULL user_hash = HMAC(user.pk); nl_question → topic
anonymous NULL reduced to {"day_bucket": "<ISO date>"} (tenant + tokens survive)

The privacy_mode column records which policy was applied to each row.

Topic classification is a plain callable — aifw never imports iil-promptfw. The built-in pseudonymous classifier emits a coarse placeholder ("unclassified"); wire a real classifier via a custom hook:

# myapp/privacy.py
from aifw.privacy import PseudonymousHook


def my_hook():
    from promptfw import classify_topic

    return PseudonymousHook(topic_classifier=classify_topic)


# settings.py
AIFW_PRIVACY_HOOK = "myapp.privacy:my_hook"  # dotted path → PrivacyHook / subclass / factory

A custom hook receives the create-payload dict (keys: user, tenant_id, metadata, …) and returns it rewritten. If a configured non-full hook raises, logging fails closed — user/metadata are scrubbed rather than leaking PII.

For supervisor-facing reports, AIUsageLog.objects.aggregate_with_k_anonymity( *group_by, k=3) returns only buckets with ≥ k entries (suppresses re-identifiable small groups).

Default-shift roadmap: the default stays "full" in the 0.11.x line to keep existing audit views (bfagent, weltenhub, travel-beat) working unchanged. A shift to "pseudonymous" as the default is planned for 0.12.0 as a documented breaking change.

Streaming (v0.4.0)

from aifw.service import sync_completion_stream
from django.http import StreamingHttpResponse


def stream_story(request):
    def generate():
        for chunk in sync_completion_stream("story_writing", messages):
            yield chunk

    return StreamingHttpResponse(generate(), content_type="text/plain")

Django Models

Model Purpose
LLMProvider Provider config (API key env var, base URL)
LLMModel Model config (max tokens, cost per million tokens)
AIActionType Action → model mapping; supports quality_level + priority dimensions
AIUsageLog Token/latency/cost tracking per request, with tenant_id + metadata + privacy_mode
TierQualityMapping Subscription tier → quality_level mapping (DB-driven)

NL2SQL (v0.7.0+)

# settings.py
INSTALLED_APPS = [
    ...
    "aifw",
    "aifw.nl2sql",   # activates NL2SQL models + migrations
]

python manage.py migrate aifw_nl2sql
python manage.py seed_nl2sql_examples   # seed verified few-shot examples
from aifw.nl2sql import NL2SQLEngine

engine = NL2SQLEngine(schema_xml="<schema>...</schema>")
result = engine.query("How many open orders do we have?")

if result.success:
    print(result.sql)
    print(result.rows)
  • Few-shot examples injected automatically from NL2SQLExample model
  • Self-healing retry — on SQL execution error, a second LLM call includes the error as context
  • Feedback capture — NL2SQLFeedback auto-created on every execution error
  • Management commands: seed_nl2sql_examples, promote_feedback, validate_schema

Management Commands

python manage.py init_aifw_config       # seed default providers & models
python manage.py check_aifw_config      # CI gate — verify all action codes have a catch-all row
python manage.py seed_nl2sql_examples   # seed NL2SQL few-shot examples
python manage.py promote_feedback       # promote corrected feedback → NL2SQLExample
python manage.py validate_schema        # validate schema-XML against real DB (exit 1 on error)

Cache Tuning

# Environment variables (optional)
AIFW_LOCAL_CACHE_TTL=30     # process-local TTL in seconds (default: 30)
AIFW_CACHE_TTL=600          # shared cache TTL in seconds  (default: 600)
from aifw.service import invalidate_action_cache, invalidate_tier_cache

invalidate_action_cache("story_writing")  # clear one action's cache entries
invalidate_action_cache()  # clear all
invalidate_tier_cache("pro")  # clear one tier

Constants

from aifw.constants import QualityLevel

QualityLevel.ECONOMY  # 2
QualityLevel.BALANCED  # 5
QualityLevel.PREMIUM  # 8
QualityLevel.ALL  # (2, 5, 8)

Configuration

Django Settings

INSTALLED_APPS = [
    "aifw",  # core: LLMProvider, LLMModel, AIActionType, AIUsageLog, TierQualityMapping
    "aifw.nl2sql",  # optional: NL2SQL models + migrations (requires `nl2sql` extra)
]

Run once after installation to seed default providers and models:

python manage.py migrate aifw
python manage.py init_aifw_config

Environment Variables (optional)

Variable Default Purpose
AIFW_LOCAL_CACHE_TTL 30 Process-local cache TTL in seconds
AIFW_CACHE_TTL 600 Shared cache TTL in seconds (Redis-backed)
AIFW_PRIVACY_MODE full Privacy policy for AIUsageLog: full | pseudonymous | anonymous (issue #8)
AIFW_PRIVACY_HOOK — Dotted path to a custom PrivacyHook (overrides AIFW_PRIVACY_MODE)
AIFW_PRIVACY_HMAC_SECRET SECRET_KEY HMAC key for pseudonymous user_hash

AIFW_PRIVACY_* are read from Django settings (not env), like Django's own SECRET_KEY. The cache TTLs above are read from the process environment.

No Django settings dict is required — all configuration is managed via Django Admin models.

Changelog

See CHANGELOG.md.

Metadata

Release files for iil-aifw 0.14.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for iil-aifw 0.14.0
File Size Uploaded Provenance
iil_aifw-0.14.0.tar.gz 122.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for iil-aifw 0.14.0
File Interpreter ABI Platform
iil_aifw-0.14.0-py3-none-any.whl Python 3 none any Details

Total release size: 214.1 kB

Release files / iil_aifw-0.14.0.tar.gz

Download URL iil_aifw-0.14.0.tar.gz
Size 122.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4578d094ff0197db232156a2b643de982be08b58313c9bb318b21c10b5e27112
BLAKE2b-256 checksum
How to use checksums
1ab7cda55aeabddb63e9510ee9a111d7d572272b7dff886322dff5e9ca419827
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / iil_aifw-0.14.0-py3-none-any.whl

Download URL iil_aifw-0.14.0-py3-none-any.whl
Size 91.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
86eeb80e57cb29c24870b8247c30666ff4bf8760c4ea358de288a2f068777ad0
BLAKE2b-256 checksum
How to use checksums
d9fb729a1c3d6f7a5d092ef0b8ca0ae7eb558d6903546033c383a98c871ad8f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Security for iil-aifw 0.14.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for iil_aifw-0.14.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page