Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

41 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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/NoRaincheck/gofre@latest

Or build from source:

git clone https://github.com/NoRaincheck/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

  1. Parse: GoFre parses your Go source files to find exported functions
  2. Build: Compiles Go code to a shared library (.so, .dylib, .dll)
  3. Generate: Creates cffi bindings for Python
  4. 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 source
  • internal/gomod/http/register.go β€” pocketpy HTTP bridge
  • internal/gomod/json/register.go β€” pocketpy JSON bridge
  • examples/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

About

(Experimental) - Write Go code, embed it in Python. Write Python web server, create a Go Binary (with PocketPy)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages