Singularity
API Reference

RPC API Reference

Complete API reference for the RPC subsystem — RPCRegistry, RPCProxy, ServiceProxy, Microservice descriptor, exception classes, and data models.

This page documents every class in the microservices.__base.rpc package and the Microservice descriptor. All signatures are taken directly from the source code.


RPCRegistry

microservices.__base.rpc.registry.RPCRegistry

Singleton registry for RPC-exposed services. Stores local service instances and remote service specs discovered from Redis.

Constructor

Takes no parameters. Initializes empty _local and _remote dictionaries.

Methods

MethodParametersReturn TypeDescription
register(name, instance, path_segments)name: str, instance: Any, path_segments: list[str]NoneRegister a local service for RPC. Introspects the instance to extract HTTP endpoint methods, their parameter signatures, and builds MethodMeta entries.
generate_spec()(none)dict[str, Any]Generate an OpenAPI-like spec for all locally registered RPC services. Returns {"rpc_version": "1.0", "base_url": "...", "services": {...}}.
generate_spec_for(name)name: strOptional[dict[str, Any]]Generate spec for a single service by name. Returns None if not found.
publish_to_redis(ttl)ttl: int = 60NoneAsync. Publish local RPC specs to shared Redis. Each service is published individually under singularity:rpc:services:{name} and the full spec under singularity:rpc:spec, both with the given TTL in seconds.
remove_from_redis()(none)NoneAsync. Remove all local RPC specs from shared Redis.
discover_remote()(none)NoneAsync. Scan Redis for all singularity:rpc:services:* keys and register any services not already in _local as RemoteServiceEntry instances.
discover_single_service(service_name)service_name: strboolAsync. Discover a single remote service from Redis on-demand. Returns True if found (locally or remotely), False otherwise.
get_proxy(caller)caller: strRPCProxyGet an RPC proxy bound to a caller identity.

The registry uses settings.celery_broker_url as the Redis connection URL for publishing and discovery. Ensure your Redis instance is accessible.


RPCClient

microservices.__base.rpc.client.RPCClient

The public RPC interface. The module-level rpc singleton is an instance of this class.

Usage Patterns

from singularity.rpc import rpc

# Pattern 1: Direct proxy call
result = await rpc("orders").payments.charge(user_id="u1", amount=9.99)

# Pattern 2: Class-level descriptor for dependency declaration
class MyService:
    payments = rpc.remote("payments")

    async def checkout(self):
        result = await self.payments.charge(user_id="u1", amount=9.99)

Methods

MethodParametersReturn TypeDescription
__call__(caller)caller: strRPCProxyGet an RPC proxy bound to the given caller identity.
remote(service_name)service_name: strRemoteServiceDescriptorDeclare a remote service dependency as a class-level attribute. Returns a descriptor that resolves to a ServiceProxy at access time.

Module-Level Functions

FunctionParametersReturn TypeDescription
rpc(singleton)RPCClientPre-created module-level singleton. Import and call directly.
get_registry()(none)RPCRegistryGet the module-level RPC registry singleton. Used internally by the Manager.

RPCProxy

microservices.__base.rpc.proxy.RPCProxy

Proxy bound to a caller identity. Attribute access returns a ServiceProxy for the target service.

Constructor

ParameterTypeDescription
callerstrThe name of the calling service
registryRPCRegistryThe RPC registry instance

Access Patterns

PatternReturnsDescription
proxy.paymentsServiceProxyDot access for standard service names
proxy["my-service"]ServiceProxyBracket access for names with hyphens or special characters

ServiceProxy

microservices.__base.rpc.proxy.ServiceProxy

Proxy for a specific target service. Method calls are dispatched locally (in-process) or remotely (HTTP) with blacklist enforcement.

Constructor

ParameterTypeDescription
service_namestrThe target service name
callerstrThe calling service name
registryRPCRegistryThe RPC registry instance

Dispatch Behavior

When you access a method on a ServiceProxy, it resolves using this priority:

  1. Local -- If service_name exists in registry._local, checks the blacklist, verifies the method exists, and returns the method directly (in-process call).
  2. Remote (cached) -- If service_name exists in registry._remote, checks the blacklist, verifies the method exists, and returns an async callable that makes an HTTP request.
  3. Remote (lazy discovery) -- If the service is not found locally or in the cache, returns an async callable that first attempts discover_single_service() from Redis, then dispatches the HTTP call.

Remote Call Details

AspectValue
HTTP Clienthttpx.AsyncClient
Timeout30.0 seconds
Custom HeaderX-RPC-Caller: {caller}
Request MethodDetermined by the remote method spec (GET, POST, etc.)

Internal Methods

MethodParametersReturn TypeDescription
_check_blacklist(blacklist)blacklist: list[str]NoneRaises RPCAccessDenied if the caller is in the blacklist.

RemoteServiceDescriptor

microservices.__base.rpc.proxy.RemoteServiceDescriptor

Python descriptor for class-level remote service declaration. Used by rpc.remote().

Constructor

ParameterTypeDescription
service_namestrThe target service name

Descriptor Protocol

When accessed on an instance, __get__ reads the _service_name attribute (injected by the Manager) and returns a ServiceProxy via rpc(caller)[service_name].


