work on docs

This commit is contained in:
Tobias Oberstein
2014-08-06 01:08:08 +02:00
parent a35a38641c
commit be1c8a1633
6 changed files with 217 additions and 114 deletions

View File

@@ -359,32 +359,33 @@ class ICaller(ISession):
"""
Call a remote procedure.
This will return a Deferred/Future, that when resolved, provides the actual result.
This will return a Deferred/Future, that when resolved, provides the actual result
returned by the called remote procedure.
If the result is a single positional return value, it'll be returned "as-is". If the
result contains multiple positional return values or keyword return values,
the result is wrapped in an instance of :class:`autobahn.wamp.types.CallResult`.
- If the result is a single positional return value, it'll be returned "as-is".
If the call fails, the returned Deferred/Future will be rejected with an instance
of :class:`autobahn.wamp.exception.ApplicationError`.
- If the result contains multiple positional return values or keyword return values,
the result is wrapped in an instance of :class:`autobahn.wamp.types.CallResult`.
If the *Caller* and *Dealer* implementations support canceling of calls, the call may
be canceled by canceling the returned Deferred/Future.
- If the call fails, the returned Deferred/Future will be rejected with an instance
of :class:`autobahn.wamp.exception.ApplicationError`.
If ``kwargs`` contains an ``options`` keyword argument that is an instance of
:class:`autobahn.wamp.types.CallOptions`, this will provide
specific options for the call to perform.
:class:`autobahn.wamp.types.CallOptions`, this will provide specific options for
the call to perform.
:param procedure: The URI of the remote procedure to be called, e.g. ``"com.myapp.hello"``.
:type procedure: str
When the *Caller* and *Dealer* implementations support canceling of calls, the call may
be canceled by canceling the returned Deferred/Future.
:param procedure: The URI of the remote procedure to be called, e.g. ``u"com.myapp.hello"``.
:type procedure: unicode
:param args: Any positional arguments for the call.
:type args: list
:param kwargs: Any keyword arguments for the call.
:type kwargs: dict
:returns: obj -- A Deferred/Future for the call result -
an instance of :class:`twisted.internet.defer.Deferred` (when running under Twisted) or
an instance of :class:`asyncio.Future` (when running under asyncio).
:returns: A Deferred/Future for the call result -
:rtype: instance of :tx:`twisted.internet.defer.Deferred` / :py:class:`asyncio.Future`
"""
@@ -414,18 +415,21 @@ class IRegistration(object):
Unregister this registration that was previously created from
:func:`autobahn.wamp.interfaces.ICallee.register`.
After a registration has been unregistered, calls won't get routed
to the endpoint any more.
After a registration has been unregistered successfully, no calls
will be routed to the endpoint anymore.
This will return a Deferred/Future, that when resolved signals
successful unregistration.
Returns an instance of :tx:`twisted.internet.defer.Deferred` (when
running on **Twisted**) or an instance of :py:class:`asyncio.Future`
(when running on **asyncio**).
If the unregistration fails, the returned Deferred/Future will be rejected
with an instance of :class:`autobahn.wamp.exception.ApplicationError`.
- If the unregistration succeeds, the returned Deferred/Future will
*resolve* (with no return value).
:returns: obj -- A Deferred/Future for the unregistration -
an instance of :class:`twisted.internet.defer.Deferred` (when running under Twisted)
or an instance of :class:`asyncio.Future` (when running under asyncio).
- If the unregistration fails, the returned Deferred/Future will be rejected
with an instance of :class:`autobahn.wamp.exception.ApplicationError`.
:returns: A Deferred/Future for the unregistration
:rtype: instance(s) of :tx:`twisted.internet.defer.Deferred` / :py:class:`asyncio.Future`
"""
@@ -438,37 +442,34 @@ class ICallee(ISession):
@abc.abstractmethod
def register(self, endpoint, procedure = None, options = None):
"""
Register an endpoint for a procedure to (subsequently) receive calls
calling that procedure.
Register a procedure for remote calling.
If ``endpoint`` is a callable (function, method or object that implements ``__call__``),
then `procedure` must be provided and an instance of
:class:`twisted.internet.defer.Deferred` (when running on Twisted) or an instance
of :class:`asyncio.Future` (when running on asyncio) is returned.
When ``endpoint`` is a callable (function, method or object that implements ``__call__``),
then ``procedure`` must be provided and an instance of
:tx:`twisted.internet.defer.Deferred` (when running on **Twisted**) or an instance
of :py:class:`asyncio.Future` (when running on **asyncio**) is returned.
If the registration succeeds the Deferred/Future will resolve to an object
that implements :class:`autobahn.wamp.interfaces.Registration`.
- If the registration *succeeds* the returned Deferred/Future will *resolve* to
an object that implements :class:`autobahn.wamp.interfaces.IRegistration`.
If the registration fails the Deferred/Future will reject with an instance
of :class:`autobahn.wamp.exception.ApplicationError`.
- If the registration *fails* the returned Deferred/Future will *reject* with an
instance of :class:`autobahn.wamp.exception.ApplicationError`.
If ``endpoint`` is an object, then each of the object's methods that are decorated
with :func:`autobahn.wamp.register` are registered as procedure endpoints, and a list of
When ``endpoint`` is an object, then each of the object's methods that is decorated
with :func:`autobahn.wamp.register` is automatically registered and a list of
Deferreds/Futures is returned that each resolves or rejects as above.
:param endpoint: The endpoint or endpoint object called under the procedure.
:type endpoint: callable
:param procedure: When ``endpoint`` is a single event handler, the URI (or URI pattern)
of the procedure to register for. When ``endpoint`` is an endpoint
object, this value is ignored (and should be ``None``).
:type procedure: str
:param endpoint: The endpoint called under the procedure.
:type endpoint: callable or object
:param procedure: When ``endpoint`` is a callable, the URI (or URI pattern)
of the procedure to register for. When ``endpoint`` is an object,
the argument is ignored (and should be ``None``).
:type procedure: unicode
:param options: Options for registering.
:type options: An instance of :class:`autobahn.wamp.types.RegisterOptions`.
:type options: instance of :class:`autobahn.wamp.types.RegisterOptions`.
:returns: obj -- A (list of) Deferred(s)/Future(s) for the registration(s) -
instance(s) of :class:`twisted.internet.defer.Deferred` (when
running under Twisted) or instance(s) of :class:`asyncio.Future`
(when running under asyncio).
:returns: A registration or a list of registrations (or errors)
:rtype: instance(s) of :tx:`twisted.internet.defer.Deferred` / :py:class:`asyncio.Future`
"""
@@ -501,26 +502,29 @@ class IPublisher(ISession):
:class:`autobahn.wamp.types.PublishOptions`, this will provide
specific options for the publish to perform.
If publication acknowledgement is requested via ``options.acknowledge == True``,
.. note::
By default, publications are non-acknowledged and the publication can
fail silently, e.g. because the session is not authorized to publish
to the topic.
When publication acknowledgement is requested via ``options.acknowledge == True``,
this function returns a Deferred/Future:
- if the publication succeeds the Deferred/Future will resolve to an object
- If the publication succeeds the Deferred/Future will resolve to an object
that implements :class:`autobahn.wamp.interfaces.IPublication`.
- if the publication fails the Deferred/Future will reject with an instance
- If the publication fails the Deferred/Future will reject with an instance
of :class:`autobahn.wamp.exception.ApplicationError`.
:param topic: The URI of the topic to publish to, e.g. ``"com.myapp.mytopic1"``.
:type topic: str
:param topic: The URI of the topic to publish to, e.g. ``u"com.myapp.mytopic1"``.
:type topic: unicode
:param args: Arbitrary application payload for the event (positional arguments).
:type args: list
:param kwargs: Arbitrary application payload for the event (keyword arguments).
:type kwargs: dict
:returns: obj -- ``None`` for non-acknowledged publications or,
for acknowledged publications, an instance of
:class:`twisted.internet.defer.Deferred` (when running under Twisted)
or an instance of :class:`asyncio.Future` (when running under asyncio).
:returns: Acknowledgement for acknowledge publications - otherwise nothing.
:rtype: ``None`` or instance of :tx:`twisted.internet.defer.Deferred` / :py:class:`asyncio.Future`
"""
@@ -551,18 +555,21 @@ class ISubscription(object):
Unsubscribe this subscription that was previously created from
:func:`autobahn.wamp.interfaces.ISubscriber.subscribe`.
After a subscription has been unsubscribed, events won't get
routed to the handler anymore.
After a subscription has been unsubscribed successfully, no events
will be routed to the event handler anymore.
This will return a Deferred/Future, that when resolved signals
successful unsubscription.
Returns an instance of :tx:`twisted.internet.defer.Deferred` (when
running on **Twisted**) or an instance of :py:class:`asyncio.Future`
(when running on **asyncio**).
If the unsubscription fails, the returned Deferred/Future will be rejected
with an instance of :class:`autobahn.wamp.exception.ApplicationError`.
- If the unsubscription succeeds, the returned Deferred/Future will
*resolve* (with no return value).
:returns: obj -- A Deferred/Future for the unsubscription -
an instance of :class:`twisted.internet.defer.Deferred` (when running under Twisted)
or an instance of :class:`asyncio.Future` (when running under asyncio).
- If the unsubscription fails, the returned Deferred/Future will *reject*
with an instance of :class:`autobahn.wamp.exception.ApplicationError`.
:returns: A Deferred/Future for the unsubscription
:rtype: instance(s) of :tx:`twisted.internet.defer.Deferred` / :py:class:`asyncio.Future`
"""
@@ -575,36 +582,34 @@ class ISubscriber(ISession):
@abc.abstractmethod
def subscribe(self, handler, topic = None, options = None):
"""
Subscribe to a topic and subsequently receive events published to that topic.
Subscribe to a topic for receiving events.
If ``handler`` is a callable (function, method or object that implements ``__call__``),
When ``handler`` is a callable (function, method or object that implements ``__call__``),
then `topic` must be provided and an instance of
:class:`twisted.internet.defer.Deferred` (when running on Twisted) or an instance
of :class:`asyncio.Future` (when running on asyncio) is returned.
:tx:`twisted.internet.defer.Deferred` (when running on **Twisted**) or an instance
of :class:`asyncio.Future` (when running on **asyncio**) is returned.
If the subscription succeeds the Deferred/Future will resolve to an object
that implements :class:`autobahn.wamp.interfaces.ISubscription`.
- If the subscription succeeds the Deferred/Future will resolve to an object
that implements :class:`autobahn.wamp.interfaces.ISubscription`.
If the subscription fails the Deferred/Future will reject with an instance
of :class:`autobahn.wamp.exception.ApplicationError`.
- If the subscription fails the Deferred/Future will reject with an instance
of :class:`autobahn.wamp.exception.ApplicationError`.
If ``handler`` is an object, then each of the object's methods that are decorated
with :func:`autobahn.wamp.subscribe` are subscribed as event handlers, and a list of
Deferreds/Futures is returned that each resolves or rejects as above.
When ``handler`` is an object, then each of the object's methods that is decorated
with :func:`autobahn.wamp.subscribe` is automatically subscribed as event handlers,
and a list of Deferreds/Futures is returned that each resolves or rejects as above.
:param handler: The event handler or handler object to receive events.
:type handler: callable or obj
:param topic: When ``handler`` is a single event handler, the URI (or URI pattern)
of the topic to subscribe to. When ``handler`` is an event handler
object, this value is ignored (and should be ``None``).
:type topic: str
:param handler: The event handler to receive events.
:type handler: callable or object
:param topic: When ``handler`` is a callable, the URI (or URI pattern)
of the topic to subscribe to. When ``handler`` is an object, this
value is ignored (and should be ``None``).
:type topic: unicode
:param options: Options for subscribing.
:type options: An instance of :class:`autobahn.wamp.types.SubscribeOptions`.
:returns: obj -- A (list of) Deferred(s)/Future(s) for the subscription(s) -
instance(s) of :class:`twisted.internet.defer.Deferred` (when
running under Twisted) or instance(s) of :class:`asyncio.Future`
(when running under asyncio).
:returns: A single Deferred/Future or a list of such objects
:rtype: instance(s) of :tx:`twisted.internet.defer.Deferred` / :py:class:`asyncio.Future`
"""

View File

@@ -15,3 +15,30 @@ Then, to get help on available build targets, just type
```sh
make
```
## Linking to Python objects
To link to a Autobahn class:
```rst
:py:class:`autobahn.websocket.protocol.WebSocketProtocol`
```
To link to a Python stdlib class:
```rst
:py:class:`zipfile.ZipFile`
```
Or to link to Python 2 or Python 3 specifically:
```rst
:py:class:`zipfile.ZipFile <py2:zipfile.ZipFile>`
:py:class:`zipfile.ZipFile <py3:zipfile.ZipFile>`
```
To link to a Twisted class:
```rst
:tx:`twisted.internet.defer.Deferred`
```

View File

@@ -0,0 +1,62 @@
##
## The code in this file is a (slightly modified) version from here:
## https://github.com/twisted/twisted/blob/trunk/docs/_extensions/apilinks.py
##
## It is hence licensed under the Twisted license (essentially BSD less advertising):
## https://github.com/twisted/twisted/blob/trunk/LICENSE
##
"""
Sphinx/docutils extension to create links to pyDoctor documentation using a
RestructuredText interpreted text role that looks like this::
:tx:`python_object_to_link_to <label>`
for example::
:tx:`twisted.internet.defer.Deferred <Deferred>`
The label is optional, hence you can also use
:tx:`twisted.internet.defer.Deferred`
"""
def make_api_link(name, rawtext, text, lineno, inliner,
options={}, content=[]):
from docutils import nodes, utils
# quick, dirty, and ugly...
if '<' in text and '>' in text:
full_name, label = text.split('<')
full_name = full_name.strip()
label = label.strip('>').strip()
else:
full_name = label = text
#get the base url for api links from the config file
env = inliner.document.settings.env
base_url = env.config.apilinks_base_url
# not really sufficient, but just testing...
# ...hmmm, maybe this is good enough after all
ref = ''.join((base_url, full_name, '.html'))
options.update(classes=["tx"])
node = nodes.reference(rawtext, utils.unescape(label), refuri=ref,
**options)
nodes = [node]
sys_msgs = []
return nodes, sys_msgs
# setup function to register the extension
def setup(app):
app.add_config_value('apilinks_base_url',
'http://twistedmatrix.com/documents/current/api/',
'env')
app.add_role('tx', make_api_link)

View File

@@ -6,11 +6,15 @@ body {
background-color: #fff;
}
code, kbd, pre, samp, span.pre {
code, kbd, pre, samp, span.pre, a.tx {
font-family: 'Source Code Pro', Consolas, Menlo, monospace;
font-size: 13px;
}
a.tx, a.tx:visited {
font-weight: bold;
}
/* scrolling for both code with and without line numbers */
[class^="highlight-"],
[class*=" highlight-"] {

View File

@@ -1,15 +1,20 @@
# -*- coding: utf-8 -*-
import os
import sys
import sphinx_bootstrap_theme
sys.path.insert(0, os.path.abspath('./_extensions'))
sys.path.insert(0, os.path.abspath('../autobahn'))
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'sphinx.ext.ifconfig',
'sphinxcontrib.spelling'
'sphinxcontrib.spelling',
'txsphinx'
]
spelling_lang = 'en_US'
@@ -231,8 +236,9 @@ htmlhelp_basename = 'AutobahnPython'
# http://sphinx-doc.org/ext/intersphinx.html
intersphinx_mapping = {
'py': ('http://docs.python.org/', None),
#'twisted': ('http://twistedmatrix.com/documents/current/api/', None),
'py2': ('http://docs.python.org/2', None),
'py3': ('http://docs.python.org/3', None),
'six': ('https://pythonhosted.org/six/', None),
}
rst_epilog = """

