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 — v0.3.0.


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

Uploaded Python 3

File details

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

File metadata

  • Download URL: arvel_permission-0.5.0.tar.gz
  • Upload date:
  • Size: 22.3 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.5.0.tar.gz
Algorithm Hash digest
SHA256 aab6fd17c13774d6e664ac8145e185b06d8d9d978da65247da7f08c4ce4b5d98
MD5 94254e71c9ee9871404110034cdf49aa
BLAKE2b-256 70f2e4564440fd1c7e72142a92d759b698060c9331c413474b00073964146f79

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for arvel_permission-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c36b5264a6090f22678666e7c4668b4602d79ba5919dd454934c88f2315767be
MD5 2be63c343e62658e2b9b53ca1b8432d4
BLAKE2b-256 9aceae1c2661b62a1ad88e0af8dd9d92a89c39848ab2537e71ce757536ce5655

See more details on using hashes here.

Provenance

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