askable-django
Django binding for askable — template tags + auto-inject middleware for LLM-aware Django apps.
Install
pip install askable-django
Add to INSTALLED_APPS and optionally MIDDLEWARE:
INSTALLED_APPS = [
...
"askable",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"askable.middleware.AskableMiddleware", # auto-injects askable/core before </body>
...
]
Template tags
{% load askable_tags %}
{# Wrap any block — renders a <div data-askable="..."> around your content #}
{% askable meta=chart_meta %}
<canvas id="revenue-chart"></canvas>
{% endaskable %}
{# Custom tag name #}
{% askable meta=chart_meta as="section" %}
{{ chart|safe }}
{% endaskable %}
{# Inline — just the attribute, for when you control the element #}
<div {% askable_attr meta=chart_meta %} class="panel">
{{ content }}
</div>
{# Manual script tag (if you're NOT using AskableMiddleware) #}
{% askable_script %}
meta argument
Pass a Python dict or string. Dicts are JSON-serialized automatically:
# views.py
def dashboard(request):
return render(request, "dashboard.html", {
"chart_meta": {
"metric": "revenue",
"period": "Q3",
"value": "$2.3M",
}
})
{% askable meta=chart_meta %}
<canvas id="chart"></canvas>
{% endaskable %}
{# renders: <div data-askable='{"metric":"revenue","period":"Q3","value":"$2.3M"}'> #}
Middleware
AskableMiddleware automatically injects @askable/core before </body> on every HTML response. No template changes needed — just add it to MIDDLEWARE.
The injected script:
- Loads
@askable/corefromesm.shCDN (~1kb gzipped) - Calls
ctx.observe(document.body) - Keeps
window.__askableContextupdated with the current prompt string
Your own JavaScript can read the context as:
const context = window.__askableContext;
// → "User is focused on: — metric: revenue, period: Q3 — value "Q3 Revenue""
// or "No UI element is currently focused."
Wire it into your AI chat handler:
async function askAI(question) {
return fetch('/ai/chat/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
question,
context: window.__askableContext,
}),
});
}
# views.py
import json
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def ai_chat(request):
data = json.loads(request.body)
question = data['question']
ui_context = data.get('context', 'No UI element is currently focused.')
response = your_llm_client.chat(
system=f"You are a helpful assistant.\n\nCurrent UI context:\n{ui_context}",
user=question,
)
return JsonResponse({'answer': response})
Flask / FastAPI
No dedicated package needed — it's the same pattern without the middleware:
{# Jinja2 template #}
<div data-askable='{{ chart_meta | tojson }}'>
{{ chart_content }}
</div>
{# Before </body> #}
<script type="module">
import { createAskableContext } from 'https://esm.sh/@askable/core@0.1.0';
const ctx = createAskableContext();
ctx.observe(document.body);
ctx.on('focus', () => { window.__askableContext = ctx.toPromptContext(); });
</script>
License
MIT
Metadata
Release files for askable-django 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| askable_django-0.1.2.tar.gz | 5.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| askable_django-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.5 kB
Release files / askable_django-0.1.2.tar.gz
| Download URL | askable_django-0.1.2.tar.gz |
|---|---|
| Size | 5.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9ca2f42c850310a4e50c777690b39019e02b760503a384ff7997fddb97493f68
|
|
BLAKE2b-256 checksum How to use checksums |
349add746f36691b6941b3d23bff529fcb65592fad775ac4f6487bc8caee5eb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 29, 2026.
Transparency logRelease files / askable_django-0.1.2-py3-none-any.whl
| Download URL | askable_django-0.1.2-py3-none-any.whl |
|---|---|
| Size | 6.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c40333e2754cb20e2fb32c139a23cb31d4bfb2fce91fc508dfbe4522c7bd81fe
|
|
BLAKE2b-256 checksum How to use checksums |
070122628548b8a03fb2d6874c9b67a888827b2bdb6e0d987ed17c37fcfafc1f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 29, 2026.
Transparency log