Package: pygo-tools
Python Golang ToolsThis project aims to bridge the gap between Python and Golang, enabling developers to easily create high performance Python
libraries with precompiled Go extensions.pygo-toolswraps thesetupfunction fromsetuptoolsand handles the process
of compiling your library's golang source before building the wheel file.pygo-toolsalso patches the resulting extension,
removing the need to manually configureLD_LIBRARY_PATHorDYLD_LIBRARY_PATHbefore runtime.Installationpipinstallpygo-toolsExample Projectshello world withsetup.pyandconfig.jsonhello world withpyproject.tomlWalkthrough for Hello World withsetup.pyandconfig.jsonProject Structure|-- Makefile
|-- config.json
|-- example
|   |-- __init__.py
|   |-- go
|   |   |-- Makefile
|   |   `-- main.go
|   |-- lib -> go/local
|   `-- wrapper.py
|-- MANIFEST.in
|-- setup.py
`-- test.pyProject Configpygo-toolslooks forconfig.jsonat the root of your project. The config contains metadata like the python package name,
golang library, python extension, andCfuncton signatures for the underlying library.{"package":"example","extension":"_example","library":"hello","signatures":["char* Hello(char* message, int count);"]}Go// example/go/main.gopackagemainimport"C"import"fmt"funchello(messagestring,countint)string{returnfmt.Sprintf("hello %s %d",message,count)}//export HellofuncHello(message*C.char,countC.int)*C.char{result:=hello(C.GoString(message),int(count))returnC.CString(result)}funcmain(){}# example/go/Makefileall:cleanbuildbuild:gobuild-buildmode=c-shared-olocal/libhello.somain.goclean:@rm-rflocalPython# example/wrapper.pyfrom_exampleimportffi,libfromdataclassesimportdataclass@dataclassclassExtensionAdapter:@staticmethoddefhello(message:str,count:int=1)->str:params=ffi.new('char[]',message.encode()),ffi.cast('int',count)result=lib.Hello(*params)returnffi.string(result).decode()# example/__init__.pyfrom.wrapperimportExtensionAdapter# test.pyfromexampleimportExtensionAdapteradapter=ExtensionAdapter()print(adapter.hello(message='world',count=4))# setup.pyfrompygo_toolsimportsetupfromsetuptoolsimportfind_packagessetup(name='example',version='0.1.0',packages=find_packages(),include_package_data=True)# MANIFEST.in
include example/go/*.go
include example/lib/*.soall:cleanbuildpost_buildbuild:python-mbuild-n--wheelunzip-ldist/*.whlclean:@rm-rfbuilddist*.egg-info@rm-rf*/go/localpost_build:@rm-rfbuild*.egg-infoBuildTheMakefileat the project level runspython -m build -n --wheelin order to create the wheel file under thedistfolder.
The binary distribution should include your python and golang source code, along with the compiled library and extension.- example/lib/libhello.so
- _example.abi3.soTestingInstall the wheel file in your virtual environment and runpython test.pyto check that things are working end to end locally.DistributingBinary distributions with compiled code should be built for each platform that you want to support during runtime. [cibuildwheel]
can be used for this. However, you can also create aDockerfileanddocker-compose.yamlto build wheels forlinux/arm64andlinux/amd64:# DockerfileARGPYTHON_VERSION=3.12FROMpublic.ecr.aws/sam/build-python${PYTHON_VERSION}RUNdnfinstall-ygolangmakeRUNpipinstall-UpipsetuptoolsRUNpipinstallpygo-toolsCOPYexampleexample/COPYsetup.pyconfig.jsonMANIFEST.in./RUNpython-mbuild-n--wheelENTRYPOINT["/bin/sh"]# docker-compose.yamlversion:'3'services:builder:build:.platform:linux/arm64volumes:-./out:/var/task/out:rwentrypoint:["/bin/sh","-c"]command:["cpdist/*out/"]Related Linkscfficibuildwheel