Improve support for building Blender as a Python Module (WITH_PYTHON_MODULE) #100913
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
15 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#100913
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Proposal
This task is to gather TODO's, tasks related to making building Blender as a Python module better (& officially) supported.
Motivation
The current status of the
bpy
moduleWITH_PYTHON_MODULE
being an unofficially supported built option isn't ideal.If developers attempt to use this and it fails, we can tell them that they're on their own... although sometimes they manage to get help from others.
From meeting with the bf-admins recently we discussed either dropping support for this entirely, or improving support.
The general agreement was that this is useful (scientific visualization, integrating Blender with existing Python setup on remote servers ... etc).
TODO
WITH_PYTHON_MODULE
is officially supported.//Possible Changes
setup.py
with Blender (needs to be investigated, perhaps postpone until the status of thepip
package has been established). See: D9230: Blender as a Python Module - Extension Module Packaging Script.Open Topics
pip
for e.g.What level of support exactly would be provide (bugs that interact with other Python modules can be quite involved). Suggest we only resolve errors that are obviously errors in Blender's code.
The
bpy
module might be integrated into tests (at least basic tests it's working as expected, it need not run the full test suit).Out of Scope
Progress
Listing recent progress that improves support for running Blender as a Python module.
bpy.so
and versioned data-files directory (e.g3.4
) is copied directly intosite-packages
, now resolved (81558783e4
).3195a38120
).5e2d139ee3
8a9d1f19ab
f7a4ede79f
2c23b4e0bf
9189260880
060da0858b
7bd60d40ef
d26220d97a
260b75a952
Python API documentation for Blender as a Python Module9f76d0c8e6
Other Remarks
Added subscriber: @ideasman42
Added subscribers: @LazyDodo, @brecht, @dr.sybren, @mont29
Added subscriber: @PratikPB2123
Added subscriber: @Clockwork-Muse
As I mentioned in one of my previous issues, you can get a pre-compiled wheel that does the "right thing" almost trivially; I have a sample stub project that builds blender and packages the wheel .
Notes on that sample;
pip wheel .
from the root of that directory, assuming blender/dependencies are available in/blender_wheel/blender
and/blender_wheel/lib
). I can't test on Mac, and Windows did something strange when I tried. I need to work on the full set of steps (was run from a manylinux image, for instance).import blenderpy
. This can be worked around by patching/flagging the module name in blender during build. I'd recommend this to make it easier to transfer scripts.release
config and only specify the minimum flags required (-DWITH_PYTHON_MODULE=ON
,-DWITH_INSTALL_PORTABLE=ON
,-DWITH_MEM_JEMALLOC=OFF
, maybe one or two more?)From personal experience, running as a module sometimes seems to just fail due to unclear context differences, up to and including segfaults. For instance (I need to post the repro for this...), if a mesh has a subdivision node below a geometry node and the subdivision node is applied, the desktop version succeeds, but segfaults in the module. Operators can be chancy - I can't get object duplication to occur (
bpy.ops.object.duplicate_move_linked()
-Alt + D
); no error, just objects aren't duplicated/linked/something.That said, having python as a module makes integrating/using it as "just another package" so much simpler, especially since installing packages into blender is non-trivial (including things like not having an easy way to set up environments).
PyPi doesn't currently easily support nightly builds (specifically, ageing them out). Nightlies might have to be something the project distributes, at least in the short term.
This issue was referenced by
2c23b4e0bf
@Clockwork-Muse thanks for your feedback.
Issues relating to PIP / wheel's ... I don't have strong opinions on, it's more a question of what level of support benefits users, how much work is this to support etc. The current "bpy" module in pip looks to be outdated. If anyone is interested to improve the state of the affairs, it would be good to know. For the time being simply improving support and making sure it's working well (when compiled locally) is a start.
Regarding running into problems with the module, from my experience nearly all of these kinds of problems also exist when running Blender in background mode, if there are crashes - those should be reported.
Added subscriber: @Raimund58
Added subscriber: @TylerGubala
... and isn't pre-built (only a couple of wheels), and doesn't have gpu support (that's a different package or two), and maybe not documentation/code completion (native modules don't always work correctly with code completion due to security concerns - opencv has this issue, for instance), and last I knew required a different "root" package, as mentioned.
It's unclear whether the author would be up to the foundation taking over that package.... summoning. @TylerGubala
That said, I wouldn't mind working on the final build script, if I can get some direction around dependencies and some other choices;
After D15291 we actually have no hard dependency on libGL and only load it at runtime when needed. Headless rendering is now possible through EGL.
If we were to officially maintain such a package as part of the Blender project, we would most likely build it on our own buildbot infrastructure instead of using
cibuildwheel
, and do it for one or maybe two Python versions.So I think any build script would not need to actually build Blender or care about its dependencies. We'd need a script to package a
bpy
folder that's already complete into a wheel, and eventually also automates uploading it to pypi.Okay, previously the dependency existed, that's good to know.
My plan/recommendation would be to pin the wheel version to the version of python that gets usually gets distributed with that version of blender. I'd previously planned to backport some of the changes to 3.0.0 (at least in a fork) to widen the python versions available, but that's likely not hugely necessary.
That aside, building especially a manylinux wheel is not necessarily a trivial task, as there are strict limitations around versioning of libc and the compiler toolset, among other things. I don't know enough about the blender release build process (or what goes into the wheel builders) to know how those limitations would play out. Still, it looks like most of it is run as a pip package, so may run on existing infra anyways (even if not officially supported).
This is also rather trivial - I've previously written a version of the script that does this - I'm just more concerned with what flags have been turned off/on. My own use case includes things like server-based GPU rendering and physics simulations neither of which are enabled in the existing
bpy
build target. I think most people are going to want an "as close to desktop as possible" package - it's a little prohibitive to reduce/bake meshes if cycles is running on the CPU...Blender releases are already built to run on many Linux distribution versions. The bpy module would have the same minimum requirements as Blender (glibc 2.17 this year, glibc 2.28 next year). To be able to use the same precompiled libraries and buildbot infrastructure.
Indeed it seems the current configuration turns off a lot of options. For an official bpy package I think we should use
blender_release.cmake
as a base, and keep features like GPU rendering, Alembic, OpenVDB and Bullet enabled.Changed status from 'Needs Triage' to: 'Confirmed'
A while back, I proposed switching to the cmake
FindPython
module in D14954. Would that be appropriate to consider as part of the other changes here as well? VFX reference platform is moving to glibc 2.28, which implies an upgrade to CentOS 8/AlmaLinux 8 (where cmake 3.20 is available in the default repositories).I thought I had a trivial permanent script that would do this solely with a
pyproject.toml
/setup.cfg
, but it isn't working now. I know I have a working version that abusespackage_data
and runs fromsetup.py
... but I want to revisit this.Why is the requirement that we package the pre-built directory, as opposed to building via scikit-build/
pip wheel
? We already need to do a separate build when we callmake bpy
(ormake release
with the option changes), so there isn't extra work required in that sense, and building viapip wheel
is far cleaner.Building a native python wheel is simpler and easier when python initiates the build, and becomes more important as python transitions to the modern
pyproject.toml
build definitions, and away fromsetup.py
. The existing python tooling does not like to wrap an externally built library, and the situation is actually going to get worse as the buildsystem modernizes (it was doable by messing around withdistutils
, but that's officially deprecated).@Clockwork-Muse I don't think building Blender as a Python module impacts the decision on D14954.
Unless there is something that patch fixes that we can't easily fix in our own Python finding script.
(answering for myself) while I wouldn't consider it a hard requirement - whatever solution is used should minimize any duplicate work regarding build-system maintenance as we already have to maintain CMake for ~3x platforms.
If using a more Python-native system adds additional work or produces a different kind build, I don't think that's an acceptable situation.
It would re-use the existing cmake build system:
(this repo branch has the entire setup required )
Call
pip wheel ${WHEEL_PROJECT_DIRECTORY}
, and the output is a.whl
(that needs to be fixed up as needed per-platform - ie,auditwheel repair
on linux - which would have to be done anyways). The wheel is then ready to install to a venv or upload to PyPi or whatever.No changes to blender are required to enable this (and before this task showed up, I was planning on using this to package and upload blender as a wheel myself). Some of the changes in this task make the resulting packages friendlier.
We have a build pipeline setup for the buildbot, broken up into multiple steps, with various configuration options, logging, incremental builds, tweaks to deal with memory constraints, etc. If we do something different for the bpy module that's harder to set up and maintain.
The buildbot doesn't call
make bpy
, it uses cmake directly.It's not obvious to me why it's hard, or why this would require deprecated functionality instead of the modern systems. If
scikit-build
can usesetuptools
to do this, then so can we?Right, but my point was that at least
WITH_MEM_JEMALLOC
is explicitly turned off for the bpy build, which is on for (most of?) the rest of the builds. It's not clear to me how much of the existing build output the bpy build can re-use.It is possible, although I haven't tested it, that because scikit-build directly uses cmake as well it may be able to integrate with external incremental builds.
The problem is that
setuptools
itself doesn't expose a way to just wrap up a pre-compiled archive/object file (not without either a lot of customization, or a hacky/unintended/unsupported approach). The way the tools are intended to work - and are migrating more heavily towards enforcing - is that python controls the build process from source.There are a couple of additional avenues I can explore here;
jemalloc is mostly a link option, but there is some stuff that indeed needs to be rebuilt. But for example GPU binaries or libmv would not need to be rebuilt.
The main concern is maintenance cost. I'm not worried it's impossible to setup scikit-build to do incremental builds for example, but rather I don't want to maintain two different ways of doing incremental builds.
I added the buildbot side support, and created a very basic packaging script to validate it works: D15957: Python: script for packing bpy module as wheel
What would help now is making this complete, generating correct packages for all platforms, ensuring tests pass, etc.
The use of
package_data
in D15957 is the "hacky" way I mentioned. The problem is that the wheel it generates doesn't reference a minor python version (eg, 3 instead of 3.10 as it should), because it doesn't know that the files that get pulled in are native modules. To an extent it thinks it's doing a python-only wheel. This may cause it to break under odd conditions (although in my current use of such a package, I haven't run into anything I directly attribute to that).The "proper" way to do this is probably to subclass one of the build/sub-build commands, and essentially just claim to have built the existing files. We shouldn't need any changes to blender itself, other than the changes already present in this task (principally
81558783e4
- if we want to build the wheel for prior versions of blender we'd need to backport that to keep the module name).Building a modern python wheel is normally done with
python -m build --wheel <package directory>
orpip wheel <package directory>
, rather than callingsetup.py
/bdist_wheel
directly. My intention is to contribute a wrapper package set up as if it were a modern native-lib python package, with a custom build command that would claim to have built the existing artifacts. This should work correctly for all platforms, and the only platform difference would be the use ofauditwheel
/delocate
or similar after the wheel is built to correct the native links.How would developers or the buildbot use this, would they call e.g.
pip wheel ../build_linux_bpy/bin
?I guess for most developers a target like
make bpy wheel
would be most convenient.Is that necessary? These seem to be copying system dynamic libraries into the package, but Blender executables should already be self contained enough.
That or
python -m build <whatever directory>
, yes.At minimum, it adjusts wheel name/metadata for linux (not as sure about other platforms), from
linux1
tomanylinux<something>
(assuming we're building on centos7,manylinux2014_<platform>
). Even if the binaries are already usable, you still need that to occur so that it's installable on multiple distros from PyPi.When messing with another package, I believe I'd tried to manually adjust the name itself, but that rendered it unusable/uninstallable.
About scikit-build -
I have experimentally verified that it does re-use build cache, however the process does disturb it, and still re-links
__init__.so
, and in at least the initial tests performed doesn't properly install the output/build the wheel (because it seems to want to re-use the existing install prefix).Ok, my preference is to not rely on additional modules like
scikit-build
,auditwheel
,delocate
unless they do something we can't do ourselves with a few lines of code. If they do something more complicated then so be it, but it doesn't seem clear yet.@Clockwork-Muse Started the transfer process:
https://github.com/pypa/pypi-support/issues/2231
@TylerGubala - I'm just an interested party, I'm not an admin or anything, the person to ping is probably @brecht
It seems @ideasman42 is the one in contact about the transfer, so will let him handle it unless my help is needed.
bpy wheels can be downloaded here for testing now:
https://builder.blender.org/download/experimental/
Developers with a buildbot account can kick off a branch build (set to
master
) to update this. It's not part of the daily builds yet.Question - will the module changes be included in 3.3 bugfixes, or starting in 3.4?
All the changes are in 3.4, I'm not aware of any plan to backport it.
Added subscriber: @Zeastin
As far as I'm aware the main TODO's in this task are done.
Some loose ends though:
bpy
package to the Blender-Foundation.Added subscriber: @rjg
Just so that it is not forgotten, the wiki page will need to be updated as well: https://wiki.blender.org/wiki/Building_Blender/Other/BlenderAsPyModule
@rjg noted, the page has been updated to reflect recent changes (API docs, utility to create
*.whl
) but the text regarding official support remains unchanged for now.@ideasman42 Please react to https://github.com/pypa/pypi-support/issues/2231
They want a defined owner.
You might need to create an account for the BF https://pypi.org/account/register/
Thanks for letting us know, replied with details for the account to use.
Added subscriber: @Lin-Hsu
Added subscriber: @synthetic
@ideasman42 Hi, since the Blender Foundation is now (co)owner of the pip
bpy
module, what are the next steps?That is not clear from the task as I can see it.
Will
bpy
be the build from the latest release andbpy-master
a nightly build?I think we'd wait until the Blender 3.4 release is out and then manually trigger a bpy build on the buildbot and upload it. Later that can get automated as part of the release process.
It would be good to try it out on the pypi test instance beforehand.
I don't expect us to publish nightly builds to pypi.
Thank you, Becht, for answering. Looking forward to get official bpy and pip support :)
Perhaps not nightlies (at least not until PyPi better supports them), but alpha/beta/rc might be reasonable? That would serve for testing the PyPi process, and getting feedback from people taking dependencies. Note that, due to the way pip works, you have to either explicitly list a pre-release version number, or enable pulling pre-release packages in general, which means that normally such packages are effectively hidden.
Side note: I have just been made aware of https://test.pypi.org/. This is intended for use in testing CI scripts, not for distribution of pre-release packages, so should help when those scripts get written.
Added subscriber: @samrun
Hi, thank you for development around building Blender bpy as a python module. I have two suggestions for improvement and not sure how easy or possible it is with the CMake build.
Thank you!
300 ms is likely just the startup cost of blender, if you run the automation twice from a single python script, is it faster the second time around?
It would be nice if this could be used for publishing software, but I think that's not a goal here. The GPL already makes that impossible for many cases. But also Blender is just not designed as separate components you can easily pick and choose, unless you do a custom build and disable options.
The main use cases I think are things like scientific research, machine learning, pipeline automation, web services, etc.
I requested to increase the package size limit since we exceed the current one:
https://github.com/pypa/pypi-support/issues/2353
I added a source code link in the description as well now, and removed @TylerGubala from the pypi project maintainers and added a credit in the project description instead. These will show up on the official release, don't think I can update the project description without making another release.
Added subscriber: @lobziq
Apple silicon m1, python 3.8. Running command
results in error
[Blender as a Python Module] link from https://pypi.org/project/bpy/3.4.0b2/ redirects to 404 docs url
https://docs.blender.org/api/current/info_advanced_blender_as_bpy.html
@lobziq You use the wrong python version. Each Blender release supports one Python version, and the package is only compatible with that version. You need Python 3.10
But let's keep this task free of support requests. Come to
blender.chat
for chatting.The link will start working once 3.4 is out.
It's docs.blender.org/api/master/info_advanced_blender_as_bpy.html
(thanks to brecht)
Added subscriber: @chewitt
Hey - not sure if this warrants a separate issue but here seems relevant...
Firstly this is awesome! Thanks so much for adding this functionality, it is saving us a huge amount of effort
I wanted to ask whether it is documented anywhere what build options are being used for the wheel on pypi, and if they match the release version of blender.
Currently it seems like alembic support is not included in bpy but is in blender - is it possible to use the same options as the release version of blender for consistency, or at a minimum add support for alembic to the bpy build?
EDIT: Now see you have pre-empted this already:
9189260880
Please disregard the above! I was getting a segfault for something unrelated and assumed it was due to alembic support not being included...Closing as issues relating to
WITH_PYTHON_MODULE
have largely been addressed, any remaining issues can be reported & handled in isolated.