This release is a pre-release and may not be stable for production use.
ppx-client
Python client for the Preference Profile Exchange (PPX) reference provider and any conformant implementation.
Install
pip install ppx-client
Requires Python 3.11+. Published version: 0.1.0a1 (PyPI).
Alpha, tracking a draft specification. Expect breaking changes. The version is
0.1.0a1on PyPI and0.1.0-alpha.1on npm — the same release in each ecosystem's required format.
Quick start (sync)
from ppx_client import (
PpxClient, GrantRequestInput, consent_redirect_url, generate_pkce,
)
with PpxClient(base_url="https://api.provider.app") as ppx:
# PKCE is mandatory and S256-only. Keep `verifier` in memory; it is sent
# only in the token exchange. The provider stores only the challenge.
pkce = generate_pkce()
req = ppx.request_grant(GrantRequestInput(
client_id="my-app",
subject_id="did:example:user-123",
purposes=["recommendation"],
allowed_domains=["fragrance"],
allowed_namespaces=["fragrance"],
allowed_operations=["read"],
cross_domain_transfer="deny",
writeback_policy="review_required",
requested_duration_days=30,
code_challenge=pkce.challenge,
# Matched EXACTLY against what you registered. Not a query parameter
# on the consent URL any more, so nobody can rewrite it in transit.
redirect_uri="https://my-app.example/callback",
))
# req.request_token is the capability, returned ONCE. Hold it in memory.
# Never log it, never put it in a URL.
# Send the user here to review and approve. This URL is safe to treat as
# public: the id in it exchanges for nothing on its own.
consent_url = consent_redirect_url(
"https://app.provider.app",
req.grant_request_id,
)
# After approval, exchange. The id alone is NOT enough.
tok = ppx.mint_token(
req.grant_request_id,
req.request_token,
pkce.verifier,
client_id="my-app",
# client_secret="…" as well, if you registered as a confidential client
)
# Use it to read scoped claims
profile = ppx.effective_profile(
context={"climate": "hot_humid"},
requested_namespaces=["fragrance"],
token=tok.access_token,
)
Async
import asyncio
from ppx_client import PpxAsyncClient, GrantRequestInput
async def main():
async with PpxAsyncClient(base_url="https://api.provider.app") as ppx:
card = await ppx.discovery_card()
print(card.name, card.supported_namespaces)
asyncio.run(main())
Grant re-use
from ppx_client import PpxGrantRevokedError
try:
fresh = ppx.refresh("my-app", cached_grant_id)
except PpxGrantRevokedError:
# Clear cache, re-run the full approval flow
cached_grant_id = None
AG-UI consent event streaming
from ppx_client import subscribe_ag_ui
for event in subscribe_ag_ui(f"https://api.provider.app/v1/ag-ui/consent/{req_id}"):
print(event["type"], event)
if event["type"] == "RUN_FINISHED":
break
Async variant: subscribe_ag_ui_async.
License
Apache-2.0.
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 ppx_client-0.1.0a2.tar.gz.
File metadata
- Download URL: ppx_client-0.1.0a2.tar.gz
- Upload date:
- Size: 20.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
311de6978c62ecc6568217ebb7ecc992165b97c68f5ca8c616623df6920b062d
|
|
| MD5 |
5b9d97599b84a6d733db44570d3b11b3
|
|
| BLAKE2b-256 |
5542c10962566f21a87f7e0104936b8ec71315a87d3890d0052d15825b133f51
|
File details
Details for the file ppx_client-0.1.0a2-py3-none-any.whl.
File metadata
- Download URL: ppx_client-0.1.0a2-py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbfa67d2125da4d2e81a3868306f3eb884bafa287978210e3543a261f95051a8
|
|
| MD5 |
bb224b35449ae50973d3ae5ab3f57f8e
|
|
| BLAKE2b-256 |
637ae3e04feccd0024a0e9a10572aedae860a29da8816a81d28c2d9aad76f3be
|