[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