Target-generic reviews and ratings for the Stapel framework
Project description
stapel-reviews
Target-generic reviews and ratings for the Stapel framework — composable Django apps that deploy as a monolith or as microservices without changing module code.
A generic review core — Review (author + rating + body about an opaque target) and Response (the target owner's reply) — driven entirely by a per-target-type policy registry. The module ships knowing nothing about what gets reviewed: a host registers its target types (a seller, a listing, a driver, a course), each with a policy, and answers the domain questions — "may this author review?", "who owns this target?" — through comm Function callbacks, so the module never imports a host model.
Install
pip install stapel-reviews
INSTALLED_APPS = [
# ...
"stapel_reviews",
]
# urls.py
path("reviews/", include("stapel_reviews.urls"))
Concepts
- Target — opaque:
target_type(a key the host registered) +target_key(an opaque host string — a UUID, a slug, a composite). No FK to any host model; the module is domain-blind. - Policy — per target type: who may review (
can_reviewcomm callback), pre/post moderation, one-review-per-author, whether owner responses are allowed (allow_response), who may moderate/respond (can_moderatecomm callback). - Aggregate — the module owns
avg/countover published reviews per target, and emits a generic fact carrying it on every visibility change, so a host catalog maintains its own rating projection (§10) without calling back.
STAPEL_REVIEWS = {
"TARGET_TYPES": {
"seller": {
"can_review": "marketplace.buyer_of_seller", # host comm Function
"can_moderate": "marketplace.is_seller_owner",
"moderation": "post",
"one_per_author": True,
"allow_response": True,
},
"listing": {"moderation": "pre"},
},
}
from stapel_reviews import services
review = services.create_review(
target_type="seller", target_key="s-42", author=user, rating=5, body="great",
)
services.moderate_review(review, actor=owner, action="hide", reason="spam")
services.respond(review, author=owner, body="thanks for the feedback")
agg = services.aggregate("seller", "s-42") # Aggregate(avg=..., count=...)
Settings
All configuration lives in the STAPEL_REVIEWS namespace (dict setting, flat
setting, or env var — resolved lazily):
| Key | Default | Meaning |
|---|---|---|
TARGET_TYPES |
{} |
The target-type registry {type: policy}, merged over the (empty) built-ins; None removes a type |
MODERATION_DEFAULT |
"post" |
Default moderation mode (post/pre) for types that don't override it |
RESPONSES |
True |
Whether owner responses are allowed by default |
RATING_MIN |
1 |
Inclusive minimum rating |
RATING_MAX |
5 |
Inclusive maximum rating |
comm surface
| Kind | Name | Contract |
|---|---|---|
| Emit | reviews.review.published |
A review became visible — carries {aggregate: {avg, count}} for the host projection |
| Emit | reviews.review.hidden |
A review left the visible set — carries the updated aggregate |
| Function | reviews.aggregate |
{target_type, target_key} -> {avg, count} |
| Callback (host) | policy can_review |
{author_id, target_type, target_key} -> bool — the host answers |
| Callback (host) | policy can_moderate |
{actor_id, target_type, target_key} -> bool — the host answers |
Extension points
See MODULE.md — the agent-facing map of every fork-free seam (the TARGET_TYPES registry and its policy callbacks, the projection emits, the aggregate Function, serializer seams, settings).
Development
pip install -e . && pip install pytest pytest-django ruff
./setup-hooks.sh
pytest tests/
License
MIT
Project details
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 stapel_reviews-0.1.3.tar.gz.
File metadata
- Download URL: stapel_reviews-0.1.3.tar.gz
- Upload date:
- Size: 36.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84621dabc770e7114b675ab61b9a66791c81e26915a6a2f8150c969a2ca669b9
|
|
| MD5 |
f7899ac3b444c87920112cbee487b69b
|
|
| BLAKE2b-256 |
aa1c9992f0a593e75921ddb47a32243f72ac7371a007d21597034d183dac064b
|
Provenance
The following attestation bundles were made for stapel_reviews-0.1.3.tar.gz:
Publisher:
publish.yml on usestapel/stapel-reviews
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stapel_reviews-0.1.3.tar.gz -
Subject digest:
84621dabc770e7114b675ab61b9a66791c81e26915a6a2f8150c969a2ca669b9 - Sigstore transparency entry: 2187996848
- Sigstore integration time:
-
Permalink:
usestapel/stapel-reviews@7920e6bf6174a2c32a4306ac8ece76cec49b6d56 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/usestapel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7920e6bf6174a2c32a4306ac8ece76cec49b6d56 -
Trigger Event:
push
-
Statement type:
File details
Details for the file stapel_reviews-0.1.3-py3-none-any.whl.
File metadata
- Download URL: stapel_reviews-0.1.3-py3-none-any.whl
- Upload date:
- Size: 35.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b3e2a058cff38b6f71bdf35b9d6e3de01d2863f2b7e5661e26628078d67961e
|
|
| MD5 |
6d6844dfa4917f522be3074784fecee7
|
|
| BLAKE2b-256 |
635a56cc6a7b83653fdc248d74069b7cbf5b21f27ab5f1fb7a0622988c1f9d6d
|
Provenance
The following attestation bundles were made for stapel_reviews-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on usestapel/stapel-reviews
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stapel_reviews-0.1.3-py3-none-any.whl -
Subject digest:
9b3e2a058cff38b6f71bdf35b9d6e3de01d2863f2b7e5661e26628078d67961e - Sigstore transparency entry: 2187996871
- Sigstore integration time:
-
Permalink:
usestapel/stapel-reviews@7920e6bf6174a2c32a4306ac8ece76cec49b6d56 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/usestapel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7920e6bf6174a2c32a4306ac8ece76cec49b6d56 -
Trigger Event:
push
-
Statement type: