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.3.tar.gz (22.9 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.3-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: arvel_permission-0.6.3.tar.gz
  • Upload date:
  • Size: 22.9 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.3.tar.gz
Algorithm Hash digest
SHA256 e2e58b3cda1f92920f505fc5147c2a005880e28f00fd61774e19b92eb7041461
MD5 9fa4c9971070a89e84503056529b2cbc
BLAKE2b-256 bf04d2468dd167910818f1a03ebb49365a635aef9eff3111bae496e03a2eddd1

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for arvel_permission-0.6.3-py3-none-any.whl
Algorithm Hash digest
SHA256 476ac19a18c5c81e28257e0ee7831949577cda3c6529deaa10e9e5ef8884c4bc
MD5 8719803d6c968d9146c1345001e603b0
BLAKE2b-256 34e8ea8bc2fe1ed9f9d058a80749429df5786b9f49f370f5c42c04941175b0bb

See more details on using hashes here.

Provenance

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