Metadata-Version: 2.4
Name: gofre
Version: 0.1.1
Summary: Build system for creating Python packages that bundle Go binaries.
Project-URL: Homepage, https://github.com/grackin/gofre
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Go
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# GoFre 🧇

A build system for creating Python packages with Go extensions, inspired by [maturin](https://github.com/PyO3/maturin)
for Rust/Python.

## Features

- **Pure Go**: No CGo required, thanks to [purego](https://github.com/ebitengine/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

```bash
go install github.com/grackin/gofre@latest
```

Or build from source:

```bash
git clone https://github.com/grackin/gofre
cd gofre
go build -o gofre .
```

## Quick Start

### Create a new project

```bash
gofre new my-package
cd my-package
```

### Write Go code

```go
// 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

```bash
gofre develop
```

### Use in Python

```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](https://programming-language-benchmarks.vercel.app/go-vs-python):

| 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](examples/webserver/README.md).

### 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](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

```bash
# 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

```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.

```toml
[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

- [maturin](https://github.com/PyO3/maturin) - Inspiration for the build system
- [purego](https://github.com/ebitengine/purego) - CGo-free C function calls
- [cffi](https://cffi.readthedocs.io/) - Python FFI
- [programming-language-benchmarks](https://programming-language-benchmarks.vercel.app/) - Benchmark data
