Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sanic as an entry point command #1866

Merged
merged 4 commits into from
Jun 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion sanic/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import os
import sys

from argparse import ArgumentParser
from importlib import import_module
from typing import Any, Dict, Optional
Expand All @@ -6,7 +9,7 @@
from sanic.log import logger


if __name__ == "__main__":
def main():
parser = ArgumentParser(prog="sanic")
parser.add_argument("--host", dest="host", type=str, default="127.0.0.1")
parser.add_argument("--port", dest="port", type=int, default=8000)
Expand All @@ -22,6 +25,10 @@
args = parser.parse_args()

try:
module_path = os.path.abspath(os.getcwd())
if module_path not in sys.path:
sys.path.append(module_path)

module_parts = args.module.split(".")
module_name = ".".join(module_parts[:-1])
app_name = module_parts[-1]
Expand Down Expand Up @@ -58,3 +65,7 @@
)
except ValueError:
logger.exception("Failed to run app")


if __name__ == "__main__":
main()
10 changes: 3 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import os
import re
import sys

from distutils.util import strtobool

from setuptools import setup
Expand Down Expand Up @@ -39,9 +38,7 @@ def open_local(paths, mode="r", encoding="utf8"):

with open_local(["sanic", "__version__.py"], encoding="latin1") as fp:
try:
version = re.findall(
r"^__version__ = \"([^']+)\"\r?$", fp.read(), re.M
)[0]
version = re.findall(r"^__version__ = \"([^']+)\"\r?$", fp.read(), re.M)[0]
except IndexError:
raise RuntimeError("Unable to determine version.")

Expand Down Expand Up @@ -70,11 +67,10 @@ def open_local(paths, mode="r", encoding="utf8"):
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
],
"entry_points": {"console_scripts": ["sanic = sanic.__main__:main"]},
}

env_dependency = (
'; sys_platform != "win32" ' 'and implementation_name == "cpython"'
)
env_dependency = '; sys_platform != "win32" ' 'and implementation_name == "cpython"'
ujson = "ujson>=1.35" + env_dependency
uvloop = "uvloop>=0.5.3" + env_dependency

Expand Down
7 changes: 6 additions & 1 deletion tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def test_asyncio_server_no_start_serving(app):
srv = loop.run_until_complete(asyncio_srv_coro)
assert srv.is_serving() is False


@pytest.mark.skipif(
sys.version_info < (3, 7), reason="requires python3.7 or higher"
)
Expand All @@ -75,6 +76,7 @@ def test_asyncio_server_start_serving(app):
loop.run_until_complete(wait_close)
# Looks like we can't easily test `serve_forever()`


def test_app_loop_not_running(app):
with pytest.raises(SanicException) as excinfo:
app.loop
Expand Down Expand Up @@ -125,7 +127,10 @@ def handler(request):

request, response = app.test_client.get("/test")

assert "'None' was returned while requesting a handler from the router" in response.text
assert (
"'None' was returned while requesting a handler from the router"
in response.text
)


@pytest.mark.parametrize("websocket_enabled", [True, False])
Expand Down
8 changes: 4 additions & 4 deletions tests/test_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ def install_signal_handlers(self):

all_tasks = (
asyncio.Task.all_tasks()
if sys.version_info < (3, 7) else
asyncio.all_tasks(asyncio.get_event_loop())
if sys.version_info < (3, 7)
else asyncio.all_tasks(asyncio.get_event_loop())
)
for task in all_tasks:
task.cancel()
Expand Down Expand Up @@ -134,8 +134,8 @@ def install_signal_handlers(self):

all_tasks = (
asyncio.Task.all_tasks()
if sys.version_info < (3, 7) else
asyncio.all_tasks(asyncio.get_event_loop())
if sys.version_info < (3, 7)
else asyncio.all_tasks(asyncio.get_event_loop())
)
for task in all_tasks:
task.cancel()
Expand Down
12 changes: 9 additions & 3 deletions tests/test_blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,24 +270,31 @@ async def handler(request):
assert response.status == 200
assert response.text == "FAIL"


