Skip to main content

Roles and permissions for Arvel — Spatie Laravel Permission v7 parity.

Project description

arvel-permission

PyPI MIT License

Roles and permissions for Arvel — a Python port of spatie/laravel-permission v7.

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).

Spatie ↔ arvel-permission

Spatie (PHP) 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.1.tar.gz (22.5 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.1-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: arvel_permission-0.6.1.tar.gz
  • Upload date:
  • Size: 22.5 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.1.tar.gz
Algorithm Hash digest
SHA256 0fe01424b527ac65ab7f0e150d123bf6f49d4cc654b11433035847df4af376ec
MD5 e264cf2274cd673e52f271271b51ab2e
BLAKE2b-256 401253577075339a10256319344a9591aa7fb91a70a5973fea74480fe861d6e3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for arvel_permission-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 70fe17ddfdecf8cd2db752e874d69731fdf57d2b42b2bd4a29761c7d75b85e64
MD5 f50b7fb6c22e544bd95394a6a2929283
BLAKE2b-256 dd27fd942f5560d35c4f3319c1706dc447bfae7a1e8366ea28a7389b287b6b0e

See more details on using hashes here.

Provenance

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