proactive-gate for Python
Decide whether a proactive assistant may speak to this person right now. Ordered checks (consent, mode, snooze, mute, intensity, quiet hours, trust ramp, dismissal cooldown, budgets), JSON policies, platform and regulatory presets, and a trace that says which check stopped the message and why.
This is the Python sibling of the TypeScript package. Both implement the same behaviour
contract in spec/ and run
the same fixtures, so a policy written for one behaves the same in the other.
pip install proactive-gate
Python 3.11 or newer, no runtime dependencies. Add [redis] (pip install "proactive-gate[redis]")
for the Redis store.
To run an unreleased state, install from the repository instead:
pip install "proactive-gate @ git+https://github.com/Bubblegunn/proactive-gate#subdirectory=python".
The package is published from the release workflow through PyPI trusted publishing, so each file carries a publish attestation naming the repository and the workflow that built it. Releases before 0.2.2 were uploaded from a local build with a token and carry none.
Use
from datetime import datetime, timezone
from proactive_gate import Candidate, EvaluateInput, Gate, UserState, default_checks
gate = Gate(default_checks(daily_limit=3))
user = UserState.from_dict({
"id": "u1", "consent": True, "timezone": "Europe/Istanbul",
"quietHours": {"start": "22:00", "end": "08:00"}, "createdAt": "2026-01-01T00:00:00Z",
})
candidate = Candidate(id="c1", type="reminder", priority="normal", surfaces=("push", "feed"))
inp = EvaluateInput(user, candidate, datetime.now(timezone.utc))
decision = gate.evaluate(inp)
if decision.allowed and gate.commit(decision, inp):
send(candidate, decision.surfaces)
else:
print(decision.rejected_by, decision.reason)
evaluate reads; commit is the atomic increment right before you send, and it is
idempotent on decision.id. Every decision carries trace, one entry per check that ran.
A policy is data
import json
from proactive_gate import Gate
gate = Gate.from_policy(json.load(open("policy.json")))
policy.json is the same document the TypeScript package and the CLI read
({"specVersion": "1.0.0", "checks": [{"id": "consent"}, {"preset": "usTcpa"}, ...]}).
Unknown check ids and presets raise ValueError naming the known ones; shadow: true
keeps a check observing without letting it decide.
Async
from proactive_gate import AsyncGate, RedisStore
import redis.asyncio as redis
gate = AsyncGate.from_policy(policy, RedisStore(redis.from_url("redis://localhost")))
decision = await gate.evaluate(inp)
Gate and AsyncGate share one decision loop (Evaluation): a check names the store keys
it needs and decides purely from their values, so the two gates cannot drift. decide()
runs that loop with values you supply, for tests with no store at all.
Stores
MemoryStore (in-process), SqliteStore (standard library, one file per host),
AsyncMemoryStore, and RedisStore over redis.asyncio (INCR, then EXPIRE on the first
increment). Any object with get, set, incr and delete works.
Presets
proactive_gate.presets holds the same fourteen presets as the TypeScript package, each with
its source URLs and a note on what it leaves out: LINE, WeChat, WeCom, Kakao, Korea's Network
Act, Japan's anti-spam law, China's minor mode, US TCPA, EU ePrivacy, Telegram and Slack.
They are reviewable defaults, not legal advice.
Conformance
pytest
runs every fixture under ../spec/fixtures through both gates. A fixture the Python package
cannot yet satisfy is listed in spec/skip/python.txt with a reason; the list is empty.
License
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file proactive_gate-0.2.5.tar.gz.
File metadata
- Download URL: proactive_gate-0.2.5.tar.gz
- Upload date:
- Size: 23.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f161f8b018a8f8ac0e159c244000fbaf4ecb7da024741b581887703bc742e396
|
|
| MD5 |
898c0444e940a0431830218c7ae14a69
|
|
| BLAKE2b-256 |
d165317a9ebcc7a017b42e49a5d7fb135af938b046a7a407b930feaa3ad5b354
|
Provenance
The following attestation bundles were made for proactive_gate-0.2.5.tar.gz:
Publisher:
release.yml on Bubblegunn/proactive-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
proactive_gate-0.2.5.tar.gz -
Subject digest:
f161f8b018a8f8ac0e159c244000fbaf4ecb7da024741b581887703bc742e396 - Sigstore transparency entry: 2730969546
- Sigstore integration time:
-
Permalink:
Bubblegunn/proactive-gate@5b5262dd821e7e473b0d0f62eb34757459feb45b -
Branch / Tag:
refs/tags/v0.2.5 - Owner: https://github.com/Bubblegunn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5b5262dd821e7e473b0d0f62eb34757459feb45b -
Trigger Event:
push
-
Statement type:
File details
Details for the file proactive_gate-0.2.5-py3-none-any.whl.
File metadata
- Download URL: proactive_gate-0.2.5-py3-none-any.whl
- Upload date:
- Size: 26.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2c25d88b20d213f4263c2c12e5ea81709773786c5c2202fbcebcc4e3f0a1397
|
|
| MD5 |
8d6629bdad3a8a2382061b37c616d343
|
|
| BLAKE2b-256 |
45cd1fb53a8d63b1a34156c18eebf56d318e5a2164041606093715aebc765505
|
Provenance
The following attestation bundles were made for proactive_gate-0.2.5-py3-none-any.whl:
Publisher:
release.yml on Bubblegunn/proactive-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
proactive_gate-0.2.5-py3-none-any.whl -
Subject digest:
b2c25d88b20d213f4263c2c12e5ea81709773786c5c2202fbcebcc4e3f0a1397 - Sigstore transparency entry: 2730969704
- Sigstore integration time:
-
Permalink:
Bubblegunn/proactive-gate@5b5262dd821e7e473b0d0f62eb34757459feb45b -
Branch / Tag:
refs/tags/v0.2.5 - Owner: https://github.com/Bubblegunn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5b5262dd821e7e473b0d0f62eb34757459feb45b -
Trigger Event:
push
-
Statement type: