Thanks to visit codestin.com
Credit goes to github.com

Skip to content

added python bindings #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

added python bindings #8

wants to merge 3 commits into from

Conversation

shaur-k
Copy link

@shaur-k shaur-k commented Jun 19, 2025

please tear me apart here

The way this works is that we basically serialize objects in C++ to Python and then back (hence "binding" objects to and from C++). the underlying Python is well abstracted outside of the JSON Serialization functions that we create a helper for (I couldn't use concepts and didn't have a great way to avoid SFINAE picking the more simple fromJSON function I wrote).

Here's some documentation to pybind: https://pybind11.readthedocs.io/en/latest/

commit 47f067c
Author: shaur-k <[email protected]>
Date:   Thu Jun 19 14:53:45 2025 -0600

    feat: clean up old PR for new version of BTCPP

commit 8c6cfac
Author: shaur-k <[email protected]>
Date:   Thu Jun 19 13:16:13 2025 -0600

    temp

commit 6a6f86e
Merge: 890396c 1b9e0e2
Author: shaur-k <[email protected]>
Date:   Thu Jun 19 12:07:36 2025 -0600

    Merge branch 'master' into python-bindings

commit 890396c
Author: Kyle Cesare <[email protected]>
Date:   Tue Sep 5 23:45:06 2023 -0600

    Fix setup.py package attributes.

commit fb33788
Author: Kyle Cesare <[email protected]>
Date:   Tue Sep 5 21:57:19 2023 -0600

    Add useful note for ex05 on shared lib location.

commit 632eb66
Author: Kyle Cesare <[email protected]>
Date:   Tue Sep 5 21:55:52 2023 -0600

    Clean up dummy node use in ex05.

commit 1a7ac0a
Author: Kyle Cesare <[email protected]>
Date:   Tue Sep 5 21:48:23 2023 -0600

    Properly specify __all__ for btpy module.

commit b425c91
Author: Kyle Cesare <[email protected]>
Date:   Mon Sep 4 19:17:31 2023 -0600

    Add docs for `JsonExporter::fromJson`.

commit 2584aec
Author: Kyle Cesare <[email protected]>
Date:   Mon Sep 4 19:03:16 2023 -0600

    Add default impl of AsyncActionNode#on_halted

commit 04f435d
Author: Kyle Cesare <[email protected]>
Date:   Mon Sep 4 19:03:07 2023 -0600

    Add `halt_tree` binding and use in demo

commit 535ea88
Author: Kyle Cesare <[email protected]>
Date:   Mon Sep 4 18:56:14 2023 -0600

    Improve python example README

commit 93b58c3
Author: Kyle Cesare <[email protected]>
Date:   Mon Sep 4 18:56:08 2023 -0600

    Formatting.

commit 0ee0a20
Author: Kyle Cesare <[email protected]>
Date:   Mon Sep 4 18:55:57 2023 -0600

    Fix some string-embedded XML indentation.

commit 0786475
Author: Kyle Cesare <[email protected]>
Date:   Mon Sep 4 18:54:11 2023 -0600

    Don't make Py_StatefulActionNode final.

commit 4ad738c
Author: Kyle Cesare <[email protected]>
Date:   Sun Sep 3 19:16:29 2023 -0600

    Add some docs to Python ex06.

commit 84ae12d
Author: Kyle Cesare <[email protected]>
Date:   Sun Sep 3 19:04:27 2023 -0600

    Add some type hints to the Python code

commit 46929a8
Author: Kyle Cesare <[email protected]>
Date:   Sun Sep 3 12:31:00 2023 -0600

    Move Python-related source files into subdirectory.

commit 9d8db3c
Author: Kyle Cesare <[email protected]>
Date:   Sun Sep 3 11:57:13 2023 -0600

    Clean up Python example XMLs.

commit ee7f464
Author: Kyle Cesare <[email protected]>
Date:   Sat Sep 2 11:08:42 2023 -0600

    Modify py::type argument to support older pybind

commit fdc2232
Author: Kyle Cesare <[email protected]>
Date:   Fri Sep 1 22:18:04 2023 -0600

    Add pyproject.toml/setup.py for building wheels.

commit 2c1b18a
Author: Kyle Cesare <[email protected]>
Date:   Fri Sep 1 21:40:14 2023 -0600

    Use docstring as tree node description.

commit 1a69d3a
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 26 22:47:56 2023 -0600

    Clean up Python ex06.

commit 0e35ac0
Author: Kyle Cesare <[email protected]>
Date:   Fri Sep 1 19:35:57 2023 -0600

    Move some dummy_nodes definitions to cpp file to fix linker error

commit 83caef7
Author: Kyle Cesare <[email protected]>
Date:   Fri Sep 1 19:35:46 2023 -0600

    Add missing pybind11 dependency to package.xml

commit c703efd
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 19 19:49:01 2023 -0600

    Implement coroutine-based Python nodes.

commit 4448376
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 19 19:07:54 2023 -0600

    Add pybind11 conan dependency.

