On Github asvetlov / aiohttp-florence
andrew.svetlov@gmail.com
import requests r = requests.get('https://api.github.com/user', auth=('user', 'pass')) print(r.status_code) print(r.headers['content-type']) print(r.text)
import aiohttp async def coro(): r = await aiohttp.get('https://api.github.com/user', auth=aiohttp.BasicAuth('user', 'pass')) print(r.status) print(r.headers['content-type']) print(await r.text()) r.close()Please never talk about the slide outside of the room. Shame on me.
Coroutine is an async def function Call a coroutine with await If a function contains awaits -- make it coroutine
async def func(): await asyncio.sleep(1)
session = requests.Session() r = session.get(url)
session = aiohttp.Session() async def coro(session): async with session.get(url) as r: print(r.status) print(await r.text())
async def coro(session): with aiohttp.Timeout(1.5): async with session.get(url) as r: ...
async with client.ws_connect( 'http://websocket-server.org/endpoint') as ws: async for msg in ws: if msg.data == 'close': await ws.close() break else: ws.send_str("Answer on " + msg.data)
from django.conf.urls import url from django.http import HttpResponse def index(request): return HttpResponse("Hello, world") urlpatterns = [ url(r'^$', index), ]
from aiohttp import web async def index(request): return web.Response(text="Hello, world") app = web.Application(loop=loop) app.router.add_route('GET', '/', index) web.run_app(app)
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") app = tornado.web.Application([ (r"/", MainHandler)]) app.listen(8888) tornado.ioloop.IOLoop.current().start()
import sqlalchemy as sa from aiopg.sa import create_engine metadata = sa.MetaData() tbl = sa.Table('tbl', metadata, sa.Column('id', sa.Integer, primary_key=True), sa.Column('val', sa.String(255))) app['db'] = await create_engine(...) async def close_db(app): app['db'].close() await app['db'].wait_closed() app.on_cleanup.append(close_db)
async def handler(request): txt = "" async with request.app['db'].acquire() as conn: await conn.execute(tbl.insert().values(val='abc')) async for row in conn.execute(tbl.select()): txt += "{}: {}\n".format(row.id, row.val) return web.Response(text=txt)
async def handler(request): ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: if msg.data == 'close': await ws.close() break else: ws.send_str(msg.data + '/answer') return ws
from aiohttp_session import get_session async def hander(request): session = await get_session(request) session['key'] = 'value' return web.Response()
EVENT_READ/EVENT_WRITE
select, poll, epoll, kqueue
def run_forever(): while True: events = selector.select(timeout) for key, mask in events: if mask & EVENT_READ: key.reader(key.fileobj) if mask & EVENT_WRITE: key.writer(key.fileobj) for timer in ready: timer.run()
async def f(): fut = asyncio.Future() fut.set_exception(RuntimeError()) del fut
... ERROR:asyncio:Future exception was never retrieved future: Future finished exception=RuntimeError() RuntimeError
$ PYTHONASYNCIODEBUG=x python myapp.py
ERROR:asyncio:Future exception was never retrieved future: Future finished exception=RuntimeError() created at filename.py:10 source_traceback: Object created at (most recent call last): ... File "filename.py", line 10, in f fut = asyncio.Future() RuntimeError
def request(method, url, *, loop=None): ... loop = asyncio.get_event_loop() await request('GET', 'http://python.org', loop=loop)
class Test(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) def tearDown(self): self.loop.close() def test_func(self): async def go(): self.assertEqual(1, await func(loop=loop)) self.loop.run_until_complete(go())
Benchmark numbers are equal to Tornado and Twisted
Good enough for highload
Support billions online users etc.
andrew.svetlov@gmail.com
@andrew_svetlov