def test_bp_middleware_order(app):
blueprint = Blueprint("test_bp_middleware_order")
order = list()

@blueprint.middleware("request")
def mw_1(request):
order.append(1)

@blueprint.middleware("request")
def mw_2(request):
order.append(2)

@blueprint.middleware("request")
def mw_3(request):
order.append(3)

@blueprint.middleware("response")
def mw_4(request, response):
order.append(6)

@blueprint.middleware("response")
def mw_5(request, response):
order.append(5)

@blueprint.middleware("response")
def mw_6(request, response):
order.append(4)
Expand All @@ -303,6 +310,7 @@ def process_response(request):
assert response.status == 200
assert order == [1, 2, 3, 4, 5, 6]


def test_bp_exception_handler(app):
blueprint = Blueprint("test_middleware")

Expand Down Expand Up @@ -585,9 +593,7 @@ def api_v1_info(request):
from uuid import uuid4

resource_id = str(uuid4())
request, response = app.test_client.get(
f"/api/v1/resources/{resource_id}"
)
request, response = app.test_client.get(f"/api/v1/resources/{resource_id}")
assert response.json == {"resource_id": resource_id}


Expand Down
7 changes: 3 additions & 4 deletions tests/test_keep_alive_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from sanic.response import text
from sanic.testing import HOST, SanicTestClient


CONFIG_FOR_TESTS = {"KEEP_ALIVE_TIMEOUT": 2, "KEEP_ALIVE": True}