Microservice

microservices.__base.microservice.Microservice

Base class for declaring remote microservice dependencies. Uses the Python descriptor protocol to bind to the caller identity at access time.

Class Attributes

AttributeTypeDefaultDescription
host_urlstr""Base URL of the remote deployment (e.g. "http://localhost:8001")
api_keystr""API key sent as X-API-Key header (optional)
timeoutfloat30.0Request timeout in seconds
service_namestr""If set, binds directly to this service (skips repo-level proxy). If empty, returns a MicroserviceProxy for multi-service access.

Descriptor Behavior

service_name__get__ ReturnsUsage Pattern
"" (empty)MicroserviceProxyself.billing.invoice.post(...) -- pick service, then method
"test" (set)MicroserviceServiceProxyself.test.get(...) -- call method directly

Usage Example

from singularity.microservices.microservice import Microservice
from singularity.config import settings

class BillingMS(Microservice):
    host_url = settings.billing_host_url
    api_key = settings.billing_api_key
    timeout = 10

class OrdersService:
    billing = BillingMS()

    async def checkout(self, order_id: str):
        result = await self.billing.invoice.post(order_id=order_id)
        return result

MicroserviceProxy

microservices.__base.rpc.proxy.MicroserviceProxy

Proxy representing a remote deployment, bound to a caller identity. Attribute access returns a MicroserviceServiceProxy for the named service.

Constructor

ParameterTypeDescription
host_urlstrBase URL of the remote deployment
api_keystrAPI key for authentication
timeoutfloatRequest timeout in seconds
callerstrThe calling service name

Access Patterns

PatternReturnsDescription
proxy.invoiceMicroserviceServiceProxyDot access for service names
proxy["my-service"]MicroserviceServiceProxyBracket access for names with hyphens

MicroserviceServiceProxy

microservices.__base.rpc.proxy.MicroserviceServiceProxy

Proxy for a specific service on a remote deployment. Method calls are dispatched via convention-based URL construction.

Constructor

ParameterTypeDescription
service_namestrThe target service name
host_urlstrBase URL of the remote deployment
api_keystrAPI key for authentication
timeoutfloatRequest timeout in seconds
callerstrThe calling service name

Method Name Convention

Method names on this proxy are resolved to HTTP endpoints using the following convention (matching the Manager's route registration):

Method NameHTTP MethodURL
getGET{host_url}/api/{service_name}
postPOST{host_url}/api/{service_name}
get_exampleGET{host_url}/api/{service_name}/example
post_order_paymentPOST{host_url}/api/{service_name}/order_payment

Remote Call Details

AspectValue
HTTP Clienthttpx.AsyncClient
TimeoutValue from Microservice.timeout
HeadersX-RPC-Caller: {caller}, X-API-Key: {api_key} (if set)

Exception Classes

microservices.__base.rpc.exceptions

All RPC exceptions inherit from RPCError, which inherits from Python's built-in Exception.

Exception Hierarchy

Exception Details

ExceptionConstructor ParametersFieldsWhen Raised
RPCError(standard Exception args)messageBase class; not raised directly
RPCServiceNotFoundservice: strserviceTarget service not found in local or remote registry
RPCMethodNotFoundservice: str, method: strservice, methodMethod not found on the target service
RPCAccessDeniedcaller: str, target: strcaller, targetCaller is in the target service's blacklist
RPCServiceUnavailableservice: str, url: str, detail: str = ""serviceRemote HTTP connection failed or returned an error

Error Messages

ExceptionMessage Format
RPCServiceNotFound"RPC service not found: '{service}'"
RPCMethodNotFound"RPC method not found: '{service}.{method}'"
RPCAccessDenied"RPC access denied: '{caller}' is blacklisted from '{target}'"
RPCServiceUnavailable"RPC service '{service}' unavailable at '{url}': {detail}"

Data Models

microservices.__base.rpc.models

Internal data classes used by the registry and proxy system.

MethodMeta

Metadata about an RPC-exposed method. Uses __slots__ for memory efficiency.

FieldTypeDefaultDescription
paramsdict(required)Parameter metadata: {name: {"type": str, "required": bool}}
return_typestr(required)String representation of the return type annotation
descriptionstr(required)First line of the method's docstring
is_asyncbool(required)Whether the method is a coroutine
http_methodstr"POST"HTTP method (GET, POST, PUT, DELETE, PATCH)
sub_pathstr""Sub-path for http_exposed routes (e.g. "status" for get=status)

LocalServiceEntry

A locally registered RPC service. Uses __slots__.

FieldTypeDescription
instanceAnyThe service instance
methodsdict[str, MethodMeta]Introspected method metadata
blacklistlist[str]Services blocked from calling this service
endpoint_prefixstrFull URL prefix (e.g. "http://localhost:8000/api/v1/payments")
path_segmentslist[str]Directory path segments (e.g. ["v1", "payments"])

RemoteServiceEntry

A remotely discovered RPC service. Uses __slots__.

FieldTypeDescription
base_urlstrBase URL of the remote deployment
blacklistlist[str]Services blocked from calling this service
methodsdict[str, Any]Method specs as raw dictionaries from Redis