Skip to content

Commit

Permalink
Merge pull request tornadoweb#3147 from bdarnell/docs62
Browse files Browse the repository at this point in the history
docs,demos: Update for asyncio.run pattern
  • Loading branch information
bdarnell authored Jun 3, 2022
2 parents 795da77 + b909d37 commit 8ebbfea
Show file tree
Hide file tree
Showing 25 changed files with 181 additions and 153 deletions.
3 changes: 2 additions & 1 deletion demos/blog/blog.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# under the License.

import aiopg
import asyncio
import bcrypt
import markdown
import os.path
Expand Down Expand Up @@ -313,4 +314,4 @@ async def main():


if __name__ == "__main__":
tornado.ioloop.IOLoop.current().run_sync(main)
asyncio.run(main())
7 changes: 3 additions & 4 deletions demos/chat/chatdemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import asyncio
import tornado.escape
import tornado.ioloop
import tornado.locks
import tornado.web
import os.path
Expand Down Expand Up @@ -107,7 +106,7 @@ def on_connection_close(self):
self.wait_future.cancel()


def main():
async def main():
parse_command_line()
app = tornado.web.Application(
[
Expand All @@ -122,8 +121,8 @@ def main():
debug=options.debug,
)
app.listen(options.port)
tornado.ioloop.IOLoop.current().start()
await asyncio.Event().wait()


if __name__ == "__main__":
main()
asyncio.run(main())
8 changes: 4 additions & 4 deletions demos/facebook/facebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
# License for the specific language governing permissions and limitations
# under the License.

import asyncio
import os.path
import tornado.auth
import tornado.escape
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

Expand Down Expand Up @@ -109,15 +109,15 @@ def render(self, post):
return self.render_string("modules/post.html", post=post)


def main():
async def main():
tornado.options.parse_command_line()
if not (options.facebook_api_key and options.facebook_secret):
print("--facebook_api_key and --facebook_secret must be set")
return
http_server = tornado.httpserver.HTTPServer(Application())
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()
await asyncio.Event().wait()


if __name__ == "__main__":
main()
asyncio.run(main())
11 changes: 7 additions & 4 deletions demos/file_upload/file_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
See file_uploader.py in this directory for code that uploads files in this format.
"""

import asyncio
import logging
from urllib.parse import unquote

import tornado.ioloop
import tornado.web
from tornado import options

Expand Down Expand Up @@ -48,9 +48,12 @@ def make_app():
return tornado.web.Application([(r"/post", POSTHandler), (r"/(.*)", PUTHandler)])


if __name__ == "__main__":
# Tornado configures logging.
async def main():
options.parse_command_line()
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
await asyncio.Event().wait()


if __name__ == "__main__":
asyncio.run(main())
5 changes: 3 additions & 2 deletions demos/file_upload/file_uploader.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
See also file_receiver.py in this directory, a server that receives uploads.
"""

import asyncio
import mimetypes
import os
import sys
from functools import partial
from urllib.parse import quote
from uuid import uuid4

from tornado import gen, httpclient, ioloop
from tornado import gen, httpclient
from tornado.options import define, options


Expand Down Expand Up @@ -110,4 +111,4 @@ def put(filenames):
sys.exit(1)

method = put if options.put else post
ioloop.IOLoop.current().run_sync(lambda: method(filenames))
asyncio.run(method(filenames))
8 changes: 4 additions & 4 deletions demos/helloworld/helloworld.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.

import asyncio
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

Expand All @@ -29,13 +29,13 @@ def get(self):
self.write("Hello, world")


def main():
async def main():
tornado.options.parse_command_line()
application = tornado.web.Application([(r"/", MainHandler)])
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()
await asyncio.Event().wait()


if __name__ == "__main__":
main()
asyncio.run(main())
8 changes: 4 additions & 4 deletions demos/s3server/s3server.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"""

import asyncio
import bisect
import datetime
import hashlib
Expand All @@ -39,7 +40,6 @@

from tornado import escape
from tornado import httpserver
from tornado import ioloop
from tornado import web
from tornado.util import unicode_type
from tornado.options import options, define
Expand All @@ -54,12 +54,12 @@
define("bucket_depth", default=0, help="Bucket file system depth limit")


def start(port, root_directory, bucket_depth):
async def start(port, root_directory, bucket_depth):
"""Starts the mock S3 server on the given port at the given path."""
application = S3Application(root_directory, bucket_depth)
http_server = httpserver.HTTPServer(application)
http_server.listen(port)
ioloop.IOLoop.current().start()
await asyncio.Event().wait()


class S3Application(web.Application):
Expand Down Expand Up @@ -265,4 +265,4 @@ def delete(self, bucket, object_name):

if __name__ == "__main__":
options.parse_command_line()
start(options.port, options.root_directory, options.bucket_depth)
asyncio.run(start(options.port, options.root_directory, options.bucket_depth))
14 changes: 6 additions & 8 deletions demos/tcpecho/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env python

from tornado.ioloop import IOLoop
from tornado import gen
import asyncio
from tornado.tcpclient import TCPClient
from tornado.options import options, define

Expand All @@ -10,15 +9,14 @@
define("message", default="ping", help="Message to send")


@gen.coroutine
def send_message():
stream = yield TCPClient().connect(options.host, options.port)
yield stream.write((options.message + "\n").encode())
async def send_message():
stream = await TCPClient().connect(options.host, options.port)
await stream.write((options.message + "\n").encode())
print("Sent to server:", options.message)
reply = yield stream.read_until(b"\n")
reply = await stream.read_until(b"\n")
print("Response from server:", reply.decode().strip())


if __name__ == "__main__":
options.parse_command_line()
IOLoop.current().run_sync(send_message)
asyncio.run(send_message())
12 changes: 8 additions & 4 deletions demos/tcpecho/server.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python

import asyncio
import logging
from tornado.ioloop import IOLoop
from tornado import gen
from tornado.iostream import StreamClosedError
from tornado.tcpserver import TCPServer
Expand All @@ -28,9 +28,13 @@ def handle_stream(self, stream, address):
print(e)


if __name__ == "__main__":
async def main():
options.parse_command_line()
logger.info("Listening on TCP port %d", options.port)
server = EchoServer()
server.listen(options.port)
logger.info("Listening on TCP port %d", options.port)
IOLoop.current().start()
await asyncio.Event().wait()


if __name__ == "__main__":
asyncio.run(main())
8 changes: 4 additions & 4 deletions demos/twitter/twitterdemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
browser.
"""

import asyncio
import logging

from tornado.auth import TwitterMixin
from tornado.escape import json_decode, json_encode
from tornado.ioloop import IOLoop
from tornado import gen
from tornado.options import define, options, parse_command_line, parse_config_file
from tornado.web import Application, RequestHandler, authenticated
Expand Down Expand Up @@ -86,7 +86,7 @@ def get(self):
self.clear_cookie(self.COOKIE_NAME)


def main():
async def main():
parse_command_line(final=False)
parse_config_file(options.config_file)

Expand All @@ -98,8 +98,8 @@ def main():
app.listen(options.port)

logging.info("Listening on http://localhost:%d" % options.port)
IOLoop.current().start()
await asyncio.Event().wait()


if __name__ == "__main__":
main()
asyncio.run(main())
8 changes: 4 additions & 4 deletions demos/websocket/chatdemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
Authentication, error handling, etc are left as an exercise for the reader :)
"""

import asyncio
import logging
import tornado.escape
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.websocket
Expand Down Expand Up @@ -91,12 +91,12 @@ def on_message(self, message):
ChatSocketHandler.send_updates(chat)


def main():
async def main():
tornado.options.parse_command_line()
app = Application()
app.listen(options.port)
tornado.ioloop.IOLoop.current().start()
await asyncio.Event().wait()


if __name__ == "__main__":
main()
asyncio.run(main())
6 changes: 3 additions & 3 deletions demos/webspider/webspider.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#!/usr/bin/env python3

import asyncio
import time
from datetime import timedelta

from html.parser import HTMLParser
from urllib.parse import urljoin, urldefrag

from tornado import gen, httpclient, ioloop, queues
from tornado import gen, httpclient, queues

base_url = "http://www.tornadoweb.org/en/stable/"
concurrency = 10
Expand Down Expand Up @@ -94,5 +95,4 @@ async def worker():


if __name__ == "__main__":
io_loop = ioloop.IOLoop.current()
io_loop.run_sync(main)
asyncio.run(main())
4 changes: 2 additions & 2 deletions docs/guide/coroutines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Coroutines
from tornado import gen

**Coroutines** are the recommended way to write asynchronous code in
Tornado. Coroutines use the Python ``await`` or ``yield`` keyword to
Tornado. Coroutines use the Python ``await`` keyword to
suspend and resume execution instead of a chain of callbacks
(cooperative lightweight threads as seen in frameworks like `gevent
<http://www.gevent.org>`_ are sometimes called coroutines as well, but
Expand Down Expand Up @@ -281,7 +281,7 @@ loop condition from accessing the results, as in this example from
Running in the background
^^^^^^^^^^^^^^^^^^^^^^^^^

`.PeriodicCallback` is not normally used with coroutines. Instead, a
As an alternative to `.PeriodicCallback`, a
coroutine can contain a ``while True:`` loop and use
`tornado.gen.sleep`::

Expand Down
7 changes: 1 addition & 6 deletions docs/guide/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ can scale to tens of thousands of open connections, making it ideal for
`WebSockets <http://en.wikipedia.org/wiki/WebSocket>`_, and other
applications that require a long-lived connection to each user.

Tornado can be roughly divided into four major components:
Tornado can be roughly divided into three major components:

* A web framework (including `.RequestHandler` which is subclassed to
create web applications, and various supporting classes).
Expand All @@ -18,11 +18,6 @@ Tornado can be roughly divided into four major components:
* An asynchronous networking library including the classes `.IOLoop`
and `.IOStream`, which serve as the building blocks for the HTTP
components and can also be used to implement other protocols.
* A coroutine library (`tornado.gen`) which allows asynchronous
code to be written in a more straightforward way than chaining
callbacks. This is similar to the native coroutine feature introduced
in Python 3.5 (``async def``). Native coroutines are recommended
in place of the `tornado.gen` module when available.

The Tornado web framework and HTTP server together offer a full-stack
alternative to `WSGI <http://www.python.org/dev/peps/pep-3333/>`_.
Expand Down
7 changes: 4 additions & 3 deletions docs/guide/queues.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

.. currentmodule:: tornado.queues

Tornado's `tornado.queues` module implements an asynchronous producer /
consumer pattern for coroutines, analogous to the pattern implemented for
threads by the Python standard library's `queue` module.
Tornado's `tornado.queues` module (and the very similar ``Queue`` classes in
`asyncio`) implements an asynchronous producer / consumer pattern for
coroutines, analogous to the pattern implemented for threads by the Python
standard library's `queue` module.

A coroutine that yields `Queue.get` pauses until there is an item in the queue.
If the queue has a maximum size set, a coroutine that yields `Queue.put` pauses
Expand Down
Loading

0 comments on commit 8ebbfea

Please sign in to comment.