Call Go from Python and call Python from Go, simply.
Project description
GoPyLink
A lightweight Python & Go cross-language call framework for in-process communication.
Features
- Python Call Go - Python call Go functions, create Go type instances and invoke methods
- Go Call Python - Go call Python functions, create Python class instances and invoke methods
- Simple API - Minimal setup with intuitive interfaces
Limitations
GoPyLink is designed for data exchange only. All function parameters and return values must be plain data types (primitives, collections, structs with all fields public).
Channels, goroutines, functions and interface types (except any) are not supported as parameters or return values.
Installation
Go
go get github.com/ray4go/go-ray/gopylink
Python
pip install gopylink
Requires: Go 1.21+, Python 3.7+
C build environment is required, click to show installation commands.
# Ubuntu/Debian
sudo apt install build-essential
# CentOS/RHEL
sudo yum groupinstall "Development Tools"
# macOS
xcode-select --install
Python calling Go
1. Export Go Functions/Types
Create a lib.go file:
package main
import "github.com/ray4go/gopylink"
// Functions to export - all exported methods become callable from Python
type Functions struct{}
func (Functions) Hello(name string) string {
return "Hello " + name
}
func (Functions) Add(a, b int) int {
return a + b
}
// Classes to export - each method creates a new instance
type Classes struct{}
type Counter struct {
value int
}
func (Classes) Counter(initial int) *Counter {
return &Counter{value: initial}
}
func (c *Counter) Incr(n int) int {
c.value += n
return c.value
}
func (c *Counter) Value() int {
return c.value
}
func init() {
gopylink.Init(Functions{}, Classes{})
}
func main() {}
2. Build Go Shared Library
go build -buildmode=c-shared -o go.lib .
3. Call Go from Python
# main.py
import gopylink
# Load the Go library
lib = gopylink.load_go_lib("go.lib")
# Call Go functions
result = lib.func_call("Hello", "World")
print(result) # Output: Hello World
result = lib.func_call("Add", 10, 20)
print(result) # Output: 30
# Create Go type instance and call methods
counter = lib.new_type("Counter", 0)
print(counter.Incr(5)) # Output: 5
print(counter.Incr(3)) # Output: 8
print(counter.Value()) # Output: 8
Run the python script:
python main.py
Go calling Python
1. Export Python Functions/Classes
# main.py
import gopylink
@gopylink.export
def greet(name: str) -> str:
return f"Hi, {name}!"
@gopylink.export
def multiply(a, b):
return a * b
@gopylink.export
class Counter:
def __init__(self, initial=0):
self.value = initial
def incr(self, n):
self.value += n
return self.value
if __name__ == "__main__":
lib = gopylink.load_go_lib("go.lib")
lib.func_call("Start") # Start the Go logic
2. Call Python from Go
package main
import (
"fmt"
"github.com/ray4go/gopylink"
)
type functions struct{}
func (functions) Start() {
// Call Python function
result := gopylink.PythonFuncCall("greet", "Gopher")
val, err := result.Get()
fmt.Printf("greet: %v, err: %v\n", val, err) // Output: greet: Hello, Gopher!, err: <nil>
// Call with typed result
result = gopylink.PythonFuncCall("multiply", 6, 7)
product, err := gopylink.Get[int](result)
fmt.Printf("multiply: %v, err: %v\n", product, err) // Output: multiply: 42, err: <nil>
// Create Python class instance
cnt := gopylink.NewPythonClassInstance("Counter", 10)
defer cnt.Close()
res := cnt.MethodCall("incr", 5)
val, err = res.Get()
fmt.Printf("Counter.incr: %v, err: %v\n", val, err) // Output: Counter.incr: 15, err: <nil>
}
func init() {
gopylink.Init(functions{}, nil)
}
func main() {}
3. Build and Run
go build -buildmode=c-shared -o go.lib .
python main.py
Note that when calling Python from Go, the entry point remains the Python script. The Go shared library is loaded into the Python process, which then starts the Go logic.
API Reference
Python API
| Function | Description |
|---|---|
load_go_lib(path) |
Load a Go shared library |
lib.func_call(name, *args) |
Call a Go function by name |
lib.new_type(name, *args) |
Create a Go type instance |
@export |
Decorator to export Python function/class to Go |
Go API
| Function | Description |
|---|---|
Init(funcRegister, classRegister) |
Initialize and register Go functions/classes |
PythonFuncCall(name, args...) |
Call a Python function |
NewPythonClassInstance(name, args...) |
Create a Python class instance |
Get[T](result) |
Get typed result from Python call |
result.Get() |
Get result as (any, error) |
handle.MethodCall(name, args...) |
Call method on Python instance |
handle.Close() |
Release Python instance |
See Go API Reference for more details.
Type Conversion
Types are automatically converted via msgpack:
| Go Type | Python Type |
|---|---|
int, int64, etc. |
int |
float32, float64 |
float |
bool |
bool |
string |
str |
[]byte |
bytes |
| slice, array | list |
map |
dict |
struct |
dict |
nil |
None |
For detailed type conversion rules, see the Cross-Language Type Conversion Guide.
Thread Safety
GoPyLink operations are thread-safe. Multiple goroutines/threads can safely call cross-language functions concurrently.
Performance Notes
Go FFI has approximately 30ns overhead per call compared to native C/C++ FFI due to Go's virtual stack. This overhead is:
- Negligible for coarse-grained operations
- Significant for micro-calls requiring millions of invocations per second
Best Practices
Golang Parameter and return types
- Prefer concrete types (primitive types, composites, structs, and their pointers) over interface types for parameters
- Do not use interface types as return values except for
anytype.
Golang Error handling
Do not return error (as it is an interface) directly from Ray Task functon / Actor methods. Instead, return concrete
types to indicate errors (e.g., return int for error code), or just panic in your code.
When ObjectRef.GetAll() / ObjectRef.Getinto() / ray.GetN(obj) is called on a panic-ed task/actor, it will return an error.
You can use fmt.Printf("%+v", err) to print the error stack trace.
License
MIT
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 Distribution
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 gopylink-1.0.1.tar.gz.
File metadata
- Download URL: gopylink-1.0.1.tar.gz
- Upload date:
- Size: 5.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
631c28c5dd1465e0ecffce4e3d3012e806a2c90f402d7ddd07afdc0a88602da3
|
|
| MD5 |
7cc2b1c672eaa7a6c3c01fcffabf3148
|
|
| BLAKE2b-256 |
d0222eefe408cd9f1fa27762c0446024fc1bff1bd5c4d289e8da8cf02a66d1c0
|
Provenance
The following attestation bundles were made for gopylink-1.0.1.tar.gz:
Publisher:
publish.yml on ray4go/GoPyLink
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gopylink-1.0.1.tar.gz -
Subject digest:
631c28c5dd1465e0ecffce4e3d3012e806a2c90f402d7ddd07afdc0a88602da3 - Sigstore transparency entry: 813566116
- Sigstore integration time:
-
Permalink:
ray4go/GoPyLink@82db81d116cded7477d8fafcc7bdea1f91ca04f3 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/ray4go
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@82db81d116cded7477d8fafcc7bdea1f91ca04f3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gopylink-1.0.1-py3-none-any.whl.
File metadata
- Download URL: gopylink-1.0.1-py3-none-any.whl
- Upload date:
- Size: 6.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fed4366ae648cda2274b196a9ed566c46fecc139a498a2af2b2e4eb5217fe4da
|
|
| MD5 |
fd2b3699b60c2313384503c1cedcc66d
|
|
| BLAKE2b-256 |
72487f53601cde8639d2f40981f0d7968630fe65a2a45426a28a126b566f6601
|
Provenance
The following attestation bundles were made for gopylink-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on ray4go/GoPyLink
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gopylink-1.0.1-py3-none-any.whl -
Subject digest:
fed4366ae648cda2274b196a9ed566c46fecc139a498a2af2b2e4eb5217fe4da - Sigstore transparency entry: 813566124
- Sigstore integration time:
-
Permalink:
ray4go/GoPyLink@82db81d116cded7477d8fafcc7bdea1f91ca04f3 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/ray4go
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@82db81d116cded7477d8fafcc7bdea1f91ca04f3 -
Trigger Event:
push
-
Statement type: