From 6454ac0944954431424bd854d1a99128af8fe6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=20=D0=92=D0=B0=D1=81?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=D0=B9?= Date: Wed, 14 Mar 2018 13:37:15 +0300 Subject: [PATCH 01/15] Add __weakref__ to Request slots --- sanic/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sanic/request.py b/sanic/request.py index cd7071d7..22d74a64 100644 --- a/sanic/request.py +++ b/sanic/request.py @@ -48,7 +48,7 @@ class Request(dict): 'app', 'headers', 'version', 'method', '_cookies', 'transport', 'body', 'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files', '_ip', '_parsed_url', 'uri_template', 'stream', '_remote_addr', - '_socket', '_port' + '_socket', '_port', '__weakref__' ) def __init__(self, url_bytes, headers, version, method, transport): From d42cb7ddb3999bc0a769b811cc4e0bcb3ca6f4ec Mon Sep 17 00:00:00 2001 From: Yun Xu Date: Thu, 15 Mar 2018 21:28:52 -0700 Subject: [PATCH 02/15] fix hang build --- tests/conftest.py | 23 ------- tests/test_auto_reload.py | 108 ------------------------------- tests/test_keep_alive_timeout.py | 7 +- tests/test_multiprocessing.py | 4 +- tests/test_request_timeout.py | 4 +- tests/test_requests.py | 8 +-- tests/test_response.py | 4 +- tests/test_server_events.py | 4 +- tests/test_signal_handlers.py | 6 +- tests/test_url_building.py | 14 ++-- tox.ini | 3 +- 11 files changed, 24 insertions(+), 161 deletions(-) delete mode 100644 tests/conftest.py delete mode 100644 tests/test_auto_reload.py diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index dd3dc6d7..00000000 --- a/tests/conftest.py +++ /dev/null @@ -1,23 +0,0 @@ -import re -import sanic - - -def pytest_collection_modifyitems(session, config, items): - base_port = sanic.testing.PORT - - worker_id = getattr(config, 'slaveinput', {}).get('slaveid', 'master') - m = re.search(r'[0-9]+', worker_id) - if m: - num_id = int(m.group(0)) + 1 - else: - num_id = 0 - new_port = base_port + num_id - - def new_test_client(app, port=new_port): - return sanic.testing.SanicTestClient(app, port) - - sanic.Sanic.test_port = new_port - sanic.Sanic.test_client = property(new_test_client) - - app = sanic.Sanic() - assert app.test_client.port == new_port diff --git a/tests/test_auto_reload.py b/tests/test_auto_reload.py deleted file mode 100644 index 104f823b..00000000 --- a/tests/test_auto_reload.py +++ /dev/null @@ -1,108 +0,0 @@ -import os -import sys -import subprocess -import signal -from threading import Thread -from time import sleep -from json.decoder import JSONDecodeError -import aiohttp -import asyncio -import async_timeout - -sanic_project_content_one = ''' -from sanic import Sanic -from sanic import response - -app = Sanic(__name__) - - -@app.route("/") -async def test(request): - return response.json({"test": 1}) - - -if __name__ == '__main__': - app.run(host="127.0.0.1", port=8000, auto_reload=True) -''' - -sanic_project_content_two = ''' -from sanic import Sanic -from sanic import response - -app = Sanic(__name__) - - -@app.route("/") -async def test(request): - return response.json({"test": 2}) - - -if __name__ == '__main__': - app.run(host="127.0.0.1", port=8000, auto_reload=True) -''' - -process_id = None - - -def execute_cmd(command): - process = subprocess.Popen(command, shell=True) - global process_id - process_id = process.pid - process.communicate() - - -class TestAutoReloading: - - def check_response(self, url, response): - """Send http request and tries to take it's response as json. - Returns a dictionary. - """ - async def req(url, excepted_response): - async with aiohttp.ClientSession() as session: - with async_timeout.timeout(10): - async with session.get(url) as response: - try: - result = await response.json() - except JSONDecodeError: - result = {} - return result == excepted_response - - loop = asyncio.get_event_loop() - return loop.run_until_complete(req(url, response)) - - def test_reloading_after_change_file(self, capsys): - if os.name != 'posix': - return - - with capsys.disabled(): - pass - sanic_app_file_path = "simple_sanic_app.py" - with open(sanic_app_file_path, "w") as _file: - _file.write(sanic_project_content_one) - - cmd = ' '.join([sys.executable, sanic_app_file_path]) - thread = Thread(target=execute_cmd, args=(cmd,)) - thread.start() - - sleep(2) # wait for completing server start process - assert self.check_response("http://127.0.0.1:8000/", {"test": 1}) - - with open(sanic_app_file_path, "w") as _file: - _file.write(sanic_project_content_two) - - sleep(2) # wait for completing server start process - assert self.check_response("http://127.0.0.1:8000/", {"test": 2}) - - thread.join(1) - os.remove(sanic_app_file_path) - - def teardown_method(self, method): - if process_id: - root_proc_path = \ - "/proc/{pid}/task/{pid}/children".format(pid=process_id) - if not os.path.isfile(root_proc_path): - return - with open(root_proc_path) as children_list_file: - children_list_pid = children_list_file.read().split() - for child_pid in children_list_pid: - os.kill(int(child_pid), signal.SIGTERM) diff --git a/tests/test_keep_alive_timeout.py b/tests/test_keep_alive_timeout.py index 4df00640..494bf633 100644 --- a/tests/test_keep_alive_timeout.py +++ b/tests/test_keep_alive_timeout.py @@ -7,7 +7,7 @@ from sanic.config import Config from sanic import server import aiohttp from aiohttp import TCPConnector -from sanic.testing import SanicTestClient, HOST +from sanic.testing import SanicTestClient, HOST, PORT class ReuseableTCPConnector(TCPConnector): @@ -43,7 +43,7 @@ class ReuseableTCPConnector(TCPConnector): class ReuseableSanicTestClient(SanicTestClient): def __init__(self, app, loop=None): - super().__init__(app, port=app.test_port) + super(ReuseableSanicTestClient, self).__init__(app) if loop is None: loop = asyncio.get_event_loop() self._loop = loop @@ -87,8 +87,7 @@ class ReuseableSanicTestClient(SanicTestClient): _server = self._server else: _server_co = self.app.create_server(host=HOST, debug=debug, - port=self.app.test_port, - **server_kwargs) + port=PORT, **server_kwargs) server.trigger_events( self.app.listeners['before_server_start'], loop) diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py index cdbd91a8..8cc40e5d 100644 --- a/tests/test_multiprocessing.py +++ b/tests/test_multiprocessing.py @@ -3,7 +3,7 @@ import random import signal from sanic import Sanic -from sanic.testing import HOST +from sanic.testing import HOST, PORT def test_multiprocessing(): @@ -20,6 +20,6 @@ def test_multiprocessing(): signal.signal(signal.SIGALRM, stop_on_alarm) signal.alarm(1) - app.run(HOST, app.test_port, workers=num_workers) + app.run(HOST, PORT, workers=num_workers) assert len(process_list) == num_workers diff --git a/tests/test_request_timeout.py b/tests/test_request_timeout.py index 80dd7218..61ba9d04 100644 --- a/tests/test_request_timeout.py +++ b/tests/test_request_timeout.py @@ -6,7 +6,7 @@ from sanic.response import text from sanic.config import Config import aiohttp from aiohttp import TCPConnector -from sanic.testing import SanicTestClient, HOST +from sanic.testing import SanicTestClient, HOST, PORT class DelayableTCPConnector(TCPConnector): @@ -108,7 +108,7 @@ class DelayableTCPConnector(TCPConnector): class DelayableSanicTestClient(SanicTestClient): def __init__(self, app, loop, request_delay=1): - super(DelayableSanicTestClient, self).__init__(app, port=app.test_port) + super(DelayableSanicTestClient, self).__init__(app) self._request_delay = request_delay self._loop = None diff --git a/tests/test_requests.py b/tests/test_requests.py index 14da4b0b..2a91fb9b 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -9,7 +9,7 @@ from sanic import Sanic from sanic.exceptions import ServerError from sanic.response import json, text from sanic.request import DEFAULT_HTTP_CONTENT_TYPE -from sanic.testing import HOST +from sanic.testing import HOST, PORT # ------------------------------------------------------------ # @@ -340,7 +340,7 @@ def test_url_attributes_no_ssl(path, query, expected_url): app.add_route(handler, path) request, response = app.test_client.get(path + '?{}'.format(query)) - assert request.url == expected_url.format(HOST, app.test_port) + assert request.url == expected_url.format(HOST, PORT) parsed = urlparse(request.url) @@ -371,9 +371,9 @@ def test_url_attributes_with_ssl(path, query, expected_url): app.add_route(handler, path) request, response = app.test_client.get( - 'https://{}:{}'.format(HOST, app.test_port) + path + '?{}'.format(query), + 'https://{}:{}'.format(HOST, PORT) + path + '?{}'.format(query), server_kwargs={'ssl': context}) - assert request.url == expected_url.format(HOST, app.test_port) + assert request.url == expected_url.format(HOST, PORT) parsed = urlparse(request.url) diff --git a/tests/test_response.py b/tests/test_response.py index b5eb891c..5b3f76de 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -10,7 +10,7 @@ from random import choice from sanic import Sanic from sanic.response import HTTPResponse, stream, StreamingHTTPResponse, file, file_stream, json -from sanic.testing import HOST +from sanic.testing import HOST, PORT from unittest.mock import MagicMock JSON_DATA = {'ok': True} @@ -187,7 +187,7 @@ def test_stream_response_writes_correct_content_to_transport(streaming_app): app.stop() - streaming_app.run(host=HOST, port=streaming_app.test_port) + streaming_app.run(host=HOST, port=PORT) @pytest.fixture diff --git a/tests/test_server_events.py b/tests/test_server_events.py index 9c0d99eb..c2ccc7dc 100644 --- a/tests/test_server_events.py +++ b/tests/test_server_events.py @@ -6,7 +6,7 @@ import signal import pytest from sanic import Sanic -from sanic.testing import HOST +from sanic.testing import HOST, PORT AVAILABLE_LISTENERS = [ 'before_server_start', @@ -31,7 +31,7 @@ def start_stop_app(random_name_app, **run_kwargs): signal.signal(signal.SIGALRM, stop_on_alarm) signal.alarm(1) try: - random_name_app.run(HOST, random_name_app.test_port, **run_kwargs) + random_name_app.run(HOST, PORT, **run_kwargs) except KeyboardInterrupt: pass diff --git a/tests/test_signal_handlers.py b/tests/test_signal_handlers.py index 967e903f..bee4f8e7 100644 --- a/tests/test_signal_handlers.py +++ b/tests/test_signal_handlers.py @@ -1,6 +1,6 @@ from sanic import Sanic from sanic.response import HTTPResponse -from sanic.testing import HOST +from sanic.testing import HOST, PORT from unittest.mock import MagicMock import asyncio from queue import Queue @@ -30,7 +30,7 @@ def test_register_system_signals(): app.listener('before_server_start')(set_loop) app.listener('after_server_stop')(after) - app.run(HOST, app.test_port) + app.run(HOST, PORT) assert calledq.get() == True @@ -46,5 +46,5 @@ def test_dont_register_system_signals(): app.listener('before_server_start')(set_loop) app.listener('after_server_stop')(after) - app.run(HOST, app.test_port, register_sys_signals=False) + app.run(HOST, PORT, register_sys_signals=False) assert calledq.get() == False diff --git a/tests/test_url_building.py b/tests/test_url_building.py index 670cafa5..98bbc20a 100644 --- a/tests/test_url_building.py +++ b/tests/test_url_building.py @@ -5,7 +5,7 @@ from sanic import Sanic from sanic.response import text from sanic.views import HTTPMethodView from sanic.blueprints import Blueprint -from sanic.testing import HOST as test_host +from sanic.testing import PORT as test_port, HOST as test_host from sanic.exceptions import URLBuildError import string @@ -15,11 +15,11 @@ URL_FOR_VALUE1 = '/myurl?arg1=v1&arg1=v2' URL_FOR_ARGS2 = dict(arg1=['v1', 'v2'], _anchor='anchor') URL_FOR_VALUE2 = '/myurl?arg1=v1&arg1=v2#anchor' URL_FOR_ARGS3 = dict(arg1='v1', _anchor='anchor', _scheme='http', - _server='{}:PORT_PLACEHOLDER'.format(test_host), _external=True) -URL_FOR_VALUE3 = 'http://{}:PORT_PLACEHOLDER/myurl?arg1=v1#anchor'.format(test_host) + _server='{}:{}'.format(test_host, test_port), _external=True) +URL_FOR_VALUE3 = 'http://{}:{}/myurl?arg1=v1#anchor'.format(test_host, test_port) URL_FOR_ARGS4 = dict(arg1='v1', _anchor='anchor', _external=True, - _server='http://{}:PORT_PLACEHOLDER'.format(test_host),) -URL_FOR_VALUE4 = 'http://{}:PORT_PLACEHOLDER/myurl?arg1=v1#anchor'.format(test_host) + _server='http://{}:{}'.format(test_host, test_port)) +URL_FOR_VALUE4 = 'http://{}:{}/myurl?arg1=v1#anchor'.format(test_host, test_port) def _generate_handlers_from_names(app, l): @@ -61,10 +61,6 @@ def test_simple_url_for_getting_with_more_params(args, url): def passes(request): return text('this should pass') - if '_server' in args: - args['_server'] = args['_server'].replace( - 'PORT_PLACEHOLDER', str(app.test_port)) - url = url.replace('PORT_PLACEHOLDER', str(app.test_port)) assert url == app.url_for('passes', **args) request, response = app.test_client.get(url) assert response.status == 200 diff --git a/tox.ini b/tox.ini index 71498013..be984b4e 100644 --- a/tox.ini +++ b/tox.ini @@ -12,13 +12,12 @@ deps = pytest-cov pytest-sanic pytest-sugar - pytest-xdist aiohttp>=2.3 chardet<=2.3.0 beautifulsoup4 gunicorn commands = - pytest tests -n 4 --cov sanic --cov-report= {posargs} + pytest tests --cov sanic --cov-report= {posargs} - coverage combine --append coverage report -m From fc8b5f378a70cc2182fcb41dd6f61b85586d517e Mon Sep 17 00:00:00 2001 From: Yun Xu Date: Thu, 15 Mar 2018 21:39:21 -0700 Subject: [PATCH 03/15] migrate to trusty --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6f2400f4..1fa1df57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ sudo: false -dist: precise language: python cache: directories: From b0ecb3170fa73fa288e140f55c3914b187b6c15e Mon Sep 17 00:00:00 2001 From: Yun Xu Date: Thu, 15 Mar 2018 22:03:36 -0700 Subject: [PATCH 04/15] fix hang build --- tests/test_keep_alive_timeout.py | 1 - tests/test_multiprocessing.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_keep_alive_timeout.py b/tests/test_keep_alive_timeout.py index 494bf633..2a9e93a2 100644 --- a/tests/test_keep_alive_timeout.py +++ b/tests/test_keep_alive_timeout.py @@ -279,4 +279,3 @@ def test_keep_alive_server_timeout(): assert isinstance(exception, ValueError) assert "Connection reset" in exception.args[0] or \ "got a new connection" in exception.args[0] - diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py index 8cc40e5d..8becfab1 100644 --- a/tests/test_multiprocessing.py +++ b/tests/test_multiprocessing.py @@ -19,7 +19,7 @@ def test_multiprocessing(): process.terminate() signal.signal(signal.SIGALRM, stop_on_alarm) - signal.alarm(1) app.run(HOST, PORT, workers=num_workers) + signal.alarm(1) assert len(process_list) == num_workers From e0b7624414b77f71389f865e9d5d04d3a1a993e5 Mon Sep 17 00:00:00 2001 From: Yun Xu Date: Thu, 15 Mar 2018 22:06:58 -0700 Subject: [PATCH 05/15] fix hang build --- tests/test_multiprocessing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py index 8becfab1..7d94a972 100644 --- a/tests/test_multiprocessing.py +++ b/tests/test_multiprocessing.py @@ -19,7 +19,7 @@ def test_multiprocessing(): process.terminate() signal.signal(signal.SIGALRM, stop_on_alarm) + signal.alarm(3) app.run(HOST, PORT, workers=num_workers) - signal.alarm(1) assert len(process_list) == num_workers From 3dfb31b1b9590d73be5d8016dc2dbf843f82b39f Mon Sep 17 00:00:00 2001 From: Charles-Axel Dein Date: Wed, 21 Mar 2018 12:07:26 +0100 Subject: [PATCH 06/15] Clarify arguments to request/response middleware --- docs/sanic/middleware.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/sanic/middleware.md b/docs/sanic/middleware.md index eafe3c6f..e041d452 100644 --- a/docs/sanic/middleware.md +++ b/docs/sanic/middleware.md @@ -10,9 +10,10 @@ Additionally, Sanic provides listeners which allow you to run code at various po There are two types of middleware: request and response. Both are declared using the `@app.middleware` decorator, with the decorator's parameter being a -string representing its type: `'request'` or `'response'`. Response middleware -receives both the request and the response as arguments. +string representing its type: `'request'` or `'response'`. +* Request middleware receives only the `request` as argument. +* Response middleware receives both the `request` and `response`. The simplest middleware doesn't modify the request or response at all: From eb4276373bac79de1c4a1a5d07e308853a57d430 Mon Sep 17 00:00:00 2001 From: TheRubyDoggy Date: Sat, 24 Mar 2018 15:34:41 +0200 Subject: [PATCH 07/15] Fix try_everything example. --- examples/try_everything.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/try_everything.py b/examples/try_everything.py index 76967be1..bc0fa8a0 100644 --- a/examples/try_everything.py +++ b/examples/try_everything.py @@ -1,7 +1,7 @@ import os from sanic import Sanic -from sanic.log import log +from sanic.log import logger from sanic import response from sanic.exceptions import ServerError @@ -82,22 +82,22 @@ def query_string(request): @app.listener('before_server_start') def before_start(app, loop): - log.info("SERVER STARTING") + logger.info("SERVER STARTING") @app.listener('after_server_start') def after_start(app, loop): - log.info("OH OH OH OH OHHHHHHHH") + logger.info("OH OH OH OH OHHHHHHHH") @app.listener('before_server_stop') def before_stop(app, loop): - log.info("SERVER STOPPING") + logger.info("SERVER STOPPING") @app.listener('after_server_stop') def after_stop(app, loop): - log.info("TRIED EVERYTHING") + logger.info("TRIED EVERYTHING") if __name__ == '__main__': From 2995b2392941d088fc2a25738be8d489dfc3865d Mon Sep 17 00:00:00 2001 From: PyManiac <11256310+PyManiacGR@users.noreply.github.com> Date: Sat, 24 Mar 2018 15:55:15 +0200 Subject: [PATCH 08/15] Update try_everything.py --- examples/try_everything.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/try_everything.py b/examples/try_everything.py index bc0fa8a0..5950c4ea 100644 --- a/examples/try_everything.py +++ b/examples/try_everything.py @@ -1,7 +1,7 @@ import os from sanic import Sanic -from sanic.log import logger +from sanic.log import logger as log from sanic import response from sanic.exceptions import ServerError @@ -82,22 +82,22 @@ def query_string(request): @app.listener('before_server_start') def before_start(app, loop): - logger.info("SERVER STARTING") + log.info("SERVER STARTING") @app.listener('after_server_start') def after_start(app, loop): - logger.info("OH OH OH OH OHHHHHHHH") + log.info("OH OH OH OH OHHHHHHHH") @app.listener('before_server_stop') def before_stop(app, loop): - logger.info("SERVER STOPPING") + log.info("SERVER STOPPING") @app.listener('after_server_stop') def after_stop(app, loop): - logger.info("TRIED EVERYTHING") + log.info("TRIED EVERYTHING") if __name__ == '__main__': From 94b9bc7950dc5ef49de9e21dcc16e4910e27a312 Mon Sep 17 00:00:00 2001 From: Ashley Sommer Date: Thu, 29 Mar 2018 11:54:59 +1000 Subject: [PATCH 09/15] Some of the tests in Sanic (test_request_timout, test_response_timeout, test_keep_alive_timeout) use a custom SanicClient with modified methods. This relies on overriding internal aiohttp Client classes. In aiohttp 3.1.0 there were some breaking changes that caused the custom methods to be no longer compatible with latest upstream aiohttp Client class. See: https://github.com/aio-libs/aiohttp/commit/903073283fa85bb3e8bb7568d3832a8fd9c06435 and: https://github.com/aio-libs/aiohttp/commit/b42e0ced4653ff62fa1829941e4f680d712b830a This commit adds aiohttp version checks to adapt to these changes. --- requirements-dev.txt | 2 +- tests/test_request_timeout.py | 38 ++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index d46aee12..674ef91d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,5 @@ aiofiles -aiohttp==1.3.5 +aiohttp>=2.3.0 chardet<=2.3.0 beautifulsoup4 coverage diff --git a/tests/test_request_timeout.py b/tests/test_request_timeout.py index 61ba9d04..b3eb78aa 100644 --- a/tests/test_request_timeout.py +++ b/tests/test_request_timeout.py @@ -58,18 +58,36 @@ class DelayableTCPConnector(TCPConnector): t = req.loop.time() print("sending at {}".format(t), flush=True) conn = next(iter(args)) # first arg is connection - try: - delayed_resp = self.orig_send(*args, **kwargs) - except Exception as e: - return aiohttp.ClientResponse(req.method, req.url) + if aiohttp.__version__ >= "3.1.0": + try: + delayed_resp = await self.orig_send(*args, **kwargs) + except Exception as e: + return aiohttp.ClientResponse(req.method, req.url, + writer=None, continue100=None, timer=None, + request_info=None, auto_decompress=None, traces=[], + loop=req.loop, session=None) + else: + try: + delayed_resp = self.orig_send(*args, **kwargs) + except Exception as e: + return aiohttp.ClientResponse(req.method, req.url) return delayed_resp - def send(self, *args, **kwargs): - gen = self.delayed_send(*args, **kwargs) - task = self.req.loop.create_task(gen) - self.send_task = task - self._acting_as = task - return self + if aiohttp.__version__ >= "3.1.0": + # aiohttp changed the request.send method to async + async def send(self, *args, **kwargs): + gen = self.delayed_send(*args, **kwargs) + task = self.req.loop.create_task(gen) + self.send_task = task + self._acting_as = task + return self + else: + def send(self, *args, **kwargs): + gen = self.delayed_send(*args, **kwargs) + task = self.req.loop.create_task(gen) + self.send_task = task + self._acting_as = task + return self def __init__(self, *args, **kwargs): _post_connect_delay = kwargs.pop('post_connect_delay', 0) From a850ce50865483f894d5d349bfca1fe67a0c1682 Mon Sep 17 00:00:00 2001 From: kot83 <33439542+kot83@users.noreply.github.com> Date: Thu, 29 Mar 2018 15:57:10 -0700 Subject: [PATCH 10/15] rename function to something else function already defined --- examples/try_everything.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/try_everything.py b/examples/try_everything.py index 5950c4ea..a775704d 100644 --- a/examples/try_everything.py +++ b/examples/try_everything.py @@ -66,7 +66,7 @@ def post_json(request): @app.route("/form") -def post_json(request): +def post_form_json(request): return response.json({"received": True, "form_data": request.form, "test": request.form.get('test')}) From 8f2d543d9fd3a0ad8f7f62f40bbb2dbe2e34d4d7 Mon Sep 17 00:00:00 2001 From: Raphael Deem Date: Sun, 1 Apr 2018 20:52:56 -0700 Subject: [PATCH 11/15] default to auto_reload in debug mode (#1159) * default to auto_reload in debug mode * disable auto-reload in testing client --- sanic/app.py | 9 ++++++++- sanic/testing.py | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sanic/app.py b/sanic/app.py index 87667825..06540088 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -649,7 +649,7 @@ class Sanic: def run(self, host=None, port=None, debug=False, ssl=None, sock=None, workers=1, protocol=None, backlog=100, stop_event=None, register_sys_signals=True, - access_log=True, auto_reload=False): + access_log=True, **kwargs): """Run the HTTP Server and listen until keyboard interrupt or term signal. On termination, drain connections before closing. @@ -667,6 +667,13 @@ class Sanic: :param protocol: Subclass of asyncio protocol class :return: Nothing """ + # Default auto_reload to false + auto_reload = False + # If debug is set, default it to true + if debug: + auto_reload = True + # Allow for overriding either of the defaults + auto_reload = kwargs.get("auto_reload", auto_reload) if sock is None: host, port = host or "127.0.0.1", port or 8000 diff --git a/sanic/testing.py b/sanic/testing.py index a639e16e..3a1d15c5 100644 --- a/sanic/testing.py +++ b/sanic/testing.py @@ -45,7 +45,7 @@ class SanicTestClient: def _sanic_endpoint_test( self, method='get', uri='/', gather_request=True, - debug=False, server_kwargs={}, + debug=False, server_kwargs={"auto_reload": False}, *request_args, **request_kwargs): results = [None, None] exceptions = [] From b6715464fd2e6ee9ad99c742520f3ce1c261da69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnulfo=20Sol=C3=ADs?= Date: Mon, 2 Apr 2018 05:53:08 +0200 Subject: [PATCH 12/15] added init docs (#1167) --- docs/sanic/debug_mode.rst | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/sanic/debug_mode.rst diff --git a/docs/sanic/debug_mode.rst b/docs/sanic/debug_mode.rst new file mode 100644 index 00000000..14356855 --- /dev/null +++ b/docs/sanic/debug_mode.rst @@ -0,0 +1,53 @@ +Debug Mode +============= + +When enabling Sanic's debug mode, Sanic will provide a more verbose logging output +and by default will enable the Auto Reload feature. + +.. warning:: + + Sanic's debug more will slow down the server's performance + and is therefore advised to enable it only in development environments. + + +Setting the debug mode +---------------------- + +By setting the ``debug`` mode a more verbose output from Sanic will be outputed +and the Automatic Reloader will be activated. + +.. code-block:: python + + from sanic import Sanic + from sanic.response import json + + app = Sanic() + + @app.route('/') + async def hello_world(request): + return json({"hello": "world"}) + + if __name__ == '__main__': + app.run(host="0.0.0.0", port=8000, debug=True) + + + +Manually setting auto reload +---------------------------- + +Sanic offers a way to enable or disable the Automatic Reloader manually, +the ``auto_reload`` argument will activate or deactivate the Automatic Reloader. + +.. code-block:: python + + from sanic import Sanic + from sanic.response import json + + app = Sanic() + + @app.route('/') + async def hello_world(request): + return json({"hello": "world"}) + + if __name__ == '__main__': + app.run(host="0.0.0.0", port=8000, auto_reload=True) \ No newline at end of file From 818a8c2196fb14aab3ee30cd2fef845d0b7148ef Mon Sep 17 00:00:00 2001 From: Fantix King Date: Sun, 22 Apr 2018 12:02:49 +0800 Subject: [PATCH 13/15] Added GINO to Extensions doc (#1200) --- docs/sanic/extensions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/sanic/extensions.md b/docs/sanic/extensions.md index d719a28f..3d3feaeb 100644 --- a/docs/sanic/extensions.md +++ b/docs/sanic/extensions.md @@ -27,3 +27,4 @@ A list of Sanic extensions created by the community. - [sanic-transmute](https://github.com/yunstanford/sanic-transmute): A Sanic extension that generates APIs from python function and classes, and also generates Swagger UI/documentation automatically. - [pytest-sanic](https://github.com/yunstanford/pytest-sanic): A pytest plugin for Sanic. It helps you to test your code asynchronously. - [jinja2-sanic](https://github.com/yunstanford/jinja2-sanic): a jinja2 template renderer for Sanic.([Documentation](http://jinja2-sanic.readthedocs.io/en/latest/)) +- [GINO](https://github.com/fantix/gino): An asyncio ORM on top of SQLAlchemy core, delivered with a Sanic extension. ([Documentation](https://python-gino.readthedocs.io/)) From 04a12b436e638a671db8d96487d692ad3d66e560 Mon Sep 17 00:00:00 2001 From: Philip Xu Date: Sun, 29 Apr 2018 21:40:18 -0400 Subject: [PATCH 14/15] Added Sanic-Auth, Sanic-CookieSession and Sanic-WTF to Extensions doc (#1210) --- docs/sanic/extensions.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/sanic/extensions.md b/docs/sanic/extensions.md index 3d3feaeb..4effd737 100644 --- a/docs/sanic/extensions.md +++ b/docs/sanic/extensions.md @@ -28,3 +28,6 @@ A list of Sanic extensions created by the community. - [pytest-sanic](https://github.com/yunstanford/pytest-sanic): A pytest plugin for Sanic. It helps you to test your code asynchronously. - [jinja2-sanic](https://github.com/yunstanford/jinja2-sanic): a jinja2 template renderer for Sanic.([Documentation](http://jinja2-sanic.readthedocs.io/en/latest/)) - [GINO](https://github.com/fantix/gino): An asyncio ORM on top of SQLAlchemy core, delivered with a Sanic extension. ([Documentation](https://python-gino.readthedocs.io/)) +- [Sanic-Auth](https://github.com/pyx/sanic-auth): A minimal backend agnostic session-based user authentication mechanism for Sanic. +- [Sanic-CookieSession](https://github.com/pyx/sanic-cookiesession): A client-side only, cookie-based session, similar to the built-in session in Flask. +- [Sanic-WTF](https://github.com/pyx/sanic-wtf): Sanic-WTF makes using WTForms with Sanic and CSRF (Cross-Site Request Forgery) protection a little bit easier. From e1c90202682d76361c77adb7bb2176730038466a Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Mon, 30 Apr 2018 04:41:17 +0300 Subject: [PATCH 15/15] Update extensions.md (#1205) Changing the description of [Sanic JWT](https://github.com/ahopkins/sanic-jwt) to include permission scoping --- docs/sanic/extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sanic/extensions.md b/docs/sanic/extensions.md index 4effd737..01c89f95 100644 --- a/docs/sanic/extensions.md +++ b/docs/sanic/extensions.md @@ -7,7 +7,7 @@ A list of Sanic extensions created by the community. - [CORS](https://github.com/ashleysommer/sanic-cors): A port of flask-cors. - [Compress](https://github.com/subyraman/sanic_compress): Allows you to easily gzip Sanic responses. A port of Flask-Compress. - [Jinja2](https://github.com/lixxu/sanic-jinja2): Support for Jinja2 template. -- [JWT](https://github.com/ahopkins/sanic-jwt): Authentication extension for JSON Web Tokens (JWT). +- [Sanic JWT](https://github.com/ahopkins/sanic-jwt): Authentication, JWT, and permission scoping for Sanic. - [OpenAPI/Swagger](https://github.com/channelcat/sanic-openapi): OpenAPI support, plus a Swagger UI. - [Pagination](https://github.com/lixxu/python-paginate): Simple pagination support. - [Motor](https://github.com/lixxu/sanic-motor): Simple motor wrapper.