Skip to content

Configuration

# settings.py: complete development example; does not start services.
from pathlib import Path

from django.http import HttpRequest

BASE_DIR = Path(__file__).resolve().parent.parent


def can_edit_hyperview(request: HttpRequest) -> bool:
    return request.user.is_superuser is True


HYPERVIEW = {
    "TEMPLATE_DIRS": [BASE_DIR / "hyperview"],  # Create this directory in your project.
    "SOURCES": [
        {"BACKEND": "dj_hyperview.sources.FileSystemSource", "OPTIONS": {}},
    ],
    "CACHE": {  # Optional: omit this section or use {} to disable caching.
        "ALIAS": "default",  # Must exist in CACHES and use a compatible backend.
        "NAMESPACE": "my-app-templates-dev",
        "TTL": 300,
        "NEGATIVE_TTL": 15,
        "FAILURE_MODE": "bypass",
    },
    "VALIDATION": {
        "MAX_BYTES": 1_000_000,
        "MAX_DEPTH": 64,
        "MAX_NODES": 20_000,
    },
    "ADMIN": {
        "EDITOR": False,  # Does not require the optional editor extra.
        "PERMISSION": can_edit_hyperview,
    },
    "EXTRA_SCHEMAS": [],  # No additional XSD files in this example.
    "SCHEMA_EXTENSIONS": {
        "BEHAVIORS": {
            "show-snackbar": {
                "ATTRIBUTES": {
                    "message": {"TYPE": "string", "REQUIRED": True},
                    "tone": {"TYPE": "string", "ENUM": ["success", "error"]},
                },
            },
        },
        "ELEMENT_ATTRIBUTES": {
            "image": {
                "variant": {"TYPE": "string", "ENUM": ["face", "fingerprint"]},
            },
        },
    },
    "REALTIME": {  # Optional: omit this section or use None to disable SSE.
        "REDIS_URL": "redis://127.0.0.1:6379/0",  # Development Redis, if you use it.
        "NAMESPACE": "my-app-dev",
    },
}

This example shows every public section, not every possible combination. Adjust paths and names to your project. Before using it:

  1. Install the package and add dj_hyperview to INSTALLED_APPS, as described in installation. Create your project's hyperview/ directory.
  2. Keep a compatible default alias in CACHES. Django defaults to LocMemCache when you do not configure it: suitable for this single-process example, not for coherence across workers. Do not overwrite deployment caches when copying.
  3. EXTRA_SCHEMAS=[] needs no additional files. The show-snackbar and image.variant declarations only validate XML; implement their mobile behavior before using them. They do not install features into Hyperview.
  4. REALTIME does not connect to Redis when settings are read. Using the transport requires [realtime], a reachable Redis service and the ASGI/client integration in the SSE guide. This example starts no services.
  5. Run python manage.py check. Create hyperview/screens/home.xml before trying the resolver below. Later snippets update one section, keeping the rest of HYPERVIEW intact unless explicitly stated otherwise.

Resolve a canonical relative POSIX name through the public API:

from dj_hyperview import TemplateResolver

template = TemplateResolver.from_settings().resolve("screens/home.xml")

Sources are queried in order and the first hit wins. Absolute paths, traversal, backslashes, empty path segments, control characters, invisible format characters, line and paragraph separators, and surrogates are rejected. Omitting CACHE keeps caching disabled and avoids cache backend initialization.

DummyCache is not a valid Hyperview cache backend because it cannot preserve generation state. To disable caching, omit CACHE instead of selecting a dummy cache alias. The system check only warns (dj_hyperview.W004), but the effect at runtime is not mild: with CACHE.FAILURE_MODE set to "raise" every lookup raises SourceUnavailable, and with "bypass" every lookup logs a template_cache_bypassed warning and reads from the sources.

FileBasedCache and its subclasses are rejected with dj_hyperview.E018, even when CACHE.FAILURE_MODE is bypass: their non-atomic add() cannot protect template generations. Select a backend with atomic add and coherent reads, or omit CACHE. This is a configuration error, not a recoverable backend outage.

