Merge pull request #408 from agoose77/master
Use app decorator instead of run arguments for before_start
This commit is contained in:
		| @@ -7,15 +7,6 @@ keyword arguments: | ||||
| - `host` *(default `"127.0.0.1"`)*: Address to host the server on. | ||||
| - `port` *(default `8000`)*: Port to host the server on. | ||||
| - `debug` *(default `False`)*: Enables debug output (slows server). | ||||
| - `before_start` *(default `None`)*: Function or list of functions to be executed | ||||
|                            before the server starts accepting connections. | ||||
| - `after_start` *(default `None`)*: Function or list of functions to be executed | ||||
|                     after the server starts accepting connections. | ||||
| - `before_stop` *(default `None`)*: Function or list of functions to be | ||||
|                     executed when a stop signal is received before it is | ||||
|                     respected. | ||||
| - `after_stop` *(default `None`)*: Function or list of functions to be executed | ||||
|                     when all requests are complete. | ||||
| - `ssl` *(default `None`)*: `SSLContext` for SSL encryption of worker(s). | ||||
| - `sock` *(default `None`)*: Socket for the server to accept connections from. | ||||
| - `workers` *(default `1`)*: Number of worker processes to spawn. | ||||
|   | ||||
| @@ -8,6 +8,7 @@ app = Sanic(__name__) | ||||
|  | ||||
| sem = None | ||||
|  | ||||
| @app.listener('before_server_start') | ||||
| def init(sanic, loop): | ||||
|     global sem | ||||
|     CONCURRENCY_PER_WORKER = 4 | ||||
| @@ -33,4 +34,4 @@ async def test(request): | ||||
|         return json(response) | ||||
|  | ||||
|  | ||||
| app.run(host="0.0.0.0", port=8000, workers=2, before_start=init) | ||||
| app.run(host="0.0.0.0", port=8000, workers=2) | ||||
|   | ||||
| @@ -26,6 +26,7 @@ async def get_pool(): | ||||
|  | ||||
| app = Sanic(name=__name__) | ||||
|  | ||||
| @app.listener('before_server_start') | ||||
| async def prepare_db(app, loop): | ||||
|     """ | ||||
|     Let's create some table and add some data | ||||
| @@ -61,5 +62,4 @@ async def handle(request): | ||||
| if __name__ == '__main__': | ||||
|     app.run(host='0.0.0.0', | ||||
|             port=8000, | ||||
|             debug=True, | ||||
|             before_start=prepare_db) | ||||
|             debug=True) | ||||
|   | ||||
| @@ -32,7 +32,7 @@ polls = sa.Table('sanic_polls', metadata, | ||||
|  | ||||
| app = Sanic(name=__name__) | ||||
|  | ||||
|  | ||||
| @app.listener('before_server_start') | ||||
| async def prepare_db(app, loop): | ||||
|     """ Let's add some data | ||||
|  | ||||
| @@ -58,9 +58,10 @@ 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}) | ||||
|                 result.append({"question": row.question, | ||||
|                                "pub_date": row.pub_date}) | ||||
|             return json({"polls": result}) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     app.run(host='0.0.0.0', port=8000, before_start=prepare_db) | ||||
|     app.run(host='0.0.0.0', port=8000) | ||||
|   | ||||
| @@ -27,6 +27,7 @@ def jsonify(records): | ||||
|  | ||||
| app = Sanic(__name__) | ||||
|  | ||||
| @app.listener('before_server_start') | ||||
| async def create_db(app, loop): | ||||
|     """ | ||||
|     Create some table and add some data | ||||
| @@ -55,4 +56,4 @@ async def handler(request): | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     app.run(host='0.0.0.0', port=8000, before_start=create_db) | ||||
|     app.run(host='0.0.0.0', port=8000) | ||||
|   | ||||
| @@ -14,14 +14,6 @@ from peewee_async import Manager, PostgresqlDatabase | ||||
|  | ||||
|  # we instantiate a custom loop so we can pass it to our db manager | ||||
|  | ||||
| def setup(app, loop): | ||||
|     database = PostgresqlDatabase(database='test', | ||||
|                                   host='127.0.0.1', | ||||
|                                   user='postgres', | ||||
|                                   password='mysecretpassword') | ||||
|  | ||||
|     objects = Manager(database, loop=loop) | ||||
|  | ||||
| ## from peewee_async docs: | ||||
| # Also there’s no need to connect and re-connect before executing async queries | ||||
| # with manager! It’s all automatic. But you can run Manager.connect() or | ||||
| @@ -48,6 +40,15 @@ objects.database.allow_sync = False # this will raise AssertionError on ANY sync | ||||
|  | ||||
| app = Sanic('peewee_example') | ||||
|  | ||||
| @app.listener('before_server_start') | ||||
| def setup(app, loop): | ||||
|     database = PostgresqlDatabase(database='test', | ||||
|                                   host='127.0.0.1', | ||||
|                                   user='postgres', | ||||
|                                   password='mysecretpassword') | ||||
|  | ||||
|     objects = Manager(database, loop=loop) | ||||
|  | ||||
| @app.route('/post/<key>/<value>') | ||||
| async def post(request, key, value): | ||||
|     """ | ||||
| @@ -75,4 +76,4 @@ async def get(request): | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     app.run(host='0.0.0.0', port=8000, before_start=setup) | ||||
|     app.run(host='0.0.0.0', port=8000) | ||||
|   | ||||
| @@ -64,12 +64,14 @@ def query_string(request): | ||||
| # Run Server | ||||
| # ----------------------------------------------- # | ||||
|  | ||||
| @app.listener('after_server_start') | ||||
| def after_start(app, loop): | ||||
|     log.info("OH OH OH OH OHHHHHHHH") | ||||
|  | ||||
|  | ||||
| @app.listener('before_server_stop') | ||||
| def before_stop(app, loop): | ||||
|     log.info("TRIED EVERYTHING") | ||||
|  | ||||
|  | ||||
| app.run(host="0.0.0.0", port=8000, debug=True, after_start=after_start, before_stop=before_stop) | ||||
| app.run(host="0.0.0.0", port=8000, debug=True) | ||||
|   | ||||
| @@ -65,6 +65,11 @@ class Blueprint: | ||||
|             app.static(uri, future.file_or_directory, | ||||
|                        *future.args, **future.kwargs) | ||||
|  | ||||
|         # Event listeners | ||||
|         for event, listeners in self.listeners.items(): | ||||
|             for listener in listeners: | ||||
|                 app.listener(event)(listener) | ||||
|  | ||||
|     def route(self, uri, methods=frozenset({'GET'}), host=None): | ||||
|         """ | ||||
|         Creates a blueprint route from a decorated function. | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import logging | ||||
| import re | ||||
| import warnings | ||||
| from asyncio import get_event_loop | ||||
| from collections import deque | ||||
| from collections import deque, defaultdict | ||||
| from functools import partial | ||||
| from inspect import isawaitable, stack, getmodulename | ||||
| from traceback import format_exc | ||||
| @@ -10,8 +10,8 @@ from urllib.parse import urlencode, urlunparse | ||||
|  | ||||
| from .config import Config | ||||
| from .constants import HTTP_METHODS | ||||
| from .handlers import ErrorHandler | ||||
| from .exceptions import ServerError, URLBuildError | ||||
| from .handlers import ErrorHandler | ||||
| from .log import log | ||||
| from .response import HTTPResponse | ||||
| from .router import Router | ||||
| @@ -21,6 +21,7 @@ from .views import CompositionView | ||||
|  | ||||
|  | ||||
| class Sanic: | ||||
|  | ||||
|     def __init__(self, name=None, router=None, | ||||
|                  error_handler=None): | ||||
|         # Only set up a default log handler if the | ||||
| @@ -46,6 +47,7 @@ class Sanic: | ||||
|         self.debug = None | ||||
|         self.sock = None | ||||
|         self.processes = None | ||||
|         self.listeners = defaultdict(list) | ||||
|  | ||||
|         # Register alternative method names | ||||
|         self.go_fast = self.run | ||||
| @@ -61,6 +63,18 @@ class Sanic: | ||||
|     # Registration | ||||
|     # -------------------------------------------------------------------- # | ||||
|  | ||||
|     # Decorator | ||||
|     def listener(self, event): | ||||
|         """ | ||||
|         Create a listener from a decorated function. | ||||
|  | ||||
|         :param event: Event to listen to. | ||||
|         """ | ||||
|         def decorator(listener): | ||||
|             self.listeners[event].append(listener) | ||||
|             return listener | ||||
|         return decorator | ||||
|  | ||||
|     # Decorator | ||||
|     def route(self, uri, methods=frozenset({'GET'}), host=None): | ||||
|         """ | ||||
| @@ -419,6 +433,7 @@ class Sanic: | ||||
|             after_stop=after_stop, ssl=ssl, sock=sock, workers=workers, | ||||
|             loop=loop, protocol=protocol, backlog=backlog, | ||||
|             stop_event=stop_event, register_sys_signals=register_sys_signals) | ||||
|  | ||||
|         try: | ||||
|             if workers == 1: | ||||
|                 serve(**server_settings) | ||||
| @@ -473,6 +488,16 @@ class Sanic: | ||||
|                           "pull/335 has more information.", | ||||
|                           DeprecationWarning) | ||||
|  | ||||
|         # Deprecate this | ||||
|         if any(arg is not None for arg in (after_stop, after_start, | ||||
|                                            before_start, before_stop)): | ||||
|             if debug: | ||||
|                 warnings.simplefilter('default') | ||||
|             warnings.warn("Passing a before_start, before_stop, after_start or" | ||||
|                           "after_stop callback will be deprecated in next " | ||||
|                           "major version after 0.4.0", | ||||
|                           DeprecationWarning) | ||||
|  | ||||
|         self.error_handler.debug = debug | ||||
|         self.debug = debug | ||||
|         loop = self.loop | ||||
| @@ -497,19 +522,18 @@ class Sanic: | ||||
|         # Register start/stop events | ||||
|         # -------------------------------------------- # | ||||
|  | ||||
|         for event_name, settings_name, args, reverse in ( | ||||
|                 ("before_server_start", "before_start", before_start, False), | ||||
|                 ("after_server_start", "after_start", after_start, False), | ||||
|                 ("before_server_stop", "before_stop", before_stop, True), | ||||
|                 ("after_server_stop", "after_stop", after_stop, True), | ||||
|         for event_name, settings_name, reverse, args in ( | ||||
|                 ("before_server_start", "before_start", False, before_start), | ||||
|                 ("after_server_start", "after_start", False, after_start), | ||||
|                 ("before_server_stop", "before_stop", True, before_stop), | ||||
|                 ("after_server_stop", "after_stop", True, after_stop), | ||||
|         ): | ||||
|             listeners = [] | ||||
|             for blueprint in self.blueprints.values(): | ||||
|                 listeners += blueprint.listeners[event_name] | ||||
|             listeners = self.listeners[event_name].copy() | ||||
|             if args: | ||||
|                 if callable(args): | ||||
|                     args = [args] | ||||
|                 listeners += args | ||||
|                     listeners.append(args) | ||||
|                 else: | ||||
|                     listeners.extend(args) | ||||
|             if reverse: | ||||
|                 listeners.reverse() | ||||
|             # Prepend sanic to the arguments when listeners are triggered | ||||
|   | ||||
| @@ -28,6 +28,7 @@ def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, | ||||
|                 results[0] = request | ||||
|         app.request_middleware.appendleft(_collect_request) | ||||
|  | ||||
|     @app.listener('after_server_start') | ||||
|     async def _collect_response(sanic, loop): | ||||
|         try: | ||||
|             response = await local_request(method, uri, *request_args, | ||||
| @@ -37,8 +38,8 @@ def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, | ||||
|             exceptions.append(e) | ||||
|         app.stop() | ||||
|  | ||||
|     app.run(host=HOST, debug=debug, port=PORT, | ||||
|             after_start=_collect_response, **server_kwargs) | ||||
|     app.run(host=HOST, debug=debug, port=PORT, **server_kwargs) | ||||
|     app.listeners['after_server_start'].pop() | ||||
|  | ||||
|     if exceptions: | ||||
|         raise ValueError("Exception during request: {}".format(exceptions)) | ||||
|   | ||||
| @@ -5,6 +5,7 @@ from sanic import Sanic | ||||
| def test_bad_request_response(): | ||||
|     app = Sanic('test_bad_request_response') | ||||
|     lines = [] | ||||
|     @app.listener('after_server_start') | ||||
|     async def _request(sanic, loop): | ||||
|         connect = asyncio.open_connection('127.0.0.1', 42101) | ||||
|         reader, writer = await connect | ||||
| @@ -15,6 +16,6 @@ def test_bad_request_response(): | ||||
|                 break | ||||
|             lines.append(line) | ||||
|         app.stop() | ||||
|     app.run(host='127.0.0.1', port=42101, debug=False, after_start=_request) | ||||
|     app.run(host='127.0.0.1', port=42101, debug=False) | ||||
|     assert lines[0] == b'HTTP/1.1 400 Bad Request\r\n' | ||||
|     assert lines[-1] == b'Error: Bad Request' | ||||
|   | ||||
| @@ -9,10 +9,10 @@ from sanic import Sanic | ||||
| from sanic.utils import HOST, PORT | ||||
|  | ||||
| AVAILABLE_LISTENERS = [ | ||||
|     'before_start', | ||||
|     'after_start', | ||||
|     'before_stop', | ||||
|     'after_stop' | ||||
|     'before_server_start', | ||||
|     'after_server_start', | ||||
|     'before_server_stop', | ||||
|     'after_server_stop' | ||||
| ] | ||||
|  | ||||
|  | ||||
| @@ -42,9 +42,10 @@ def test_single_listener(listener_name): | ||||
|     random_name_app = Sanic(''.join( | ||||
|         [choice(ascii_letters) for _ in range(choice(range(5, 10)))])) | ||||
|     output = list() | ||||
|     start_stop_app( | ||||
|         random_name_app, | ||||
|         **{listener_name: create_listener(listener_name, output)}) | ||||
|     # Register listener | ||||
|     random_name_app.listener(listener_name)( | ||||
|         create_listener(listener_name, output)) | ||||
|     start_stop_app(random_name_app) | ||||
|     assert random_name_app.name + listener_name == output.pop() | ||||
|  | ||||
|  | ||||
| @@ -52,9 +53,9 @@ def test_all_listeners(): | ||||
|     random_name_app = Sanic(''.join( | ||||
|         [choice(ascii_letters) for _ in range(choice(range(5, 10)))])) | ||||
|     output = list() | ||||
|     start_stop_app( | ||||
|         random_name_app, | ||||
|         **{listener_name: create_listener(listener_name, output) | ||||
|            for listener_name in AVAILABLE_LISTENERS}) | ||||
|     for listener_name in AVAILABLE_LISTENERS: | ||||
|         listener = create_listener(listener_name, output) | ||||
|         random_name_app.listener(listener_name)(listener) | ||||
|     start_stop_app(random_name_app) | ||||
|     for listener_name in AVAILABLE_LISTENERS: | ||||
|         assert random_name_app.name + listener_name == output.pop() | ||||
|   | ||||
| @@ -27,10 +27,11 @@ def test_register_system_signals(): | ||||
|     async def hello_route(request): | ||||
|         return HTTPResponse() | ||||
|  | ||||
|     app.run(HOST, PORT, | ||||
|             before_start=set_loop, | ||||
|             after_start=stop, | ||||
|             after_stop=after) | ||||
|     app.listener('after_server_start')(stop) | ||||
|     app.listener('before_server_start')(set_loop) | ||||
|     app.listener('after_server_stop')(after) | ||||
|  | ||||
|     app.run(HOST, PORT) | ||||
|     assert calledq.get() == True | ||||
|  | ||||
|  | ||||
| @@ -42,9 +43,9 @@ def test_dont_register_system_signals(): | ||||
|     async def hello_route(request): | ||||
|         return HTTPResponse() | ||||
|  | ||||
|     app.run(HOST, PORT, | ||||
|             before_start=set_loop, | ||||
|             after_start=stop, | ||||
|             after_stop=after, | ||||
|             register_sys_signals=False) | ||||
|     app.listener('after_server_start')(stop) | ||||
|     app.listener('before_server_start')(set_loop) | ||||
|     app.listener('after_server_stop')(after) | ||||
|  | ||||
|     app.run(HOST, PORT, register_sys_signals=False) | ||||
|     assert calledq.get() == False | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Eli Uriegas
					Eli Uriegas