New submission from Caleb Hattingh <caleb.hatti...@gmail.com>:
Hi Yury, As discussed, below is a very rough outline of a proposed TOC for an asyncio tutorial. No content has been written yet (only what you see below). I think we should nail down the TOC first. Asyncio Tutorial ================ Proposed Table of Contents: - Why asyncio? - Reason #1: thread safety by not using threads at all. - Reason #2: very many concurrent socket connections, which threads make cumbersome. - Demo: concurrency without threads - (only goals here are to *briefly* introduce the syntax, and then demonstrate concurrency without threads) - show two tasks, one prints out integers 0-9, while the other prints out letters of the alphabet, A-I. - pose the question: "they're running concurrently but we're not using threads: how is that possible?" - explain that there is a thing called an "event loop" behind the scenes that allows execution to switch between the two every time one of them "waits". - emphasize that you can easily spot where the switch can happen, it is where you see the "await" keyword. Switches will occur nowhere else. - The difference between functions and `async def` functions - async & await - show `async def` functions, compare to `def` functions. - use inspect module to show what things actually are, e.g. function, coroutine function, coroutine, generator function, generator, asynchronous generator function, asynchronous generator. - point out you can only use "await" inside an async def fn - point out that `await <x>` is an expression, and you can use it in most places any other expression can be used. - How to run `async def` functions - point out there are two different issues: (a) `async def` functions can call other functions, and other `async def` functions using `await`, but also, (b) how to "get started" with the first `async def` function? Answer: run the event loop. - show `asyncio.run()`, in particular running an `async def main()` function, which itself can call others. - Dealing with concurrent functions - (This is maybe too similar to the new docs in the section https://docs.python.org/3/library/asyncio-task.html?highlight=asyncio%20run#coroutines-and-tasks) - What if you want to run an `async def` function, but you don't want to wait for it? Answer: create a "task" for it. - What if you want to run multiple functions concurrently, and you do want to wait for all of them to finish? Answer: use `gather` or `wait()` - Case Study: chat server/client (my proposal) - (goal is to walk through building a realistic example of using asyncio) - (This will be a lot more fun than a web-crawler. Web-crawlers are super boring!) - (I'm pretty confident the size of the code can be kept small. A lot can be done in under 50 lines, as I showed in the case studies in my book) - server uses streams API - server receives many long-lived connections - user can create/join a "room", and then start typing messages. Other connected clients in the same room will see the messages. - client implementation has some options: - could use Tkinter gui, using streams API in an event loop on a separate thread. (This would show how asyncio isn't some alien thing, but is part of python. Would also show how to set up asyncio to work in a separate thread. Finally, would not require any external dependencies, only the stdlib is needed for the entire case study.) - could use a browser client, connecting back to the server over a websocket connection. (This might seem simpler, but in fact introduces a lot more complexity than just using tkinter. We need to bring in html, css, probably some js and probably also a third-party websockets python library. I feel like it isn't a good fit for a stdlib python tutorial, but it is a more modern approach.) - there are not a lot of other options. terminal-based client might be possible, but probably hard, not cross-platform, and will be unappealing to many people. - When describing the code, point out: - you have to choose a "message protocol" (size-prefixed is fine) - you must put `send` and `recv` in separate tasks - server will "keep track" of connected clients and the room (or rooms?) they've joined - startup and shutdown, specific references to the new `run()` function - <others>? ---------- assignee: docs@python components: Documentation, asyncio messages: 326628 nosy: asvetlov, cjrh, docs@python, willingc, yselivanov priority: normal severity: normal status: open title: Asyncio Tutorial type: enhancement versions: Python 3.7, Python 3.8 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue34831> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com