django-deacon
Deacon is an AI support agent that answers questions from your own docs and content, and says when it doesn't know. This app adds its chat widget to every page of a Django site.
You need a Deacon account, and there's a free plan.
Install
pip install django-deacon
Set it up
Add the app and your key to settings.py:
INSTALLED_APPS = [
# ...the rest of your apps
"django_deacon",
]
DEACON_KEY = "pk_your_widget_key"
Then load the tag in the <head> of your base template:
{% load deacon %}
<head>
{# ...the rest of your head #}
{% deacon_widget %}
</head>
To find your key, open Install from the button at the top of the Deacon dashboard. The snippet there has it in data-key, and it starts with pk_. It isn't a secret, since every visitor's browser reads it, but you can read it from the environment like any setting: DEACON_KEY = os.environ.get("DEACON_KEY"). If the key is missing, the tag prints nothing and logs a warning that says why, so your pages still render. A setting of the wrong type raises ImproperlyConfigured, which says why.
Deacon only runs on the sites listed on Install. A listed domain covers its subdomains, so example.com covers app.example.com. If your site lives somewhere else, such as example.fly.dev, add that address on Install too.
When you run python manage.py runserver, Install notices the widget on 127.0.0.1:8000 and lets you add it in one click. Chats on a development address don't count towards your plan.
If you tell Deacon who is signed in, with the window.deaconUser script from Deacon's install guide, put that script above {% deacon_widget %} in the head, because the widget reads it as it starts.
Options
| Setting | Type | Default | What it does |
|---|---|---|---|
DEACON_KEY |
str | none | Your Deacon key. Without it the tag prints nothing and logs a warning. |
DEACON_CONTEXT |
dict | none | Details Deacon takes into account when it answers, the same on every page, such as {"product": "api", "docs_version": "3.2"}. Up to 12 keys, each value a string, number or boolean. Anyone can read them in the page's HTML, so never put a secret here. |
DEACON_PAGE_VIEWS |
bool | True |
The same script counts visits for Deacon's website analytics. Set this to False to send no page views or JavaScript errors from your site. Chat still works. |
DEACON_KEY = "pk_your_widget_key"
DEACON_CONTEXT = {"product": "api", "docs_version": "3.2"}
DEACON_PAGE_VIEWS = False
Content Security Policy
If your site sends a Content Security Policy with a nonce, the tag carries the request's nonce. It reads it from Django's own CSP support (Django 6.0 and later), which needs the django.template.context_processors.csp context processor, or from django-csp's request.csp_nonce, which needs django.template.context_processors.request.
The policy also needs Deacon's address, https://heydeacon.com, in script-src, connect-src and frame-src, and 'unsafe-inline' in style-src, because the widget writes its styles where a nonce can't reach. Keep the nonce out of style-src, since a nonce there makes browsers ignore 'unsafe-inline':
from django.utils.csp import CSP
SECURE_CSP = {
"default-src": [CSP.SELF],
"script-src": [CSP.SELF, CSP.NONCE, "https://heydeacon.com"],
"style-src": [CSP.SELF, CSP.UNSAFE_INLINE],
"connect-src": [CSP.SELF, "https://heydeacon.com"],
"frame-src": ["https://heydeacon.com"],
}
Opening the chat from your own button
The widget comes with its own button. To use one of yours instead, hide Deacon's in Appearance in the dashboard and call window.Deacon.open() from your button or link. Deacon.close() and Deacon.toggle() work too.
What it adds
The tag prints the same tag Install gives you:
<script src="https://heydeacon.com/widget/v1/loader.js" data-key="pk_your_widget_key" async></script>
It loads in the background without holding up the page. Works with Django 5.2 and later, on Python 3.11 and later.
License
MIT
Metadata
Release files for django-deacon 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| django_deacon-1.0.0.tar.gz | 5.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_deacon-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.1 kB
Release files / django_deacon-1.0.0.tar.gz
| Download URL | django_deacon-1.0.0.tar.gz |
|---|---|
| Size | 5.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6d7aba4c1ac90c688ada6a2ca4fdb017ae104bc7482a035197e739ff6d1e75bf
|
|
BLAKE2b-256 checksum How to use checksums |
a21cfb991095f70cfb93f0928ff8618003776a9704b70b8fce21aa73bd174013
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / django_deacon-1.0.0-py3-none-any.whl
| Download URL | django_deacon-1.0.0-py3-none-any.whl |
|---|---|
| Size | 6.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b1aef7ce0134aa0eb41f2b2f8dd6e5f4cfb905c83587ad059c1e51def577ccc9
|
|
BLAKE2b-256 checksum How to use checksums |
578db6669858f84c636c15d7395892ad64e2e3f1f39de86b58b43e859ab3d3d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for django-deacon 1.0.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.