Metadata-Version: 2.5
Name: z4j-flask
Version: 1.10.0
Summary: z4j Flask framework adapter (Apache 2.0)
Project-URL: Changelog, https://github.com/z4jdev/z4j-flask/blob/main/CHANGELOG.md
Project-URL: Documentation, https://z4j.dev
Project-URL: Homepage, https://z4j.com
Project-URL: Issues, https://github.com/z4jdev/z4j-flask/issues
Project-URL: Source, https://github.com/z4jdev/z4j-flask
Author: z4j contributors
License: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Flask
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: flask>=3.1.3
Requires-Dist: z4j-bare<2,>=1.10.0
Requires-Dist: z4j-core<2,>=1.10.0
Provides-Extra: all
Requires-Dist: z4j-apscheduler<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-arq<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-arqcron<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-celery<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-celerybeat<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-dramatiq<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-huey<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-hueyperiodic<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-rq<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-rqscheduler<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-taskiq<2,>=1.10.0; extra == 'all'
Requires-Dist: z4j-taskiqscheduler<2,>=1.10.0; extra == 'all'
Provides-Extra: arq
Requires-Dist: z4j-arq<2,>=1.10.0; extra == 'arq'
Requires-Dist: z4j-arqcron<2,>=1.10.0; extra == 'arq'
Provides-Extra: celery
Requires-Dist: z4j-celery<2,>=1.10.0; extra == 'celery'
Requires-Dist: z4j-celerybeat<2,>=1.10.0; extra == 'celery'
Provides-Extra: dramatiq
Requires-Dist: z4j-apscheduler<2,>=1.10.0; extra == 'dramatiq'
Requires-Dist: z4j-dramatiq<2,>=1.10.0; extra == 'dramatiq'
Provides-Extra: huey
Requires-Dist: z4j-huey<2,>=1.10.0; extra == 'huey'
Requires-Dist: z4j-hueyperiodic<2,>=1.10.0; extra == 'huey'
Provides-Extra: rq
Requires-Dist: z4j-rq<2,>=1.10.0; extra == 'rq'
Requires-Dist: z4j-rqscheduler<2,>=1.10.0; extra == 'rq'
Provides-Extra: taskiq
Requires-Dist: z4j-taskiq<2,>=1.10.0; extra == 'taskiq'
Requires-Dist: z4j-taskiqscheduler<2,>=1.10.0; extra == 'taskiq'
Description-Content-Type: text/markdown

# z4j-flask

[![PyPI version](https://img.shields.io/pypi/v/z4j-flask.svg)](https://pypi.org/project/z4j-flask/)
[![Python](https://img.shields.io/pypi/pyversions/z4j-flask.svg)](https://pypi.org/project/z4j-flask/)
[![License](https://img.shields.io/pypi/l/z4j-flask.svg)](https://github.com/z4jdev/z4j-flask/blob/main/LICENSE)

The Flask framework adapter for [z4j](https://z4j.com).

Adds the z4j agent into your Flask app via a one-line `Z4J(app)`
initializer. It registers installed engine adapters only when their required
native handles are configured on the Flask app (`CELERY_APP`, `RQ_APP` or
`RQ_REDIS_URL`, `ARQ_REDIS_SETTINGS`, `HUEY`, or `TASKIQ_BROKER`). Dramatiq can
instead use a process-global broker that already has registered actors.

## Compatibility

- Flask 3.1.3+ (no upper cap)
- Python 3.11+

Pair with an engine adapter (`z4j-celery`, `z4j-rq`, `z4j-dramatiq`, `z4j-huey`, `z4j-arq`, `z4j-taskiq`); each engine adapter carries its own upstream floor.

Full per-adapter matrix at <https://z4j.dev/reference/compatibility/>.

## What it ships

- **One-line install**, `Z4J(app)` and the agent connects on the
  next worker boot
- **Configured engine discovery**, supports multiple installed adapters when
  each adapter's required native handle is present in Flask config
- **TaskIQ middleware discovery**, `TASKIQ_BROKER` attaches z4j capture without
  guessing an event loop; TaskIQ broker startup binds its actual owner loop
- **Per-task metadata from supporting engine adapters**; `z4j-celery`,
  `z4j-rq`, and `z4j-dramatiq` expose `@z4j_meta` rather than this framework
  package defining one
- **Service-user safe**, auto-relocates the local outbound buffer
  to `$TMPDIR/z4j-{uid}` when `$HOME` is unwritable

## Install

```bash
pip install z4j-flask z4j-celery z4j-celerybeat
```

Wire it into your app:

```python
from flask import Flask
from myproject.celery import app as celery_app
from z4j_flask import Z4J

app = Flask(__name__)
app.config["CELERY_APP"] = celery_app
Z4J(app)  # reads Z4J_TOKEN, Z4J_HMAC_SECRET, Z4J_BRAIN_URL, Z4J_PROJECT_ID
```

Mint the agent from the dashboard's Agents page and retain both values it shows:
the bearer token and the HMAC secret.

For `TASKIQ_BROKER`, initialize `Z4J(app)` before the component that starts the
broker. Flask discovery attaches the middleware, and TaskIQ's real broker
startup binds its owner loop. A separate TaskIQ worker process still needs its
own agent and must attach before the TaskIQ CLI starts the broker.

## Reliability

- Agent startup and delivery failures are logged and isolated from Flask
  request handlers and worker code; capture hooks make no brain network request
  inline.
- Engine event queues and the SQLite outbound buffer are bounded. Queue
  overflow drops new events and buffer pressure evicts oldest rows; both losses
  are logged.

## Documentation

Full docs at [z4j.dev/frameworks/flask/](https://z4j.dev/frameworks/flask/).

## License

Apache-2.0, see [LICENSE](LICENSE).

## Links

- Homepage: https://z4j.com
- Documentation: https://z4j.dev
- PyPI: https://pypi.org/project/z4j-flask/
- Issues: https://github.com/z4jdev/z4j-flask/issues
- Changelog: [CHANGELOG.md](CHANGELOG.md)
- Security: security@z4j.com (see [SECURITY.md](SECURITY.md))
