|
Introduction
PyAMF isn’t just about the Adobe Flash Player talking to a Python backend, oh no. We have put together a client module which allows you to make AMF calls to an HTTP Gateway, whether that be PyAMF or other AMF implementations. If you come from a Adobe Flash background, this API should feel very natural to you.
Contents
The examples below are working, so feel free to try this out right now.
This example connects to a AMF gateway running at http://demo.pyamf.org/gateway/recordset and invokes the remote Python getLanguages method that is mapped to service.getLanguages. The result is printed on stdout.
1 2 3 4 5 6 | from pyamf.remoting.client import RemotingService
client = RemotingService('http://demo.pyamf.org/gateway/recordset')
service = client.getService('service')
print service.getLanguages()
|
Use setCredentials(username, password) to authenticate with an AMF client:
1 2 3 4 5 6 7 8 9 10 | from pyamf.remoting.client import RemotingService
client = RemotingService('https://demo.pyamf.org/gateway/authentication')
client.setCredentials('jane', 'doe')
service = client.getService('calc')
print service.sum(85, 115) # should print 200.0
client.setCredentials('abc', 'def')
print service.sum(85, 115).description # should print Authentication Failed
|
Enable logging with a DEBUG level to log messages including the timestamp and level name.
1 2 3 4 5 6 7 8 9 10 11 | from pyamf.remoting.client import RemotingService
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s')
gateway = 'http://demo.pyamf.org/gateway/recordset'
client = RemotingService(gateway, logger=logging)
service = client.getService('service')
print service.getLanguages()
|
AMF0 is the default AMF encoding used by the client. You can force it to use AMF3 by supplying the amf_version keyword to the RemotingService. See pyamf.ENCODING_TYPES for more info.
1 2 3 4 5 6 7 8 | from pyamf import AMF0, AMF3
from pyamf.remoting.client import RemotingService
gateway = 'http://demo.pyamf.org/gateway/helloworld'
client = RemotingService(gateway, amf_version=AMF3)
service = client.getService('echo')
print service("Hello AMF3 world!")
|
By default the client identifies itself with a ‘PyAMF/x.x’ user agent header. You can modify this by providing a custom user_agent keyword to your RemotingService. The example client below will be seen as ‘MyApp/0.1.0’ by the server.
1 2 3 4 5 6 7 8 | from pyamf.remoting.client import RemotingService
appName = 'MyApp/0.1.0'
gateway = 'http://demo.pyamf.org/gateway/helloworld'
client = RemotingService(gateway, user_agent=appName)
service = client.getService('echo')
print service.echo('Hello World!')
|
The referer also provides the client a way to identify itself, similar to the user_agent in the previous example. You can modify this by providing a custom referrer keyword to your RemotingService. The example client below will be seen as ‘client.py’ by the server. The default is None.
1 2 3 4 5 6 7 8 | from pyamf.remoting.client import RemotingService
appReferer = 'client.py'
gateway = 'http://demo.pyamf.org/gateway/helloworld'
client = RemotingService(gateway, referer=appReferer)
service = client.getService('echo')
print service.echo('Hello World!')
|
You can modify the headers of the HTTP request using this convenient API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from pyamf.remoting.client import RemotingService
gw = RemotingService('http://demo.pyamf.org/gateway/recordset')
gw.addHTTPHeader("Accept-encoding", "gzip")
gw.addHTTPHeader('Set-Cookie', 'sessionid=QT3cUmACNeKQo5oPeM0')
gw.removeHTTPHeader('Set-Cookie')
username = 'admin'
password = 'admin'
auth = ('%s:%s' % (username, password)).encode('base64')[:-1]
gw.addHTTPHeader("Authorization", "Basic %s" % auth)
service = gw.getService('service')
print service.getLanguages()
|
As of PyAMF 0.6, the client will now raise an appropriate error if remoting call returns an error. The default behaviour is to raise a RemotingError but this behaviour can be modified:
# service method
def type_error():
raise TypeError('some useful message here')
And from the console:
>>> from pyamf.remoting.client import RemotingService
>>> gateway = RemotingService('http://example.org/gw')
>>> service = gateway.getService('type_error')
>>> service()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/nick/projects/pyamf/pyamf/remoting/client/__init__.py", line 121, in __call__
return self._call(ServiceMethodProxy(self, None), *args)
File "/Users/nick/projects/pyamf/pyamf/remoting/client/__init__.py", line 107, in _call
response.body.raiseException()
File "/Users/nick/projects/pyamf/pyamf/remoting/__init__.py", line 335, in raiseException
raise get_exception_from_fault(self), self.description, None
TypeError: some useful message here
The gateway returns an error code which is mapped to an exception class. A number of built-in exceptions are automatically mapped:
Use pyamf.add_error_class() to add new code/class combos and pyamf.remove_error_class() to remove classes.