Skip to main content

Roles and permissions for Arvel — async-first authorization with HasRoles / HasPermissions mixins.

Project description

arvel-permission

PyPI MIT License

Roles and permissions for Arvel. Adds Role and Permission models, HasRoles / HasPermissions mixins for your user model, route middleware, and a bridge into the authorization Gate.

Status: Pre-alpha.


Documentation: https://arvel.dev/packages/permission


Install

uv add arvel-permission
# or: pip install arvel-permission

Register the provider in bootstrap/providers.py:

from arvel_permission import PermissionServiceProvider

providers = [
    # ...other providers...
    PermissionServiceProvider,
]

Run the migration (adds roles, permissions, model_has_roles, model_has_permissions, and role_has_permissions):

arvel migrate

Make a model role-aware

Mix in HasRoles and HasPermissions, and wire the polymorphic relations:

from typing import ClassVar

from arvel.database import Model, id_
from arvel.database.orm import MorphToMany
from arvel_permission import (
    HasRoles, HasPermissions, Role, Permission,
    model_has_roles, model_has_permissions,
)


class User(Model, HasRoles, HasPermissions):
    __tablename__ = "users"
    id: int = id_(init=False)
    default_guard_name: ClassVar[str] = "web"

    roles: ClassVar[MorphToMany[Role]] = MorphToMany(
        Role, table=model_has_roles, name="model", related_key="role_id"
    )
    permissions: ClassVar[MorphToMany[Permission]] = MorphToMany(
        Permission, table=model_has_permissions, name="model", related_key="permission_id"
    )

All trait methods are async and need an active DB session in scope. In a request that's set up for you; in scripts and tests, run them inside the framework's session context.

Assign and check

await user.assign_role("editor")
await user.give_permission_to("posts.publish")

await user.has_role("editor")              # -> bool
await user.has_any_role("editor", "admin")
await user.has_permission_to("posts.publish")
names = await user.get_role_names()

Other methods: remove_role, sync_roles, has_all_roles, has_level, revoke_permission_to, sync_permissions, get_all_permissions, get_direct_permissions, get_permissions_via_roles.

Permissions resolve through roles automatically — has_permission_to is true when the user holds the permission directly or via any assigned role. With wildcard_enabled (the default), a held posts.* satisfies a check for posts.edit.

Route middleware

The package ships three middleware classes. Register them yourself — the provider does not wire them:

from arvel_permission import RoleMiddleware, PermissionMiddleware, RoleOrPermissionMiddleware

RoleMiddleware("admin")
PermissionMiddleware("posts.publish")
RoleOrPermissionMiddleware("admin|posts.publish")   # pipe = OR

A failed check raises UnauthorizedException, which the framework's default handler turns into a 401 (unauthenticated) or 403 (unauthorized) response.

Gate integration

When PermissionServiceProvider boots and a Gate is bound, it registers a before hook so await gate.allows("posts.edit", user) resolves through the user's permissions. If no Gate is bound, this is skipped silently — no manual wiring needed.

Configuration

PermissionConfig is a frozen model — there are no environment variables. Override defaults by setting the provider's config before boot:

from arvel_permission import PermissionConfig, PermissionServiceProvider


class AppPermissionProvider(PermissionServiceProvider):
    config = PermissionConfig(default_guard_name="api", wildcard_enabled=True)

Notable fields: default_guard_name (web), cache_enabled (true), wildcard_enabled (true), events_enabled (false), cache_ttl (86400).

API at a glance

The HasRoles and HasPermissions mixins expose snake_case Python equivalents of the camelCase methods Laravel devs are used to:

Camel-case (PHP convention) arvel-permission (Python)
assignRole assign_role
removeRole remove_role
syncRoles sync_roles
hasRole has_role
hasAnyRole has_any_role
hasAllRoles has_all_roles
givePermissionTo give_permission_to
revokePermissionTo revoke_permission_to
syncPermissions sync_permissions
hasPermissionTo has_permission_to
getAllPermissions get_all_permissions
getRoleNames get_role_names

License

MIT — see LICENSE.

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

arvel_permission-0.6.5.tar.gz (24.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

arvel_permission-0.6.5-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file arvel_permission-0.6.5.tar.gz.

File metadata

  • Download URL: arvel_permission-0.6.5.tar.gz
  • Upload date:
  • Size: 24.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for arvel_permission-0.6.5.tar.gz
Algorithm Hash digest
SHA256 1649b4a4a541f555d8532d54b7bac48de0720f62abe4f36c939aa573820ef295
MD5 41f60e8a8cbe642355331cf1f4cd8cbc
BLAKE2b-256 75c060892a8027d1f4d1b5f4d95b8a01a87e9001b78f1b3b0276245923e2760f

See more details on using hashes here.

Provenance

The following attestation bundles were made for arvel_permission-0.6.5.tar.gz:

Publisher: publish.yml on mohamed-rekiba/arvel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file arvel_permission-0.6.5-py3-none-any.whl.

File metadata

File hashes

Hashes for arvel_permission-0.6.5-py3-none-any.whl
Algorithm Hash digest
SHA256 3bf56f53e20dd1f6b5a8317a0f86404eadc50c16588e58712d71b52905d2a3c5
MD5 039612ac9fef43050c358ad79c48af8c
BLAKE2b-256 252751ff8a2c3fc092438b08ea1003c5c4b07e39290b046123bcd191b1ef2f3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for arvel_permission-0.6.5-py3-none-any.whl:

Publisher: publish.yml on mohamed-rekiba/arvel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page