t.p.amp : module documentation

AMP is a protocol for sending multiple asynchronous request/response
pairs over the same connection. Requests and responses are both
collections of key/value pairs.

AMP is a very simple protocol which is not an application. This module
is a "protocol construction kit" of sorts; it attempts to be the
simplest wire-level implementation of Deferreds. AMP provides the
following base-level features:

Asynchronous request/response handling (hence the name)

Requests and responses are both key/value pairs

Binary transfer of all data: all data is length-prefixed. Your
application will never need to worry about quoting.

Command dispatching (like HTTP Verbs): the protocol is extensible, and
multiple AMP sub-protocols can be grouped together easily.

The protocol implementation also provides a few additional features
which are not part of the core wire protocol, but are nevertheless very
useful:

Tight TLS integration, with an included StartTLS command.

Handshaking to other protocols: because AMP has well-defined message
boundaries and maintains all incoming and outgoing requests for you,
you can start a connection over AMP and then switch to another
protocol. This makes it ideal for firewall-traversal applications where
you may have only one forwarded port but multiple applications that
want to use it.

Using AMP with Twisted is simple. Each message is a command, with a
response. You begin by defining a command type. Commands specify their
input and output in terms of the types that they expect to see in the
request and response key-value pairs. Here's an example of a command that
adds two integers, 'a' and 'b':

The 'errors' mapping here tells AMP that if a responder to Divide emits
a ZeroDivisionError,
then the other side should be informed that an error of the type
'ZERO_DIVISION' has occurred. Writing a responder which takes advantage of
this is very simple - just raise your exception normally:

On the client side, the errors mapping will be used to determine what
the 'ZERO_DIVISION' error means, and translated into an asynchronous
exception, which can be handled normally as any Deferred would
be:

In general, the order of keys is arbitrary. Specific uses of AMP may
impose an ordering requirement, but unless this is specified explicitly,
any ordering may be generated and any ordering must be accepted. This
applies to the command-related keys _command and _ask as well
as any other keys.

Values are limited to the maximum encodable size in a 16-bit length,
65535 bytes.

Keys are limited to the maximum encodable size in a 8-bit length, 255
bytes. Note that we still use 2-byte lengths to encode keys. This small
redundancy has several features:

If an implementation becomes confused and starts emitting corrupt data,
or gets keys confused with values, many common errors will be signalled
immediately instead of delivering obviously corrupt packets.

A single NUL will separate every key, and a double NUL separates
messages. This provides some redundancy when debugging traffic dumps.

NULs will be present at regular intervals along the protocol, providing
some padding for otherwise braindead C implementations of the protocol,
so that <stdio.h> string functions will see the NUL and stop.

This makes it possible to run an AMP server on a port also used by a
plain-text protocol, and easily distinguish between non-AMP clients
(like web browsers) which issue non-NUL as the first byte, and AMP
clients, which always issue NUL as the first byte.

Local arguments are never actually relayed across the wire. This is
just a shim so that StartTLS can pretend to have some arguments: if
arguments acquire documentation properties, replace this with something
nicer later.

(Private) Normalize an argument name from the wire for use with Python
code. If the return value is going to be a python keyword it will be
capitalized. If it contains any dashes they will be replaced with
underscores.

The rationale behind this method is that AMP should be an inherently
multi-language protocol, so message keys may contain all manner of bizarre
bytes. This is not a complete solution; there are still forms of arguments
that this implementation will be unable to parse. However, Python
identifiers share a huge raft of properties with identifiers from many
other languages, so this is a 'good enough' effort for now. We deal
explicitly with dashes because that is the most likely departure: Lisps
commonly use dashes to separate method names, so protocols initially
implemented in a lisp amp dialect may use dashes in argument or command
names.

Parameters

key

a str, looking something like 'foo-bar-baz' or 'from'

Returns

a str which is a valid python identifier, looking something like
'foo_bar_baz' or 'From'.