Build system for creating Python packages that bundle Go binaries.
Project description
GoFre ๐ง
A build system for creating Python packages with Go extensions, inspired by maturin for Rust/Python.
Features
- Pure Go: No CGo required, thanks to purego
- cffi Bindings: Fast, type-safe Python bindings
- Cross-Platform: Linux, macOS, Windows support
- PEP 517 Compliant: Standard Python packaging
- Binary Bundling: Include Go binaries in your Python packages
Installation
go install github.com/grackin/gofre@latest
Or build from source:
git clone https://github.com/grackin/gofre
cd gofre
go build -o gofre .
Quick Start
Create a new project
gofre new my-package
cd my-package
Write Go code
// pkg/core/core.go
package core
//export Add
func Add(a, b int64) int64 {
return a + b
}
//export Multiply
func Multiply(a, b int64) int64 {
return a * b
}
Build and install
gofre develop
Use in Python
import my_package
result = my_package.Add(2, 3)
print(result) # 5
Commands
| Command | Description |
|---|---|
gofre new <name> |
Create a new project |
gofre build |
Build the package |
gofre build -o <dir> |
Build with custom output directory |
gofre develop |
Build and install in current venv |
gofre publish |
Publish to PyPI |
gofre bench |
Run benchmarks |
Benchmarks
GoFre provides significant performance improvements over pure Python by leveraging Go's performance.
Note: The overhead of FFI calls means that very simple operations (like sum()) may not benefit from Go extensions.
GoFre shines for complex computational workloads.
fibonacci(30) - Recursive Implementation
| Implementation | Time | Speedup |
|---|---|---|
| Pure Python | 175.1 ms | 1.0x |
| GoFre | 3.0 ms | 58x |
count_primes(100,000)
| Implementation | Time | Speedup |
|---|---|---|
| Pure Python | 97.9 ms | 1.0x |
| GoFre | 1.5 ms | 63x |
matrix_multiply(50x50)
| Implementation | Time | Speedup |
|---|---|---|
| Pure Python | 14.8 ms | 1.0x |
| GoFre | 0.6 ms | 24x |
Real-World Benchmarks
Based on programming-language-benchmarks:
| Benchmark | Pure Python | Go Forge | Speedup |
|---|---|---|---|
| binarytrees(18) | >30s | 2.3s | >13x |
| fasta(2.5M) | 4.7s | 0.12s | 39x |
| knucleotide | >30s | 0.68s | >44x |
| json-serde | 1.9s | 0.14s | 14x |
Webserver Benchmarks
GoFre also benchmarks HTTP server performance across six approaches โ from pure Python to Go with embedded pocketpy. See the full results and methodology.
Quick Summary
| Server | Req/sec (avg) | Idle RSS | Peak RSS | Binary |
|---|---|---|---|---|
| Pure Go (stdlib) | ~42,000 | 10.3 MB | 19.0 MB | 8.0 MB |
| Go + pocketpy | ~40,000 | 13.3 MB | 21.8 MB | 9.7 MB |
| Pure Python | ~4,600 | 15.2 MB | 15.4 MB | โ |
| CPython + Go cffi | ~4,500 | 23.1 MB | 29.6 MB | 2.1 MB |
| FastAPI + uvicorn | ~7,000 | 36.9 MB | 37.4 MB | โ |
| Flask (dev server) | ~2,100 | 26.5 MB | 27.8 MB | โ |
Go + pocketpy delivers ~5-6x the throughput of FastAPI/Flask while keeping memory under 22 MB peak in a single 9.7 MB binary. See examples/webserver/README.md for full details.
Project Structure
gofre/
โโโ main.go
โโโ go.mod
โโโ cmd/ # CLI commands
โโโ internal/ # Library code
โ โโโ bindings/ # Go parser + Python code generator
โ โโโ build/ # Build system (Go + wheel)
โ โโโ config/ # Config loader (pyproject.toml)
โ โโโ pocketpy/ # Embedded pocketpy interpreter (excluded with no_pocketpy tag)
โ โโโ gomod/ # Bridge modules (http, json)
โโโ tests/ # Unit tests
User Project Structure
my-package/
โโโ pyproject.toml
โโโ go.mod
โโโ pkg/
โ โโโ core/
โ โโโ core.go # Go code with //export functions
โโโ cmd/
โโโ main.go # CGo bridge
Build artifacts go to build/ and dist/ by default. Use --output-dir to put them elsewhere.
How It Works
- Parse: GoFre parses your Go source files to find exported functions
- Build: Compiles Go code to a shared library (
.so,.dylib,.dll) - Generate: Creates cffi bindings for Python
- Package: Builds a wheel with the shared library and Python wrappers
Cross-Compilation
# Build for Linux from macOS
GOOS=linux GOARCH=amd64 gofre build
# Build for Windows from macOS
GOOS=windows GOARCH=amd64 gofre build
# Build for macOS arm64 from Intel
GOOS=darwin GOARCH=arm64 gofre build
Platform Support
| Platform | Architecture | Status |
|---|---|---|
| Linux | x86_64 | โ |
| Linux | aarch64 | โ |
| macOS | x86_64 | โ |
| macOS | arm64 | โ |
| Windows | x86_64 | โ |
| Windows | arm64 | โ |
Configuration
pyproject.toml
[build-system]
requires = ["gofre>=0.1.0"]
build-backend = "gofre.build"
[project]
name = "my-package"
version = "0.1.0"
requires-python = ">=3.8"
dependencies = ["cffi>=1.0.0"]
[tool.gofre]
module = "github.com/user/my-package"
bindings = "cffi"
pkg-dir = "pkg"
build-tags = []
Build Tags
Use build-tags to pass custom Go build tags to go build. This is useful for excluding parts of the codebase from
compilation.
[tool.gofre]
module = "github.com/user/my-package"
build-tags = ["no_pocketpy"]
This produces:
go build -buildmode=c-shared -tags no_pocketpy -o output ./cmd/
GoFre ships with the no_pocketpy build tag, which excludes the embedded pocketpy interpreter and related bridge code.
Files excluded by build tags:
internal/pocketpy/*โ pocketpy Go wrapper and C sourceinternal/gomod/http/register.goโ pocketpy HTTP bridgeinternal/gomod/json/register.goโ pocketpy JSON bridgeexamples/webserver_binary/โ pocketpy-based webserver example
When no_pocketpy is set, the cffi exports in http/cffi_exports.go and json/cffi_exports.go remain available. If
your cmd/ imports pocketpy directly, the build will fail with a missing import error.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License
Acknowledgments
- maturin - Inspiration for the build system
- purego - CGo-free C function calls
- cffi - Python FFI
- programming-language-benchmarks - Benchmark data
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gofre-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gofre-0.1.1-py3-none-any.whl
- Upload date:
- Size: 2.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
633a1d2b98bbd4768aed0a671c9e281175e75d0ce3841898479e84cb66b9f15e
|
|
| MD5 |
ae7b3c1c62cb90b34ea60d77a5c85420
|
|
| BLAKE2b-256 |
702178714e4ad43133ba591c8c226d20ba5801fbfbb09de7086ec3974a61c64e
|
Provenance
The following attestation bundles were made for gofre-0.1.1-py3-none-any.whl:
Publisher:
workflow.yml on NoRaincheck/gofre
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gofre-0.1.1-py3-none-any.whl -
Subject digest:
633a1d2b98bbd4768aed0a671c9e281175e75d0ce3841898479e84cb66b9f15e - Sigstore transparency entry: 2172991178
- Sigstore integration time:
-
Permalink:
NoRaincheck/gofre@e7608bdea23b1f8b1adffb1c3654cc48ae356482 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/NoRaincheck
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@e7608bdea23b1f8b1adffb1c3654cc48ae356482 -
Trigger Event:
push
-
Statement type: