From 2d8c86acb274690528abd3496df1407d5792bd80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Medina?= Date: Mon, 10 Aug 2020 18:23:57 +0100 Subject: [PATCH 1/4] Define algorithms submodule --- src/bindings/PyDP/bindings.cpp | 5 +++-- src/bindings/PyDP/pydp_lib/algorithm_builder.hpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bindings/PyDP/bindings.cpp b/src/bindings/PyDP/bindings.cpp index 4d98bfc4..d83ef71c 100644 --- a/src/bindings/PyDP/bindings.cpp +++ b/src/bindings/PyDP/bindings.cpp @@ -37,12 +37,13 @@ PYBIND11_MODULE(pydp, m) { init_base_percentile(m); // Algorithms - init_algorithms_bounded_functions(m); + auto malgorithms = m.def_submodule("algorithms"); + init_algorithms_bounded_functions(malgorithms); init_algorithms_util(m); init_algorithms_distributions(m); init_algorithms_order_statistics(m); init_algorithms_rand(m); - init_algorithms_count(m); + init_algorithms_count(malgorithms); // Proto init_proto(m); diff --git a/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp b/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp index 8c27d294..bbfec101 100644 --- a/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp +++ b/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp @@ -73,7 +73,7 @@ class AlgorithmBuilder { void declare(py::module& m) { py::class_ pyself(m, get_algorithm_name().c_str()); - pyself.attr("__module__") = "pydp"; + pyself.attr("__module__") = "algorithm"; // Constructors if constexpr (is_bounded_algorithm()) { From c729da623709ffdc1124a1ee22dde85b16904b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Medina?= Date: Mon, 10 Aug 2020 22:36:28 +0100 Subject: [PATCH 2/4] Start defining new Python API --- pydp/__init__.py | 2 +- pydp/algorithms/__init__.py | 16 ++++++++++++++++ src/bindings/PyDP/bindings.cpp | 2 +- src/bindings/PyDP/pydp_lib/algorithm_builder.hpp | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 pydp/algorithms/__init__.py diff --git a/pydp/__init__.py b/pydp/__init__.py index f0491e47..745d6fc8 100644 --- a/pydp/__init__.py +++ b/pydp/__init__.py @@ -1,3 +1,3 @@ -from .pydp import * +from pydp import algorithms __version__ = "0.1.4" diff --git a/pydp/algorithms/__init__.py b/pydp/algorithms/__init__.py new file mode 100644 index 00000000..031b83ac --- /dev/null +++ b/pydp/algorithms/__init__.py @@ -0,0 +1,16 @@ +__all__ = ["Count"] + + +class Count: + def __init__(self, epsilon=1.0, dtype="int"): + from ..pydp import _algorithms + + if dtype == "int": + self.__algorithm = _algorithms.CountInt(epsilon) + elif dtype == "float": + self.__algorithm = _algorithms.CountDouble(epsilon) + else: + raise RuntimeError(f"dtype: {dtype} is not supported") + + def result(self, list): + return self.__algorithm.result(list) diff --git a/src/bindings/PyDP/bindings.cpp b/src/bindings/PyDP/bindings.cpp index d83ef71c..34a32e9a 100644 --- a/src/bindings/PyDP/bindings.cpp +++ b/src/bindings/PyDP/bindings.cpp @@ -37,7 +37,7 @@ PYBIND11_MODULE(pydp, m) { init_base_percentile(m); // Algorithms - auto malgorithms = m.def_submodule("algorithms"); + auto malgorithms = m.def_submodule("_algorithms"); init_algorithms_bounded_functions(malgorithms); init_algorithms_util(m); init_algorithms_distributions(m); diff --git a/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp b/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp index bbfec101..fe9cf0ce 100644 --- a/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp +++ b/src/bindings/PyDP/pydp_lib/algorithm_builder.hpp @@ -73,7 +73,7 @@ class AlgorithmBuilder { void declare(py::module& m) { py::class_ pyself(m, get_algorithm_name().c_str()); - pyself.attr("__module__") = "algorithm"; + pyself.attr("__module__") = "_algorithms"; // Constructors if constexpr (is_bounded_algorithm()) { From d0f8ce3cf7dd6d0292de116b013f19582882a7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Medina?= Date: Wed, 12 Aug 2020 16:53:07 +0100 Subject: [PATCH 3/4] Rename pydp.so to _pydp.so --- .github/workflows/pypipublish_linux.yml | 6 +++--- .github/workflows/pypipublish_osx.yml | 8 ++++---- .gitignore | 2 +- build_PyDP.sh | 4 ++-- pydp/__init__.py | 2 +- setup.py | 2 +- src/bindings/BUILD | 2 +- src/bindings/PyDP/bindings.cpp | 2 +- src/python/BUILD | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/pypipublish_linux.yml b/.github/workflows/pypipublish_linux.yml index 4c258693..f96cafe3 100644 --- a/.github/workflows/pypipublish_linux.yml +++ b/.github/workflows/pypipublish_linux.yml @@ -19,7 +19,7 @@ jobs: cd third_party/differential-privacy git checkout 0b0a5c2315d84a6a7b1ff34591e33ec11680891e cd - - rm -rf third_party/differential-privacy/java + rm -rf third_party/differential-privacy/java rm -rf third_party/differential-privacy/examples/java - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 @@ -55,8 +55,8 @@ jobs: - name: Build pydp lib run: | bazel build src/python:bindings_test --verbose_failures - rm -f pydp.so - cp -f ./bazel-bin/src/bindings/pydp.so ./pydp + rm -f _pydp.so + cp -f ./bazel-bin/src/bindings/_pydp.so ./pydp - name: Build wheel run: | diff --git a/.github/workflows/pypipublish_osx.yml b/.github/workflows/pypipublish_osx.yml index 2534ce64..dc647714 100644 --- a/.github/workflows/pypipublish_osx.yml +++ b/.github/workflows/pypipublish_osx.yml @@ -19,7 +19,7 @@ jobs: cd third_party/differential-privacy git checkout 0b0a5c2315d84a6a7b1ff34591e33ec11680891es cd - - rm -rf third_party/differential-privacy/java + rm -rf third_party/differential-privacy/java rm -rf third_party/differential-privacy/examples/java - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 @@ -36,8 +36,8 @@ jobs: - name: Build pydp lib run: | bazel build src/python:bindings_test --verbose_failures - rm -f pydp.so - cp -f ./bazel-bin/src/bindings/pydp.so ./pydp + rm -f _pydp.so + cp -f ./bazel-bin/src/bindings/_pydp.so ./pydp - name: Build wheel @@ -49,4 +49,4 @@ jobs: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.TOKEN }} run: | - twine upload --skip-existing dist/*.whl \ No newline at end of file + twine upload --skip-existing dist/*.whl diff --git a/.gitignore b/.gitignore index 93312cf7..3f031637 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -pydp.so +_pydp.so # bazel files bazel-bin bazel-out diff --git a/build_PyDP.sh b/build_PyDP.sh index fee7b2ca..3227b180 100755 --- a/build_PyDP.sh +++ b/build_PyDP.sh @@ -2,5 +2,5 @@ pipenv install --dev --skip-lock bazel build src/python:bindings_test --verbose_failures -find ./ -name pydp.so -print0 | xargs -0 -I {} rm {} -cp -f ./bazel-bin/src/bindings/pydp.so ./pydp +find ./ -name _pydp.so -print0 | xargs -0 -I {} rm {} +cp -f ./bazel-bin/src/bindings/_pydp.so ./pydp diff --git a/pydp/__init__.py b/pydp/__init__.py index 745d6fc8..c1431116 100644 --- a/pydp/__init__.py +++ b/pydp/__init__.py @@ -1,3 +1,3 @@ -from pydp import algorithms +from ._pydp import * __version__ = "0.1.4" diff --git a/setup.py b/setup.py index 6ecd57b6..89ddb1ca 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ def read(fname): include_package_data=True, keywords="pydp", name="python-dp", - package_data={"pydp": ["pydp.so"],}, + package_data={"_pydp": ["_pydp.so"],}, packages=find_packages(exclude=["tests"]), # need to check this setup_requires=setup_requirements, test_suite="tests", diff --git a/src/bindings/BUILD b/src/bindings/BUILD index 3fa8691d..df8a4616 100644 --- a/src/bindings/BUILD +++ b/src/bindings/BUILD @@ -1,7 +1,7 @@ load("@pybind11_bazel//:build_defs.bzl", "pybind_extension") pybind_extension( - name = "pydp", + name = "_pydp", srcs = glob([ "PyDP/*.cpp", "PyDP/base/*.cpp", diff --git a/src/bindings/PyDP/bindings.cpp b/src/bindings/PyDP/bindings.cpp index 34a32e9a..c460e7c8 100644 --- a/src/bindings/PyDP/bindings.cpp +++ b/src/bindings/PyDP/bindings.cpp @@ -28,7 +28,7 @@ void init_algorithms_rand(py::module &); // proto void init_proto(py::module &); -PYBIND11_MODULE(pydp, m) { +PYBIND11_MODULE(_pydp, m) { m.doc() = "Google Differential Privacy python extension"; // Base diff --git a/src/python/BUILD b/src/python/BUILD index ad4cae3d..2dfadd94 100644 --- a/src/python/BUILD +++ b/src/python/BUILD @@ -4,5 +4,5 @@ py_binary( name = "bindings_test", srcs = ["__init__.py"], main = "__init__.py", - data = ["//src/bindings:pydp.so"] + data = ["//src/bindings:_pydp.so"] ) From 537032fb02bac00f282de636a7dd1e3260354d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Medina?= Date: Wed, 12 Aug 2020 17:23:42 +0100 Subject: [PATCH 4/4] Update Python API --- pydp/__init__.py | 2 ++ pydp/algorithms/__init__.py | 17 ++--------------- pydp/algorithms/laplacian/__init__.py | 3 +++ pydp/algorithms/laplacian/count.py | 21 +++++++++++++++++++++ 4 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 pydp/algorithms/laplacian/__init__.py create mode 100644 pydp/algorithms/laplacian/count.py diff --git a/pydp/__init__.py b/pydp/__init__.py index c1431116..8f2ec341 100644 --- a/pydp/__init__.py +++ b/pydp/__init__.py @@ -1,3 +1,5 @@ from ._pydp import * +from pydp import algorithms + __version__ = "0.1.4" diff --git a/pydp/algorithms/__init__.py b/pydp/algorithms/__init__.py index 031b83ac..afc01e21 100644 --- a/pydp/algorithms/__init__.py +++ b/pydp/algorithms/__init__.py @@ -1,16 +1,3 @@ -__all__ = ["Count"] +from . import laplacian - -class Count: - def __init__(self, epsilon=1.0, dtype="int"): - from ..pydp import _algorithms - - if dtype == "int": - self.__algorithm = _algorithms.CountInt(epsilon) - elif dtype == "float": - self.__algorithm = _algorithms.CountDouble(epsilon) - else: - raise RuntimeError(f"dtype: {dtype} is not supported") - - def result(self, list): - return self.__algorithm.result(list) +__all__ = ["laplacian"] diff --git a/pydp/algorithms/laplacian/__init__.py b/pydp/algorithms/laplacian/__init__.py new file mode 100644 index 00000000..4faab78d --- /dev/null +++ b/pydp/algorithms/laplacian/__init__.py @@ -0,0 +1,3 @@ +from .count import Count + +__all__ = ["Count"] diff --git a/pydp/algorithms/laplacian/count.py b/pydp/algorithms/laplacian/count.py new file mode 100644 index 00000000..38bc31d1 --- /dev/null +++ b/pydp/algorithms/laplacian/count.py @@ -0,0 +1,21 @@ +from ..._pydp import _algorithms + + +def map_type_str(type): + if type == "int": + return "Int" + elif type == "float": + return "Double" + else: + raise RuntimeError(f"dtype: {dtype} is not supported") + + +class Count: + def __init__(self, epsilon=1.0, dtype="int"): + class_ = getattr(_algorithms, f"Count{map_type_str(dtype)}") + + self.dtype = dtype + self.__algorithm = class_(epsilon) + + def result(self, list): + return self.__algorithm.result(list)