Python Reference
Type Mappings
| IDL Type | Python Type | Example |
|---|---|---|
string |
str |
"hello" |
int |
int |
42 |
float |
float |
3.14 |
bool |
bool |
True, False |
[]Type |
list |
[1, 2, 3] |
map[string]Type |
dict |
{"key": "value"} |
Enum |
str |
"pending" |
Struct |
dict |
{"field": "value"} |
T [optional] |
None or type |
None or value |
Structs as Dictionaries
Each struct in your IDL becomes a dictionary in Python:
from checkout import Product, Cart, CartItem
# Create instances using dicts
product = {
"productId": "prod001",
"name": "Wireless Mouse",
"description": "Ergonomic mouse",
"price": 29.99,
"stock": 50,
"imageUrl": "https://example.com/mouse.jpg" # optional field
}
cart = {
"cartId": "cart_1234",
"items": [],
"subtotal": 0.0
}
Optional Fields
Optional fields can be None:
# Define with optional field
product = {
"productId": "prod001",
"name": "Wireless Mouse",
"description": "Ergonomic mouse",
"price": 29.99,
"stock": 50,
"imageUrl": None # optional field can be None
}
# Check for optional field
if product.get("imageUrl"):
print(product["imageUrl"])
Error Handling
Throw RPCError with custom codes:
from pulserpc import RPCError
# Standard JSON-RPC errors
throw RPCError(-32602, "Invalid params")
# Custom application errors (use codes >= 1000)
throw RPCError(1001, "CartNotFound: Cart does not exist")
throw RPCError(1002, "CartEmpty: Cannot create order from empty cart")
Common error codes:
-32700: Parse error-32600: Invalid request-32601: Method not found-32602: Invalid params-32603: Internal error1000+: Custom application errors
Server Implementation
Extend generated service classes:
from server import PulseRPCServer, CatalogService
class CatalogServiceImpl(CatalogService):
def listProducts(self):
# Return list of Product dicts
return [
{"productId": "p1", "name": "Item 1", "price": 10.0, "stock": 5},
{"productId": "p2", "name": "Item 2", "price": 20.0, "stock": 3}
]
def getProduct(self, productId):
# Return None for optional return type
for p in products:
if p["productId"] == productId:
return p
return None
# Start server
server = PulseRPCServer(host="0.0.0.0", port=8080)
server.register("CatalogService", CatalogServiceImpl())
server.serve_forever()
Client Usage
from client import HTTPTransport, CatalogServiceClient
transport = HTTPTransport("http://localhost:8080")
catalog = CatalogServiceClient(transport)
# Method calls return Python dicts or None
products = catalog.listProducts()
for product in products:
print(f"{product['name']}: ${product['price']}")
# Optional methods return None if not found
product = catalog.getProduct("prod001")
if product:
print(product['name'])
Validation
PulseRPC automatically validates:
- Required fields are present
- Types match IDL definition
- Enum values are valid
# This will raise RPCError (-32602) if validation fails
cart = cart.addToCart({
'productId': 'prod001',
'quantity': 2
})
Best Practices
- Use dicts for struct values: All struct values should be dictionaries
- Handle None for optionals: Always check if optional return values are None
- Use descriptive error codes: Custom errors should have codes >= 1000
- Validate early: Let PulseRPC validate input, validate business logic in handlers
- Keep state in handlers: Store in-memory state in service implementation classes
Working with Nested Structs
# Nested structs work naturally as dicts
order = {
"orderId": "order_123",
"cart": {
"cartId": "cart_123",
"items": [...],
"subtotal": 59.98
},
"shippingAddress": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zipCode": "94105",
"country": "USA"
},
"paymentMethod": "credit_card",
"status": "pending",
"total": 59.98,
"createdAt": 1642000000
}