Skip to content

Commit

Permalink
feat: add pip install pycasbin (#175)
Browse files Browse the repository at this point in the history
* feat: add pip install pycasbin

Signed-off-by: stonex <[email protected]>

* fix: fix casbin-cpp url and remove pytest requirement

Signed-off-by: stonex <[email protected]>

* docs: remove the cmake install pycasbin and add pip install pycasbin module

Signed-off-by: stonex <[email protected]>
  • Loading branch information
sheny1xuan authored Dec 3, 2021
1 parent 00d8414 commit 42f6bfb
Show file tree
Hide file tree
Showing 26 changed files with 969 additions and 49 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ jobs:
- name: Configuring CMake files
id: building-files
run: |
mkdir build && cd build && cmake ..
mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release
- name: Building library
id: building-lib
run: |
cd build && cmake --build . --config Debug --target all -j 10 --
cd build && cmake --build . --config Release --target all -j 10 --
- name: Tests
id: test-lib
run: |
cd build
ctest -j10 -C Debug -T test --output-on-failure -T test --output-on-failure
ctest -j10 -C Release -T test --output-on-failure -T test --output-on-failure
- name: Cleanup
id: clean-up
run: |
Expand Down
50 changes: 23 additions & 27 deletions .github/workflows/python_binding.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,27 @@ name: Python Bindings Test
on: [push, pull_request]

jobs:
benchmark:
name: Python Bindings Test
runs-on: macos-latest
build:
strategy:
fail-fast: false
matrix:
platform: [windows-latest, macos-latest, ubuntu-latest]
python-version: ["3.6", "3.8", "3.10"]

runs-on: ${{ matrix.platform }}

steps:
- name: Checkout
id: checkout
uses: actions/checkout@v2
- name: Configuring CMake files
id: building-files
run: |
mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE:STRING=Release
- name: Building library
id: building-lib
run: |
cd build && cmake --build . --config Release --target all -j 10 --
- name: Installing pycasbin
id: installing-pycasbin
run: |
cd build && sudo cmake --build . --config Release --target install -j 10 --
- name: Run Tests
id: run-tests
run: |
cd tests/python && python3 pycasbin_test_suite.py
- name: Cleanup
id: clean-up
run: |
rm -r build
rm tests/python/pycasbin.so
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Add requirements
run: python -m pip install --upgrade wheel setuptools

- name: Build and install
run: pip install --verbose .

- name: Test
run: cd pycasbin/tests && python pycasbin_test_suite.py
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,6 @@ MigrationBackup/
cmake-build/
xcode-build/
cmake-build*/

# pip
*.egg-info
21 changes: 10 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ endif()

project(
casbin
VERSION 1.43.0
VERSION 1.44.0
DESCRIPTION "An authorization library that supports access control models like ACL, RBAC, ABAC in C/C++"
HOMEPAGE_URL https://github.com/casbin/casbin-cpp
LANGUAGES CXX C
Expand All @@ -54,7 +54,6 @@ endif()
option(CASBIN_BUILD_TEST "State whether to build test" ON)
option(CASBIN_BUILD_BENCHMARK "State whether to build benchmarks" ON)
option(INTENSIVE_BENCHMARK "State whether to build intensive benchmarks" OFF)
option(CASBIN_BUILD_BINDINGS "State whether to build language bindings" ON)
option(CASBIN_BUILD_PYTHON_BINDINGS "State whether to build python bindings" ON)
option(CASBIN_INSTALL "State whether to install casbin targets on the current system" ON)

Expand All @@ -68,15 +67,6 @@ if(NOT DEFINED CMAKE_INSTALL_MESSAGE)
set(CMAKE_INSTALL_MESSAGE "LAZY")
endif()

if(CASBIN_BUILD_BINDINGS)
add_subdirectory(bindings)
endif()

if(CASBIN_BUILD_TEST)
enable_testing()
add_subdirectory(tests)
endif()

# Change the path max size to avoid problem on Windows.
if(NOT DEFINED CMAKE_OBJECT_PATH_MAX)
set(CMAKE_OBJECT_PATH_MAX 300)
Expand All @@ -95,6 +85,15 @@ include(FindExtPackages)

add_subdirectory(casbin)

if(CASBIN_BUILD_PYTHON_BINDINGS)
add_subdirectory(pycasbin)
endif()

if(CASBIN_BUILD_TEST)
enable_testing()
add_subdirectory(tests)
endif()

if(CASBIN_INSTALL)
message(CHECK_START "[casbin]: Installing casbin ...")
export(
Expand Down
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include README.md LICENSE
graft include
graft casbin
graft pycasbin/
global-include CMakeLists.txt *.cmake
11 changes: 4 additions & 7 deletions cmake/modules/FindExtPackages.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ if(CASBIN_BUILD_TEST)
endif()
endif()

if(CASBIN_BUILD_BINDINGS)
if(CASBIN_BUILD_PYTHON_BINDINGS)
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
# pybind11
# https://github.com/pybind/pybind11
find_package(pybind11 2.7.0 REQUIRED)
endif()
if(CASBIN_BUILD_PYTHON_BINDINGS)
# pybind11
# https://github.com/pybind/pybind11
find_package(pybind11 2.8.0 REQUIRED)
endif()
2 changes: 1 addition & 1 deletion cmake/modules/Findpybind11.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ include(FetchContent)
FetchContent_Declare(
pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG v2.7.1
GIT_TAG v2.8.0
)

FetchContent_MakeAvailable(pybind11)
Expand Down
55 changes: 55 additions & 0 deletions pycasbin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2021 The casbin Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set(SOURCES
src/main.cpp
src/py_cached_enforcer.cpp
src/py_enforcer.cpp
src/py_model.cpp
src/py_config.cpp
src/py_synced_enforcer.cpp
src/py_adapter.cpp
)

set(HEADERS
src/py_casbin.h
)

add_library(pycasbin MODULE ${SOURCES} ${HEADERS})

target_include_directories(pycasbin PUBLIC ${CASBIN_INCLUDE_DIR})

set_target_properties(pycasbin PROPERTIES
CXX_STANDARD 17
)

# For in-source versioning macro
add_definitions(-DPY_CASBIN_VERSION=${PY_CASBIN_VERSION})

target_link_libraries(pycasbin
PRIVATE
pybind11::module
pybind11::lto
pybind11::windows_extras
casbin
nlohmann_json::nlohmann_json
)

pybind11_extension(pycasbin)
pybind11_strip(pycasbin)
# For testing
# install(
# TARGETS pycasbin
# LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/tests/python
# )
107 changes: 107 additions & 0 deletions pycasbin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## Language Bindings for `casbin-cpp`

At present, `casbin-cpp` provides language bindings for Python, we named it `pycasbin`.

## Python Bindings

### Use `pip` install the `pycasbin` module

It is assumed you have `CMake >=v3.19` and `Python >= 3.6` installed. Current `pycasbin` only support `pip` install in local machine.

1. Clone/download the project:
```bash
git clone https://github.com/casbin/casbin-cpp.git
```

2. Update `wheel setuptools`:
```bash
python -m pip install --upgrade wheel setuptools
```

3. Install the `pycasbin` module:
```bash
cd casbin-cpp && pip install --verbose .
```

Now, you're ready to go!
### Usage
It is assumed that you have `pycasbin` module correctly installed on your system.
First, we import the `pycasbin` module to a python source file:
```python
import pycasbin as casbin
```
Suppose we want a function to check authorization of a request:
```python
def isAuthorized(req):
result = True
if result:
print('Authorized')
else
print('Not authorized!')
```
Here, the request can be a list or a dictionary in the forms:
```python
req = ['subject1', 'object1', 'action1'] # and so on..
req = {
"sub": "subject1",
"obj": "object1",
"act": "action1" # ... and so on
}
```
We can Enforce this request (or compute the `result` of this request) through `casbin.Enforce()`.
For that, we need to create a `casbin.Enforcer`:
```python
e = casbin.Enforcer('path/to/model.conf', 'path/to/policy.csv')
```
Make sure that the paths are relative to the current python source file or an absolute path.
Apart from the regular `Enforcer`, you may also use `CachedEnforcer`
depending on your use case.
Incorporating the `Enforcer` in our example gives us:
```python
def isAuthorized(req):
result = e.Enforce(req)
if result:
print('Authorized')
else
print('Not authorized!')
```
Rest of the method's name is on par with `casbin-cpp`.

#### Summary

This sums up the basic usage of `pycasbin` module:

```python
import pycasbin as casbin
e = casbin.Enforcer('path/to/model.conf', 'path/to/policy.csv')
def isAuthorized(req):
result = e.Enforce(req)
if result:
print('Authorized')
else
print('Not authorized!')
isAuthorized(['subject1', 'object1', 'action1'])
isAuthorized(['subject2', 'object2', 'action2'])
# ... and so on
```
If you've done everything right, you'll see your output
without any errors.
45 changes: 45 additions & 0 deletions pycasbin/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2021 The casbin Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This is the main file for python bindings workflow
*/

#include <pybind11/pybind11.h>
#include "py_casbin.h"

namespace py = pybind11;

PYBIND11_MODULE(pycasbin, m) {
m.doc() = R"pbdoc(
Casbin Authorization Library
-----------------------
.. currentmodule:: pycasbin
.. autosummary::
:toctree: _generate
Enforcer
)pbdoc";

bindPyEnforcer(m);
bindPyCachedEnforcer(m);
bindPyModel(m);
bindPyConfig(m);
bindPySyncedEnforcer(m);
bindPyAdapter(m);

m.attr("__version__") = PY_CASBIN_VERSION;
}
Loading

0 comments on commit 42f6bfb

Please sign in to comment.