Framework - Flask
Package: z4j-flask - Flask 2.3+ / 3.x.
Install + wire
Section titled “Install + wire”from flask import Flaskfrom z4j_flask import Z4J
z4j = Z4J()
def create_app(): app = Flask(__name__) app.config.from_object("myapp.config.Config")
z4j.init_app(app, { "brain_url": app.config["Z4J_BRAIN_URL"], "token": app.config["Z4J_TOKEN"], "project_id": app.config.get("Z4J_PROJECT_ID", "default"), }) return appOr the one-shot form:
Z4J(app, {...config...})Lifecycle
Section titled “Lifecycle”Flask’s application context doesn’t have a natural “startup” hook. z4j-flask uses app.before_request (first-request) to start the agent. This is fine for web processes; for worker processes, call z4j.start() manually in your worker boot.
from myapp import create_appfrom z4j_flask import z4j
app = create_app()z4j.start(app) # or place inside `with app.app_context():`
# ... RQ worker loop ...Multi-process
Section titled “Multi-process”Same as Django: each worker is its own agent. Set agent_name to include the role:
import socket, osz4j.init_app(app, {..., "agent_name": f"web-{socket.gethostname()}-{os.getpid()}"})Config keys
Section titled “Config keys”See Django for the full Z4J config dict - the keys are identical.
Blueprints
Section titled “Blueprints”z4j does not register any Flask blueprints. It attaches as pure background behavior - your URL space is untouched.
CLI (flask ...)
Section titled “CLI (flask ...)”Management commands don’t start the agent unless you explicitly call z4j.start(app).
Troubleshooting
Section titled “Troubleshooting”- Agent starts but never connects - the first request triggers start. If your app has no inbound traffic yet (fresh deploy), the agent will appear offline until traffic arrives. Call
z4j.start(app)at app-factory time if you prefer eager-start. - Gunicorn preload mode - the agent’s asyncio loop is per-worker. Preload is fine, but each worker still opens its own WebSocket after fork.