Bitwise Toolbox
from bitaware import BitFlag, BitAware
class PermissionTypes(BitFlag):
READ = 1
CREATE = 2
EDIT = 4
ADMIN = 8
class UserPermission(BitAware[PermissionTypes]):
def __init__(self, value: int):
super().__init__(value, PermissionTypes)
pass
# "User Roles" Named sets can be used interchangeably
READER = PermissionTypes.READ
CREATOR = PermissionTypes.CREATE | PermissionTypes.READ
EDITOR = PermissionTypes.EDIT | PermissionTypes.READStandalone:
permission = UserPermission(PermissionTypes.ADMIN | PermissionTypes.READ)
print(permission.has(PermissionTypes.ADMIN)) # True
print(permission.has(PermissionTypes.CREATE)) # FalseAs Pydantic field:
class User(BaseModel):
name: str
permissions: UserPermissionUsage
user = User(name="test_user", permissions=UserPermission.READER)
admin = User(name="admin_user", permissions=PermissionTypes.READ | PermissionTypes.ADMIN)
print(user.model_dump_json(indent=2))Above code will print:
{
"name": "test_user",
"permissions": 1
}x = UserPermission(12)
print(str(x)) # EDIT|ADMIN [EDIT, ADMIN]
print(repr(x)) # UserPermission(PermissionTypes.EDIT | PermissionTypes.ADMIN)
print(list(x)) # [<PermissionTypes.EDIT: 4>, <PermissionTypes.ADMIN: 8>]For predefined named flag set:
x = UserPermission(UserPermission.CREATOR)
print(str(x)) # CREATOR [READ, CREATE]
print(repr(x)) # UserPermission(PermissionTypes.READ | PermissionTypes.CREATE)
print(list(x)) # [<PermissionTypes.READ: 1>, <PermissionTypes.CREATE: 2>]Predefined named flag sets:
print(UserPermission.properties()) # {<PermissionTypes.READ|CREATE: 3>: 'CREATOR', <PermissionTypes.READ|EDIT: 5>: 'EDITOR', <PermissionTypes.READ: 1>: 'READER'}uv run pytestIf you discover any security-related issues, please email email instead of using the issue tracker.
Copyright (c) 2025 Wojciech Nowicki