OpenImageIO
OpenImageIO copied to clipboard
[FEATURE REQUEST] pip install OpenImageIO
Hi,
Please automate and unify python builds and make it available via pip install OpenImageIO
Exemplary project providing build for all possible python versions under releases: https://github.com/isl-org/Open3D/releases/tag/v0.14.1
This would be a great thing. But it's well outside my expertise, so what I really need is for somebody who has more Python ecosystem knowledge, preferably somebody who has done this exact thing on another project, to step forward and take the lead on this task. I think that this has recently been done on both OpenColorIO and OpenTimelineIO, so maybe there is somebody who both works on those projects and OIIO and would like to give this a try and can do it efficiently since they already know how it works?
upvote on this one!
Please! It's sooo complicated to get oiio working with Python in Windows, especially for casual Python users. Just spent an entire day figuring it out (including little idiosyncrasies like making sure it builds with ocio) via Microsoft vcpkg - and even them I'm stuck with Python 3.10 and have no idea how to build it for 3.9. Anyone??
I'm currently working on that. I have fully static builds working on Linux and Windows. I haven't started macOS yet.
I'm aiming for having a library that comes with most plugins. The only excluded plugins are OpenVDB, R3D, Nuke, DCMTK, OpenCV and the iv command.
Oh, and I'll need testers eventually. If you (or someone you know) are interested, please let me know and also tell which platform and architecture you would like to test on.
Thanks!
I can test on mac, windows and centos 7.
willing to test on ubuntu 20.04 x86_64
This would be a really big help, especially for pure python developers (or tech-artists). I've spent a good part of my day trying to get the python bindings to work on windows through vcpkg, and I seem to come across a lot of old threads where others face the same issue.
@JeanChristopheMorinPerso pinging - any updates on this? can we help you test? thanks!
I'll update when I have more news. The work I'm doing is not sponsored by any company, which means I do that in my own free time.
Windows users are looking forward to this function, the person who makes it will be respected by everyone
I can probably give an update. I had all platforms working last year. But I'm blocked on licensing issues. OIIO has a lot of dependencies (direct and transitive) and there is a lot of licenses involved.
I'm happy to help test on macOS Ventura if needed. A pip installer would be great, or even improved docs on installing for python.
@JeanChristopheMorinPerso, how much work needs to be done? I'd be happy to help with writing a setup.py, but might be limited by experience/knowledge.
Hi @ziggycross, I don't have any update. I'm mainly waiting on the TSC to be fully formed and in place and for things to settle before starting to work on this again. The reason being we'll have to figure out which plugin is safe to ship with the wheels in terms of licenses. In other words, I'm not blocked on the software side, I'm blocked on the legal stuff.
Creating the python package isn't too complex and I'd say is even quite straightforward for someone with compilation and packaging experience. What's complex is really figuring out the right set of plugins, taking into consideration their licenses and the compatibility of these licenses with OIIO's license and how these dependencies can be redistributed without violating their licenses and without changing OIIO's license. And the thing is this is out of my area of expertise and I'm also not in a position of making these decisions anyway.
Thanks for the thoughtful response @JeanChristopheMorinPerso. Do you think perhaps it would be possible to include the files needed to run an offline pip install? That way anyone who has built the necessary files or installed OIIO from homebrew, etc, could install it to their environment with a single command.
If you think this could be a good idea, I'd be happy to give it a shot.
Very familiar with Python packaging and can hit this one on Dev Days if folks are still interested
Hopefully @JeanChristopheMorinPerso can fill you in on where he is with this, and there is some meaningful way to divide up the work that's left to do?
@JeanChristopheMorinPerso Do you have a WIP branch somewhere? I can ask @tieguy for help with the licensing.
Hi @aclark4life! I'm quite happy to hear that someone with python packaging experience is wants to help! I have plenty of packaging experience too, but I'm lacking time. So all help is very welcome!
I have a branch (actually two, but the branch I'm pointing you to is the main one that has all the changes). See https://github.com/JeanChristopheMorinPerso/oiio/compare/master..python_wheels_windows. The branch is named windows something, but it also contains all the stuff for macOS and Linux. The last time I pushed to this branch, everything was compiling, linking and everything was working on all platforms.
The last commit was probably a year ago, so I'm sure there will be tons of conflicts and plenty of things to change. But it has the general idea in it.
The general idea is to statically link everything we legally can, support all platforms, support python 3.7+ and we need wheels. The wheels shouldn't be too heavy (I think what I had done was to statically link everything in the libiio (or whatever the library name is), dynamically link it to the python binding and the CLI apps). You'll see that I use conan to build everything statically. Conan was chosen because it was the most straight forward way to do that without hundreds of lines of cross-platform bash to get all dependencies that we can in static, no shared.
The elephant in the room is ffmpeg and other GPL dependencies. But since the OIIO is now part of the ASWF, we have access to LF lawyers to answer any question we have licensing wise. It would actually be good to go through LF because we have other projects that will also have to deal with this type of stuff (OpenRV, etc).
But I don't think for now that we need to care much about GPL stuff. Just getting everything working will be a good first step, and we can disable some dependencies if required, and dynamically link others if required, etc.
As you can see from what I just wrote, this issue is more a compilation exercise than python packaging in itself. Though there is still a big packaging part in the sense that we need to ship something that is rock solid (ie OIIO users should have to deal with DLL hell when pip install OIIO). Compiling is the big issue, and getting everything working and something that won't generate a huge amount of support once released (which is quite important and why I want to statically link stuff).
Feel free to take a look at what I did, ask questions and give us your opinion!
@JeanChristopheMorinPerso Thanks!
OK I agree this is not a one day task, but if I work on it between now and dev days, then we can probably get something ready to merge by then 🚀
Here's a PR from @JeanChristopheMorinPerso branch to a rebased master so folks can follow along:
- https://github.com/aclark4life/oiio/pull/1
I made a "brute force" attempt to rebase the branch against master, but gave up about half way through when I realized the result wouldn't be coherent 😄
So, falling back to a PR and I'll continue to review all the moving parts in hopes if starting to make some tangible progress.
First q:
- Is libaom intended to part of this branch? It looks like it is added here and is not in master but I'm not sure what that has to do with creating wheels, if anything.
Additional comments:
- You can see @wiredfool's comment about dancing around licenses here: https://github.com/python-pillow/Pillow/issues/7150#issuecomment-1730312846
- Never used Conan but I'll take a look! Looks interesting (to someone who knows some C and zero C++)
- Static linking seems to be working for Homebrew so maybe checking out their build stuff will help.
@aclark4life libaom is a dependency of libheif if I'm not mistaken.
@JeanChristopheMorinPerso Right and neither build script (aom, heif) is currently in master so my question is: were these added for the sole purpose of creating wheels? I assume "yes" and if that's confirmed then we may want to break out tasks for this issue into at the very least two tracks, maybe three:
- Build deps
- Assemble wheels
- Integrate with CI (e.g. PyPI Trusted Publisher)
In other words, I'm making the assumption that a PR to master for a dep like this could get merged without issue whereas the entire wheel creation process has a much broader scope.
OIIO has a direct dependency on libheif, see https://github.com/OpenImageIO/oiio/blob/822304b0851eb7083da918097b8be5b99ff2286a/src/heif.imageio/heifinput.cpp#L9. Maybe there isn't a build script for it (and aom), but it's still a direct dependency. Though, it's good to note that each OIIO plugin is optional. So it's an optional dep, like a lot of other OIIO dependencies.
Anyway, I wouldn't focus on this right now. I would focus on getting something working first, and then we can worry on which plugins we will bundle or not, and which dependency we dynamically or statically link.
Right! As far as that goes, a rebase or merge of your code with current master could still happen if I put some effort into it, but I'm not entirely convinced that a new branch including lessons learned isn't a better way to go. Opinions welcome.
Here's what your branch build looks like for me:
(oiio) alexclark@MH02233809MLI ~/Developer/oiio ±python_wheels_windows⚡ » python -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (cmake>=3.12, ninja, setuptools, wheel)
* Getting build dependencies for sdist...
running egg_info
writing OpenImageIO.egg-info/PKG-INFO
writing dependency_links to OpenImageIO.egg-info/dependency_links.txt
writing entry points to OpenImageIO.egg-info/entry_points.txt
writing top-level names to OpenImageIO.egg-info/top_level.txt
reading manifest file 'OpenImageIO.egg-info/SOURCES.txt'
adding license file 'LICENSE.md'
writing manifest file 'OpenImageIO.egg-info/SOURCES.txt'
* Building sdist...
running sdist
running egg_info
writing OpenImageIO.egg-info/PKG-INFO
writing dependency_links to OpenImageIO.egg-info/dependency_links.txt
writing entry points to OpenImageIO.egg-info/entry_points.txt
writing top-level names to OpenImageIO.egg-info/top_level.txt
reading manifest file 'OpenImageIO.egg-info/SOURCES.txt'
adding license file 'LICENSE.md'
writing manifest file 'OpenImageIO.egg-info/SOURCES.txt'
running check
creating OpenImageIO-2.4.0.dev1
creating OpenImageIO-2.4.0.dev1/OpenImageIO.egg-info
creating OpenImageIO-2.4.0.dev1/src
creating OpenImageIO-2.4.0.dev1/src/python
creating OpenImageIO-2.4.0.dev1/src/python/OpenImageIO
copying files to OpenImageIO-2.4.0.dev1...
copying LICENSE.md -> OpenImageIO-2.4.0.dev1
copying README.md -> OpenImageIO-2.4.0.dev1
copying pyproject.toml -> OpenImageIO-2.4.0.dev1
copying setup.py -> OpenImageIO-2.4.0.dev1
copying OpenImageIO.egg-info/PKG-INFO -> OpenImageIO-2.4.0.dev1/OpenImageIO.egg-info
copying OpenImageIO.egg-info/SOURCES.txt -> OpenImageIO-2.4.0.dev1/OpenImageIO.egg-info
copying OpenImageIO.egg-info/dependency_links.txt -> OpenImageIO-2.4.0.dev1/OpenImageIO.egg-info
copying OpenImageIO.egg-info/entry_points.txt -> OpenImageIO-2.4.0.dev1/OpenImageIO.egg-info
copying OpenImageIO.egg-info/not-zip-safe -> OpenImageIO-2.4.0.dev1/OpenImageIO.egg-info
copying OpenImageIO.egg-info/top_level.txt -> OpenImageIO-2.4.0.dev1/OpenImageIO.egg-info
copying src/python/OpenImageIO/__init__.py -> OpenImageIO-2.4.0.dev1/src/python/OpenImageIO
copying src/python/OpenImageIO/_commands.py -> OpenImageIO-2.4.0.dev1/src/python/OpenImageIO
Writing OpenImageIO-2.4.0.dev1/setup.cfg
Creating tar archive
removing 'OpenImageIO-2.4.0.dev1' (and everything under it)
* Building wheel from sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (cmake>=3.12, ninja, setuptools, wheel)
* Getting build dependencies for wheel...
running egg_info
writing OpenImageIO.egg-info/PKG-INFO
writing dependency_links to OpenImageIO.egg-info/dependency_links.txt
writing entry points to OpenImageIO.egg-info/entry_points.txt
writing top-level names to OpenImageIO.egg-info/top_level.txt
reading manifest file 'OpenImageIO.egg-info/SOURCES.txt'
adding license file 'LICENSE.md'
writing manifest file 'OpenImageIO.egg-info/SOURCES.txt'
* Installing packages in isolated environment... (wheel)
* Building wheel...
running bdist_wheel
running build
running build_py
creating build
creating build/lib.macosx-13-arm64-cpython-311
creating build/lib.macosx-13-arm64-cpython-311/OpenImageIO
copying src/python/OpenImageIO/__init__.py -> build/lib.macosx-13-arm64-cpython-311/OpenImageIO
copying src/python/OpenImageIO/_commands.py -> build/lib.macosx-13-arm64-cpython-311/OpenImageIO
running build_ext
cmake /private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-via-sdist-hct6pcjc/OpenImageIO-2.4.0.dev1 -G=Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH= -DCMAKE_INSTALL_PREFIX=/tmp/oiio -DCMAKE_INSTALL_LIBDIR=/tmp/oiio/lib -DCMAKE_CXX_STANDARD=17 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 -DBUILD_SHARED_LIBS=ON -DPython_EXECUTABLE=/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/bin/python -DPYTHON_SITE_DIR=/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-via-sdist-hct6pcjc/OpenImageIO-2.4.0.dev1/build/lib.macosx-13-arm64-cpython-311/OpenImageIO -DLINKSTATIC=ON -DEXTRA_CPP_ARGS= -DOIIO_DOWNLOAD_MISSING_TESTDATA=OFF -DOIIO_BUILD_TESTS=OFF -DOIIO_BUILD_TOOLS=ON -DUSE_EXTERNAL_PUGIXML=1 -DBUILD_FMT_VERSION=9.0.0 -DVERBOSE=1
CMake Warning:
Ignoring extra path from command line:
"/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-via-sdist-hct6pcjc/OpenImageIO-2.4.0.dev1"
CMake Error: The source directory "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-via-sdist-hct6pcjc/OpenImageIO-2.4.0.dev1" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
Traceback (most recent call last):
File "/Users/alexclark/Developer/oiio/lib/python3.11/site-packages/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
main()
File "/Users/alexclark/Developer/oiio/lib/python3.11/site-packages/pyproject_hooks/_in_process/_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/alexclark/Developer/oiio/lib/python3.11/site-packages/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
return _build_backend().build_wheel(wheel_directory, config_settings,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/build_meta.py", line 434, in build_wheel
return self._build_with_temp_dir(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/build_meta.py", line 419, in _build_with_temp_dir
self.run_setup()
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/build_meta.py", line 341, in run_setup
exec(code, locals())
File "<string>", line 84, in <module>
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/__init__.py", line 103, in setup
return distutils.core.setup(**attrs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup
return run_commands(dist)
^^^^^^^^^^^^^^^^^^
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
dist.run_commands()
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
self.run_command(cmd)
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/dist.py", line 989, in run_command
super().run_command(command)
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
cmd_obj.run()
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/wheel/bdist_wheel.py", line 364, in run
self.run_command("build")
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
self.distribution.run_command(command)
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/dist.py", line 989, in run_command
super().run_command(command)
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
cmd_obj.run()
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/command/build.py", line 131, in run
self.run_command(cmd_name)
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
self.distribution.run_command(command)
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/dist.py", line 989, in run_command
super().run_command(command)
File "/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
cmd_obj.run()
File "<string>", line 52, in run
File "/opt/homebrew/Cellar/[email protected]/3.11.5/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", line 413, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['cmake', '/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-via-sdist-hct6pcjc/OpenImageIO-2.4.0.dev1', '-G=Ninja', '-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_PREFIX_PATH=', '-DCMAKE_INSTALL_PREFIX=/tmp/oiio', '-DCMAKE_INSTALL_LIBDIR=/tmp/oiio/lib', '-DCMAKE_CXX_STANDARD=17', '-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13', '-DBUILD_SHARED_LIBS=ON', '-DPython_EXECUTABLE=/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-env-lnc4x_lz/bin/python', '-DPYTHON_SITE_DIR=/private/var/folders/h3/y65b4jj54mg4bwtsqzqhtvzr0000gs/T/build-via-sdist-hct6pcjc/OpenImageIO-2.4.0.dev1/build/lib.macosx-13-arm64-cpython-311/OpenImageIO', '-DLINKSTATIC=ON', '-DEXTRA_CPP_ARGS=', '-DOIIO_DOWNLOAD_MISSING_TESTDATA=OFF', '-DOIIO_BUILD_TESTS=OFF', '-DOIIO_BUILD_TOOLS=ON', '-DUSE_EXTERNAL_PUGIXML=1', '-DBUILD_FMT_VERSION=9.0.0', '-DVERBOSE=1']' returned non-zero exit status 1.
ERROR Backend subprocess exited when trying to invoke build_wheel
Not sure exactly what's going on there so right now I'm in a test repo experimenting with C++, CMake, Python.
The build command might be trying to create an sdist and then create a wheel from the sdist. If setuptools isn't told to include the c++ stuff, then it won't be included in the sdist. You can trying with python -m build -w, which should build a wheel without going through an sdist I think.
As for starting from scratch, that's an option and probably what I would do. Lots of things changed since I made this experiment, so it'll be easier to start from scratch. I think my modifications to CMakeLists.txt, conanfile.txt, the pyproject.toml + setup.py can probably be taken as is. The patch on OCIO is probably not needed anymore, the /MT flags are probably not needed anymore (if we target Python 3+). I would personally keep https://github.com/JeanChristopheMorinPerso/oiio/compare/master..python_wheels_windows#diff-43abf0e22a47875cd78c49ee12eb52a081009b929a76e48a8589ae393549adeb and only tweak what's needed (like the dependency versions, ocio, pugixml, etc).
But feel free to start from scratch. That's what I would do (though, like I just said, I would cherry-pick stuff).
One thing I'd like to do though is to not use setuptools. I'd prefer to use https://github.com/scikit-build/scikit-build-core instead. Note that this is not scikit-build. It's a new build backend related to scikit-build but is not scikit-build-core. This backend simplifies quite a bit of things since it nateively understands cmake and we don't need a setup.py file anymore. We would only need a pyproject.toml.
OK here's a new branch with a new pyproject.toml that appears to build something with scikit-build-core and no setuptools!
As for cherry-picking, here's a list of commits, if possible, please let me know which ones to keep and I'll deal with all the conflicts.
- 386fe451132d775680b9c1bed35ba3bdfc262e20 - Add more notes
- 56f55b76750000256d103d2d606498b1a240f665 - Some cleanup and add TODOs
- efe2cc15686a632ddb2a0b04be35740027aaddfa - Add support for macOS
- ~09b2ecd9b0ccbcc0e7cd9faad1e9e8c5da117f69 - Build from setup.py~
- ~05de2fccc9b481a78bea399c55ecebe759691cf8 - Working windows build!~
- ~886bc62ae49527e054367a21e9d833d38b31ed25 - Remove unnecessary changes~
- ~fed4ee9142e9625ce8013bfcd80f947098287015- Require Python Development.Module instead of Development since the libpython is not required to build the extension~
- ~9f30c1403d5afe1f5a9251d297d67c9397b97384 - Cleanup a little bit run on CentOS~
- ~51e91e11b40e1be6abe598802944d781d040cde6 - Remove unused scripts~
- ~7d6de70cb86718055f9791b59fa2a58d944be633 - Working version~
- ~3d43f748ce6b6b0f7522697f3db09de4e8276987 - Fix OpenColorIO~
- ~6b0a380d63d37c119c0933a7e83df9c204fde11b - wip~
Hi @aclark4life, it's a little bit difficult to point to which commit can be cherry picked. The commits where made organically and not methodologically. I tried to be methodical, but thins evolved through the commits. So here is some hints:
I think my modifications to CMakeLists.txt (and the other cmake files), conanfile.txt, the pyproject.toml + setup.py can probably be taken as is (or setup.py dropped if we can use scikit-build-core). The patch on OCIO is probably not needed anymore, the /MT flags are probably not needed anymore (if we target Python 3+). I would personally keep https://github.com/JeanChristopheMorinPerso/oiio/compare/master..python_wheels_windows#diff-43abf0e22a47875cd78c49ee12eb52a081009b929a76e48a8589ae393549adeb and only tweak what's needed (like the dependency versions, ocio, pugixml, etc).
@aclark4life @JeanChristopheMorinPerso Hello, just curious if there has been any progress on this? I also tried looking into a building the most recent release (2.5.5.0) using conan, but the current config does not seem to work (tried using conan 1.62.0 and 2.0.14). Both seemed to have different issues with the deps. Basically, I am interested in building a version of oiio that is compatible with Python 3.10 so that it can interoperate with Blender.
@taranlu-houzz Loosely targeting end-of-year to finish something that can be merged.
Hello @aclark4life, just curious if there has been any update on this?