SnakeBridge Examples

Copy Markdown View Source
            
    
        
        
       
            

This directory contains examples demonstrating SnakeBridge's capabilities for bridging Elixir and Python over gRPC.

Quick Start

Run all examples:

./run_all.sh

Or run individual examples:

cd basic && mix run --no-start -e Demo.run
cd math_demo && mix run --no-start -e Demo.run
cd wrapper_args_example && mix run --no-start -e Demo.run
cd signature_showcase && mix run --no-start -e Demo.run
cd coverage_report_example && mix run --no-start -e Demo.run
cd stub_fallback_example && mix run --no-start -e Demo.run
cd class_constructor_example && mix run --no-start -e Demo.run
cd streaming_example && mix run --no-start -e Demo.run
cd strict_mode_example && mix run --no-start -e Demo.run
cd python_idioms_example && mix run --no-start -e Demo.run
cd universal_ffi_example && mix run --no-start -e Demo.run
cd multi_session_example && mix run --no-start -e Demo.run
cd affinity_defaults_example && mix run --no-start -e Demo.run
# etc.

Examples Overview

ExampleDescriptionKey Features
basicCore functionality demoMath, strings, JSON, OS calls with explicit output
math_demoDiscovery APIs and runtime calls__functions__/0, __search__/1, generated modules
proof_pipelineMulti-step LaTeX/SymPy pipelineChaining multiple Python libraries
types_showcasePython ↔ Elixir type mappingint, float, str, list, dict, None, bool, bytes
error_showcaseML error translationShapeMismatch, OutOfMemory, DtypeMismatch
docs_showcaseDocumentation parsingRST/Google/NumPy docstrings, math rendering
telemetry_showcaseTelemetry integrationEvent logging, timing, metrics
twenty_libraries20 Python stdlib librariesPerformance demo with 40 sequential gRPC calls
wrapper_args_exampleWrapper opts and varargsOptional kwargs, runtime flags, __args__
signature_showcaseSignature + arity modelOptional args, keyword-only validation, variadic fallback
coverage_report_exampleCoverage reportingJSON/Markdown reports, signature tier counts
stub_fallback_exampleStub-based signatures.pyi discovery, stub docstrings
class_constructor_exampleClass constructorsnew/N generation from __init__, method calls
streaming_exampleStreaming wrappers*_stream variants with callbacks
bridge_client_examplePython BridgeClient demoExecuteTool/ExecuteStreamingTool, chunk decoding
strict_mode_exampleStrict signature thresholdsmin_signature_tier enforcement
session_lifecycle_exampleSession lifecycle managementAuto-ref, SessionContext, cleanup
multi_session_exampleMultiple snakes in the pitConcurrent sessions, isolation, affinity modes under load
affinity_defaults_exampleSingle-pool affinity defaultsDefault strictness, per-call overrides, busy-worker behavior
python_idioms_examplePython idioms bridgeGenerators, context managers, callbacks
protocol_integration_exampleProtocol integrationInspect/String.Chars, Enumerable, dynamic exceptions
universal_ffi_exampleUniversal FFI showcase (v0.10.0+)SnakeBridge.call/4, get/3, method/4, attr/3, bytes/1, auto-sessions, graceful serialization

Verbose Output Format

All examples use an explicit format showing exactly what happens with each Python call:

 Calculate square root

  Elixir call:     Math.sqrt/1
  
  Python module:   math
  Python function: sqrt
  Arguments:       [144]

    Response from Python (1250 µs)

 Result: {:ok, 12.0}

Example Details

basic

Demonstrates core SnakeBridge functionality with Python's standard library:

  • Math operations (math.sqrt, math.pow, math.log)
  • String operations (len, upper, type)
  • JSON serialization (json.dumps, json.loads)
  • OS operations (os.getcwd, os.getenv, platform.system)

math_demo

Shows the discovery API for generated modules:

  • List available functions with Math.__functions__()
  • Search for functions with Math.__search__("sqrt")
  • Explore generated code structure

proof_pipeline

A real-world example using multiple Python ML libraries:

  • PyLatexEnc for LaTeX parsing
  • SymPy for symbolic math
  • Custom verification logic

types_showcase

Demonstrates how Python types map to Elixir:

  • intinteger()
  • floatfloat()
  • strString.t()
  • listlist()
  • dictmap()
  • Nonenil
  • boolboolean()
  • Complex nested structures

error_showcase

Shows SnakeBridge's ML error translation:

  • Shape mismatch errors with tensor dimensions
  • Out of memory errors with device info
  • Dtype mismatch errors with conversion suggestions
  • ErrorTranslator.translate/1 usage

docs_showcase

Demonstrates documentation parsing:

  • Google-style docstrings
  • NumPy-style docstrings
  • Sphinx-style docstrings
  • Math expression rendering (:math:$...$)

telemetry_showcase

Shows telemetry integration:

  • Start/stop events with timing
  • Error events
  • Concurrent call tracking
  • Aggregate metrics

wrapper_args_example

Shows wrapper args handling:

  • Optional keyword arguments via opts
  • Runtime flags like idempotent
  • __args__ varargs support

signature_showcase

Demonstrates the signature + arity model:

  • Optional args via keyword opts
  • Required keyword-only validation
  • Variadic fallback wrappers for missing signatures
  • Sanitized function names (classpy_class)
  • C-extension calls via numpy

coverage_report_example

Demonstrates coverage reporting for a generate-all library:

  • JSON + Markdown coverage reports
  • Signature tier counts and doc coverage ratios
  • Local module coverage without external dependencies

stub_fallback_example

Demonstrates stub-based fallback when runtime signatures are missing:

  • Local .pyi discovery next to the module
  • Stub docstrings and signatures
  • Generated wrappers from stub metadata

class_constructor_example

Demonstrates class constructors generated from __init__:

  • new/0 for empty constructors
  • new/2 for required args
  • Optional kwargs for configuration

streaming_example

Demonstrates streaming wrapper generation:

  • *_stream variants with callbacks
  • Runtime opts passed through opts

bridge_client_example

Demonstrates Python BridgeClient usage against the Elixir BridgeServer:

  • ExecuteTool and ExecuteStreamingTool via snakebridge_client.py
  • Correlation header propagation and chunk decoding
  • Enable with SNAKEBRIDGE_BRIDGE_CLIENT=1

strict_mode_example

Demonstrates strict signature thresholds:

  • Strict signature tier enforcement with min_signature_tier
  • Expected failure when a symbol falls below the tier
  • Relaxed tier configuration to pass

session_lifecycle_example

Demonstrates session lifecycle management:

  • Auto-ref for complex objects
  • SessionContext scoping for per-process sessions
  • Automatic cleanup on owner exit
  • Manual session release

multi_session_example

Multiple Snakes in the Pit - Demonstrates running multiple isolated Python sessions concurrently:

  • Concurrent sessions with Task.async and different session IDs
  • State isolation between sessions (objects in session A invisible to B)
  • Affinity modes under load (:hint, :strict_queue, :strict_fail_fast) across pools
  • Per-call affinity overrides on strict and hint pools
  • Auto-session behavior and how affinity applies to process-scoped sessions
  • Tainted preferred worker behavior (:session_worker_unavailable)
  • Streaming calls that depend on session-bound refs
  • Named sessions for logical grouping and reuse
  • Parallel processing pattern with Task.async_stream
  • Session-scoped object lifetime management

Use cases: multi-tenant apps, A/B testing, parallel workers with isolated state.

The affinity section intentionally drives a busy-worker scenario so you can see: hint mode fallback (ref error), strict queue waiting, and strict fail-fast returning {:error, :worker_busy}.

The example config (examples/multi_session_example/config/runtime.exs) defines three pools with per-pool affinity modes so you can compare behaviors in a single run.

affinity_defaults_example

Demonstrates how affinity behaves in a single-pool configuration:

  • Global default affinity via SnakeBridge.ConfigHelper.configure_snakepit!(affinity: ...)
  • Per-call overrides (:hint, :strict_queue, :strict_fail_fast)
  • Busy-worker scenarios with strict queue waiting and fail-fast errors

python_idioms_example

Demonstrates Python idioms support:

  • Lazy iteration over Python generators/iterators
  • with_python macro for context managers
  • Passing Elixir callbacks into Python functions

protocol_integration_example

Demonstrates protocol integration for Python refs:

twenty_libraries

Performance demonstration calling 20 Python standard library modules:

  • 40 total calls (2 per library)
  • Timing for each call
  • Summary statistics (fastest, slowest, average)

Libraries used: math, json, os, sys, platform, datetime, random, hashlib, base64, urllib.parse, re, collections, itertools, functools, string, textwrap, uuid, time, calendar, statistics

universal_ffi_example

Comprehensive showcase of Universal FFI features (v0.10.0+):

  • SnakeBridge.call/4 - Call any Python function dynamically
  • SnakeBridge.get/3 - Get module attributes
  • SnakeBridge.method/4 and attr/3 - Call methods/get attributes on refs
  • SnakeBridge.bytes/1 - Explicit binary encoding for hashlib, crypto, etc.
  • Non-string key maps (integer/tuple keys)
  • Auto-session management
  • Bang variants (call!, get!, method!, attr!)
  • Streaming with SnakeBridge.stream/5
  • Graceful serialization - containers preserve structure, only non-serializable leaves become refs (e.g., re.compile() patterns mixed with metadata)

This is the canonical reference for Universal FFI usage - the "escape hatch" for calling Python without code generation.

Requirements

  • Elixir 1.14+
  • Python 3.10+
  • Snakepit 0.9.0+

License

MIT - See the main repository LICENSE file.