[Pkg-privacy-commits] [pyptlib] 87/136: update documentation and examples to reflect the new API
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 13:25:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository pyptlib.
commit abf1f650c023f2f66a3a72d696ce759e9c1f6bc7
Author: Ximin Luo <infinity0 at gmx.com>
Date: Mon Aug 19 18:25:04 2013 +0100
update documentation and examples to reflect the new API
---
ChangeLog | 2 +
examples/client.py | 13 ++---
examples/server.py | 13 ++---
pyptlib/client.py | 2 +-
pyptlib/core.py | 10 ++++
pyptlib/server.py | 15 ++++--
sphinx/API.rst | 152 ++++++++++++++++++++++++++---------------------------
sphinx/conf.py | 4 +-
8 files changed, 115 insertions(+), 96 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c49319f..af0e837 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@ Changes in version 0.0.4 - UNRELEASED
- Add a subprocess management module, which should make it easier to
write composed plugins such as obfs-flash, and the 2-INT termination
behaviour specified in the PT spec.
+ - Present a more object-oriented public API, and refactor internals to
+ have better separation of concerns,
Changes in version 0.0.3 - 2013-02-18
diff --git a/examples/client.py b/examples/client.py
index 6ea4ab1..d165066 100755
--- a/examples/client.py
+++ b/examples/client.py
@@ -5,13 +5,14 @@
import sys
-import pyptlib
-import pyptlib.client
+from pyptlib.client import ClientTransportPlugin
+from pyptlib.config import EnvError
if __name__ == '__main__':
+ client = ClientTransportPlugin()
try:
- managed_info = pyptlib.client.init(["blackfish", "bluefish"])
- except pyptlib.config.EnvError, err:
+ managed_info = client.init(["blackfish", "bluefish"])
+ except EnvError, err:
print "pyptlib could not bootstrap ('%s')." % str(err)
sys.exit(1)
@@ -26,7 +27,7 @@ if __name__ == '__main__':
reportFailure(transport, "Failed to launch ('%s')." % str(err))
continue
- pyptlib.client.reportSuccess(transport, socks_version, bind_addrport, None, None)
+ client.reportMethodSuccess(transport, socks_version, bind_addrport, None, None)
# After spawning our transports, report that we are done.
- pyptlib.client.reportEnd()
+ client.reportMethodsEnd()
diff --git a/examples/server.py b/examples/server.py
index 3e3d0c0..bef188d 100755
--- a/examples/server.py
+++ b/examples/server.py
@@ -5,13 +5,14 @@
import sys
-import pyptlib
-import pyptlib.server
+from pyptlib.server import ServerTransportPlugin
+from pyptlib.config import EnvError
if __name__ == '__main__':
+ server = ServerTransportPlugin()
try:
- managed_info = pyptlib.server.init(["blackfish", "bluefish"])
- except pyptlib.config.EnvError, err:
+ managed_info = server.init(["blackfish", "bluefish"])
+ except EnvError, err:
print "pyptlib could not bootstrap ('%s')." % str(err)
sys.exit(1)
@@ -29,7 +30,7 @@ if __name__ == '__main__':
reportFailure(transport, "Failed to launch ('%s')." % str(err))
continue
- pyptlib.server.reportSuccess(transport, bind_addrport, None)
+ server.reportMethodSuccess(transport, bind_addrport, None)
# Report back after we finish spawning transports.
- pyptlib.server.reportEnd()
+ server.reportMethodsEnd()
diff --git a/pyptlib/client.py b/pyptlib/client.py
index 5b93627..7f7b2b8 100644
--- a/pyptlib/client.py
+++ b/pyptlib/client.py
@@ -44,7 +44,7 @@ def init(supported_transports):
client.init(supported_transports)
retval = {}
retval['state_loc'] = client.config.getStateLocation()
- retval['transports'] = client.served_transports
+ retval['transports'] = client.getServedTransports()
return retval
diff --git a/pyptlib/core.py b/pyptlib/core.py
index 14c3319..9512d0f 100644
--- a/pyptlib/core.py
+++ b/pyptlib/core.py
@@ -85,6 +85,16 @@ class TransportPlugin(object):
self.served_transports = wanted_transports
return { 'transports': wanted_transports }
+ def getServedTransports(self):
+ """
+ Return the names of the transports that this plugin is serving.
+
+ :raises: :class:`ValueError` if called before :func:`init`.
+ """
+ if self.served_transports is None:
+ raise ValueError("init not yet called")
+ return self.served_transports
+
def reportMethodError(self, name, message):
"""
Write a message to stdout announcing that we failed to launch a transport.
diff --git a/pyptlib/server.py b/pyptlib/server.py
index 6f38b7d..d4f3d4f 100644
--- a/pyptlib/server.py
+++ b/pyptlib/server.py
@@ -33,19 +33,28 @@ class ServerTransportPlugin(TransportPlugin):
self.emit('SMETHOD %s %s:%s' % (name, addrport[0],
addrport[1]))
+ def getServedBindAddresses(self):
+ """
+ Return the names of the transports that this plugin is serving, each
+ mapped to '(ip,port)' of the location where the transport should bind.
+
+ :raises: :class:`ValueError` if called before :func:`init`.
+ """
+ return dict((k, v)
+ for k, v in self.config.getServerBindAddresses().items()
+ if k in self.getServedTransports())
+
def init(supported_transports):
"""DEPRECATED. Use ServerTransportPlugin().init() instead."""
server = ServerTransportPlugin()
server.init(supported_transports)
config = server.config
- transports = dict(((k, v) for k, v in config.getServerBindAddresses().items()
- if k in server.served_transports))
retval = {}
retval['state_loc'] = config.getStateLocation()
retval['orport'] = config.getORPort()
retval['ext_orport'] = config.getExtendedORPort()
- retval['transports'] = transports
+ retval['transports'] = server.getServedBindAddresses()
retval['auth_cookie_file'] = config.getAuthCookieFile()
return retval
diff --git a/sphinx/API.rst b/sphinx/API.rst
index 5915273..09ed55c 100644
--- a/sphinx/API.rst
+++ b/sphinx/API.rst
@@ -30,65 +30,63 @@ An application using pyptlib should start by calling
:func:`pyptlib.config.checkClientMode` to learn whether Tor wants it
to run as a client or as a server.
+You should then create a :class:`pyptlib.client.ClientTransportPlugin`
+or :class:`pyptlib.server.ServerTransportPlugin` as appropriate. This
+object is your main entry point to the pyptlib API, so you should
+keep it somewhere for later access.
+
1) Get transport information from Tor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-If Tor wants the application to run as a client, the next step is to
-run :func:`pyptlib.client.init`. Otherwise, the application should run
-:func:`pyptlib.server.init`.
-
-:func:`init` expects to be passed a list with the names of the
-transports your application supports.
+The next step is to run :func:`init <pyptlib.core.TransportPlugin.init>`
+to parse the rest of the configuration and communicate the results
+to Tor. You should pass a list of names of the transports your
+application supports.
-The application should be prepared for
-:exc:`pyptlib.config.EnvError`, which signifies that the
-environment was not prepared by Tor.
-
-The application should store the return value of the :func:`init`
-function.
+The application should be prepared for :exc:`pyptlib.config.EnvError`,
+which signifies that the environment was not prepared by Tor.
Consider an example of the fictional application *rot0r* which
-implements the pluggable transports *rot13* and *rot26*. If
-*rot0r*, in step 1, learned that Tor expects it to act as a client,
-it should now do:
+implements the pluggable transports *rot13* and *rot26*. If *rot0r*,
+in step 1, learned that Tor expects it to act as a client, it should
+now do:
.. code-block::
python
- import pyptlib.client
- import pyptlib.config
+ from pyptlib.client import ClientTransportPlugin
+ from pyptlib.config import EnvError
+ client = ClientTransportPlugin()
try:
- managed_info = pyptlib.client.init(["rot13", "rot26"])
- except pyptlib.config.EnvError, err:
+ client.init(supported_transports=["rot13", "rot26"])
+ except EnvError, err:
print "pyptlib could not bootstrap ('%s')." % str(err)
+Afterwards, the API's ``config`` attribute provides methods to find
+out how Tor wants your application to be configured. For example, if
+you store state, it should go in :func:`client.config.getStateLocation()
+<pyptlib.config.Config.getStateLocation>`. For a complete list, see
+the documentation for that module.
+
2) Launch transports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Client case (skip if you are a server)
"""""""""""""""""""""""""""""""""""""""""""
-If your application is a client, the return value of
-:func:`pyptlib.client.init` is a dictionary of the format:
-
-========== ========== ==========
-Key Type Value
-========== ========== ==========
-state_loc string Directory where the managed proxy should dump its state files (if needed).
-transports list Strings of the names of the transports that should be launched. The list can be empty.
-========== ========== ==========
-
-Your application should then use the *transports* key to learn which transports it should launch.
+Your application should then use :func:`client.getServedTransports()
+<pyptlib.core.TransportPlugin.getServedTransports>` to learn which
+transports it should launch.
Proceeding with the previous example:
.. code-block::
python
- if 'rot13' in managed_info['transports']:
+ if 'rot13' in client.getServedTransports():
launch_rot13_client()
- if 'rot26' in managed_info['transports']:
+ if 'rot26' in client.getServedTransports():
launch_rot26_client()
@@ -98,61 +96,55 @@ Proceeding with the previous example:
Server case (skip if you are a client):
""""""""""""""""""""""""""""""""""""""""""""
-If your application is a server, the return value of
-:func:`pyptlib.server.init` is a dictionary of the format:
-
-=============== ========== ==========
-Key Type Value
-================ ========== ==========
-state_loc string Directory where the managed proxy should dump its state files (if needed).
-orport tuple (ip,port) tuple pointing to Tor's ORPort.
-ext_orport tuple (ip,port) tuple pointing to Tor's Extended ORPort. None if Extended ORPort is not supported.
-transports dict A dictionary 'transport => (ip,port)' where 'transport' is the name of the transport that should be spawned, and '(ip,port)' is the location where the transport should bind. The dictionary can be empty.
-auth_cookie_file string Directory where the managed proxy should find the Extended ORPort authentication cookie.
-================ ========== ==========
+Your application should then use :func:`server.getServedBindAddresses()
+<pyptlib.server.ServerTransportPlugin.getServedBindAddresses>` to
+learn which transports it should launch.
-Your application should then use the *transports* key and attempt to
-launch the appropriate transports. Furthermore, since the application
-runs as a server, it should push data to Tor's ORPort. The TCP/IP
-location of the ORPort is provided in the *orport* key.
+Since the application runs as a server, it will push data to Tor's
+ORPort, which you can get using :func:`server.config.getORPort()
+<pyptlib.server_config.ServerConfig.getORPort>`.
Proceeding with the previous example:
.. code-block::
python
- if 'rot13' in managed_info['transports']:
- launch_rot13_server(managed_info['transports']['rot13'], managed_info['orport'])
- if 'rot26' in managed_info['transports']:
- launch_rot26_server(managed_info['transports']['rot26'], managed_info['orport'])
+ transports = server.getServedBindAddresses()
+ if 'rot13' in transports:
+ launch_rot13_server(transports['rot13'], server.config.getORPort())
+ if 'rot26' in transports:
+ launch_rot26_server(transports['rot26'], server.config.getORPort())
3) Report results back to Tor.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For every transport that the application launches, it reports to
-pyptlib whether it was launched successfully or not. This way, Tor is
-informed on whether a transport is expected to work or not.
+pyptlib whether it was launched successfully or not. This way, Tor
+is informed on whether a transport is expected to work or not.
Client case (skip if you are a server):
""""""""""""""""""""""""""""""""""""""""""""
-Everytime a transport is successfully launched, the application calls
-:func:`pyptlib.client.reportSuccess` with the name of the transport
-that was launched, the address where it is listening for connections,
-and the SOCKS version that the upstream SOCKS server supports.
+Every time a transport is successfully launched, the application
+calls :func:`client.reportMethodSuccess
+<pyptlib.client.ClientTransportPlugin.reportMethodSuccess>` with the
+name of the transport that was launched, the address where it is
+listening for connections, and the SOCKS version that the upstream
+SOCKS server supports.
For example, if *rot13* was launched successfully, waits for
-connections in '127.0.0.1:42042' and supports SOCKSv4, the appropriate
-call would be:
+connections in '127.0.0.1:42042' and supports SOCKSv4, the
+appropriate call would be:
.. code-block::
python
- pyptlib.client.reportSuccess('rot13', 5, ('127.0.0.1', 42042))
+ client.reportMethodSuccess('rot13', 5, ('127.0.0.1', 42042))
-Everytime a transport failed to launch, the application calls
-:func:`pyptlib.client.reportFailure` with the name of the transport
-and a message.
+Every time a transport failed to launch, the application calls
+:func:`client.reportMethodError
+<pyptlib.core.TransportPlugin.reportMethodError>` with the name of
+the transport and a message.
For example, if *rot26* failed to launch, the appropriate call
would be:
@@ -160,14 +152,16 @@ would be:
.. code-block::
python
- pyptlib.client.reportFailure('rot26', 'Could not bind to 127.0.0.1:666 (Operation not permitted)')
+ client.reportMethodError('rot26', 'Could not bind to 127.0.0.1:666 (Operation not permitted)')
Server case (skip if you are a client):
""""""""""""""""""""""""""""""""""""""""""""
-Everytime a transport is successfully launched, the application calls
-:func:`pyptlib.server.reportSuccess` with the name of the transport
-that was launched, and the address where it is listening for connections.
+Everytime a transport is successfully launched, the application
+calls :func:`server.reportMethodSuccess
+<pyptlib.server.ServerTransportPlugin.reportMethodSuccess>` with the
+name of the transport that was launched, and the address where it is
+listening for connections.
For example, if *rot13* was launched successfully and waits for
connections in '127.0.0.1:42042', the appropriate call would be:
@@ -175,11 +169,12 @@ connections in '127.0.0.1:42042', the appropriate call would be:
.. code-block::
python
- pyptlib.server.reportSuccess('rot13', ('127.0.0.1', 42042))
+ server.reportMethodSuccess('rot13', ('127.0.0.1', 42042))
-Everytime a transport failed to launch, the application calls
-:func:`pyptlib.server.reportFailure` with the name of the transport
-and a message.
+Everytime a transport failed to launch, the application should call
+:func:`server.reportMethodError
+<pyptlib.core.TransportPlugin.reportMethodError>` with the name of
+the transport and a message.
For example, if *rot26* failed to launch, the appropriate call
would be:
@@ -187,15 +182,16 @@ would be:
.. code-block::
python
- pyptlib.server.reportFailure('rot26', 'Could not bind to 127.0.0.1:666 (Operation not permitted)')
+ server.reportMethodError('rot26', 'Could not bind to 127.0.0.1:666 (Operation not permitted)')
4) Stop using pyptlib and start accepting connections
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When the application finishes launching connections, it should call
-:func:`pyptlib.client.reportEnd` (or
-:func:`pyptlib.server.reportEnd`), to announce to pyptlib that all
-transports were launched. This way, Tor knows that it can start
-pushing traffic to the application.
+:func:`reportMethodsEnd()
+<pyptlib.core.TransportPlugin.reportMethodsEnd>`, to announce to
+pyptlib that all transports were launched. This way, Tor knows that
+it can start pushing traffic to the application.
-After this point, pyptlib has no other use.
+After this point, the API object (in this current version of pyptlib)
+has no other use.
diff --git a/sphinx/conf.py b/sphinx/conf.py
index f8725b1..ddf717a 100644
--- a/sphinx/conf.py
+++ b/sphinx/conf.py
@@ -50,9 +50,9 @@ copyright = u'2012, Brandon Wiley'
# built documents.
#
# The short X.Y version.
-version = '0.0.1'
+version = '0.0.4'
# The full version, including alpha/beta/rc tags.
-release = '0.0.1'
+release = '0.0.4.UNRELEASED'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/pyptlib.git
More information about the Pkg-privacy-commits
mailing list