Settings reference

All keys are optional except the fields inside each configured source. Cache defaults apply only when CACHE is a non-empty mapping; omitting it or using an empty mapping disables Hyperview caching. REALTIME omitted or None is disabled; an empty realtime mapping is an error, not another disabled form.

Every message that python manage.py check can report is listed in the system check reference.

Unknown keys are rejected, not ignored. A key that HYPERVIEW, a SOURCES entry, CACHE, VALIDATION or ADMIN does not define, such as MAX_BYTE, PERMISION or a lowercase cache, produces dj_hyperview.E023 from python manage.py check and HyperviewConfigurationError when settings are read. A typo therefore cannot silently fall back to a default and weaken a limit, a cache policy or the Admin permission. The error names the key and lists the valid ones. The removed keys SCHEMA_PROFILE, VALIDATION.MODE and VALIDATION.SCHEMA keep their own errors and are not reported twice.

Setting Type Default Meaning
HYPERVIEW Mapping {} Package configuration in Django settings. An absent or empty mapping configures no sources and no cache.
TEMPLATE_DIRS List or tuple of strings or Path objects () Ordered project-owned roots inherited by FileSystemSource instances that do not override template_dirs. Missing roots emit an operational warning and are skipped at runtime.
SOURCES Sequence of mappings () Ordered source definitions. The first source that resolves a canonical template name wins. An empty sequence resolves no templates.
SOURCES[].BACKEND Dotted import path Required Importable source class for one entry. Built-in paths are shown below.
SOURCES[].OPTIONS Mapping {} Keyword arguments passed to that source class constructor. Supported keys are backend-specific; entries the constructor does not accept, or required arguments it does not receive, produce dj_hyperview.E024.
CACHE Mapping Omitted (disabled) Enables raw-source and source-miss caching when non-empty, for the sources that opt in (see cache consistency). It does not cache compiled templates; the loader keeps those in process (see template engine behavior).
CACHE.ALIAS String "default" Django cache alias with atomic add and coherent reads. DummyCache and FileBasedCache are unsupported.
CACHE.NAMESPACE Non-empty string "dj-hyperview" Prefix domain that isolates all Hyperview cache keys. Change it to abandon previously published cache state.
CACHE.TTL Integer greater than or equal to 1 300 seconds Lifetime of successful raw-template and resolved-source entries. Generation keys do not expire.
CACHE.NEGATIVE_TTL Integer greater than or equal to 0 15 seconds Lifetime of explicit source misses. Zero disables effective negative-entry retention.
CACHE.FAILURE_MODE bypass or raise "bypass" bypass falls back to authoritative sources after ordinary cache failures; raise reports SourceUnavailable. Invalidation remains fail-closed in both modes.
VALIDATION Mapping {} Resource limits for mandatory source safety and automatic rendered validation.
VALIDATION.MAX_BYTES Positive integer 1,000,000 bytes Maximum UTF-8 size accepted for raw source and the final rendered document.
VALIDATION.MAX_DEPTH Positive integer 64 levels Maximum depth of the final parsed XML tree, with an absolute maximum of 256 imposed by the parser safety ceiling. A comment or processing instruction is a node one level below its parent, so it counts too.
VALIDATION.MAX_NODES Positive integer 20,000 nodes Maximum number of nodes under and including the root element of the final parsed XML document: elements, comments and processing instructions. Text content is not a node, and a comment or processing instruction outside the root element is not counted, so only MAX_BYTES bounds those.
ADMIN Mapping {} Optional Django Admin enhancements.
ADMIN.EDITOR Boolean False Replace the database template textarea with the optional HXML-aware Ace editor with one conservative Format and Validate action. Requires the editor extra and django_ace in INSTALLED_APPS.
ADMIN.PERMISSION Callable or dotted callable path Superuser-only callback Authoritative mutation policy for adding, changing, and deleting stored templates. The callable receives the current HttpRequest and must return the literal boolean True; exceptions and non-boolean results deny access.
EXTRA_SCHEMAS List or tuple of strings or Path objects () Local XSD roots merged into the bundled Hyperview 0.111.0 registry and completion catalog. URLs are rejected.
SCHEMA_EXTENSIONS Mapping {} Typed app-owned behavior and element-attribute declarations; standard declarations cannot be replaced.
REALTIME Exact mapping or None None Optional SSE transport configuration. Does not create an endpoint, client or connection.
REALTIME.REDIS_URL String Required when enabled Validated server-owned Redis URL; not a cache alias. Excluded from the normalized object's repr.
REALTIME.NAMESPACE String Required when enabled App/environment domain: [a-z0-9][a-z0-9_-]{0,63}.

