diff --git a/tornado/auth.py b/tornado/auth.py
index d4f50369..91a29519 100644
--- a/tornado/auth.py
+++ b/tornado/auth.py
@@ -697,9 +697,9 @@ class GoogleMixin(OpenIdMixin, OAuthMixin):
Some of the available resources are:
- Gmail Contacts - http://www.google.com/m8/feeds/
- Calendar - http://www.google.com/calendar/feeds/
- Finance - http://finance.google.com/finance/feeds/
+ * Gmail Contacts - http://www.google.com/m8/feeds/
+ * Calendar - http://www.google.com/calendar/feeds/
+ * Finance - http://finance.google.com/finance/feeds/
You can authorize multiple resources by separating the resource
URLs with a space.
@@ -740,6 +740,9 @@ class GoogleMixin(OpenIdMixin, OAuthMixin):
class FacebookMixin(object):
"""Facebook Connect authentication.
+ New applications should consider using `FacebookGraphMixin` below instead
+ of this class.
+
To authenticate with Facebook, register your application with
Facebook at http://www.facebook.com/developers/apps.php. Then
copy your API Key and Application Secret to the application settings
@@ -799,10 +802,10 @@ class FacebookMixin(object):
http://wiki.developers.facebook.com/index.php/Extended_permission.
The most common resource types include:
- publish_stream
- read_stream
- email
- sms
+ * publish_stream
+ * read_stream
+ * email
+ * sms
extended_permissions can be a single permission name or a list of
names. To get the session secret and session key, call
@@ -918,13 +921,14 @@ class FacebookMixin(object):
return hashlib.md5(body).hexdigest()
class FacebookGraphMixin(OAuth2Mixin):
+ """Facebook authentication using the new Graph API and OAuth2."""
_OAUTH_ACCESS_TOKEN_URL = "https://graph.facebook.com/oauth/access_token?"
_OAUTH_AUTHORIZE_URL = "https://graph.facebook.com/oauth/authorize?"
_OAUTH_NO_CALLBACKS = False
def get_authenticated_user(self, redirect_uri, client_id, client_secret,
code, callback, extra_fields=None):
- """ Handles the login for the Facebook user, returning a user object.
+ """Handles the login for the Facebook user, returning a user object.
Example usage::
diff --git a/tornado/autoreload.py b/tornado/autoreload.py
index 69738bdc..2ed0faec 100644
--- a/tornado/autoreload.py
+++ b/tornado/autoreload.py
@@ -16,8 +16,14 @@
"""A module to automatically restart the server when a module is modified.
+Most applications should not call this module directly. Instead, pass the
+keyword argument ``debug=True`` to the `tornado.web.Application` constructor.
+This will enable autoreload mode as well as checking for changes to templates
+and static resources.
+
This module depends on IOLoop, so it will not work in WSGI applications
-and Google AppEngine.
+and Google AppEngine. It also will not work correctly when HTTPServer's
+multi-process mode is used.
"""
import functools
diff --git a/tornado/options.py b/tornado/options.py
index e41e3678..2a89e51d 100644
--- a/tornado/options.py
+++ b/tornado/options.py
@@ -310,7 +310,10 @@ class Error(Exception):
def enable_pretty_logging():
- """Turns on formatted logging output as configured."""
+ """Turns on formatted logging output as configured.
+
+ This is called automatically by `parse_command_line`.
+ """
root_logger = logging.getLogger()
if options.log_file_prefix:
channel = logging.handlers.RotatingFileHandler(
diff --git a/tornado/stack_context.py b/tornado/stack_context.py
index 5b012c53..53edbd27 100644
--- a/tornado/stack_context.py
+++ b/tornado/stack_context.py
@@ -61,19 +61,19 @@ class _State(threading.local):
_state = _State()
class StackContext(object):
+ '''Establishes the given context as a StackContext that will be transferred.
+
+ Note that the parameter is a callable that returns a context
+ manager, not the context itself. That is, where for a
+ non-transferable context manager you would say::
+
+ with my_context():
+
+ StackContext takes the function itself rather than its result::
+
+ with StackContext(my_context):
+ '''
def __init__(self, context_factory):
- '''Establishes the given context as a StackContext that will be transferred.
-
- Note that the parameter is a callable that returns a context
- manager, not the context itself. That is, where for a
- non-transferable context manager you would say::
-
- with my_context():
-
- StackContext takes the function itself rather than its result::
-
- with StackContext(my_context):
- '''
self.context_factory = context_factory
# Note that some of this code is duplicated in ExceptionStackContext
@@ -98,19 +98,19 @@ class StackContext(object):
_state.contexts = self.old_contexts
class ExceptionStackContext(object):
+ '''Specialization of StackContext for exception handling.
+
+ The supplied exception_handler function will be called in the
+ event of an uncaught exception in this context. The semantics are
+ similar to a try/finally clause, and intended use cases are to log
+ an error, close a socket, or similar cleanup actions. The
+ exc_info triple (type, value, traceback) will be passed to the
+ exception_handler function.
+
+ If the exception handler returns true, the exception will be
+ consumed and will not be propagated to other exception handlers.
+ '''
def __init__(self, exception_handler):
- '''Specialization of StackContext for exception handling.
-
- The supplied exception_handler function will be called in the
- event of an uncaught exception in this context. The semantics are
- similar to a try/finally clause, and intended use cases are to log
- an error, close a socket, or similar cleanup actions. The
- exc_info triple (type, value, traceback) will be passed to the
- exception_handler function.
-
- If the exception handler returns true, the exception will be
- consumed and will not be propagated to other exception handlers.
- '''
self.exception_handler = exception_handler
def __enter__(self):
diff --git a/tornado/testing.py b/tornado/testing.py
index 9c42e8a5..e5cee162 100644
--- a/tornado/testing.py
+++ b/tornado/testing.py
@@ -3,13 +3,13 @@
This module contains three parts:
-* AsyncTestCase/AsyncHTTPTestCase: Subclasses of unittest.TestCase
+* `AsyncTestCase`/`AsyncHTTPTestCase`: Subclasses of unittest.TestCase
with additional support for testing asynchronous (IOLoop-based) code.
-* LogTrapTestCase: Subclass of unittest.TestCase that discards log output
+* `LogTrapTestCase`: Subclass of unittest.TestCase that discards log output
from tests that pass and only produces output for failing tests.
-* main(): A simple test runner (wrapper around unittest.main()) with support
+* `main()`: A simple test runner (wrapper around unittest.main()) with support
for the tornado.autoreload module to rerun the tests when code changes.
These components may be used together or independently. In particular,
diff --git a/tornado/websocket.py b/tornado/websocket.py
index 104349d7..ca203828 100644
--- a/tornado/websocket.py
+++ b/tornado/websocket.py
@@ -1,17 +1,16 @@
+"""Server-side implementation of the WebSocket protocol.
+
+`WebSockets `_ allow for bidirectional
+communication between the browser and server.
+
+.. warning::
+
+ The WebSocket protocol is still in development. This module currently
+ implements the "draft76" version of the protocol, which is supported
+ only by Chrome and Safari. See this `browser compatibility table
+ `_ on Wikipedia.
+"""
# Author: Jacob Kristhammar, 2010
-#
-# Updated version of websocket.py[1] that implements latest[2] stable version
-# of the websocket protocol.
-#
-# NB. It's no longer possible to manually select which callback that should
-# be invoked upon message reception. Instead you must override the
-# on_message(message) method to handle incoming messsages.
-# This also means that you don't have to explicitly invoke
-# receive_message, in fact you shouldn't.
-#
-# [1] http://github.com/facebook/tornado/blob/
-# 2c89b89536bbfa081745336bb5ab5465c448cb8a/tornado/websocket.py
-# [2] http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
import functools
import hashlib
diff --git a/tornado/wsgi.py b/tornado/wsgi.py
index 8b6177f7..6527d30c 100644
--- a/tornado/wsgi.py
+++ b/tornado/wsgi.py
@@ -16,38 +16,17 @@
"""WSGI support for the Tornado web framework.
-We export WSGIApplication, which is very similar to web.Application, except
-no asynchronous methods are supported (since WSGI does not support
-non-blocking requests properly). If you call self.flush() or other
-asynchronous methods in your request handlers running in a WSGIApplication,
-we throw an exception.
+WSGI is the Python standard for web servers, and allows for interoperability
+between Tornado and other Python web frameworks and servers. This module
+provides WSGI support in two ways:
-Example usage::
-
- import tornado.web
- import tornado.wsgi
- import wsgiref.simple_server
-
- class MainHandler(tornado.web.RequestHandler):
- def get(self):
- self.write("Hello, world")
-
- if __name__ == "__main__":
- application = tornado.wsgi.WSGIApplication([
- (r"/", MainHandler),
- ])
- server = wsgiref.simple_server.make_server('', 8888, application)
- server.serve_forever()
-
-See the 'appengine' demo for an example of using this module to run
-a Tornado app on Google AppEngine.
-
-Since no asynchronous methods are available for WSGI applications, the
-httpclient and auth modules are both not available for WSGI applications.
-
-We also export WSGIContainer, which lets you run other WSGI-compatible
-frameworks on the Tornado HTTP server and I/O loop. See WSGIContainer for
-details and documentation.
+* `WSGIApplication` is a version of `tornado.web.Application` that can run
+ inside a WSGI server. This is useful for running a Tornado app on another
+ HTTP server, such as Google App Engine. See the `WSGIApplication` class
+ documentation for limitations that apply.
+* `WSGIContainer` lets you run other WSGI applications and frameworks on the
+ Tornado HTTP server. For example, with this class you can mix Django
+ and Tornado handlers in a single server.
"""
import cgi
@@ -70,10 +49,38 @@ except ImportError:
from cStringIO import StringIO as BytesIO # python 2
class WSGIApplication(web.Application):
- """A WSGI-equivalent of web.Application.
+ """A WSGI equivalent of `tornado.web.Application`.
+ WSGIApplication is very similar to web.Application, except no
+ asynchronous methods are supported (since WSGI does not support
+ non-blocking requests properly). If you call self.flush() or other
+ asynchronous methods in your request handlers running in a
+ WSGIApplication, we throw an exception.
+
+ Example usage::
+
+ import tornado.web
+ import tornado.wsgi
+ import wsgiref.simple_server
+
+ class MainHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("Hello, world")
+
+ if __name__ == "__main__":
+ application = tornado.wsgi.WSGIApplication([
+ (r"/", MainHandler),
+ ])
+ server = wsgiref.simple_server.make_server('', 8888, application)
+ server.serve_forever()
+
+ See the 'appengine' demo for an example of using this module to run
+ a Tornado app on Google AppEngine.
+
+ Since no asynchronous methods are available for WSGI applications, the
+ httpclient and auth modules are both not available for WSGI applications.
We support the same interface, but handlers running in a WSGIApplication
- do not support flush() or asynchronous methods.
+ do not support flush() or asynchronous methods.
"""
def __init__(self, handlers=None, default_host="", **settings):
web.Application.__init__(self, handlers, default_host, transforms=[],
@@ -94,7 +101,7 @@ class WSGIApplication(web.Application):
class HTTPRequest(object):
- """Mimics httpserver.HTTPRequest for WSGI applications."""
+ """Mimics `tornado.httpserver.HTTPRequest` for WSGI applications."""
def __init__(self, environ):
"""Parses the given WSGI environ to construct the request."""
self.method = environ["REQUEST_METHOD"]
@@ -182,8 +189,11 @@ class WSGIContainer(object):
tornado.ioloop.IOLoop.instance().start()
This class is intended to let other frameworks (Django, web.py, etc)
- run on the Tornado HTTP server and I/O loop. It has not yet been
- thoroughly tested in production.
+ run on the Tornado HTTP server and I/O loop.
+
+ The `tornado.web.FallbackHandler` class is often useful for mixing
+ Tornado and WSGI apps in the same server. See
+ https://github.com/bdarnell/django-tornado-demo for a complete example.
"""
def __init__(self, wsgi_application):
self.wsgi_application = wsgi_application
diff --git a/website/sphinx/auth.rst b/website/sphinx/auth.rst
index 46065945..80207458 100644
--- a/website/sphinx/auth.rst
+++ b/website/sphinx/auth.rst
@@ -2,4 +2,42 @@
============================================================
.. automodule:: tornado.auth
- :members:
+
+ Common protocols
+ ----------------
+
+ .. autoclass:: OpenIdMixin
+ :members:
+
+ .. autoclass:: OAuthMixin
+ :members:
+
+ .. autoclass:: OAuth2Mixin
+ :members:
+
+ Twitter
+ -------
+
+ .. autoclass:: TwitterMixin
+ :members:
+
+ FriendFeed
+ ----------
+
+ .. autoclass:: FriendFeedMixin
+ :members:
+
+ Google
+ ------
+
+ .. autoclass:: GoogleMixin
+ :members:
+
+ Facebook
+ --------
+
+ .. autoclass:: FacebookMixin
+ :members:
+
+ .. autoclass:: FacebookGraphMixin
+ :members:
diff --git a/website/sphinx/testing.rst b/website/sphinx/testing.rst
index 9378d927..fdb1008d 100644
--- a/website/sphinx/testing.rst
+++ b/website/sphinx/testing.rst
@@ -2,4 +2,23 @@
==================================================================
.. automodule:: tornado.testing
- :members:
+
+ Asynchronous test cases
+ -----------------------
+
+ .. autoclass:: AsyncTestCase
+ :members:
+
+ .. autoclass:: AsyncHTTPTestCase
+ :members:
+
+ Controlling log output
+ ----------------------
+
+ .. autoclass:: LogTrapTestCase
+ :members:
+
+ Test runner
+ -----------
+
+ .. autofunction:: main
diff --git a/website/sphinx/wsgi.rst b/website/sphinx/wsgi.rst
index 489e85d9..d0a72cdb 100644
--- a/website/sphinx/wsgi.rst
+++ b/website/sphinx/wsgi.rst
@@ -2,4 +2,18 @@
==============================================================================
.. automodule:: tornado.wsgi
- :members:
+
+ WSGIApplication
+ ---------------
+
+ .. autoclass:: WSGIApplication
+ :members:
+
+ .. autoclass:: HTTPRequest
+ :members:
+
+ WSGIContainer
+ -------------
+
+ .. autoclass:: WSGIContainer
+ :members: