Generating Server Bindings for Python in libadr
The Oracle Solaris 11.4 code that is generated is currently compatible with Python 2.7 and Python 3.5. However, Python updates might affect that compatibility, so you should specify the exact version of Python. Furthermore, do not add new Python 2.7 code. This version of Python is near the end of support by the community.
This section provides examples for generating server bindings for Python 3.5.
Example 3-9 Generating Server Bindings for Python 3.5
This example shows how to generate Python server bindings for the API Snake
, which has the interface, Cobra
, with one method, multiply
.
<api xmlns="https://xmlns.oracle.com/radadr" name="com.oracle.solaris.rad.snake"> <summary> Snake API </summary> <doc> <para> This is a testing module for Python Server Modules. </para> </doc> <version major="1" minor="0"/> <interface name="Cobra" stability="private"> <method name="multiply" stability="private"> <doc> Multiply two numbers. </doc> <result type="integer"/> <argument name="first" type="integer"/> <argument name="second" type="integer"/> </method> </interface> </api>
The following example shows how to generate Python server bindings for snake.adr
in the build
sub-directory.
$ radadrgen -l python35 -s server -d build snake.adr
When you run radadrgen
in this example, the following files are generated:
-
api.snake.h
andapi.snake_impl.c
C files – These files are generated so that the Python module can reuse the existing RAD marshalling and dispatching framework. -
com/oracle/solaris/rad/snake_iface.py
Python file – This file contains an abstract definition of an interface, which should be extended to provide a concrete implementation.
Example 3-10 Showing a radadrgen
-Generated Interface From the Python File
""" Snake API This is a testing module for Python Server Modules. """ try: import modapi except ImportError: import rad.server.modapidoc as modapi from rad.server import RADInstance from rad.client import * import abc import six dom = "com.oracle.solaris.rad.snake" vers = (1, 0) @ClassStability("private") class Cobra(six.with_metaclass(abc.ABCMeta, RADInstance)): """""" _rad_type = "Cobra" _rad_domain = dom _rad_version = vers _rad_singleton = None __metaclass__ = abc.ABCMeta def __init__(self, name = None, user = None, freef = None, dynamic = False): super(Cobra, self).__init__(_rad_moddata, name, user, freef, dynamic) @MethodStability("private") @abc.abstractmethod def multiply(self, first, second): """Multiply two numbers.""" pass
The methods in the example are decorated to indicate that they are abstract and to indicate their RAD stability level. You can write the Python code to implement the abstract interface.
Example 3-11 Implementing Interfaces Generated by radadrgen
from . import snake_iface import rad.client as radcli import rad.server as radser class Cobra(snake_iface.Cobra): def __init__(self, name = None, user = None, freef = None): super(Cobra, self).__init__(name, user, freef) def multiply(self, first, second): return (first * second) def rad_init(): radser.rad_log(radser.rad_log_lvl.RL_DEBUG, "Initializing: %s" % "com.oracle.solaris.rad.snake") Cobra._rad_insert_singleton(radser.rad_container) return 0 def rad_fini(handle): radser.rad_log(radser.rad_log_lvl.RL_DEBUG, "Finalizing: %s" % "com.oracle.solaris.rad.snake") return 0
In this example, the Snake
module is implemented and is exporting the rad_init and rad_fini functions, which provides the capability for the module to setup or remove an execution environment. In this example, you are logging and creating a singleton instance to represent the Snake
module.
The RAD daemon converts the ADR (RAD's native data representation format) types to or from the Python types. For basic types, the conversion is straightforward mapping. For derived types, the conversion is more complex, but essentially follows the same process as illustrated above for interfaces. radadrgen
generates the required types in the binding. The various generated components are identical to any such components in the Python client binding.