# Google App Engine

Introduction

This howto will show you how to use a PyAMF application (0.3.1 or newer) with Google App Engine.

Google App Engine (GAE) lets you run your web applications on Google’s infrastructure for free. You can serve your app using a free domain name on the appspot.com domain, or use Google Apps to serve it from your own domain.

GAE applications are implemented using Python 2.5.2. The runtime environment includes the full Python language and most of the Python standard library, including Django.

## Prerequisites

Before you can start using GAE you need to download and install:

- Python 2.5 or newer for your platform from the Python website. Users of Mac OS X 10.5 or newer already have Python 2.5 installed.
- Google App Engine SDK
- PyAMF 0.3.1 or newer

## Create Project

Start a new GAE project:

- Create a new folder for your project
- Copy `main.py`, `app.yaml`, and `index.yaml` from `google_appengine/new_project_template` to your new folder. On a Mac you can find it under `/usr/local`
- Move the `pyamf` folder from your unpacked `PyAMF-0.x.x` folder to the root folder of the new GAE project

Your folder structure of your project should now look something like this:

    + MyProject
      - main.py
      - app.yaml
      - index.yaml
      - pyamf

## Application

You can setup your application using the `WebAppGateway` or the `WSGIGateway`.

### WebApp Gateway

The `WebAppGateway` class allows a GAE application to handle AMF requests on the root URL and other standard HTTP requests on another URL (`/helloworld` in the example below).

The `main.py` module tells GAE what code to launch. Modify it for PyAMF:

     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

    import logging
    import wsgiref.handlers

    from google.appengine.ext import webapp

    from pyamf.remoting.gateway.google import WebAppGateway

    class MainPage(webapp.RequestHandler):
        def get(self):
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.out.write('Hello, webapp World!')

    def echo(data):
        return data

    services = {
        'myservice.echo': echo,
    }

    def main():
        gateway = WebAppGateway(services, logging=logger, debug=True)
        application_paths = [('/', gateway), ('/helloworld', MainPage)]
        application = webapp.WSGIApplication(application_paths, debug=True)

        wsgiref.handlers.CGIHandler().run(application)

### WSGI Gateway

If you don’t want to use the pure `google.appengine` approach as described above, you can also use the `WSGIGateway` by modifying your `main.py` like this:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    import logging
    import wsgiref.handlers

    from pyamf.remoting.gateway.wsgi import WSGIGateway

    def echo(data):
        return data

    services = {
        'myservice.echo': echo,
    }

    def main():
        gateway = WSGIGateway(services, logger=logging, debug=True)
        wsgiref.handlers.CGIHandler().run(gateway)

    if __name__ == '__main__':
        main()

## Start the server

Run this command from your application folder:

    dev_appserver.py --debug --address=localhost --port=8080 .

## Test the application

### Python

To test the gateway you can use a Python AMF client like this:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16

    import logging

    from pyamf.remoting.client import RemotingService

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

    path = 'http://localhost:8080/'
    gw = RemotingService(path, logger=logging, debug=True)
    service = gw.getService('myservice')

    print service.echo('Hello World!')

### Flash

Create a new Adobe Flash document and place a `TextField` on the stage. Make it dynamic in the Properties pane, and give it the instance name `output`. Then, paste the following code into the Actions pane:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    import flash.net.*;

    var netConnection:NetConnection = new NetConnection();
    netConnection.connect("http://localhost:8080/");

    var responder:Responder = new Responder(onComplete, onFail);
    netConnection.call("myservice.echo", responder, "Flash talked to PyAMF.  They both say hello.");

    function onComplete(results)
    {
            output.htmlText = results;
    }

    function onFail(results)
    {
            for each (var thisResult in results)
            {
                    output.text += thisResult;
            }
    }

Run `Debug` > `Debug` movie to test PyAMF with Google App Engine! Other examples for Flex etc can be found on the Examples page.

## Future Plans

This method works fine as long as the app is only going to be the gateway. It would be beneficial, however, to have the SWF running on the same instance.

If you have suggestions join us on the IRC channel or use the mailinglist.

## Useful Resources

http://aralbalkan.com/1307
  Aral Balkan - Building Flash applications with Google App Engine.
http://pyamf.org/wiki/DjangoHowto
  PyAMF integration with Django.
http://pyamf.org/wiki/ByteArrayExample
  ByteArray example using Django and Flex.
http://blog.pyamf.org/archives/pyamf-and-google-app-engine
  Related post on PyAMF blog.
http://pyamf.appspot.com/punit
  Run the PyAMF test suite on the Google App Engine.