old_conn = None
Expand Down Expand Up @@ -46,7 +47,7 @@ async def acquire_connection(self, origin, timeout):
cert=self.cert,
verify=self.verify,
trust_env=self.trust_env,
http2=self.http2
http2=self.http2,
)
connection = httpx.dispatch.connection.HTTPConnection(
origin,
Expand Down Expand Up @@ -166,9 +167,7 @@ async def _collect_response(loop):
try:
return results[-1]
except Exception:
raise ValueError(
f"Request object expected, got ({results})"
)
raise ValueError(f"Request object expected, got ({results})")

def kill_server(self):
try:
Expand Down
1 change: 1 addition & 0 deletions tests/test_request_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,7 @@ async def post_handler(request):
assert response.status == 200
assert response.text == data


def test_streaming_new_api(app):
@app.post("/non-stream")
async def handler(request):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_request_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def __init__(self, *args, **kwargs):
async def send(self, request, timeout=None):

if self.connection is None:
self.connection = (await self.connect(timeout=timeout))
self.connection = await self.connect(timeout=timeout)

if self._request_delay:
await asyncio.sleep(self._request_delay)
Expand Down
25 changes: 15 additions & 10 deletions tests/test_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def test_non_chunked_streaming_adds_correct_headers(non_chunked_streaming_app):


def test_non_chunked_streaming_returns_correct_content(
non_chunked_streaming_app
non_chunked_streaming_app,
):
request, response = non_chunked_streaming_app.test_client.get("/")
assert response.text == "foo,bar"
Expand All @@ -257,7 +257,7 @@ def test_stream_response_status_returns_correct_headers(status):

@pytest.mark.parametrize("keep_alive_timeout", [10, 20, 30])
def test_stream_response_keep_alive_returns_correct_headers(
keep_alive_timeout
keep_alive_timeout,
):
response = StreamingHTTPResponse(sample_streaming_fn)
headers = response.get_headers(
Expand Down Expand Up @@ -286,7 +286,7 @@ def test_stream_response_does_not_include_chunked_header_if_disabled():


def test_stream_response_writes_correct_content_to_transport_when_chunked(
streaming_app
streaming_app,
):
response = StreamingHTTPResponse(sample_streaming_fn)
response.protocol = MagicMock(HttpProtocol)
Expand Down Expand Up @@ -434,9 +434,10 @@ def file_route(request, filename):
request, response = app.test_client.get(f"/files/{source}")
assert response.status == 200
assert response.body == get_file_content(static_file_directory, source)
assert response.headers[
"Content-Disposition"
] == f'attachment; filename="{dest}"'
assert (
response.headers["Content-Disposition"]
== f'attachment; filename="{dest}"'
)


@pytest.mark.parametrize("file_name", ["test.file", "decode me.txt"])
Expand Down Expand Up @@ -510,9 +511,10 @@ def file_route(request, filename):
request, response = app.test_client.get(f"/files/{source}")
assert response.status == 200
assert response.body == get_file_content(static_file_directory, source)
assert response.headers[
"Content-Disposition"
] == f'attachment; filename="{dest}"'
assert (
response.headers["Content-Disposition"]
== f'attachment; filename="{dest}"'
)


@pytest.mark.parametrize("file_name", ["test.file", "decode me.txt"])
Expand Down Expand Up @@ -581,7 +583,10 @@ def file_route(request, filename):
request, response = app.test_client.get(f"/files/{file_name}")
assert response.status == 206
assert "Content-Range" in response.headers
assert response.headers["Content-Range"] == f"bytes {range.start}-{range.end}/{range.total}"
assert (
response.headers["Content-Range"]
== f"bytes {range.start}-{range.end}/{range.total}"
)


def test_raw_response(app):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ async def handler(request, ws):
ev.clear()
request, response = await app.asgi_client.websocket("/test/1")
second_set = ev.is_set()
assert(first_set and second_set)
assert first_set and second_set


def test_method_not_allowed(app):
Expand Down
12 changes: 3 additions & 9 deletions tests/test_signal_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ def after(app, loop):
calledq.put(mock.called)


@pytest.mark.skipif(
os.name == "nt", reason="May hang CI on py38/windows"
)
@pytest.mark.skipif(os.name == "nt", reason="May hang CI on py38/windows")
def test_register_system_signals(app):
"""Test if sanic register system signals"""

Expand All @@ -51,9 +49,7 @@ async def hello_route(request):
assert calledq.get() is True


@pytest.mark.skipif(
os.name == "nt", reason="May hang CI on py38/windows"
)
@pytest.mark.skipif(os.name == "nt", reason="May hang CI on py38/windows")
def test_dont_register_system_signals(app):
"""Test if sanic don't register system signals"""

Expand All @@ -69,9 +65,7 @@ async def hello_route(request):
assert calledq.get() is False


@pytest.mark.skipif(
os.name == "nt", reason="windows cannot SIGINT processes"
)
@pytest.mark.skipif(os.name == "nt", reason="windows cannot SIGINT processes")
def test_windows_workaround():
"""Test Windows workaround (on any other OS)"""
# At least some code coverage, even though this test doesn't work on
Expand Down
4 changes: 1 addition & 3 deletions tests/test_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,7 @@ def test_static_file_content_type(app, static_file_directory, file_name):
def test_static_directory(app, file_name, base_uri, static_file_directory):
app.static(base_uri, static_file_directory)

request, response = app.test_client.get(
uri=f"{base_uri}/{file_name}"
)
request, response = app.test_client.get(uri=f"{base_uri}/{file_name}")
assert response.status == 200
assert response.body == get_file_content(static_file_directory, file_name)

Expand Down
5 changes: 4 additions & 1 deletion tests/test_url_for.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ def index(request):
assert app.url_for("hostindex") == "/"
assert app.url_for("hostpath") == "/path"
assert app.url_for("hostindex", _external=True) == "http://example.com/"
assert app.url_for("hostpath", _external=True) == "http://path.example.com/path"
assert (
app.url_for("hostpath", _external=True)
== "http://path.example.com/path"
)
3 changes: 1 addition & 2 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ def _iternal_method(self):
def get(self, request):
self._iternal_method()
return text(
f"I am get method and global var "
f"is {self.global_var}"
f"I am get method and global var " f"is {self.global_var}"
)

app.add_route(DummyView.as_view(), "/")
Expand Down
2 changes: 2 additions & 0 deletions tests/test_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,11 @@ def test_handle_quit(worker):
assert not worker.alive
assert worker.exit_code == 0


async def _a_noop(*a, **kw):
pass


def test_run_max_requests_exceeded(worker):
loop = asyncio.new_event_loop()
worker.ppid = 1
Expand Down