SkillAgentSearch skills...

Pyproc

Call Python from Go without CGO or microservices - Unix domain socket based IPC for ML inference and data processin

Install / Use

/learn @YuminosukeSato/Pyproc
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

pyproc

Run Python like a local function from Go — no CGO, no microservices.

Go Reference Go Report Card Go Coverage codecov PyPI License CI

🎯 Purpose & Problem Solved

The Challenge

Go excels at building high-performance web services, but sometimes you need Python:

  • Machine Learning Models: Your models are trained in PyTorch/TensorFlow
  • Data Science Libraries: You need pandas, numpy, scikit-learn
  • Legacy Code: Existing Python code that's too costly to rewrite
  • Python-Only Libraries: Some libraries only exist in Python ecosystem

Traditional solutions all have major drawbacks:

| Solution | Problems | |----------|----------| | CGO + Python C API | Complex setup, crashes can take down entire Go service, GIL still limits performance | | REST/gRPC Microservice | Network latency, deployment complexity, service discovery, more infrastructure | | Shell exec | High startup cost (100ms+), no connection pooling, process management nightmare | | Embedded Python | GIL bottleneck, memory leaks, difficult debugging |

The Solution: pyproc

pyproc lets you call Python functions from Go as if they were local functions, with:

  • Zero network overhead - Uses Unix Domain Sockets for IPC
  • Process isolation - Python crashes don't affect your Go service
  • True parallelism - Multiple Python processes bypass the GIL
  • Simple deployment - Just your Go binary + Python scripts
  • Connection pooling - Reuse connections for high throughput

🎯 Target Audience & Use Cases

Perfect for teams who need to:

  • Integrate existing Python ML models (PyTorch, TensorFlow, scikit-learn) into Go services
  • Process data with Python libraries (pandas, numpy) from Go applications
  • Handle 1-5k RPS with JSON payloads under 100KB
  • Deploy on the same host/pod without network complexity
  • Migrate gradually from Python microservices to Go while preserving Python logic

Ideal deployment scenarios:

  • Kubernetes same-pod deployments with shared volume for UDS
  • Docker containers with shared socket volumes
  • Traditional server deployments on Linux/macOS

❌ Non-Goals

pyproc is NOT designed for:

  • Cross-host communication - Use gRPC/REST APIs for distributed systems
  • Windows UDS support - Windows named pipes are not supported
  • GPU management - Use dedicated ML serving frameworks (TensorRT, Triton)
  • Large-scale ML serving - Consider Ray Serve, MLflow, or KServe for enterprise ML
  • Real-time streaming - Use Apache Kafka or similar for high-throughput streams
  • Database operations - Use native Go database drivers directly

🔄 Alternatives & Comparison

pyproc is a dedicated IPC engine for integrating Python ML/DS code into Go services on the same host. It differs from general-purpose plugin systems and embedded runtimes in design philosophy.

| Solution | Pros | Cons | Best For | |----------|------|------|----------| | go-embed-python | ✅ Python runtime embedded / No Python installation required on host | ❌ Increased binary size / Python operations are DIY | Tools distributed as a single binary | | go-plugin (HashiCorp) | ✅ Multi-language plugin support / Proven in Terraform, Vault | ❌ Requires gRPC proto definitions / Not optimized for Python | Language-agnostic plugin architecture | | pyproc | ✅ Optimized for ML/DS workloads / Built-in worker pool, health checks, auto-restart / Ultra-low latency (~45µs p50) | ❌ Python-only / Same-host only | Integrating Python ML/DS into Go services |

When to Choose What

Choose go-embed-python if:

  • You want to distribute a single binary (no Python required on host)
  • Increased binary size is acceptable

Choose go-plugin if:

  • You need multi-language support (Rust, Ruby, etc.) beyond Python
  • You're integrating with HashiCorp ecosystem

Choose pyproc if:

  • You're calling Python ML models (PyTorch, TensorFlow) or DS libraries (pandas, NumPy) from Go
  • You need low latency (<100µs) on the same host
  • You want built-in worker pool management, health checks, and auto-restart

Non-Goals (Recap)

pyproc is NOT designed for:

  • General-purpose plugin system → Use go-plugin
  • Embedded Python runtime → Consider go-embed-python
  • Cross-host communication → Use gRPC/REST microservices
  • GPU cluster management → Use Ray Serve, Triton

🔐 Trust Model & Security Considerations

pyproc is designed for trusted code execution

pyproc is NOT a sandbox environment. It operates under the following assumptions:

  • Target: Python code developed and managed by your organization (ML models, data processing logic)
  • Process isolation: Python crashes do not affect the Go service
  • No security isolation: Python workers can access the same filesystem and network as the parent Go process

Intended Use Cases

✅ Recommended:

  • Running your own trained PyTorch/TensorFlow models for inference
  • Data transformation pipelines using pandas/NumPy
  • Integrating scikit-learn models into Go recommendation engines

❌ Not Recommended:

  • Executing arbitrary user-submitted Python scripts
  • Dynamically loading third-party plugins
  • Running untrusted code

Security Details

For detailed threat model, security architecture, and best practices, see SECURITY.md.

Key Guarantees:

  • OS-level access control via Unix Domain Socket filesystem permissions
  • Fault tolerance through process isolation
  • Configurable resource limits (memory, CPU)

Limitations:

  • Inter-process communication on the same host only (cross-host is out of scope)
  • Does not provide sandbox environment (use gVisor, Firecracker if needed)

📋 Compatibility Matrix

| Component | Requirements | |-----------|-------------| | Operating System | Linux, macOS (Unix Domain Sockets required) | | Go Version | 1.22+ | | Python Version | 3.9+ (3.12 recommended) | | Deployment | Same host/pod only | | Container Runtime | Docker, containerd, any OCI-compatible | | Orchestration | Kubernetes (same-pod), Docker Compose, systemd | | Architecture | amd64, arm64 |

✨ Features

  • No CGO Required - Pure Go implementation using Unix Domain Sockets
  • Bypass Python GIL - Run multiple Python processes in parallel
  • Type-Safe API - Call Python with compile-time type checking using Go generics (zero overhead)
  • Minimal Overhead - 45μs p50 latency, 200,000+ req/s with 8 workers
  • Production Ready - Health checks, graceful shutdown, automatic restarts
  • Easy Deployment - Single binary + Python scripts, no service mesh needed
  • Full Observability - OpenTelemetry tracing, Prometheus metrics, structured logging (v0.7.1+)

🚀 Quick Start (5 minutes)

1. Install

Go side:

go get github.com/YuminosukeSato/pyproc@latest

Python side:

pip install pyproc-worker

2. Create a Python Worker

# worker.py
from pyproc_worker import expose, run_worker

@expose
def predict(req):
    """Your ML model or Python logic here"""
    return {"result": req["value"] * 2}

if __name__ == "__main__":
    run_worker()

3. Call from Go (Type-Safe API - Recommended)

package main

import (
    "context"
    "fmt"
    "log"
    "github.com/YuminosukeSato/pyproc/pkg/pyproc"
)

// Define request/response types (compile-time type safety)
type PredictRequest struct {
    Value float64 `json:"value"`
}

type PredictResponse struct {
    Result float64 `json:"result"`
}

func main() {
    // Create a pool of Python workers
    pool, err := pyproc.NewPool(pyproc.PoolOptions{
        Config: pyproc.PoolConfig{
            Workers:              4,  // Run 4 Python processes
            MaxInFlight:          10, // Global concurrent requests
            MaxInFlightPerWorker: 1,  // Per-worker in-flight cap
        },
        WorkerConfig: pyproc.WorkerConfig{
            SocketPath:   "/tmp/pyproc.sock",
            PythonExec:   "python3",
            WorkerScript: "worker.py",
        },
    }, nil)
    if err != nil {
        log.Fatal(err)
    }

    // Start all workers
    ctx := context.Background()
    if err := pool.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer pool.Shutdown(ctx)

    // Call Python function with type safety (automatically load-balanced)
    result, err := pyproc.CallTyped[PredictRequest, PredictResponse](
        ctx, pool, "predict", PredictRequest{Value: 42},
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Result: %v\n", result.Result) // Result: 84 (type-safe!)
}

4. Run

go run main.go

That's it! You're now calling Python from Go without CGO or microservices.

Try the demo in this repo

If you cloned this repository, you can run a working end to end example without installing a Python package by using the bundled worker module.

make demo

This starts a Python worker from examples/basic/worker.py and calls it from Go. The example adjusts PYTHONPATH to import the local worker/python/pyproc_worker package.

📊 Observability (v0.7.1+)

pyproc includes built-in support for distribute

View on GitHub
GitHub Stars292
CategoryDevelopment
Updated20h ago
Forks14

Languages

Go

Security Score

95/100

Audited on Apr 1, 2026

No findings