Python Golang Tools
This project aims to bridge the gap between Python and Golang, enabling developers to easily create high performance Python
libraries with precompiled Go extensions. pygo-tools wraps the setup function from setuptools and handles the process
of compiling your library's golang source before building the wheel file. pygo-tools also patches the resulting extension,
removing the need to manually configure LD_LIBRARY_PATH or DYLD_LIBRARY_PATH before runtime.
Installation
pip install pygo-tools
Example Projects
Walkthrough for Hello World with setup.py and config.json
Project Structure
|-- Makefile
|-- config.json
|-- example
| |-- __init__.py
| |-- go
| | |-- Makefile
| | `-- main.go
| |-- lib -> go/local
| `-- wrapper.py
|-- MANIFEST.in
|-- setup.py
`-- test.py
Project Config
pygo-tools looks for config.json at the root of your project. The config contains metadata like the python package name,
golang library, python extension, and C functon signatures for the underlying library.
{
"package": "example",
"extension": "_example",
"library": "hello",
"signatures": [
"char* Hello(char* message, int count);"
]
}
Go
// example/go/main.go
package main
import "C"
import "fmt"
func hello(message string, count int) string {
return fmt.Sprintf("hello %s %d", message, count)
}
//export Hello
func Hello(message *C.char, count C.int) *C.char {
result := hello(C.GoString(message), int(count))
return C.CString(result)
}
func main() {}
# example/go/Makefile
all: clean build
build:
go build -buildmode=c-shared -o local/libhello.so main.go
clean:
@rm -rf local
Python
# example/wrapper.py
from _example import ffi, lib
from dataclasses import dataclass
@dataclass
class ExtensionAdapter:
@staticmethod
def hello(message: str, count: int = 1) -> str:
params = ffi.new('char[]', message.encode()), ffi.cast('int', count)
result = lib.Hello(*params)
return ffi.string(result).decode()
# example/__init__.py
from .wrapper import ExtensionAdapter
# test.py
from example import ExtensionAdapter
adapter = ExtensionAdapter()
print(adapter.hello(message='world', count=4))
# setup.py
from pygo_tools import setup
from setuptools import find_packages
setup(
name='example',
version='0.1.0',
packages=find_packages(),
include_package_data=True
)
# MANIFEST.in
include example/go/*.go
include example/lib/*.so
all: clean build post_build
build:
python -m build -n --wheel
unzip -l dist/*.whl
clean:
@rm -rf build dist *.egg-info
@rm -rf */go/local
post_build:
@rm -rf build *.egg-info
Build
The Makefile at the project level runs python -m build -n --wheel in order to create the wheel file under the dist folder.
The binary distribution should include your python and golang source code, along with the compiled library and extension.
- example/lib/libhello.so
- _example.abi3.so
Testing
Install the wheel file in your virtual environment and run python test.py to check that things are working end to end locally.
Distributing
Binary 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 a Dockerfile and docker-compose.yaml to build wheels for linux/arm64
and linux/amd64:
# Dockerfile
ARG PYTHON_VERSION=3.12
FROM public.ecr.aws/sam/build-python${PYTHON_VERSION}
RUN dnf install -y golang make
RUN pip install -U pip setuptools
RUN pip install pygo-tools
COPY example example/
COPY setup.py config.json MANIFEST.in ./
RUN python -m build -n --wheel
ENTRYPOINT ["/bin/sh"]
# docker-compose.yaml
version: '3'
services:
builder:
build: .
platform: linux/arm64
volumes:
- ./out:/var/task/out:rw
entrypoint: ["/bin/sh", "-c"]
command: ["cp dist/* out/"]
Related Links
Metadata
Release files for pygo-tools 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pygo-tools-0.1.8.tar.gz | 8.5 kB | Without provenance | Details for pygo-tools-0.1.8.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pygo_tools-0.1.8-py3-none-any.whl | Python 3 | none | any | Details for pygo_tools-0.1.8-py3-none-any.whl |
Total release size: 16.9 kB
Release files / pygo-tools-0.1.8.tar.gz
| Download URL | pygo-tools-0.1.8.tar.gz |
|---|---|
| Size | 8.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4707aaa145f4c1c60a683dba36e62b5999d761a4f9c0976d5a9899f0b8765b52
|
|
BLAKE2b-256 checksum How to use checksums |
4d277ee0ca64577b9fe579261ed1e52b9a805c9767a7f590786a1c9887535386
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.0.0 CPython/3.10.0
|
Release files / pygo_tools-0.1.8-py3-none-any.whl
| Download URL | pygo_tools-0.1.8-py3-none-any.whl |
|---|---|
| Size | 8.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
688bc2b95b8b107c8cfac5f10906f8769349f18e75dffaf746cf79b5e3cea968
|
|
BLAKE2b-256 checksum How to use checksums |
54eca68df2df8b8cc02ce60d4573424bdf93dd0590ae5cad85dd6d4a4fe33b8e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.0.0 CPython/3.10.0
|
Security for pygo-tools 0.1.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.