it' still good idea to avoid accessing shared state from inside coroutine it makes your code much easier to reason about more importantlyeven though an ideal world might have all asynchronous execution happen inside coroutinesthe reality is that some futures are executed behind the scenes inside threads or processes stick to "share nothingphilosophy to avoid ton of difficult bugs in additionasyncio allows us to collect logical sections of code together inside single coroutineeven if we are waiting for other work elsewhere as specific instanceeven though the yield from asyncio sleep call in the random_sleep coroutine is allowing ton of stuff to happen inside the event loopthe coroutine itself looks like it' doing everything in order this ability to read related pieces of asynchronous code without worrying about the machinery that waits for tasks to complete is the primary benefit of the asyncio module asyncio for networking asyncio was specifically designed for use with network socketsso let' implement dns server more accuratelylet' implement one extremely basic feature of dns server the domain name system' basic purpose is to translate domain namessuch as www amazon com into ip addresses such as it has to be able to perform many types of queries and know how to contact other dns servers if it doesn' have the answer required we won' be implementing any of thisbut the following example is able to respond directly to standard dns query to look up ips for my three most recent employersimport asyncio from contextlib import suppress ip_map 'facebook com ' ' 'yougov com ' ' 'wipo int ' def lookup_dns(data)domain 'pointerpart_length data[ while part_length