View File

@@ -50,7 +50,7 @@ When using **Twisted**, you derive from :class:`autobahn.twisted.wamp.Applicatio
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
whereas when you are using **asyncio**, you derive from :class:`autobahn.asyncio.wamp.ApplicationSession`
@@ -62,7 +62,7 @@ whereas when you are using **asyncio**, you derive from :class:`autobahn.asyncio
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
As can be seen, the only difference between Twisted and asyncio is the import (line 1). The rest of the code is identical.
@@ -131,14 +131,10 @@ The *Caller* and *Callee* will usually run application code, while the *Dealer*
Registering Procedures
......................
To make a procedure available for remote calling, the procedure needs to be *registered*.
Registering a procedure is done by calling :func:`autobahn.wamp.interfaces.ICallee.register`.
To make a procedure available for remote calling, the procedure needs to be *registered*. Registering a procedure is done by calling :func:`autobahn.wamp.interfaces.ICallee.register` from a session.
Here is an example using **Twisted**
Twisted
.. code-block:: python
:linenos:
:emphasize-lines: 14
@@ -150,7 +146,7 @@ Twisted
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
def add2(x, y):
return x + y
@@ -161,11 +157,17 @@ Twisted
except Exception as e:
print("could not register procedure: {0}".format(e))
The procedure ``add2`` is registered (line 14) under the URI ``com.myapp.add2``. When the registration succeeds, callers will immediately be able to call the procedure using the URI under which it was registered (``com.myapp.add2``).
The procedure ``add2`` is registered (line 14) under the URI ``u"com.myapp.add2"`` immediately in the ``onJoin`` callback which fires when the session has connected to a *Router* and joined a *Realm*.
The same code for **asyncio** looks like this
.. tip::
asyncio
You can register *local* functions like in above example, *global* functions as well as *methods* on class instances. Further, procedures can also be automatically registered using *decorators* (see :ref:`registering-procedure-using-decorators`)
When the registration succeeds, authorized callers will immediately be able to call the procedure (see :ref:`calling-procedures`) using the URI under which it was registered (``u"com.myapp.add2"``).
A registration may also fail, e.g. when a procedure is already registered under the given URI or when the session is not authorized to register procedures.
Using **asyncio**, the example looks like this
.. code-block:: python
:linenos:
@@ -178,7 +180,7 @@ asyncio
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
def add2(x, y):
return x + y
@@ -189,9 +191,10 @@ asyncio
except Exception as e:
print("could not register procedure: {0}".format(e))
The differences to Twisted are:
The differences compared with the Twisted variant are:
* the import (as with the previous examples)
* the ``import`` of ``ApplicationSession``
* the use of ``@coroutine`` to decorate co-routines
* the use of ``yield from`` instead of ``yield``
@@ -204,8 +207,6 @@ Calling a procedure (that has been previously registered) is done using :func:`a
Here is how you would call the procedure ``add2`` that we registered in :ref:`registering-procedures` under URI ``com.myapp.add2`` in **Twisted**
Twisted
.. code-block:: python
:linenos:
:emphasize-lines: 11
@@ -217,7 +218,7 @@ Twisted
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
try:
res = yield self.call(u'com.myapp.add2', 2, 3)
@@ -227,8 +228,6 @@ Twisted
And here is the same done on **asyncio**
asyncio
.. code-block:: python
:linenos:
:emphasize-lines: 11
@@ -240,7 +239,7 @@ asyncio
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
try:
res = yield from self.call(u'com.myapp.add2', 2, 3)
@@ -289,7 +288,7 @@ Here is a **Twisted** example
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
def oncounter(count):
print("event received: {0}", count)
@@ -319,7 +318,7 @@ The corresponding **asyncio** code looks like this
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
def oncounter(count):
print("event received: {0}", count)
@@ -356,7 +355,7 @@ Here is a **Twisted** example that will publish an event to topic ``u'com.myapp.
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
counter = 0
while True:
@@ -378,7 +377,7 @@ The corresponding **asyncio** code looks like this
class MyComponent(ApplicationSession):
def onJoin(self, details):
print("session established")
print("session ready")
counter = 0
while True: