# TurboGears

Introduction

PyAMF provides a simple WSGI Application that can be used to setup RPC style service easily in Python. Because TurboGears2 supports WSGI from top-to-bottom, it’s very simple to setup a TG2 app that contains web-services for your Flex and Flash applications.

## Install TurboGears

If you haven’t installed TG2, you’ll need to do that first. After that’s done, you can create a new TG2 project in the normal way:

    paster quickstart pyamftest
    cd pyamftest
    paster serve development.ini --reload

Your project should now be started, and you should be able to browse to it at http://127.0.0.1:8080.

## Creating the PyAMF gateway

Now, you’re ready to start creating a PyAMF gateway for your Flex app. The first thing to do is to create a new `mygateway.py` file wherever you want it:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import logging

    from pyamf.remoting.gateway.wsgi import WSGIGateway

    logging.basicConfig(
        level=logging.DEBUG,
        format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s'
    )

    class Services(object):

        def echo(self, data):
            return "Turbogears gateway says:" + str(data)

        def sum(self, a, b):
            return a + b

        def scramble(self, text):
            from random import shuffle
            s = [x for x in text]
            shuffle(s)
            return ''.join(s)

    # Expose our services
    services = {"Services" : Services()}

    GatewayController = WSGIGateway(services, logger=logging, debug=True)

This sets up a GatewayController WSGI app that has three services that can be called from Flex: `echo`, `sum`, and `scramble`, which each do exactly what they say they do.

## Setup a controller

Then you can import your `GatewayController` into `root.py`:

    from tg import use_wsgi_app
    from mygateway import GatewayController

Now all you have to do is add a method that delegates to the wsgi app:

    @expose()
    def gateway(self, *args, **kwargs):
        return use_wsgi_app(GatewayController)

Of course, you’ll need to import `use_wsgi_app` from `tg`, and your `GatewayController` from wherever you put it. But once you’ve done those things you’ll have a AMF Gateway mounted at `/gateway` which you can approach from Flex.

## Create a Flex Client

Now we’re ready for the big time event, we can create a brand new Flex client which talks to our TG2 hosted PyAMF services. This little tutorial pretty much assumes that you know how to use Flex and just want to see how to connect it to a TurboGears app.

Here’s the MXML:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="left">

        <mx:RemoteObject endpoint="http://127.0.0.1:8080/gateway"
                         destination="Services" id="remoteObj"
                         result="displayResult(event)" fault="remoteFault(event)">
            <mx:method name="scramble" result="scrambleResult(event)"/>
        </mx:RemoteObject>

        <mx:Button click="remoteObj.echo('Hello, There!')" label="Hello"/>

        <mx:HBox width="100%">
            <mx:Button click="remoteObj.sum(new Number(a.text), new Number(b.text))" label="Sum"/>
            <mx:TextInput id="a" text="47"/>
            <mx:TextInput id="b" text="99"/>
        </mx:HBox>
        <mx:HBox width="100%">
            <mx:Button click="remoteObj.scramble(c.text)" label="Scramble"/>
            <mx:TextInput id="c" text="She sells seashells by the seashore" width="100%"/>
        </mx:HBox>

        <mx:Text id="result" width="100%" height="100%" />

        <mx:Script>
        <![CDATA[
            import mx.utils.ObjectUtil;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;

            private function displayResult(re:ResultEvent): void {
                result.text += ObjectUtil.toString(re.result) + "\n";
            }

            private function scrambleResult(re:ResultEvent): void {
                c.text = re.result as String;
            }

            private function remoteFault(fault:FaultEvent): void {
                result.text = fault.fault.faultDetail;
            }
        ]]>
        </mx:Script>
    </mx:Application>

You can paste that into a new Flex Builder project (or use the free SDK to create a project with the text editor of your choice). You can then put the HTML and SWF files generated by Flex Builder into your TG2 project’s static directory (wherever you want them to be available) at which point you should be able to browse there, get your Flex app, and use it to connect to the web services you just created.