Automatic Hyperview XSD 1.1 validation

The package always validates final rendered documents and fragments against one corrected Hyperview 0.111.0 registry. Raw source remains context-free: safety and Django compilation do not invent variables or render a scenario. Configuring VALIDATION changes only MAX_BYTES, MAX_DEPTH, and MAX_NODES; it cannot skip or replace standard validation. Separate fixed caps allow at most 128 attributes and 8 in-scope namespaces on one element, and 32 namespace declarations, counting every rebinding, on the path from the root to one element; exceeding any of them fails with the validation code max_attributes. They do not replace these three limits as the bounds on the whole document: lower the three settings for untrusted input, because validation cost grows with the nodes and attributes of a document (see Security). Template source has one more fixed limit, on the work that unclosed {{, {% and {# delimiters cost Django's lexer; exceeding it fails with the code max_unclosed.

SCHEMA_PROFILE, VALIDATION.MODE, and VALIDATION.SCHEMA are removed settings. Their presence produces a configuration error, including their former default values. Delete them rather than replacing them with a new selector. Register only application extensions when needed:

# First create this local schema using the custom-schemas guide.
HYPERVIEW["EXTRA_SCHEMAS"] = [
    *HYPERVIEW["EXTRA_SCHEMAS"],
    BASE_DIR / "schema" / "hypertodo.xsd",
]

Project schemas declare namespaced custom elements. To accept Hyperview elements inside one, use xs:any with namespace="https://hyperview.org/hyperview", as the custom schema guide does. An xs:import of that namespace cannot supply its components: each extra schema is also compiled on its own, without the Hyperview schema, so a ref or type that names one fails with dj_hyperview.E012 (reason: schema_invalid). Includes, imports, and redefines may reference only plain local files below their root schema's directory. Remote references, traversal (any .. segment), percent-encoded locations, control or other non-printable characters, the characters ?, # and :, backslash/URI ambiguity, DTD/entities, and arbitrary xs:override are rejected. Each extra schema may reference at most 256 distinct file paths, including its root; cycles are visited once. Symlink escapes remain forbidden, also through the dependencies of a schema file that is itself a symlink.

After every extra schema passes on its own, the system check compiles them all together with the bundled Hyperview schema. Two schemas that declare the same global name differently, or a schema that declares a Hyperview or alert name differently from the bundled schemas, fail the check with dj_hyperview.E012 (reason: duplicate_schema_declaration) instead of failing the first request. A registry that compiles cleanly is cached, so the first request does not compile it again.

Validation, static Admin checks, and completion use one immutable registry identity: the internal correction revision, normalized registrations, and complete transitive dependency fingerprints (resolved paths, sizes and nanosecond mtimes). References are rechecked before cache hits. Changed dependencies or HYPERVIEW settings refresh all consumers without restarting Django.

The fixed trusted package overlay leaves upstream XSD artifacts unchanged. get_hyperview_catalog() returns active catalog_format: 2 without public profile metadata. The config-free get_hyperview_schema_path() and build_hyperview_catalog() helpers still inspect the archived upstream 0.110.0 resources, not the active corrected runtime registry.

Follow Add custom HXML elements for namespace registration and the custom component example. Standard validation does not require an additional install or callback.

Admin editor

The enhanced editor is deliberately separate from database storage:

uv add "dj-hyperview[editor]"
# Add django_ace to your existing INSTALLED_APPS; retain other applications.
# Keep dj_hyperview.contrib.database if using database templates.
HYPERVIEW["ADMIN"] = {**HYPERVIEW["ADMIN"], "EDITOR": True}

Enabling the setting without the extra, or without django_ace in INSTALLED_APPS, produces an actionable Django system-check error. When the setting is false, the standard Django textarea remains unchanged.

Stored templates are executable Django template source, so mutations default to superusers even when a staff user holds the model's ordinary add, change, or delete permissions. A project can replace that policy with an inline callable:

HYPERVIEW["ADMIN"] = {
    **HYPERVIEW["ADMIN"],
    "PERMISSION": lambda request: request.user.is_superuser,
}

For reusable and testable production configuration, create this module first, then reference its dotted path:

# sample_app/permissions.py
from django.http import HttpRequest


def can_edit_hyperview(request: HttpRequest) -> bool:
    """Return whether the current user may mutate stored HXML templates."""
    return request.user.has_perm("dj_hyperview_database.change_hyperviewtemplate")
HYPERVIEW["ADMIN"] = {
    **HYPERVIEW["ADMIN"],
    "PERMISSION": "sample_app.permissions.can_edit_hyperview",
}

The callback is authoritative for all three mutation operations rather than an additional Django model-permission check. Admin-site access still requires an active staff user. Standard model view permission continues to govern read-only access. Missing paths, non-callables, and callbacks that cannot accept one request fail Django system checks; runtime exceptions and non-boolean return values fail closed.

Source backend options

OPTIONS is an optional mapping. The resolver passes its entries to the configured backend constructor as keyword arguments. The bundled backends support the following options:

Backend Option Default Meaning
FileSystemSource template_dirs HYPERVIEW["TEMPLATE_DIRS"] Ordered template roots for this source instance, supplied as a list or tuple of strings or Path objects. Earlier roots win.
DatabaseSource using None A configured Django database alias. A fixed alias permits source caching; omitting it delegates to Django database routing and disables source caching because the selected database can vary.

template_dirs must be a list or tuple of roots. Do not pass a single string, Path, generator, set, or other iterable: only reusable ordered collections are accepted. A root that is temporarily unavailable emits a system-check warning; resolution continues through later roots.

For example, one filesystem source can override the global roots:

# Create tenant-hyperview/ first. This changes SOURCES, not other sections.
HYPERVIEW["SOURCES"] = [
    {
        "BACKEND": "dj_hyperview.sources.FileSystemSource",
        "OPTIONS": {"template_dirs": [BASE_DIR / "tenant-hyperview"]},
    },
]

A custom backend defines its own supported OPTIONS through its constructor. There is no package-wide list for third-party options. System checks bind OPTIONS to the constructor signature of an importable backend: a misspelled option, an unexpected one, or a missing required argument produces dj_hyperview.E024 ("OPTIONS do not match the backend constructor") instead of a TypeError on every request. Reading settings fails the same way. A custom backend is also never cached unless it declares cacheable = True; see cache consistency. See Filesystem and Database and admin for backend-specific behavior.

Template engine behavior

Named templates use dj-hyperview's dedicated resolver-backed template engine by default. That engine copies only context_processors, string_if_invalid, builtins, and libraries from the first configured DjangoTemplates backend or subclass. It deliberately isolates security-sensitive options such as autoescape and replaces the backend's loaders, so template lookup still follows HYPERVIEW["SOURCES"] and never falls through to unrelated Django template directories.

The engine's loader keeps the templates it compiled, so a template that resolves to the same content is validated and compiled once instead of on every render. The resolver still runs on every lookup, so invalidation, cache generations and the per-render revision snapshot behave as before. A stored template is reused only when the new resolution matches it in every field, content included, so a custom source whose revision does not follow its content never serves stale code. Validation and compile errors are never stored. A template keeps one entry per source, name and origin, so a template that is published again replaces its previous version instead of adding to it. The memory is bounded for each engine to 256 templates and 524,288 characters (512 Ki) of source, and the least recently used template leaves first. A compiled template takes about 5 to 25 bytes of memory per character of its source, and up to about 100 for dense markup, so that is about 12 MiB for typical templates and 50 MiB at worst. A source over 524,288 characters is compiled on every render. The settings a compile depends on are read when the engine is built: HYPERVIEW, TEMPLATES and DEBUG rebuild the default engine, which starts empty, and a loader that Django builds from TEMPLATES keeps the sources and limits it read when it was built, as it did before. ResolverLoader.reset() empties the loader. A subclass that overrides get_contents() or get_template_sources() compiles on every render, because an override may read state that the cache cannot see. Compiled templates are shared between threads, as in Django's cached loader, so a custom tag must keep no per-render state on its nodes; the tags and filters of this package keep none.

The response path does not switch engines when SOURCES is empty. An empty source list therefore produces a normal missing-template result. To opt out and select a consumer Django engine explicitly, pass its alias, for example using="django", to HyperviewTemplateResponse. The dj_hyperview.W005 system check calls out an absent configuration or an explicitly empty source list. Temporarily unavailable filesystem roots emit dj_hyperview.W006 and do not prevent later roots from resolving templates.

Continue with Filesystem, Database and admin, Cache consistency, Security, Testing, Release and rollback, or the public Python API. Return to the documentation home.

Corrected schema boundaries

The internal correction revision is package-owned, not a user-selectable profile. It accepts signed decimal percentages on the nine margin attributes while keeping integer and auto values, and adds only these verified declarations:

Element Added attributes Boundary
text ellipsizeMode clip, head, middle, tail; clip is iOS-specific
text, text-field accessibilityLabel String, including empty text
text accessibilityRole button, none
image accessibilityRole, alt Role button; alternative text is a string
text importantForAccessibility auto, yes, no, no-hide-descendants; Android-specific
date-field cancel-label, done-label Strings consumed by the iOS modal, not Android's native picker

The correction restricts only style@width, not the shared upstream sizing types. It accepts nonnegative decimal points with a leading digit (0, 84, 12.5, 0.5) and decimal percentages (0%, 12.5%, .5%, 150%); a leading + is accepted. It rejects negative values, auto, .5 without %, trailing decimal points, units, exponent notation, arbitrary suffixes, NaN, and Infinity.

These are deliberate lexical boundaries. Hyperview 0.110.0 truncates point values with parseInt: 12.5 becomes 12. Validation never rewrites the input. React Native itself supports fractional dimensions and auto, but this pinned Hyperview converter passes auto as NaN, not as the native auto value.

The corrected schema does not permit accessibilityElementsHidden as a boolean string, move styles outside its owning screen, accept arbitrary native properties, or establish native visual/accessibility parity. The evidence is pinned client source plus package tests, not device E2E testing.

Register typed schema extensions

SCHEMA_EXTENSIONS defaults to {}. Invalid registrations produce dj_hyperview.E021. Registration describes server validation and editor metadata, not executable mobile implementations.

The complete example at the top declares a required message, a tone enum, and an image.variant enum. Merge new declarations into your existing registry; do not replace unrelated behaviors or attributes. This valid fragment uses them:

<view xmlns="https://hyperview.org/hyperview">
  <behavior trigger="load" action="show-snackbar" message="Saved" tone="success" />
</view>

A descriptor requires TYPE: string, boolean, integer, or decimal. REQUIRED defaults to False; True requires the attribute's presence, not nonempty string content. Optional ENUM is a nonempty sequence of unique XML strings and is valid only with TYPE: "string". There are no implicit defaults, coercions or output mutations. XML boolean lexical forms are true, false, 1, and 0; declaring a type does not convert a mobile client's raw attribute.

All sections and descriptor keys are closed. Names must be unqualified ASCII XML names; names starting with xml are reserved. Standard actions and standard attributes cannot be redefined. Qualified and unqualified names are distinct: custom message can coexist with standard alert:message. ELEMENT_ATTRIBUTES can add attributes only to existing Hyperview elements other than behavior. Use BEHAVIORS for action-specific attributes; custom actions are supported on behavior, not inline on view, text, or other built-in elements.

Strings can be empty, including an opaque revocation token. Register DOM target identifiers as strings when they may reference a host outside the current fragment; registration does not impose document-wide xs:IDREF existence. See custom schema contracts for validation, catalog and trust boundaries.

Optional realtime broker

HYPERVIEW["REALTIME"] centralizes the Redis URL and namespace. Omitted or None means disabled. An enabled mapping must contain exactly REDIS_URL and NAMESPACE; empty mappings, extra keys, ALIAS or invalid values produce dj_hyperview.E022 and HyperviewConfigurationError when reading settings. Configuration errors never silently fall back to disabled. Diagnostics do not include the secret URL.

from dj_hyperview.conf import get_settings
from dj_hyperview.realtime import RedisBroker

realtime = get_settings().realtime
broker = (
    RedisBroker(realtime.redis_url, realtime.namespace)
    if realtime is not None
    else None
)

get_settings().realtime returns immutable RealtimeSettings or None; its repr excludes redis_url. Reading settings, running checks and constructing the broker do not import redis-py or connect. Subscription/publication requires the [realtime] extra. When REALTIME is enabled but redis-py cannot be found, python manage.py check reports the warning dj_hyperview.W007 with the hint pip install "dj-hyperview[realtime]"; the check only looks for the package and never imports it. Configuration alone creates no endpoint, producer or mobile listener. To disable this section without losing template sources or schemas:

HYPERVIEW["REALTIME"] = None

There is no REALTIME.ALIAS adapter. CACHE.ALIAS selects a Django cache, not a Pub/Sub transport. Use a distinct app/environment namespace: Redis database numbers do not isolate Pub/Sub. A namespace prevents collisions, not unauthorized access. Use rediss:// for remote services; TLS certificate verification and hostname checks remain required. See the complete SSE guide for application integration and the cache comparison.

URLs support redis://, rediss:// and unix:///absolute/socket. The only query option is one canonical db=0 (or another nonnegative database number), without a conflicting TCP URL database path. Retry, timeout, SSL and unknown query options are rejected: redis-py URL options can otherwise override safe kwargs. Namespace syntax is [a-z0-9][a-z0-9_-]{0,63}; topics are at most 32 supplied items matching [A-Za-z0-9][A-Za-z0-9._:-]{0,127}. Duplicates are coalesced, but still count toward that input bound. Topics are server-selected, never query parameters. The broker prefixes them with namespace:.

Redis permissions and TLS

The package issues PUBLISH and SUBSCRIBE on channels named <namespace>:<topic>. Redis also receives AUTH when the URL carries credentials and SELECT when it selects a database other than 0. redis-py also sends CLIENT SETINFO with its library name and version whenever it opens a connection. The rule below denies that command, and redis-py ignores the error (its Connection.on_connect in 7.4.1 and 8.1.0 catches ResponseError around both commands), so the connection works; the denied attempts may appear in ACL LOG. No scripting permission is required. Since Redis 7.0 the default for new ACL users is resetchannels (the acl-pubsub-default setting), so +publish +subscribe alone is refused with NOPERM until the user is also granted the namespace's channels:

ACL SETUSER hv on >secret resetchannels &my-app-dev:* -@all +publish +subscribe +select

Replace my-app-dev with your REALTIME.NAMESPACE, drop +select when the URL uses database 0, and try the rule with a throwaway user on your Redis version. A rejected command shows up in the publisher log as realtime_publish_failed error_type=NoPermissionError; a subscription that cannot start raises RealtimeUnavailable without further detail, so check the ACL first when a stream never starts.

TLS is deliberately narrow. A rediss:// URL always verifies the certificate and the host name, and the URL accepts no query option except db, so there is no setting for a CA bundle, a client certificate or a key. A private CA must be trusted through the process's default trust store, for example with the SSL_CERT_FILE or SSL_CERT_DIR environment variables that OpenSSL reads. A unix:///absolute/socket URL carries no credentials; authenticate such a connection with the socket's file permissions.

Call broker.publish_after_commit(event, topics, *, using) with an explicit Django database alias: using is keyword-only and has no default, so omitting it raises TypeError. It snapshots the closed envelope and topics before scheduling. Rollback publishes nothing; invalid inputs fail before scheduling. Publication failure never fails the committed business operation. It logs only a fixed code and the exception type name, as realtime_publish_failed error_type=<TypeName>, never the exception message, which can contain the Redis URL. A per-process daemon worker has a queue of 32 jobs; each commit caller waits at most two seconds including queue time. Expired queued jobs do not start I/O. Forked children create their own worker, not an inherited client. The worker keeps one Redis connection per configuration and reuses it for later hints, sending all channels of a hint in one pipeline round trip. It replaces the connection after a failure, after 30 seconds without use, or after five minutes of age, so that the host name is resolved again even under steady traffic. It checks the connection that a hint uses against those limits, and sweeps every connection at most every 30 seconds, whether hints arrive or not, so a configuration that is never used again does not keep its connection open until the process ends. The sweep also forgets a configuration, with the failures counted for it, once nothing was attempted on it for 30 seconds and its breaker is not open: a configuration that only ever failed does not stay in memory, and a failure that old stops counting toward the breaker. After three consecutive failures of one configuration, including a client that cannot be built, publications for it fail fast for five seconds instead of each paying the connection timeout. The breaker logs the fixed code realtime_publish_circuit_open once when it opens, not for each dropped hint. The first publication after that pause is the probe: success closes the breaker, failure reopens it for another five seconds. A worker ended by a BaseException, such as a gevent Timeout, is replaced by the next commit. Hints dropped this way follow the same at-most-once rule as every other failure.

The caller deadline is not a total I/O deadline. DNS resolution cannot be preempted; socket timeouts apply per operation, including multiple pipeline responses. One slow worker can block later hints until they expire. An in-flight hint may finish late or partially. There is no retry, rollback, delivery receipt, EVAL requirement or durability claim. No thread is created per hint.

await broker.subscribe(topics) waits for each actual SUBSCRIBE acknowledgement within a two-second setup budget. Only then does it return an owned async iterator, beginning with one resync; pre-ACK data is conservatively covered by that resync. Cleanup has a separate two-second cooperative budget, so failed setup plus cleanup can take longer than the setup deadline. Cancellation does not forcibly stop an OS resolver already running in asyncio's executor. Repeated cancellation during failed setup waits for the same owned cleanup budget before propagating cancellation; it does not restart that budget.

Each subscription owns its client/one-connection pool and queue of at most 32 closed JSON payloads (each at most 4096 bytes). Overflow discards pending hints and retains one resync until consumed. This is a logical retained-payload bound, not a peak allocation guarantee inside redis-py. No transparent reconnection is allowed: a lost connection closes the iterator; the application may subscribe again and must reauthorize before its new resync. A cancelled __anext__ wait (for example a heartbeat deadline) does not close ownership; call aclose(). Idle connections have no two-second socket read timeout. The application owns heartbeat cadence, stream lifetime, authorization, connection admission caps, and realtime_asgi/sse_response composition.

System check reference

python manage.py check reports these IDs. Each message names the failing setting and carries a hint; messages never include file paths, exception text or secret values. Errors fail the check, and warnings describe configuration that works but probably is not what you meant. E020 is not used.

ID Raised when Fix
dj_hyperview.E001 HYPERVIEW is not a mapping. Make it a dictionary.
dj_hyperview.E002 TEMPLATE_DIRS is not a sequence, or an entry is not a path. Use a list or tuple of strings or Path objects.
dj_hyperview.E003 SOURCES is not a sequence, an entry is not a mapping, its BACKEND cannot be imported (the message names the exception class), or its OPTIONS is not a mapping. Correct the entry; use a dotted path to an importable source class.
dj_hyperview.E004 CACHE is not a mapping, CACHE.ALIAS names no configured cache, or CACHE.NAMESPACE is not a non-empty string. Define the alias in CACHES and supply a namespace.
dj_hyperview.E005 CACHE.TTL is not an integer of at least 1, or CACHE.NEGATIVE_TTL is not an integer of at least 0. Use a plain integer; bool is rejected.
dj_hyperview.E006 CACHE.FAILURE_MODE is neither bypass nor raise. Choose one of the two values.
dj_hyperview.E007 VALIDATION is not a mapping, or the removed key VALIDATION.MODE is present. Use a mapping with limits only; delete MODE.
dj_hyperview.E008 The removed key VALIDATION.SCHEMA is present. Delete it; validation cannot be replaced.
dj_hyperview.E009 A VALIDATION.MAX_* limit is not a positive integer (a bool or other int subclass counts as invalid), or MAX_DEPTH is above 256. Use a plain positive integer; keep MAX_DEPTH at 256 or less.
dj_hyperview.E010 DatabaseSource is configured but dj_hyperview.contrib.database is not in INSTALLED_APPS. Install the contrib app and migrate, or remove the source.
dj_hyperview.E011 DatabaseSource OPTIONS["using"] is neither None nor a configured database alias. Name an alias that exists in DATABASES.
dj_hyperview.E012 EXTRA_SCHEMAS is not a sequence of files, one file is not a valid local XSD 1.1 schema, or the schemas do not compile together with the Hyperview schema. The message ends with (reason: <code>), such as unreadable, forbidden_schema_reference, schema_invalid or duplicate_schema_declaration. Fix the file named by the index, or declare each global name once; see Automatic Hyperview XSD 1.1 validation.
dj_hyperview.E013 xmlschema, a required dependency, is not installed. Repair the package installation.
dj_hyperview.E014 ADMIN is not a mapping, or ADMIN.EDITOR is not a boolean. Use a mapping and True or False.
dj_hyperview.E015 ADMIN.EDITOR is on but django-ace is not installed. Install dj-hyperview[editor].
dj_hyperview.E016 ADMIN.EDITOR is on but django_ace is not in INSTALLED_APPS. Add django_ace before dj_hyperview.
dj_hyperview.E017 ADMIN.PERMISSION is not a callable that accepts one request, or its dotted path cannot be imported. Pass a callable, or a dotted path to an importable callable; see Admin editor.
dj_hyperview.E018 CACHE.ALIAS uses FileBasedCache or a subclass, whose add() is not atomic. Select another backend or omit CACHE; bypass does not override this.
dj_hyperview.E019 The removed key SCHEMA_PROFILE is present. Delete it; the corrected schema is automatic.
dj_hyperview.E021 A SCHEMA_EXTENSIONS registration is invalid; the message names the path. Follow Register typed schema extensions.
dj_hyperview.E022 REALTIME is neither None nor a mapping with exactly a valid REDIS_URL and NAMESPACE. See Optional realtime broker.
dj_hyperview.E023 A key that HYPERVIEW, a SOURCES entry, CACHE, VALIDATION or ADMIN does not define. Remove it or fix its spelling; the hint lists the valid keys.
dj_hyperview.E024 SOURCES[].OPTIONS do not match the source constructor: an unknown keyword or a missing required argument. Pass only keyword arguments the constructor accepts.
dj_hyperview.W001 CACHE.ALIAS names a backend that cannot be initialized now. Correct the CACHES entry; runtime behavior follows CACHE.FAILURE_MODE.
dj_hyperview.W002 TEMPLATE_DIRS is set but no FileSystemSource is configured to use it. Add FileSystemSource or remove TEMPLATE_DIRS.
dj_hyperview.W003 A FileSystemSource has no template roots. Set TEMPLATE_DIRS or OPTIONS["template_dirs"].
dj_hyperview.W004 CACHE.ALIAS is a DummyCache. Omit CACHE; with FAILURE_MODE="raise" every lookup would fail.
dj_hyperview.W005 No SOURCES are configured, so nothing resolves. Add a source, or pass using="django" to the response.
dj_hyperview.W006 A template root is not an available directory right now; it is skipped at runtime. Create or mount the directory.
dj_hyperview.W007 REALTIME is configured but redis-py is not installed. Install dj-hyperview[realtime].