Configuration¶
PyJinHx provides several configuration options for customizing template discovery and rendering behavior.
Default Environment¶
The default Jinja environment controls where templates are loaded from.
Auto-Detection¶
By default, PyJinHx walks upward from the current directory to find your project root:
Project root is detected by looking for common markers:
pyproject.tomlmain.py.git.gitignorepackage.jsonuv.lock
Setting a Custom Path¶
from pyjinhx import Renderer
# Set explicit template path
Renderer.set_default_environment("./components")
# Now all components look for templates under ./components
Using a Jinja Environment¶
For full control, pass a Jinja Environment:
from jinja2 import Environment, FileSystemLoader
from pyjinhx import Renderer
env = Environment(
loader=FileSystemLoader("./templates"),
autoescape=True,
trim_blocks=True,
lstrip_blocks=True,
)
Renderer.set_default_environment(env)
Clearing the Default¶
Logging¶
PyJinHx uses Python's standard logging:
Logged events include:
- Component class registration warnings (duplicates)
- Component instance registration warnings (ID conflicts)
Application setup¶
For web apps, use a single call:
PjxSettings has two fields:
invalidation_backend— cross-worker invalidation backend (defaultNone)reactive_dev— enable reactive dev guardrails (defaultFalse)
The load-cache scope is derived from invalidation_backend: a backend (e.g. Redis) makes cross-request caching safe across workers, so load() results are cached per worker process; without one, they are cached per request only — the only multi-worker-safe default.
Pass a settings object via settings=, or override individual fields with explicit setup() keyword arguments. Explicit setup() kwargs take precedence over values from settings=.
Environment variables¶
PjxSettings.from_env() builds settings from the environment:
REDIS_URL— wires aRedisInvalidationBackend(which derives cross-request caching)PJX_INVALIDATION_DB— wires aSqliteInvalidationBackendwith the given path (used whenREDIS_URLis not set)PJX_REACTIVE_DEV— enables reactive dev mode when set to1,true, oryes
See Configuration API for PjxSettings, lifespan chaining, and cache defaults.
Load cache scope¶
You don't pick a scope — it follows the backend. By default (no invalidation_backend), load() results are cached per request only, the only multi-worker-safe behavior. Configure a cross-worker backend to opt into cross-request caching per worker process:
from pyjinhx import setup
setup(app) # per-request caching (default, multi-worker safe)
setup(app, invalidation_backend=...) # cross-request per worker; see integrations.redis
Registry.request_scope() initializes a request-scoped cache on entry and clears it on exit. With a backend configured, reads also use the process-wide store; otherwise only the request store is used. Within-request caching always happens — it dedups the repeated load() calls of the reactive OOB walk.
See Cache & Invalidation and Reactivity.
Invalidation fan-out¶
For multi-worker production, set a cross-worker invalidation_backend so invalidate() fans out to every process (and enables cross-request caching):
from pyjinhx import PjxSettings, setup
from pyjinhx.integrations.redis import RedisInvalidationBackend
setup(
app,
settings=PjxSettings(
invalidation_backend=RedisInvalidationBackend("redis://..."),
),
)
See Cache & Invalidation and Redis integration.
Reactive dev mode¶
Enable development guardrails to catch common reactive mistakes:
from pyjinhx.dev import enable_reactive_dev, disable_reactive_dev
enable_reactive_dev() # log warnings
enable_reactive_dev(strict=True) # raise RuntimeError instead
disable_reactive_dev()
Guardrails cover: mutations without a consuming render(), dirtied keys without mounted, and depends_on() outside the static react superset.
Inspect the dependency graph with dependency_graph() or format_dependency_graph(). See Mutations, Keys & PjxContext.