commit 21d450e
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 19 18:52:52 2023 -0600

    Add `BehaviorTreeFactory.register_from_plugin` binding.

commit d1fe0e3
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 19 18:52:39 2023 -0600

    Implement C++ <-> Python type interop via JSON.

commit cfa553a
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 19 12:52:01 2023 -0600

    Disable zero variadic arg warning.

commit 7927e67
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 19 12:51:44 2023 -0600

    Fix onHalted override copy-paste error.

commit 712370b
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 12:30:01 2023 -0600

    Add useful command for ex04.

commit dc9e953
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 12:28:16 2023 -0600

    Fix typo in ex04.

commit ed78e84
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 12:27:34 2023 -0600

    Fix NodeStatus enum value ordering.

commit 2a22fa8
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 12:05:05 2023 -0600

    Add note about Py_getInput return value.

commit 37ae114
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 12:01:52 2023 -0600

    Add simple README.

commit adf5cef
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 11:56:52 2023 -0600

    Add ROS2 interop example.

commit 404a195
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 11:56:38 2023 -0600

    Add builder args to be passed to node ctors.

commit 9493f10
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 11:56:23 2023 -0600

    Return None if blackboard value doesn't exist.

commit 6188c21
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 11:10:10 2023 -0600

    Ignore pycache.

commit b22772e
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 10:55:49 2023 -0600

    Put generic methods on abstract base class.

commit 17da541
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 10:54:59 2023 -0600

    Clean up port handling.

commit 4ff5673
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 10:54:37 2023 -0600

    Export minimal set of identifiers to Python lib.

commit 351c33a
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 10:54:25 2023 -0600

    Use proper PYBIND11_OVERRIDE macros.

commit 1f9db33
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 10:30:18 2023 -0600

    Eliminate some code duplication.

commit f560500
Author: Kyle Cesare <[email protected]>
Date:   Sun Aug 13 00:22:11 2023 -0600

    Add stateful action bindings.

commit 9fdcda1
Author: Kyle Cesare <[email protected]>
Date:   Sat Aug 12 23:09:20 2023 -0600

    Implement minimal Python bindings to SyncActionNode
@shaur-k shaur-k self-assigned this Jun 19, 2025
@shaur-k shaur-k changed the title Squashed commit of the following: added python bindings Jun 19, 2025
@henrygerardmoore
Copy link

henrygerardmoore commented Jun 19, 2025

I can't review this all yet, but would it be possible to add a bunch of tests that serialize a type back and forth and ensure it's the same? Or serialize it, change it, then test that the deserialized one has that change? Those or some set of tests like them are probably necessary before we should consider merging this big of a change, IMO

@pac48
Copy link

pac48 commented Jun 19, 2025

I think we lost this code.

@shaur-k shaur-k force-pushed the python-bindings branch 2 times, most recently from 2899a69 to 86416c5 Compare June 20, 2025 03:26
@shaur-k shaur-k marked this pull request as draft June 20, 2025 14:37
@shaur-k
Copy link
Author

shaur-k commented Jun 20, 2025

throwing back to draft to finish some implementation and clean up that I found last night

@shaur-k shaur-k marked this pull request as ready for review June 20, 2025 20:51
@shaur-k
Copy link
Author

shaur-k commented Jun 20, 2025

this is ready again, except @henrygerardmoore i know i need to add some better tests, but you can build this and run the python_examples to see what works

Copy link

@griswaldbrooks griswaldbrooks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first pass


inline py::object from_json(const nl::json& j)
{
if (j.is_null())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like you should be able to change this to use a std::variant or function map using https://json.nlohmann.me/api/basic_json/type/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can even do some sort of mapping of the py:: types. This if/else tree is just kind of hard to look at.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and of course if you are returning, the you should use an if not an else if

}
}

inline nl::json to_json(const py::handle& obj)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above, something should be done to simplify this, more to look like a mapping between objects

return s;
}
}
catch (...)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usually if you don't swallow the exception?

{
py::object obj;

// The input could not exist on the blackboard, in which case we return Python

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The input could not exist on the blackboard, in which case we return Python
// The input was not on the blackboard, in which case we return Python

}
catch(py::error_already_set& e)
{
// If that fails, then assume it's a string literal with quotation marks

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😅

Comment on lines +118 to +119
py::object obj;
obj = type(name, config, *args, **kwargs);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does

Suggested change
py::object obj;
obj = type(name, config, *args, **kwargs);
py::object obj = type(name, config, *args, **kwargs);

work?

py::object obj;
obj = type(name, config, *args, **kwargs);

// TODO: Increment the object's reference count or else it

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this? Is this the recommended pattern?

#else
__attribute__((visibility("default")))
#endif
bool toPythonObject(const BT::Any& val, pybind11::object& dest)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool toPythonObject(const BT::Any& val, pybind11::object& dest)
bool toPythonObject(const BT::Any& val, pybind11::object& dest)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants