Skip to main content

Zero-dependency polyglot code execution — run 23 languages from Python

Project description

Polyrun logo

⚡ Zero-dependency polyglot code execution

Run code in 23 languages from a single Python import — no pip dependencies required.

CI PyPI Python MIT License Downloads


from polyrun import Rust, Node, Go, Python, Bash, Julia, Zig

result = Rust.run('fn main() { println!("Hello from Rust! ⚡"); }')
print(result.text())  # Hello from Rust! ⚡

⚡ Supported languages (23)

# Language Import Binary needed Type
1 Node.js / JavaScript Node, JS node Interpreted
2 Python Python python3 Interpreted
3 Bash Bash bash Interpreted
4 Ruby Ruby ruby Interpreted
5 PHP PHP php Interpreted
6 Perl Perl perl Interpreted
7 Lua Lua lua Interpreted
8 R R Rscript Interpreted
9 TypeScript TypeScript, TS tsx / ts-node / npx Transpiled
10 Go Go go Compiled
11 Rust Rust rustc Compiled
12 C C gcc Compiled
13 C++ Cpp g++ Compiled
14 Java Java javac + java Compiled
15 Kotlin Kotlin kotlinc + java Compiled to JAR
16 Swift Swift swift Interpreted
17 Haskell Haskell runghc Interpreted
18 Elixir Elixir elixir Interpreted
19 Dart Dart dart JIT
20 Julia Julia julia JIT
21 Groovy Groovy groovy Interpreted
22 Zig Zig zig Compiled

No pip dependencies. Uses only Python's stdlib: subprocess, tempfile, shutil, json. Language runtimes must be installed separately and on your PATH.


⚡ Installation

pip install polyrun

From source:

git clone https://github.com/og-py3/Polyrun.git
cd Polyrun
pip install -e .

⚡ Quick start

Hello world in every language

from polyrun import (
    Node, Python, Ruby, PHP, Bash, Perl, Lua, R, TypeScript,
    Go, Rust, C, Cpp, Java, Kotlin, Swift, Haskell,
    Elixir, Dart, Julia, Groovy, Zig,
)

Node.run("console.log('⚡ node')")
Python.run("print('⚡ python')")
Ruby.run("puts '⚡ ruby'")
PHP.run("echo '⚡ php';")
Bash.run("echo '⚡ bash'")
Perl.run("print '⚡ perl\n';")
Lua.run("print('⚡ lua')")
R.run("cat('⚡ R\n')")
TypeScript.run('const x: string = "⚡ typescript"; console.log(x);')
Go.run('package main\nimport "fmt"\nfunc main(){fmt.Println("⚡ go")}')
Rust.run('fn main(){println!("⚡ rust");}')
C.run('#include <stdio.h>\nint main(){puts("⚡ c");return 0;}')
Cpp.run('#include <iostream>\nint main(){std::cout<<"⚡ cpp"<<std::endl;}')
Java.run('public class Hi{public static void main(String[] a){System.out.println("⚡ java");}}')
Kotlin.run('fun main(){println("⚡ kotlin")}')
Swift.run('print("⚡ swift")')
Haskell.run('main :: IO ()\nmain = putStrLn "⚡ haskell"')
Elixir.run('IO.puts("⚡ elixir")')
Dart.run('void main(){print("⚡ dart");}')
Julia.run('println("⚡ julia")')
Groovy.run("println '⚡ groovy'")
Zig.run('const std=@import("std");\npub fn main()!void{try std.io.getStdOut().writer().print("⚡ zig\\n",.{});}')

⚡ RunResult API

result = Python.run("print('hello')")

result.text()        # "hello"          — stripped stdout
result.lines()       # ["hello"]        — stdout as list
result.json()        # parse stdout as JSON
result.ok()          # True             — returncode == 0
result.stdout        # raw stdout string
result.stderr        # raw stderr string
result.returncode    # integer exit code
result.language      # "Python"

⚡ stdin passthrough

result = Node.run(
    "process.stdin.resume(); let d=''; "
    "process.stdin.on('data', c => d += c); "
    "process.stdin.on('end', () => console.log(d.trim().toUpperCase()));",
    input_data="hello world",
)
print(result.text())  # HELLO WORLD

⚡ Environment variables

result = Bash.run("echo $GREETING", env={"GREETING": "⚡ polyrun"})
print(result.text())  # ⚡ polyrun

⚡ Error handling

from polyrun import Rust
from polyrun.exceptions import CompilationError, PolyRuntimeError, LanguageNotFoundError

try:
    Rust.run("fn main() { this_wont_compile }")

except CompilationError as e:
    print(f"❌ Compile error [{e.language}]: {e.stderr}")

except PolyRuntimeError as e:
    print(f"❌ Runtime error [{e.language}] exit {e.returncode}: {e.stderr}")

except LanguageNotFoundError as e:
    print(f"❌ Install {e.binary} to use {e.language}")
Exception When raised Attributes
CompilationError Compiler exits non-zero .language, .stderr
PolyRuntimeError Program exits non-zero .language, .stderr, .returncode
LanguageNotFoundError Binary not on PATH .language, .binary

RuntimeError is kept as an alias for PolyRuntimeError for backwards compatibility.


⚡ Pipeline — chain languages

from polyrun import Node, Python, Bash
from polyrun.pipeline import Pipeline

result = (
    Pipeline()
    .then(Node,   "console.log(JSON.stringify({value: 21}))")
    .then(Python, "import sys,json; d=json.load(sys.stdin); print(d['value']*2)")
    .then(Bash,   'read n; echo "⚡ The answer is $n"')
    .run()
)
print(result.text())  # ⚡ The answer is 42

⚡ Bridge — JSON data exchange

from polyrun import Go
from polyrun.pipeline import Bridge

code = """
package main
import ("encoding/json";"fmt";"os")
func main() {
    var d map[string]interface{}
    json.NewDecoder(os.Stdin).Decode(&d)
    nums := d["numbers"].([]interface{})
    sum := 0.0
    for _, n := range nums { sum += n.(float64) }
    fmt.Println(sum)
}
"""
result = Bridge.send(Go, code, data={"numbers": [1,2,3,4,5]})
print(result.text())  # 15

⚡ Check installed languages

from polyrun.detect import check, available

check()   # prints ⚡ Polyrun availability table
⚡ Polyrun — language availability (8/22 installed)
──────────────────────────────────────────────────
  ✅  Node.js / JavaScript
  ✅  Python
  ❌  Java
  ✅  Rust
  ...

⚡ Architecture

┌──────────────────────────────────────────────────────────┐
│                    Your Python code                       │
│  from polyrun import Rust, Node, Go, Julia               │
│  result = Rust.run(code, input_data="hello")             │
└────────────────────────┬─────────────────────────────────┘
                         ▼
┌──────────────────────────────────────────────────────────┐
│  ⚡ polyrun                                               │
│  BaseRunner — 23 language runners                        │
│  Pipeline   — stdout → stdin chaining                    │
│  Bridge     — JSON encode/decode                         │
│  detect     — shutil.which availability checks           │
│  exceptions — CompilationError / PolyRuntimeError / …   │
└────────────────────────┬─────────────────────────────────┘
                         ▼
┌──────────────────────────────────────────────────────────┐
│  subprocess + tempfiles (isolated per run)               │
│  1. Write code → temp file                               │
│  2. Compile if needed (gcc, rustc, javac, kotlinc, zig)  │
│  3. Run via subprocess, capture stdout/stderr            │
│  4. Return RunResult, clean up temp dir                  │
└──────────────────────────────────────────────────────────┘

⚡ Project structure

polyrun/
├── polyrun/
│   ├── __init__.py           # 23 runner singletons
│   ├── base.py               # BaseRunner + RunResult
│   ├── pipeline.py           # Pipeline + Bridge
│   ├── detect.py             # ⚡ availability report
│   ├── exceptions.py         # CompilationError / PolyRuntimeError / LanguageNotFoundError
│   ├── py.typed              # PEP 561 marker
│   └── runners/              # 22 runner modules
│       ├── node.py  java.py  c.py    cpp.py   rust.py  go.py
│       ├── python.py  ruby.py  php.py  bash.py  typescript.py  perl.py
│       ├── lua.py  r.py  kotlin.py  haskell.py  swift.py  elixir.py
│       └── dart.py  julia.py  groovy.py  zig.py
├── tests/
│   ├── conftest.py                    # auto-skip for missing runtimes
│   ├── test_base.py
│   ├── test_detect.py
│   ├── test_exceptions.py
│   ├── test_pipeline.py
│   ├── test_runners_interpreted.py    # Node, Python, Ruby, PHP, Bash, Perl, Lua, R
│   ├── test_runners_compiled.py       # C, C++, Rust, Go, Java, Kotlin, Haskell, Swift, Dart, Zig
│   └── test_runners_functional.py     # TypeScript, Elixir, Julia, Groovy + cross-language
├── logo.svg
├── demo.py
├── pyproject.toml
├── setup.py
├── CHANGELOG.md
├── CONTRIBUTING.md
└── LICENSE

⚡ Running the tests

pip install pytest pytest-cov
pytest tests/ -v

# With coverage report:
pytest tests/ --cov=polyrun --cov-report=term-missing

# Tests auto-skip for any runtime not installed on your machine.

⚡ Publishing to PyPI

pip install build twine
python -m build
twine upload dist/*

⚡ Contributing

See CONTRIBUTING.md — adding a new language runner takes about 30 lines of code.


License

MIT — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polyrun-0.2.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

polyrun-0.2.0-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

Details for the file polyrun-0.2.0.tar.gz.

File metadata

  • Download URL: polyrun-0.2.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.6

File hashes

Hashes for polyrun-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b915568bec5a8c00bba5a5cbd989813c2f67a5f4fc442bce6c202fae68e98bf9
MD5 99192e4f7f919df832447038466075f9
BLAKE2b-256 582bb3ab2a06edc1b60f5f931b312f06bde6c7d1ecb045860dc3ffe35acf5432

See more details on using hashes here.

File details

Details for the file polyrun-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: polyrun-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.6

File hashes

Hashes for polyrun-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5af6b908f55a2c3e6e1b5792ae961a1666ddc92c1f1ced245a9b921c694f2439
MD5 748358c65fefc658e89c326cd2517683
BLAKE2b-256 b9005a310ea39edbc5cb0d41d2885bef73b5b7a72d02c57536634fddb64b747d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page