Packages
snakepit
0.12.0
0.13.0
0.12.0
0.11.1
0.11.0
0.10.1
0.10.0
0.9.1
0.9.0
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
High-performance pooler and session manager for external language integrations. Supports Python, Node.js, Ruby, and more with gRPC streaming, session management, and production-ready process cleanup.
Current section
Files
Jump to
Current section
Files
priv/python/snakepit_bridge/adapters/showcase/handlers/basic_ops.py
"""Basic operations handler for showcase adapter."""
import time
from typing import Dict, Any
from datetime import datetime, date
from decimal import Decimal
from ..tool import Tool
from snakepit_bridge import telemetry
class BasicOpsHandler:
"""Handler for basic operations like ping, echo, and error demonstrations."""
def get_tools(self) -> Dict[str, Tool]:
"""Return all tools provided by this handler."""
return {
"ping": Tool(self.ping),
"echo": Tool(self.echo),
"add": Tool(self.add),
"error_demo": Tool(self.error_demo),
"adapter_info": Tool(self.adapter_info),
"telemetry_demo": Tool(self.telemetry_demo),
"serialization_demo": Tool(self.serialization_demo),
}
def ping(self, ctx, message: str = "pong") -> Dict[str, str]:
"""Simple ping operation."""
return {"message": message, "timestamp": str(time.time())}
def echo(self, ctx, **kwargs) -> Dict[str, Any]:
"""Echo back all provided arguments."""
return {"echoed": kwargs}
def add(self, ctx, a: float, b: float) -> float:
"""Add two numbers together."""
return a + b
def error_demo(self, ctx, error_type: str = "generic") -> None:
"""Demonstrate error handling with different error types."""
if error_type == "value":
raise ValueError("This is a demonstration ValueError")
elif error_type == "runtime":
raise RuntimeError("This is a demonstration RuntimeError")
else:
raise Exception("This is a generic exception")
def adapter_info(self, ctx) -> Dict[str, Any]:
"""Return information about the adapter capabilities."""
return {
"adapter_name": "ShowcaseAdapter",
"version": "2.0.0", # Updated version for refactored adapter
"capabilities": [
"binary_serialization",
"streaming",
"ml_workflows",
"session_state_via_elixir"
],
"handlers": [
"BasicOpsHandler",
"SessionOpsHandler",
"BinaryOpsHandler",
"StreamingOpsHandler",
"ConcurrentOpsHandler",
"MLWorkflowHandler"
]
}
def telemetry_demo(self, ctx, operation: str = "compute", delay_ms: int = 100) -> Dict[str, Any]:
"""
Demonstrate telemetry emission from Python.
This tool shows how to use the telemetry API to emit events that are
captured by Elixir and made available to :telemetry handlers.
Args:
ctx: Session context
operation: Name of the operation to simulate
delay_ms: How long to simulate work (milliseconds)
Returns:
Dict with operation results and telemetry info
"""
correlation_id = telemetry.get_correlation_id()
# Example 1: Manual event emission
telemetry.emit(
"tool.execution.start",
{"system_time": time.time_ns()},
{"tool": "telemetry_demo", "operation": operation},
correlation_id=correlation_id
)
# Example 2: Using span context manager (automatic timing)
with telemetry.span("tool.execution", {"tool": "telemetry_demo", "operation": operation}, correlation_id):
# Simulate some work
time.sleep(delay_ms / 1000.0)
# Emit a custom metric during the span
telemetry.emit(
"tool.result_size",
{"bytes": 42},
{"tool": "telemetry_demo"},
correlation_id=correlation_id
)
return {
"operation": operation,
"delay_ms": delay_ms,
"telemetry_enabled": telemetry.is_enabled(),
"correlation_id": correlation_id,
"message": "Telemetry events emitted successfully! Check Elixir :telemetry handlers."
}
def serialization_demo(self, ctx, demo_type: str = "all") -> Dict[str, Any]:
"""
Demonstrate graceful serialization of non-JSON objects.
This tool returns various types that would normally fail JSON serialization:
- datetime objects (converted via isoformat)
- Custom classes (converted to marker with type info)
- Objects with to_dict/model_dump methods (converted automatically)
Args:
ctx: Session context
demo_type: Type of demo - "datetime", "custom", "convertible", or "all"
Returns:
Dict containing objects that exercise graceful serialization
"""
# Custom class without conversion methods
class CustomResponse:
def __init__(self, status, data):
self.status = status
self.data = data
def __repr__(self):
return f"CustomResponse(status={self.status})"
# Class with to_dict method (like many API response objects)
class ApiResponse:
def __init__(self, code, message):
self.code = code
self.message = message
def to_dict(self):
return {"code": self.code, "message": self.message}
# Class with model_dump method (Pydantic v2 style)
class PydanticLike:
def __init__(self, field1, field2):
self.field1 = field1
self.field2 = field2
def model_dump(self):
return {"field1": self.field1, "field2": self.field2}
result = {"demo_type": demo_type, "description": "Graceful serialization demo"}
if demo_type in ("datetime", "all"):
result["datetime_demo"] = {
"datetime_now": datetime.now(),
"date_today": date.today(),
"preserved_string": "This stays as-is",
"preserved_number": 42,
}
if demo_type in ("custom", "all"):
result["custom_class_demo"] = {
"custom_object": CustomResponse(200, "success"),
"preserved_string": "This is preserved",
"nested": {
"another_custom": CustomResponse(404, "not found"),
"normal_value": 123,
},
}
if demo_type in ("convertible", "all"):
result["convertible_demo"] = {
"api_response": ApiResponse(200, "OK"),
"pydantic_like": PydanticLike("value1", "value2"),
}
if demo_type in ("mixed_list", "all"):
result["mixed_list_demo"] = [
1,
"two",
datetime.now(),
CustomResponse(500, "error"),
{"nested": "dict"},
ApiResponse(201, "Created"),
]
if demo_type in ("complex", "all"):
result["complex_demo"] = self._build_complex_demo()
return result
def _build_complex_demo(self) -> Dict[str, Any]:
"""
Build a complex demo showing nested structures with various conversion patterns.
Demonstrates:
- Objects with model_dump() -> converted to dict
- Objects with to_dict() -> converted to dict
- Objects without conversion methods -> become markers
- Nested structures mixing serializable and non-serializable
- Secret redaction in repr (when enabled)
"""
import uuid
# Object with model_dump() method - converts automatically
class ServiceResponse:
def __init__(self, data, metadata):
self.id = f"resp-{uuid.uuid4().hex[:8]}"
self.data = data
self.metadata = metadata
self.created = datetime.now()
def model_dump(self):
return {
"id": self.id,
"data": self.data,
"metadata": self.metadata,
"created": self.created.isoformat(),
}
# Object with to_dict() method - converts automatically
class QueryResult:
def __init__(self, value, score=None):
self.value = value
self.score = score
self._internal = [] # Internal state not exposed
def to_dict(self):
return {
"value": self.value,
"score": self.score,
}
# Object WITHOUT conversion methods - becomes marker
class InternalClient:
def __init__(self, endpoint):
self.endpoint = endpoint
self._api_key = "sk-secret-key-12345" # Has secret
def __repr__(self):
# Real repr might accidentally expose secrets
return f"InternalClient(endpoint={self.endpoint}, api_key={self._api_key})"
# Another object without conversion - becomes marker
class RequestLog:
def __init__(self, request_id, payload, response_obj):
self.request_id = request_id
self.payload = payload
self.response = response_obj # Nested non-serializable
self.timestamp = datetime.now()
# No conversion method
# Build nested structure
client = InternalClient("https://api.example.com")
logs = [
RequestLog(
request_id="req-001",
payload={"query": "test"},
response_obj=ServiceResponse(
data={"result": "success"},
metadata={"latency_ms": 245}
)
),
RequestLog(
request_id="req-002",
payload={"query": "another"},
response_obj=ServiceResponse(
data={"result": "partial"},
metadata={"latency_ms": 1820}
)
),
]
result = QueryResult(value="computed result", score=0.95)
return {
"description": "Complex nested structure with mixed serialization",
"client": client, # Marker (with redacted secret if repr enabled)
"result": result, # Converts via to_dict()
"logs": logs, # List of RequestLog markers
"summary": {
"total_requests": len(logs),
"request_ids": [log.request_id for log in logs],
},
"latest_response": ServiceResponse( # Converts via model_dump()
data={"final": "output"},
metadata={"processed": True}
),
}