Tuscany SCA Native - Python Extension

The Tuscany Python extension allows Python scripts to be used as components in SCA composites and as clients that can invoke SCA services.

The following samples demonstrate use of the Python extension:

System Requirements

In order to install and use the Tuscany SCA Python Extension there are some extra requirements in addition to the Tuscany SCA requirements:

Software Download Link
Python version 2.5 http://www.python.org/download/
Please download and follow the installation instructions.

Installing the Tuscany SCA Python Extension

Getting the Tuscany SCA Python Extension working with the binary release on Linux and Mac OS X

  1. Ensure the Python libraries are available on the PATH environment variable
  2. Add the <tuscany_sca_install_dir>/extensions/python/lib directory to the PYTHONPATH environment variable

Getting the Tuscany SCA Python Extension working with the source release on Linux and Mac OS X

  1. You will need the Tuscany SCA and SDO libraries - follow the instructions here to build the SCA libraries and default extensions
  2. The following environment variables are required:
    • TUSCANY_SCACPP=<path to built Tuscany SCA>
    • TUSCANY_SDOCPP=<path to installed Tuscany SDO>
    • PYTHON_LIB=<path to Python libraries>
    • PYTHON_INCLUDE=<path to Python includes>
    • PYTHON_VERSION=<name of the Python version>
      Note: If you are using a default installation of Python 2.5 these are usually:
      PYTHON_LIB=/usr/lib
      PYTHON_INCLUDE=/usr/include/python2.5
      PYTHON_VERSION=python2.5
  3. Build the Python source only with the following command sequence:
    • cd <tuscany_sca_install_dir>
    • ./configure --prefix=$TUSCANY_SCACPP --enable-python --enable-cpp=no --enable-wsbinding=no
    • make
    • make install
    NOTE: If you don't provide a --prefix configure option, it will by default install into /usr/local/tuscany/sca

Getting the Tuscany SCA Python Extension working with the binary release on Windows

  1. Ensure the Python libraries are available on the PATH environment variable
  2. Add the <tuscany_sca_install_dir>\extensions\python\bin directory to the PYTHONPATH environment variable

Getting the Tuscany SCA Python Extension working with the source release on Windows

  1. Unzip the supplied source zip file
  2. The following environment variables are required:
    • TUSCANY_SCACPP=<path to built Tuscany SCA>
    • TUSCANY_SDOCPP=<path to installed Tuscany SDO>
    • PYTHON_HOME=<path to installed Python>
  3. You must have set up the environment for Microsoft Visual C++ tools. The build command will call vcvars32 to set the environment. Ensure the directory containing this is on your path. This will be where you installed the compiler.
  4. Build the source:
    • cd <to where you unzipped the source>
    • build
    This will build all the projects and put the required output into the 'deploy' directory

    Alternatively, open the workspace at <tuscany_sca_install_dir>/projects/tuscany_sca/tuscany_sca.dsw in Visual Studio 6 or at at <tuscany_sca_install_dir>/projectsvc7/tuscany_sca/tuscany_sca.sln in Visual Studio 7.1 - you can build projects individually
  5. Set the TUSCANY_SCACPP environment variable to point to the 'deploy' directory that was just created

The Tuscany Python Programming Model

This section will explain the Tuscany Python programming model to help you to write your own Python components and clients.

The Tuscany Python component and client support comes from a Python extension package that is built in the <tuscany_sca_install_dir>/extensions/python/bin directory on Windows and <tuscany_sca_install_dir>/extensions/python/lib on Linux and Mac OS X. This package must be made available to your Python environment by adding this directory to your PYTHONPATH environment variable. This makes the sca module available for use by clients and allows references and properties to be used in your Python components

Clients

Using the sca module, a Python client can search for an SCA service with:

import sca

calculator = sca.locateservice("CalculatorComponent/CalculatorService")

This finds the component and service as defined in the composite and componentType side files and returns a proxy object that can call the SCA service. You can then simply call a business method on "calculator", like this:

result = calculator.add(12.3, 45.6)

Components

Python component implementations are standard Python scripts, where class-level functions or module-level functions can be invoked by the Tuscany runtime. To use a Python component implementation, use the implementation.python element in your .composite file. For example, the following snippet will use the Python script at path/to/module/PythonModuleName.py, where the path is relative to the location of the composite file:

<implementation.python module="PythonModuleName" path="path/to/module"/>

To instantiate a class instance and use a class-level function, the Python class must have a default constructor (an __init__ method that takes no arguments besides 'self') and the class attribute must be defined in the implementation.python element in your composite, like so:

<implementation.python module="PythonModuleName" path="path/to/module" class="PythonClassName"/>

Tuscany currently supports passing simple types (strings, ints, floats, etc) as well as Service Data Objects into and out of Ruby components. Service Data Objects are represented in Python as xml.etree.ElementTree Element objects (see the PythonWeatherForecast sample for a demonstration).

You can write a componentType file for your Python component, but you don't have to - the Python extension automatically exposes a service and adds references and properties to your Python component implementation classes based on the information in the composite file.

References

References are automatically added to your Python component implementation when the runtime loads the implementation script, so they can be used like so:

# The module-level div function
def div(val1, val2):
    # Use the divideService reference
    result = divideService.divide(val1, val2)
    return result

and in your composite file:

<component name="CalculatorComponent">
    <implementation.python module="CalculatorImpl"/>
    <reference name="divideService">DivideComponent/DivideService</reference>
</component>

Properties

A composite with a property defined for a component like so:

<component name="DivideComponent">
    <implementation.python module="DivideImpl"/>
    <property name="doRounding">true</property>
</component>

means the property is automatically instantiated and assigned the property value in the Python component implementation, so it can be used like so:

def divide(val1, val2):
    result = float(val1) / float(val2)
    print "Python - DivideImpl.divide " + str(val1) + " / " + str(val2) + " = " + str(result)

    # Use the doRounding property
    if doRounding:
        result = round(result)
        print "Python - DivideImpl.divide is rounding the result to " + str(result)

    return result

Getting Help

First place to look is at the Tuscany FAQ at http://incubator.apache.org/tuscany/faq.html

Any problem with this release can be reported to the Tuscany mailing lists or create a JIRA issue at http://issues.apache.org/jira/browse/Tuscany.