{"id":4184,"library":"pycasbin","title":"PyCasbin","description":"PyCasbin is a powerful and efficient open-source authorization library for Python projects (currently v2.8.0). It supports enforcing access control based on various models like ACL, RBAC, and ABAC. The library is actively maintained with frequent updates and aims for feature parity across its different language implementations.","status":"active","version":"2.8.0","language":"en","source_language":"en","source_url":"https://github.com/apache/casbin-pycasbin","tags":["authorization","access-control","rbac","abac","acl","security"],"install":[{"cmd":"pip install pycasbin","lang":"bash","label":"Install PyCasbin"}],"dependencies":[],"imports":[{"note":"The primary class `Enforcer` is accessed directly via the `casbin` top-level package, not `pycasbin`.","wrong":"from pycasbin import Enforcer","symbol":"Enforcer","correct":"import casbin\nenforcer = casbin.Enforcer(...)"},{"note":"For thread-safe operations in multi-threaded applications, use `SyncedEnforcer`.","symbol":"SyncedEnforcer","correct":"from casbin import SyncedEnforcer"},{"note":"Asynchronous operations are supported from PyCasbin >= 1.23.0. The `Enforcer` class itself can act as an async enforcer, or `AsyncEnforcer` can be imported explicitly.","symbol":"AsyncEnforcer","correct":"from casbin.enforcer import Enforcer as AsyncEnforcer\n# or\nfrom casbin.enforcer import AsyncEnforcer # if using direct import and not renaming"}],"quickstart":{"code":"import casbin\nimport os\n\n# Create dummy model and policy files for the example\nwith open('model.conf', 'w') as f:\n    f.write('''\n[request_definition]\nr = sub, obj, act\n\n[policy_definition]\np = sub, obj, act\n\n[policy_effect]\ne = some(where (p.eft == allow))\n\n[matchers]\nm = r.sub == p.sub && r.obj == p.obj && r.act == p.act\n''')\n\nwith open('policy.csv', 'w') as f:\n    f.write('''\np, alice, data1, read\np, bob, data2, write\np, data2_admin, data2, *\n''')\n\nasync def run_enforcer():\n    # Initialize an enforcer with a model file and a policy file\n    # For real applications, use an adapter (e.g., casbin_sqlalchemy_adapter)\n    e = casbin.Enforcer('model.conf', 'policy.csv')\n\n    # Test if 'alice' can 'read' 'data1'\n    if await e.enforce('alice', 'data1', 'read'):\n        print(\"Alice CAN read data1\")\n    else:\n        print(\"Alice CANNOT read data1\")\n\n    # Test if 'bob' can 'read' 'data2'\n    if await e.enforce('bob', 'data2', 'read'):\n        print(\"Bob CAN read data2\")\n    else:\n        print(\"Bob CANNOT read data2\")\n\n    # Test if 'bob' can 'write' 'data2'\n    if await e.enforce('bob', 'data2', 'write'):\n        print(\"Bob CAN write data2\")\n    else:\n        print(\"Bob CANNOT write data2\")\n\n    # Add a policy dynamically\n    await e.add_policy('cathy', 'data3', 'read')\n    if await e.enforce('cathy', 'data3', 'read'):\n        print(\"Cathy CAN read data3 (after adding policy)\")\n\n    # Remove temporary files\n    os.remove('model.conf')\n    os.remove('policy.csv')\n\nif __name__ == '__main__':\n    import asyncio\n    asyncio.run(run_enforcer())","lang":"python","description":"This quickstart demonstrates how to initialize `casbin.Enforcer` with a model (`.conf`) and policy (`.csv`) file, and then use the `enforce()` method to check permissions. It also shows a dynamic policy addition. Note the use of `asyncio.run` as the `enforce` method is asynchronous."},"warnings":[{"fix":"Consult the official changelog and documentation on GitHub for details when upgrading from PyCasbin v1.x to v2.x.","message":"Version 2.0.0 introduced breaking changes. While specific API changes are not fully detailed in the public changelog, a major version bump indicates potential incompatibilities. Users upgrading from v1.x should review the changelog for any necessary adaptations.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"For performance-critical applications with extensive policies, consider benchmarking or evaluating `Go-Casbin` via its FFI or gRPC interfaces if raw speed is paramount, or carefully design policies to minimize complexity.","message":"Performance differences: The Python implementation of Casbin (`PyCasbin`) can be significantly slower (up to 30x in some cases) than its Go counterpart (`Go-Casbin`) when dealing with large or complex policy sets. This is primarily due to differences in the underlying expression evaluation engines.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Initialize your application's logger before importing `casbin` or explicitly configure logging for the `casbin` logger (`logging.getLogger('casbin')`) to avoid conflicts or ensure messages are captured. Use the `logging_config` parameter during enforcer initialization if specific logging settings are required for `pycasbin`.","message":"Logging configuration: PyCasbin uses Python's standard `logging` module. If an application sets up its own logger, this can lead to duplicate log messages or prevent PyCasbin's logs from appearing if the application's logging is not correctly configured to handle it.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always ensure array literals used with the `in` operator contain at least two elements if this specific syntax is causing issues, or consult the Casbin model syntax documentation for your specific implementation details to ensure correct usage.","message":"ABAC `in` operator behavior: When using the `in` operator in matchers for Attribute-Based Access Control (ABAC) with array literals (e.g., `r.obj in ('data2', 'data3')`), some Casbin implementations across languages might have specific requirements, such as the array length being greater than one to avoid unexpected behavior or panics. Ensure your array literals are well-formed and test thoroughly.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}