Skip to content

Commit

Permalink
Merge branch 'master' into Making-static-route-more-verbose-if-file-n…
Browse files Browse the repository at this point in the history
…ot-found
  • Loading branch information
ahopkins authored Dec 28, 2020
2 parents 95cbfd6 + 449bc41 commit 684b6b6
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 151 deletions.
6 changes: 6 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ environment:
PYTHON_VERSION: "3.8.x"
PYTHON_ARCH: "64"

# - TOXENV: py39-no-ext
# PYTHON: "C:\\Python39-x64\\python"
# PYTHONPATH: "C:\\Python39-x64"
# PYTHON_VERSION: "3.9.x"
# PYTHON_ARCH: "64"

init: SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"

install:
Expand Down
27 changes: 23 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ matrix:
dist: xenial
sudo: true
name: "Python 3.8 without Extensions"
- env: TOX_ENV=py39
python: 3.9
dist: bionic
sudo: true
name: "Python 3.9 with Extensions"
- env: TOX_ENV=py39-no-ext
python: 3.9
dist: bionic
sudo: true
name: "Python 3.9 without Extensions"
- env: TOX_ENV=type-checking
python: 3.6
name: "Python 3.6 Type checks"
Expand All @@ -40,6 +50,10 @@ matrix:
- env: TOX_ENV=type-checking
python: 3.8
name: "Python 3.8 Type checks"
- env: TOX_ENV=type-checking
python: 3.9
dist: bionic
name: "Python 3.9 Type checks"
- env: TOX_ENV=lint
python: 3.6
name: "Python 3.6 Linter checks"
Expand All @@ -61,23 +75,28 @@ matrix:
dist: xenial
sudo: true
name: "Python 3.8 Bandit security scan"
- env: TOX_ENV=security
python: 3.9
dist: bionic
sudo: true
name: "Python 3.9 Bandit security scan"
- env: TOX_ENV=docs
python: 3.7
dist: xenial
sudo: true
name: "Python 3.7 Documentation tests"
- env: TOX_ENV=pyNightly
python: 'nightly'
python: "nightly"
name: "Python nightly with Extensions"
- env: TOX_ENV=pyNightly-no-ext
python: 'nightly'
python: "nightly"
name: "Python nightly without Extensions"
allow_failures:
- env: TOX_ENV=pyNightly
python: 'nightly'
python: "nightly"
name: "Python nightly with Extensions"
- env: TOX_ENV=pyNightly-no-ext
python: 'nightly'
python: "nightly"
name: "Python nightly without Extensions"
install:
- pip install -U tox
Expand Down
23 changes: 23 additions & 0 deletions docs/sanic/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,26 @@ Open the address `http://0.0.0.0:8000 <http://0.0.0.0:8000>`_ in your web browse
the message *Hello world!*.

You now have a working Sanic server!

5. Application registry
-----------------------

When you instantiate a Sanic instance, that can be retrieved at a later time from the Sanic app registry. This can be useful, for example, if you need to access your Sanic instance from a location where it is not otherwise accessible.

.. code-block:: python
# ./path/to/server.py
from sanic import Sanic
app = Sanic("my_awesome_server")
# ./path/to/somewhere_else.py
from sanic import Sanic
app = Sanic.get_app("my_awesome_server")
If you call ``Sanic.get_app("non-existing")`` on an app that does not exist, it will raise ``SanicException`` by default. You can, instead, force the method to return a new instance of ``Sanic`` with that name:

.. code-block:: python
app = Sanic.get_app("my_awesome_server", force_create=True)
2 changes: 1 addition & 1 deletion docs/sanic/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ which allows the handler function to work with any of the HTTP methods in the li
async def get_handler(request):
return text('GET request - {}'.format(request.args))
There is also an optional `host` argument (which can be a list or a string). This restricts a route to the host or hosts provided. If there is a also a route with no host, it will be the default.
There is also an optional `host` argument (which can be a list or a string). This restricts a route to the host or hosts provided. If there is also a route with no host, it will be the default.

.. code-block:: python
Expand Down
4 changes: 0 additions & 4 deletions docs/sanic/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ More information about
the available arguments to `httpx` can be found
[in the documentation for `httpx <https://www.encode.io/httpx/>`_.

Additionally, Sanic has an asynchronous testing client. The difference is that the async client will not stand up an
instance of your application, but will instead reach inside it using ASGI. All listeners and middleware are still
executed.

.. code-block:: python
@pytest.mark.asyncio
async def test_index_returns_200():
Expand Down
5 changes: 4 additions & 1 deletion examples/run_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from sanic import Sanic, response


app = Sanic(__name__)


Expand Down Expand Up @@ -42,7 +43,9 @@ async def handler_file(request):

@app.route("/file_stream")
async def handler_file_stream(request):
return await response.file_stream(Path("../") / "setup.py", chunk_size=1024)
return await response.file_stream(
Path("../") / "setup.py", chunk_size=1024
)


@app.route("/stream", stream=True)
Expand Down
97 changes: 35 additions & 62 deletions sanic/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
import logging.config
import os
import re
import warnings

from asyncio import CancelledError, Protocol, ensure_future, get_event_loop
from collections import defaultdict, deque
from functools import partial
from inspect import getmodulename, isawaitable, signature, stack
from inspect import isawaitable, signature
from socket import socket
from ssl import Purpose, SSLContext, create_default_context
from traceback import format_exc
Expand Down Expand Up @@ -38,6 +37,9 @@


class Sanic:
_app_registry: Dict[str, "Sanic"] = {}
test_mode = False

def __init__(
self,
name=None,
Expand All @@ -52,15 +54,10 @@ def __init__(

# Get name from previous stack frame
if name is None:
warnings.warn(
"Sanic(name=None) is deprecated and None value support "
"for `name` will be removed in the next release. "
raise SanicException(
"Sanic instance cannot be unnamed. "
"Please use Sanic(name='your_application_name') instead.",
DeprecationWarning,
stacklevel=2,
)
frame_records = stack()[1]
name = getmodulename(frame_records[1])

# logging
if configure_logging:
Expand Down Expand Up @@ -90,7 +87,8 @@ def __init__(
self.named_response_middleware = {}
# Register alternative method names
self.go_fast = self.run
self.test_mode = False

self.__class__.register_app(self)

@property
def loop(self):
Expand Down Expand Up @@ -714,28 +712,6 @@ def blueprint(self, blueprint, **options):
self._blueprint_order.append(blueprint)
blueprint.register(self, options)

def register_blueprint(self, *args, **kwargs):
"""
Proxy method provided for invoking the :func:`blueprint` method
.. note::
To be deprecated in 1.0. Use :func:`blueprint` instead.
:param args: Blueprint object or (list, tuple) thereof
:param kwargs: option dictionary with blueprint defaults
:return: None
"""

if self.debug:
warnings.simplefilter("default")
warnings.warn(
"Use of register_blueprint will be deprecated in "
"version 1.0. Please use the blueprint method"
" instead",
DeprecationWarning,
)
return self.blueprint(*args, **kwargs)

def url_for(self, view_name: str, **kwargs):
r"""Build a URL based on a view name and the values provided.
Expand Down Expand Up @@ -1026,7 +1002,6 @@ def run(
workers: int = 1,
protocol: Optional[Type[Protocol]] = None,
backlog: int = 100,
stop_event: Any = None,
register_sys_signals: bool = True,
access_log: Optional[bool] = None,
unix: Optional[str] = None,
Expand Down Expand Up @@ -1056,9 +1031,6 @@ def run(
:param backlog: a number of unaccepted connections that the system
will allow before refusing new connections
:type backlog: int
:param stop_event: event to be triggered
before stopping the app - deprecated
:type stop_event: None
:param register_sys_signals: Register SIG* events
:type register_sys_signals: bool
:param access_log: Enables writing access logs (slows server)
Expand Down Expand Up @@ -1086,13 +1058,6 @@ def run(
protocol = (
WebSocketProtocol if self.websocket_enabled else HttpProtocol
)
if stop_event is not None:
if debug:
warnings.simplefilter("default")
warnings.warn(
"stop_event will be removed from future versions.",
DeprecationWarning,
)
# if access_log is passed explicitly change config.ACCESS_LOG
if access_log is not None:
self.config.ACCESS_LOG = access_log
Expand Down Expand Up @@ -1149,7 +1114,6 @@ async def create_server(
sock: Optional[socket] = None,
protocol: Type[Protocol] = None,
backlog: int = 100,
stop_event: Any = None,
access_log: Optional[bool] = None,
unix: Optional[str] = None,
return_asyncio_server=False,
Expand Down Expand Up @@ -1182,9 +1146,6 @@ async def create_server(
:param backlog: a number of unaccepted connections that the system
will allow before refusing new connections
:type backlog: int
:param stop_event: event to be triggered
before stopping the app - deprecated
:type stop_event: None
:param access_log: Enables writing access logs (slows server)
:type access_log: bool
:param return_asyncio_server: flag that defines whether there's a need
Expand All @@ -1204,13 +1165,6 @@ async def create_server(
protocol = (
WebSocketProtocol if self.websocket_enabled else HttpProtocol
)
if stop_event is not None:
if debug:
warnings.simplefilter("default")
warnings.warn(
"stop_event will be removed from future versions.",
DeprecationWarning,
)
# if access_log is passed explicitly change config.ACCESS_LOG
if access_log is not None:
self.config.ACCESS_LOG = access_log
Expand Down Expand Up @@ -1292,7 +1246,6 @@ def _helper(
loop=None,
protocol=HttpProtocol,
backlog=100,
stop_event=None,
register_sys_signals=True,
run_async=False,
auto_reload=False,
Expand All @@ -1307,13 +1260,6 @@ def _helper(
context = create_default_context(purpose=Purpose.CLIENT_AUTH)
context.load_cert_chain(cert, keyfile=key)
ssl = context
if stop_event is not None:
if debug:
warnings.simplefilter("default")
warnings.warn(
"stop_event will be removed from future versions.",
DeprecationWarning,
)
if self.config.PROXIES_COUNT and self.config.PROXIES_COUNT < 0:
raise ValueError(
"PROXIES_COUNT cannot be negative. "
Expand Down Expand Up @@ -1453,9 +1399,36 @@ async def __call__(self, scope, receive, send):
# -------------------------------------------------------------------- #
# Configuration
# -------------------------------------------------------------------- #

def update_config(self, config: Union[bytes, str, dict, Any]):
"""Update app.config.
Please refer to config.py::Config.update_config for documentation."""

self.config.update_config(config)

# -------------------------------------------------------------------- #
# Class methods
# -------------------------------------------------------------------- #

@classmethod
def register_app(cls, app: "Sanic") -> None:
"""Register a Sanic instance"""
if not isinstance(app, cls):
raise SanicException("Registered app must be an instance of Sanic")

name = app.name
if name in cls._app_registry and not cls.test_mode:
raise SanicException(f'Sanic app name "{name}" already in use.')

cls._app_registry[name] = app

@classmethod
def get_app(cls, name: str, *, force_create: bool = False) -> "Sanic":
"""Retrieve an instantiated Sanic instance"""
try:
return cls._app_registry[name]
except KeyError:
if force_create:
return cls(name)
raise SanicException(f'Sanic app name "{name}" not found.')
9 changes: 6 additions & 3 deletions sanic/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,18 @@ def __repr__(self):
return f"<{class_name}: {self.method} {self.path}>"

def body_init(self):
""".. deprecated:: 20.3"""
""".. deprecated:: 20.3
To be removed in 21.3"""
self.body = []

def body_push(self, data):
""".. deprecated:: 20.3"""
""".. deprecated:: 20.3
To be removed in 21.3"""
self.body.append(data)

def body_finish(self):
""".. deprecated:: 20.3"""
""".. deprecated:: 20.3
To be removed in 21.3"""
self.body = b"".join(self.body)

async def receive_body(self):
Expand Down
Loading

0 comments on commit 684b6b6

Please sign in to comment.