From d52f5f0b094088bc372cb01ab90f43e828da9195 Mon Sep 17 00:00:00 2001 From: Raphael Deem Date: Sat, 21 Jan 2017 18:26:32 -0800 Subject: [PATCH] remove loop as argument and update examples --- examples/aiohttp_example.py | 9 +-- examples/sanic_aiopg_example.py | 60 +++++++++---------- examples/sanic_aiopg_sqlalchemy_example.py | 49 +++++++-------- examples/sanic_asyncpg_example.py | 53 +++++++--------- examples/sanic_peewee.py | 16 +++-- sanic/sanic.py | 7 +-- sanic/server.py | 2 +- sanic/utils.py | 4 +- ...{test_sanic.py => test_signal_handlers.py} | 33 ++++++---- 9 files changed, 109 insertions(+), 124 deletions(-) rename tests/{test_sanic.py => test_signal_handlers.py} (56%) diff --git a/examples/aiohttp_example.py b/examples/aiohttp_example.py index 8e7892a7..a8fb20f0 100644 --- a/examples/aiohttp_example.py +++ b/examples/aiohttp_example.py @@ -1,12 +1,8 @@ from sanic import Sanic from sanic.response import json -import uvloop import aiohttp -#Create an event loop manually so that we can use it for both sanic & aiohttp -loop = uvloop.new_event_loop() - app = Sanic(__name__) async def fetch(session, url): @@ -24,10 +20,9 @@ async def test(request): """ url = "https://api.github.com/repos/channelcat/sanic" - async with aiohttp.ClientSession(loop=loop) as session: + async with aiohttp.ClientSession() as session: response = await fetch(session, url) return json(response) -app.run(host="0.0.0.0", port=8000, loop=loop) - +app.run(host="0.0.0.0", port=8000, workers=2) diff --git a/examples/sanic_aiopg_example.py b/examples/sanic_aiopg_example.py index 73ef6c64..fb1ea100 100644 --- a/examples/sanic_aiopg_example.py +++ b/examples/sanic_aiopg_example.py @@ -10,8 +10,6 @@ import aiopg from sanic import Sanic from sanic.response import json -asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) - database_name = os.environ['DATABASE_NAME'] database_host = os.environ['DATABASE_HOST'] database_user = os.environ['DATABASE_USER'] @@ -21,45 +19,47 @@ connection = 'postgres://{0}:{1}@{2}/{3}'.format(database_user, database_password, database_host, database_name) -loop = asyncio.get_event_loop() async def get_pool(): return await aiopg.create_pool(connection) app = Sanic(name=__name__) -pool = loop.run_until_complete(get_pool()) - - -async def prepare_db(): - """ Let's create some table and add some data +async def prepare_db(app, loop): """ - async with pool.acquire() as conn: - async with conn.cursor() as cur: - await cur.execute('DROP TABLE IF EXISTS sanic_polls') - await cur.execute("""CREATE TABLE sanic_polls ( - id serial primary key, - question varchar(50), - pub_date timestamp - );""") - for i in range(0, 100): - await cur.execute("""INSERT INTO sanic_polls - (id, question, pub_date) VALUES ({}, {}, now()) - """.format(i, i)) + Let's create some table and add some data + """ + async with aiopg.create_pool(connection) as pool: + async with pool.acquire() as conn: + async with conn.cursor() as cur: + await cur.execute('DROP TABLE IF EXISTS sanic_polls') + await cur.execute("""CREATE TABLE sanic_polls ( + id serial primary key, + question varchar(50), + pub_date timestamp + );""") + for i in range(0, 100): + await cur.execute("""INSERT INTO sanic_polls + (id, question, pub_date) VALUES ({}, {}, now()) + """.format(i, i)) @app.route("/") async def handle(request): - async with pool.acquire() as conn: - async with conn.cursor() as cur: - result = [] - await cur.execute("SELECT question, pub_date FROM sanic_polls") - async for row in cur: - result.append({"question": row[0], "pub_date": row[1]}) - return json({"polls": result}) - + result = [] + async def test_select(): + async with aiopg.create_pool(connection) as pool: + async with pool.acquire() as conn: + async with conn.cursor() as cur: + await cur.execute("SELECT question, pub_date FROM sanic_polls") + async for row in cur: + result.append({"question": row[0], "pub_date": row[1]}) + res = await test_select() + return json({'polls': result}) if __name__ == '__main__': - loop.run_until_complete(prepare_db()) - app.run(host='0.0.0.0', port=8000, loop=loop) + app.run(host='0.0.0.0', + port=8000, + debug=True, + before_start=prepare_db) diff --git a/examples/sanic_aiopg_sqlalchemy_example.py b/examples/sanic_aiopg_sqlalchemy_example.py index cb9f6c57..802d4fbe 100644 --- a/examples/sanic_aiopg_sqlalchemy_example.py +++ b/examples/sanic_aiopg_sqlalchemy_example.py @@ -12,8 +12,6 @@ import sqlalchemy as sa from sanic import Sanic from sanic.response import json -asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) - database_name = os.environ['DATABASE_NAME'] database_host = os.environ['DATABASE_HOST'] database_user = os.environ['DATABASE_USER'] @@ -23,8 +21,6 @@ connection = 'postgres://{0}:{1}@{2}/{3}'.format(database_user, database_password, database_host, database_name) -loop = asyncio.get_event_loop() - metadata = sa.MetaData() @@ -34,40 +30,37 @@ polls = sa.Table('sanic_polls', metadata, sa.Column("pub_date", sa.DateTime)) -async def get_engine(): - return await create_engine(connection) - app = Sanic(name=__name__) -engine = loop.run_until_complete(get_engine()) -async def prepare_db(): +async def prepare_db(app, loop): """ Let's add some data """ - async with engine.acquire() as conn: - await conn.execute('DROP TABLE IF EXISTS sanic_polls') - await conn.execute("""CREATE TABLE sanic_polls ( - id serial primary key, - question varchar(50), - pub_date timestamp - );""") - for i in range(0, 100): - await conn.execute( - polls.insert().values(question=i, - pub_date=datetime.datetime.now()) - ) + async with create_engine(connection) as engine: + async with engine.acquire() as conn: + await conn.execute('DROP TABLE IF EXISTS sanic_polls') + await conn.execute("""CREATE TABLE sanic_polls ( + id serial primary key, + question varchar(50), + pub_date timestamp + );""") + for i in range(0, 100): + await conn.execute( + polls.insert().values(question=i, + pub_date=datetime.datetime.now()) + ) @app.route("/") async def handle(request): - async with engine.acquire() as conn: - result = [] - async for row in conn.execute(polls.select()): - result.append({"question": row.question, "pub_date": row.pub_date}) - return json({"polls": result}) + async with create_engine(connection) as engine: + async with engine.acquire() as conn: + result = [] + async for row in conn.execute(polls.select()): + result.append({"question": row.question, "pub_date": row.pub_date}) + return json({"polls": result}) if __name__ == '__main__': - loop.run_until_complete(prepare_db()) - app.run(host='0.0.0.0', port=8000, loop=loop) + app.run(host='0.0.0.0', port=8000, before_start=prepare_db) diff --git a/examples/sanic_asyncpg_example.py b/examples/sanic_asyncpg_example.py index 142480e1..9bb7d9c1 100644 --- a/examples/sanic_asyncpg_example.py +++ b/examples/sanic_asyncpg_example.py @@ -10,8 +10,6 @@ from asyncpg import create_pool from sanic import Sanic from sanic.response import json -asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) - DB_CONFIG = { 'host': '', 'user': '', @@ -21,45 +19,40 @@ DB_CONFIG = { } def jsonify(records): - """ Parse asyncpg record response into JSON format - + """ + Parse asyncpg record response into JSON format """ return [{key: value for key, value in zip(r.keys(), r.values())} for r in records] -loop = asyncio.get_event_loop() - -async def make_pool(): - return await create_pool(**DB_CONFIG) - app = Sanic(__name__) -pool = loop.run_until_complete(make_pool()) - -async def create_db(): - """ Create some table and add some data +async def create_db(app, loop): """ - async with pool.acquire() as connection: - async with connection.transaction(): - await connection.execute('DROP TABLE IF EXISTS sanic_post') - await connection.execute("""CREATE TABLE sanic_post ( - id serial primary key, - content varchar(50), - post_date timestamp - );""") - for i in range(0, 100): - await connection.execute(f"""INSERT INTO sanic_post - (id, content, post_date) VALUES ({i}, {i}, now())""") + Create some table and add some data + """ + async with create_pool(**DB_CONFIG) as pool: + async with pool.acquire() as connection: + async with connection.transaction(): + await connection.execute('DROP TABLE IF EXISTS sanic_post') + await connection.execute("""CREATE TABLE sanic_post ( + id serial primary key, + content varchar(50), + post_date timestamp + );""") + for i in range(0, 100): + await connection.execute(f"""INSERT INTO sanic_post + (id, content, post_date) VALUES ({i}, {i}, now())""") @app.route("/") async def handler(request): - async with pool.acquire() as connection: - async with connection.transaction(): - results = await connection.fetch('SELECT * FROM sanic_post') - return json({'posts': jsonify(results)}) + async with create_pool(**DB_CONFIG) as pool: + async with pool.acquire() as connection: + async with connection.transaction(): + results = await connection.fetch('SELECT * FROM sanic_post') + return json({'posts': jsonify(results)}) if __name__ == '__main__': - loop.run_until_complete(create_db()) - app.run(host='0.0.0.0', port=8000, loop=loop) + app.run(host='0.0.0.0', port=8000, before_start=create_db) diff --git a/examples/sanic_peewee.py b/examples/sanic_peewee.py index d5479193..f3981b36 100644 --- a/examples/sanic_peewee.py +++ b/examples/sanic_peewee.py @@ -9,19 +9,18 @@ from sanic import Sanic from sanic.response import json ## peewee_async related imports -import uvloop import peewee from peewee_async import Manager, PostgresqlDatabase # we instantiate a custom loop so we can pass it to our db manager -loop = uvloop.new_event_loop() -database = PostgresqlDatabase(database='test', - host='127.0.0.1', - user='postgres', - password='mysecretpassword') +def setup(app, loop): + database = PostgresqlDatabase(database='test', + host='127.0.0.1', + user='postgres', + password='mysecretpassword') -objects = Manager(database, loop=loop) + objects = Manager(database, loop=loop) ## from peewee_async docs: # Also there’s no need to connect and re-connect before executing async queries @@ -76,5 +75,4 @@ async def get(request): if __name__ == "__main__": - app.run(host='0.0.0.0', port=8000, loop=loop) - + app.run(host='0.0.0.0', port=8000, before_start=setup) diff --git a/sanic/sanic.py b/sanic/sanic.py index 0f882d01..b50922e9 100644 --- a/sanic/sanic.py +++ b/sanic/sanic.py @@ -42,7 +42,6 @@ class Sanic: self.response_middleware = deque() self.blueprints = {} self._blueprint_order = [] - self.loop = None self.debug = None self.sock = None self.processes = None @@ -275,8 +274,8 @@ class Sanic: def run(self, host="127.0.0.1", port=8000, debug=False, before_start=None, after_start=None, before_stop=None, after_stop=None, ssl=None, - sock=None, workers=1, loop=None, protocol=HttpProtocol, - backlog=100, stop_event=None, register_sys_signals=True): + sock=None, workers=1, protocol=HttpProtocol, backlog=100, + stop_event=None, register_sys_signals=True): """ Runs the HTTP Server and listens until keyboard interrupt or term signal. On termination, drains connections before closing. @@ -296,7 +295,6 @@ class Sanic: :param sock: Socket for the server to accept connections from :param workers: Number of processes received before it is respected - :param loop: asyncio compatible event loop :param protocol: Subclass of asyncio protocol class :return: Nothing """ @@ -319,7 +317,6 @@ class Sanic: 'error_handler': self.error_handler, 'request_timeout': self.config.REQUEST_TIMEOUT, 'request_max_size': self.config.REQUEST_MAX_SIZE, - 'loop': loop, 'register_sys_signals': register_sys_signals, 'backlog': backlog } diff --git a/sanic/server.py b/sanic/server.py index aaf90727..1b19c784 100644 --- a/sanic/server.py +++ b/sanic/server.py @@ -289,7 +289,7 @@ def serve(host, port, request_handler, error_handler, before_start=None, :param protocol: Subclass of asyncio protocol class :return: Nothing """ - loop = loop or async_loop.new_event_loop() + loop = async_loop.new_event_loop() asyncio.set_event_loop(loop) if debug: diff --git a/sanic/utils.py b/sanic/utils.py index 1eaa0493..1943652c 100644 --- a/sanic/utils.py +++ b/sanic/utils.py @@ -16,7 +16,7 @@ async def local_request(method, uri, cookies=None, *args, **kwargs): def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, - loop=None, debug=False, server_kwargs={}, + debug=False, server_kwargs={}, *request_args, **request_kwargs): results = [] exceptions = [] @@ -36,7 +36,7 @@ def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, app.stop() app.run(host=HOST, debug=debug, port=PORT, - after_start=_collect_response, loop=loop, **server_kwargs) + after_start=_collect_response, **server_kwargs) if exceptions: raise ValueError("Exception during request: {}".format(exceptions)) diff --git a/tests/test_sanic.py b/tests/test_signal_handlers.py similarity index 56% rename from tests/test_sanic.py rename to tests/test_signal_handlers.py index 589253f7..756df828 100644 --- a/tests/test_sanic.py +++ b/tests/test_signal_handlers.py @@ -4,12 +4,20 @@ from sanic.utils import HOST, PORT from unittest.mock import MagicMock import pytest import asyncio +from queue import Queue -async def stop(app): - await asyncio.sleep(0.2) +async def stop(app, loop): + await asyncio.sleep(0.1) app.stop() +calledq = Queue() + +def set_loop(app, loop): + loop.add_signal_handler = MagicMock() + +def after(app, loop): + calledq.put(loop.add_signal_handler.called) def test_register_system_signals(): """Test if sanic register system signals""" @@ -19,11 +27,11 @@ def test_register_system_signals(): async def hello_route(request): return HTTPResponse() - loop = asyncio.new_event_loop() - loop.add_signal_handler = MagicMock() - asyncio.ensure_future(stop(app), loop=loop) - app.run(HOST, PORT, loop=loop) - assert loop.add_signal_handler.called == True + app.run(HOST, PORT, + before_start=set_loop, + after_start=stop, + after_stop=after) + assert calledq.get() == True def test_dont_register_system_signals(): @@ -34,8 +42,9 @@ def test_dont_register_system_signals(): async def hello_route(request): return HTTPResponse() - loop = asyncio.new_event_loop() - loop.add_signal_handler = MagicMock() - asyncio.ensure_future(stop(app), loop=loop) - app.run(HOST, PORT, loop=loop, register_sys_signals=False) - assert loop.add_signal_handler.called == False + app.run(HOST, PORT, + before_start=set_loop, + after_start=stop, + after_stop=after, + register_sys_signals=False) + assert calledq.get() == False