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.2.tar.gz (22.7 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.2-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: arvel_permission-0.6.2.tar.gz
  • Upload date:
  • Size: 22.7 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.2.tar.gz
Algorithm Hash digest
SHA256 9366a1c6038768b2305c567d67b41275274b4b9aa54b4e79368b226fd6edc72a
MD5 4fa0115e3efa48569a0e7d54fa6faa3f
BLAKE2b-256 e17d9a2f983c57f18c1df89029cd51254e078f57f7a6daa4cadaecebd04aa19e

See more details on using hashes here.

Provenance

The following attestation bundles were made for arvel_permission-0.6.2.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.2-py3-none-any.whl.

File metadata

File hashes

Hashes for arvel_permission-0.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 324293fdaa5e48af9d927628c7c9f9a041ad42e33f7d64f70b5b978a7bd05bbb
MD5 385e9f65225d3e01876ef74ad3e77a67
BLAKE2b-256 2305fb77663708242f6e0607286819e0aead6d89052b72540b222ade58e750e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for arvel_permission-0.6.2-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