diff --git a/.github/workflows/CD.yml b/.github/workflows/CD.yml index fc3f3bf4..9b7a2960 100644 --- a/.github/workflows/CD.yml +++ b/.github/workflows/CD.yml @@ -130,7 +130,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04, macos-14] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4d138694..0120715e 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -122,7 +122,7 @@ jobs: os: [ubuntu-24.04, macos-14] # Bazel uses hermetic python, these are just placeholders - python-version: ['3_8', '3_9', '3_10', '3_11'] + python-version: ['3_8', '3_9', '3_10', '3_11', '3_12'] steps: - uses: actions/checkout@v4 # configuring python for bazel abi and platform repo rules diff --git a/CHANGES.md b/CHANGES.md index a6c5aa20..f258bbf3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +# Version 2.0.5 + +Feat: + +- Add support for python 3.12 + # Version 2.0.4 Chore: diff --git a/MODULE.bazel b/MODULE.bazel index 6dbb229a..535ed7f0 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,6 +1,6 @@ module( name = "org_openmined_psi", - version = "2.0.4", + version = "2.0.5", ) http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") diff --git a/package-lock.json b/package-lock.json index 2ad12baf..6d6d2140 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@openmined/psi.js", - "version": "2.0.4", + "version": "2.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@openmined/psi.js", - "version": "2.0.4", + "version": "2.0.5", "license": "Apache-2.0", "dependencies": { "@grpc/grpc-js": "^1.11.3", @@ -11697,4 +11697,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 5c0f325a..4d8d24ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@openmined/psi.js", - "version": "2.0.4", + "version": "2.0.5", "description": "Private Set Intersection for JavaScript", "repository": { "type": "git", diff --git a/private_set_intersection/python/psi_bindings.cpp b/private_set_intersection/python/psi_bindings.cpp index c0c354d5..9b5c1d94 100644 --- a/private_set_intersection/python/psi_bindings.cpp +++ b/private_set_intersection/python/psi_bindings.cpp @@ -17,7 +17,10 @@ namespace py = pybind11; template T throwOrReturn(const absl::StatusOr& in) { - if (!in.ok()) throw std::runtime_error(std::string(in.status().message())); + if (!in.ok()) { + py::gil_scoped_acquire acquire; + throw std::runtime_error(std::string(in.status().message())); + } return *in; } @@ -29,6 +32,7 @@ auto saveProto(const T& obj) { template auto loadProto(T& obj, const py::bytes& data) { if (!obj.ParseFromString(data)) { + py::gil_scoped_acquire acquire; throw std::invalid_argument("failed to parse proto data"); } } @@ -47,74 +51,107 @@ void bind(pybind11::module& m) { py::class_(m, "cpp_proto_server_setup") .def(py::init<>()) - .def("load", [](psi_proto::ServerSetup& obj, - const py::bytes& data) { return loadProto(obj, data); }) + .def( + "load", + [](psi_proto::ServerSetup& obj, const py::bytes& data) { + return loadProto(obj, data); + }, + py::call_guard()) .def("save", [](const psi_proto::ServerSetup& obj) { return saveProto(obj); }) - .def_static("Load", [](const py::bytes& data) { - psi_proto::ServerSetup obj; - loadProto(obj, data); - return obj; - }); + .def_static( + "Load", + [](const py::bytes& data) { + psi_proto::ServerSetup obj; + loadProto(obj, data); + return obj; + }, + py::call_guard()); py::class_(m, "cpp_proto_request") .def(py::init<>()) - .def("load", [](psi_proto::Request& obj, - const py::bytes& data) { return loadProto(obj, data); }) + .def( + "load", + [](psi_proto::Request& obj, const py::bytes& data) { + return loadProto(obj, data); + }, + py::call_guard()) .def("save", [](const psi_proto::Request& obj) { return saveProto(obj); }) - .def_static("Load", [](const py::bytes& data) { - psi_proto::Request obj; - loadProto(obj, data); - return obj; - }); + .def_static( + "Load", + [](const py::bytes& data) { + psi_proto::Request obj; + loadProto(obj, data); + return obj; + }, + py::call_guard()); py::class_(m, "cpp_proto_response") .def(py::init<>()) - .def("load", [](psi_proto::Response& obj, - const py::bytes& data) { return loadProto(obj, data); }) + .def( + "load", + [](psi_proto::Response& obj, const py::bytes& data) { + return loadProto(obj, data); + }, + py::call_guard()) .def("save", [](const psi_proto::Response& obj) { return saveProto(obj); }) - .def_static("Load", [](const py::bytes& data) { - psi_proto::Response obj; - loadProto(obj, data); - return obj; - }); + .def_static( + "Load", + [](const py::bytes& data) { + psi_proto::Response obj; + loadProto(obj, data); + return obj; + }, + py::call_guard()); py::class_(m, "cpp_client") .def_static( "CreateWithNewKey", [](bool reveal_intersection) { auto client = psi::PsiClient::CreateWithNewKey(reveal_intersection); - if (!client.ok()) + if (!client.ok()) { + py::gil_scoped_acquire acquire; throw std::runtime_error(std::string(client.status().message())); + } return std::move(*client); - }) + }, + py::call_guard()) .def_static( "CreateFromKey", [](const std::string& key_bytes, bool reveal_intersection) { auto client = psi::PsiClient::CreateFromKey(key_bytes, reveal_intersection); - if (!client.ok()) + if (!client.ok()) { + py::gil_scoped_acquire acquire; throw std::runtime_error(std::string(client.status().message())); + } return std::move(*client); - }) - .def("CreateRequest", - [](const psi::PsiClient& obj, - const std::vector& inputs) { - return throwOrReturn(obj.CreateRequest(absl::MakeSpan(inputs))); - }) - .def("GetIntersection", - [](const psi::PsiClient& obj, - const psi_proto::ServerSetup& server_setup, - const psi_proto::Response& server_response) { - return throwOrReturn( - obj.GetIntersection(server_setup, server_response)); - }) - .def("GetIntersectionSize", - [](const psi::PsiClient& obj, - const psi_proto::ServerSetup& server_setup, - const psi_proto::Response& server_response) { - return throwOrReturn( - obj.GetIntersectionSize(server_setup, server_response)); - }) + }, + py::call_guard()) + .def( + "CreateRequest", + [](const psi::PsiClient& obj, + const std::vector& inputs) { + return throwOrReturn(obj.CreateRequest(absl::MakeSpan(inputs))); + }, + py::call_guard()) + .def( + "GetIntersection", + [](const psi::PsiClient& obj, + const psi_proto::ServerSetup& server_setup, + const psi_proto::Response& server_response) { + return throwOrReturn( + obj.GetIntersection(server_setup, server_response)); + }, + py::call_guard()) + .def( + "GetIntersectionSize", + [](const psi::PsiClient& obj, + const psi_proto::ServerSetup& server_setup, + const psi_proto::Response& server_response) { + return throwOrReturn( + obj.GetIntersectionSize(server_setup, server_response)); + }, + py::call_guard()) .def("GetPrivateKeyBytes", [](const psi::PsiClient& obj) { return py::bytes(obj.GetPrivateKeyBytes()); }); @@ -124,30 +161,40 @@ void bind(pybind11::module& m) { "CreateWithNewKey", [](bool reveal_intersection) { auto server = psi::PsiServer::CreateWithNewKey(reveal_intersection); - if (!server.ok()) + if (!server.ok()) { + py::gil_scoped_acquire acquire; throw std::runtime_error(std::string(server.status().message())); + } return std::move(*server); - }) + }, + py::call_guard()) .def_static( "CreateFromKey", [](const std::string& key_bytes, bool reveal_intersection) { auto server = psi::PsiServer::CreateFromKey(key_bytes, reveal_intersection); - if (!server.ok()) + if (!server.ok()) { + py::gil_scoped_acquire acquire; throw std::runtime_error(std::string(server.status().message())); + } return std::move(*server); - }) - .def("CreateSetupMessage", - [](const psi::PsiServer& obj, double fpr, int64_t num_client_inputs, - const std::vector& inputs, psi::DataStructure ds) { - return throwOrReturn(obj.CreateSetupMessage( - fpr, num_client_inputs, absl::MakeSpan(inputs), ds)); - }) - .def("ProcessRequest", - [](const psi::PsiServer& obj, - const psi_proto::Request& client_request) { - return throwOrReturn(obj.ProcessRequest(client_request)); - }) + }, + py::call_guard()) + .def( + "CreateSetupMessage", + [](const psi::PsiServer& obj, double fpr, int64_t num_client_inputs, + const std::vector& inputs, psi::DataStructure ds) { + return throwOrReturn(obj.CreateSetupMessage( + fpr, num_client_inputs, absl::MakeSpan(inputs), ds)); + }, + py::call_guard()) + .def( + "ProcessRequest", + [](const psi::PsiServer& obj, + const psi_proto::Request& client_request) { + return throwOrReturn(obj.ProcessRequest(client_request)); + }, + py::call_guard()) .def("GetPrivateKeyBytes", [](const psi::PsiServer& obj) { return py::bytes(obj.GetPrivateKeyBytes()); }); diff --git a/tools/package.bzl b/tools/package.bzl index e502e1c6..67ea95e0 100644 --- a/tools/package.bzl +++ b/tools/package.bzl @@ -1,2 +1,2 @@ """ Version of the current release """ -VERSION_LABEL = "2.0.4" +VERSION_LABEL = "2.0.5"