Client-Side Python Mapping for Interfaces
Proxy Classes
On the client side, a Slice interface maps to a Python class with methods that correspond to the operations on that interface. Consider the following Slice interface:
interface Simple
{
void op();
}
The Python mapping generates the following definition for use by the client:
class SimplePrx(Ice.ObjectPrx):
def op(self, context: dict[str, str] | None = None) -> None:
...
def opAsync(self, context: dict[str, str] | None = None) -> Awaitable[None]:
...
As you can see, the compiler generates a proxy class SimplePrx. In general, the generated name is <interface-name>Prx.
In the client's address space, an instance of SimplePrx is the local ambassador for a remote instance of an Ice object that implements Simpleand is known as a proxy instance. All the details about the server-side object, such as its address, what protocol to use, and its object identity are encapsulated in that instance.
Inheritance from Ice.ObjectPrx
All generated proxy classes inherit directly or indirectly from the Ice.ObjectPrx class, reflecting the fact that all Slice interfaces implicitly inherit from Object.
Creating a Proxy
Use the constructor of the generated proxy class to create a proxy from a communicator and a “stringified” proxy. For example:
import M
simple = M.SimplePrx(communicator, "simple:tcp -h localhost -p 4061")
__init__ is inherited from Ice.ObjectPrx.
Interface Inheritance
Inheritance relationships among Slice interfaces are maintained in the generated Python classes. For example:
interface A { ... }
interface B { ... }
interface C extends A, B { ... }
The generated code for CPrx reflects the inheritance hierarchy:
class CPrx(APrx, BPrx):
...
Given a proxy for C, a client can invoke any operation defined for interface C, as well as any operation inherited from C's base interfaces.
Casting Proxies in Python
The Python mapping for a proxy also generates 3 static methods for converting a proxy into a proxy of another type:
class SimplePrx(Ice.ObjectPrx):
@staticmethod
def uncheckedCast(proxy, facet=None)
@staticmethod
def checkedCastAsync(proxy, facet=None, context=None)
@staticmethod
def checkedCast(proxy, facet=None, context=None)
uncheckedCast
uncheckedCast allows you to convert any proxy into a SimplePrx proxy. For example:
# Convert a SimplePrx into a WidgetPrx, even though the two types are unrelated.
widget = WidgetPrx.uncheckedCast(simple)
uncheckedCast is a local operation that always succeeds.
checkedCastAsync
checkedCastAsyncis a conditional cast of the proxy: this method makes a remote call to the target object to check if this object implements the proxy’s Slice interface. For example:
# Call operation ice_isA on the Ice object to check if it implements Slice interface
# Widget.
widget = await WidgetPrx.checkedCastAsync(simple)
If the target object implements the Slice interface, checkedCastAsyncreturns a non-null proxy, just like uncheckedCast. If the target object doesn’t implement this interface, checkedCastAsync returns None. checkedCastAsynccan also throw an exception, for example if it cannot reach the remote object.
While checkedCastAsync sounds safer than uncheckedCast (you’re making an additional check before casting), in practice you know or should know the type of your proxies and calling checkedCastAsync is rarely necessary.
checkedCast
checkedCast is the synchronous equivalent of checkedCastAsync: it blocks the caller until the response it receives. You should prefer async methods over their their synchronous equivalent when making remote calls with Ice.
Proxy Factory Methods
The base proxy class ObjectPrx supports a variety of methods for customizing a proxy. Since proxies are immutable, each of these factory methods returns a copy of the original proxy that contains the desired modification. For example, you can obtain a proxy configured with a ten second invocation timeout as shown below:
greeter = VisitorCenter.GreeterPrx(communicator, "greeter:tcp -h localhost -p 4061")
# Create a new GreeterPrx and assign it to greeter.
greeter = greeter.ice_timeout(4000)
The factory methods usually return a proxy of the same type as the current proxy, as in the example above.
The only exceptions are the factory methods ice_facet and ice_identity. Calls to either of these methods may produce a proxy for an object of an unrelated type, and you need to cast the returned proxy. For example:
greeter = VisitorCenter.GreeterPrx(communicator, "greeter:tcp -h localhost -p 4061")
greeterAdmin = VisitorCenter.GreeterAdminPrx.uncheckedCast(
greeter.ice_facet("admin"))