Fix some examples and docs (#2052)

This commit is contained in:
Adam Hopkins 2021-03-10 11:19:38 +02:00 committed by GitHub
parent 5ca8bb85cd
commit ec7e4390e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 90 deletions

View File

@ -1,11 +1,8 @@
FROM python:3.5 FROM sanicframework/sanic:LTS
MAINTAINER Channel Cat <channelcat@gmail.com>
ADD . /code RUN mkdir /srv
RUN pip3 install git+https://github.com/channelcat/sanic COPY . /srv
EXPOSE 8000 WORKDIR /srv
WORKDIR /code CMD ["sanic", "simple_server.app"]
CMD ["python", "simple_server.py"]

View File

@ -1,86 +1,75 @@
'''
Based on example from https://github.com/Skyscanner/aiotask-context
and `examples/{override_logging,run_async}.py`.
Needs https://github.com/Skyscanner/aiotask-context/tree/52efbc21e2e1def2d52abb9a8e951f3ce5e6f690 or newer
$ pip install git+https://github.com/Skyscanner/aiotask-context.git
'''
import asyncio
import uuid
import logging import logging
from signal import signal, SIGINT
from sanic import Sanic
from sanic import response
import uvloop
import aiotask_context as context import aiotask_context as context
from sanic import Sanic, response
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class RequestIdFilter(logging.Filter): class RequestIdFilter(logging.Filter):
def filter(self, record): def filter(self, record):
record.request_id = context.get('X-Request-ID') try:
record.request_id = context.get("X-Request-ID")
except ValueError:
record.request_id = "n/a"
return True return True
LOG_SETTINGS = { LOG_SETTINGS = {
'version': 1, "version": 1,
'disable_existing_loggers': False, "disable_existing_loggers": False,
'handlers': { "handlers": {
'console': { "console": {
'class': 'logging.StreamHandler', "class": "logging.StreamHandler",
'level': 'DEBUG', "level": "DEBUG",
'formatter': 'default', "formatter": "default",
'filters': ['requestid'], "filters": ["requestid"],
}, },
}, },
'filters': { "filters": {
'requestid': { "requestid": {
'()': RequestIdFilter, "()": RequestIdFilter,
}, },
}, },
'formatters': { "formatters": {
'default': { "default": {
'format': '%(asctime)s %(levelname)s %(name)s:%(lineno)d %(request_id)s | %(message)s', "format": "%(asctime)s %(levelname)s %(name)s:%(lineno)d %(request_id)s | %(message)s",
}, },
}, },
'loggers': { "loggers": {
'': { "": {"level": "DEBUG", "handlers": ["console"], "propagate": True},
'level': 'DEBUG',
'handlers': ['console'],
'propagate': True
}, },
} }
}
app = Sanic(__name__, log_config=LOG_SETTINGS) app = Sanic(__name__, log_config=LOG_SETTINGS)
@app.middleware('request') @app.on_request
async def set_request_id(request): async def set_request_id(request):
request_id = request.headers.get('X-Request-ID') or str(uuid.uuid4()) request_id = request.id
context.set("X-Request-ID", request_id) context.set("X-Request-ID", request_id)
log.info(f"Setting {request.id=}")
@app.on_response
async def set_request_header(request, response):
response.headers["X-Request-ID"] = request.id
@app.route("/") @app.route("/")
async def test(request): async def test(request):
log.debug('X-Request-ID: %s', context.get('X-Request-ID')) log.debug("X-Request-ID: %s", context.get("X-Request-ID"))
log.info('Hello from test!') log.info("Hello from test!")
return response.json({"test": True}) return response.json({"test": True})
if __name__ == '__main__': @app.before_server_start
asyncio.set_event_loop(uvloop.new_event_loop()) def setup(app, loop):
server = app.create_server(host="0.0.0.0", port=8000, return_asyncio_server=True)
loop = asyncio.get_event_loop()
loop.set_task_factory(context.task_factory) loop.set_task_factory(context.task_factory)
task = asyncio.ensure_future(server)
try:
loop.run_forever() if __name__ == "__main__":
except: app.run(port=9999, debug=True)
loop.stop()

View File

@ -1,24 +1,23 @@
from sanic import Sanic
from sanic import response
import logging import logging
from sanic import Sanic, text
logging_format = "[%(asctime)s] %(process)d-%(levelname)s " logging_format = "[%(asctime)s] %(process)d-%(levelname)s "
logging_format += "%(module)s::%(funcName)s():l%(lineno)d: " logging_format += "%(module)s::%(funcName)s():l%(lineno)d: "
logging_format += "%(message)s" logging_format += "%(message)s"
logging.basicConfig( logging.basicConfig(format=logging_format, level=logging.DEBUG)
format=logging_format,
level=logging.DEBUG
)
log = logging.getLogger() log = logging.getLogger()
# Set logger to override default basicConfig # Set logger to override default basicConfig
sanic = Sanic() app = Sanic("app")
@sanic.route("/") @app.route("/")
def test(request): def test(request):
log.info("received request; responding with 'hey'") log.info("received request; responding with 'hey'")
return response.text("hey") return text("hey")
sanic.run(host="0.0.0.0", port=8000)
app.run(host="0.0.0.0", port=8000)

View File

@ -9,15 +9,19 @@ Run with xdist params:
$ pytest examples/pytest_xdist.py -n 8 # 8 workers $ pytest examples/pytest_xdist.py -n 8 # 8 workers
""" """
import re import re
import pytest
from sanic_testing import SanicTestClient
from sanic_testing.testing import PORT as PORT_BASE
from sanic import Sanic from sanic import Sanic
from sanic.response import text from sanic.response import text
from sanic.testing import PORT as PORT_BASE, SanicTestClient
import pytest
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def test_port(worker_id): def test_port(worker_id):
m = re.search(r'[0-9]+', worker_id) m = re.search(r"[0-9]+", worker_id)
if m: if m:
num_id = m.group(0) num_id = m.group(0)
else: else:
@ -30,9 +34,9 @@ def test_port(worker_id):
def app(): def app():
app = Sanic() app = Sanic()
@app.route('/') @app.route("/")
async def index(request): async def index(request):
return text('OK') return text("OK")
return app return app
@ -42,8 +46,8 @@ def client(app, test_port):
return SanicTestClient(app, test_port) return SanicTestClient(app, test_port)
@pytest.mark.parametrize('run_id', range(100)) @pytest.mark.parametrize("run_id", range(100))
def test_index(client, run_id): def test_index(client, run_id):
request, response = client._sanic_endpoint_test('get', '/') request, response = client._sanic_endpoint_test("get", "/")
assert response.status == 200 assert response.status == 200
assert response.text == 'OK' assert response.text == "OK"

View File

@ -1,39 +1,45 @@
from sanic import response from sanic import Sanic, response
from sanic import Sanic
from sanic.blueprints import Blueprint from sanic.blueprints import Blueprint
# Usage # Usage
# curl -H "Host: example.com" localhost:8000 # curl -H "Host: example.com" localhost:8000
# curl -H "Host: sub.example.com" localhost:8000 # curl -H "Host: sub.example.com" localhost:8000
# curl -H "Host: bp.example.com" localhost:8000/question # curl -H "Host: bp.example.com" localhost:8000/question
# curl -H "Host: bp.example.com" localhost:8000/answer # curl -H "Host: bp.example.com" localhost:8000/answer
app = Sanic() app = Sanic(__name__)
bp = Blueprint("bp", host="bp.example.com") bp = Blueprint("bp", host="bp.example.com")
@app.route('/', host=["example.com", @app.route(
"somethingelse.com", "/", host=["example.com", "somethingelse.com", "therestofyourdomains.com"]
"therestofyourdomains.com"]) )
async def hello(request): async def hello_0(request):
return response.text("Some defaults") return response.text("Some defaults")
@app.route('/', host="sub.example.com") @app.route("/", host="sub.example.com")
async def hello(request): async def hello_1(request):
return response.text("42") return response.text("42")
@bp.route("/question") @bp.route("/question")
async def hello(request): async def hello_2(request):
return response.text("What is the meaning of life?") return response.text("What is the meaning of life?")
@bp.route("/answer") @bp.route("/answer")
async def hello(request): async def hello_3(request):
return response.text("42") return response.text("42")
@app.get("/name")
def name(request):
return response.text(request.app.url_for("name", _external=True))
app.blueprint(bp) app.blueprint(bp)
if __name__ == '__main__': if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000) app.run(host="0.0.0.0", port=8000)

View File

@ -358,6 +358,28 @@ class Sanic(BaseSanic):
Keyword arguments that are not request parameters will be included in Keyword arguments that are not request parameters will be included in
the output URL's query string. the output URL's query string.
There are several _special_ keyword arguments that will alter how the
URL will be returned:
1. **_anchor**: ``str`` - Adds an ``#anchor`` to the end
2. **_scheme**: ``str`` - Should be either ``"http"`` or ``"https"``,
default is ``"http"``
3. **_external**: ``bool`` - Whether to return the path or a full URL
with scheme and host
4. **_host**: ``str`` - Used when one or more hosts are defined for a
route to tell Sanic which to use
(only applies with ``_external=True``)
5. **_server**: ``str`` - If not using ``_host``, this will be used
for defining the hostname of the URL
(only applies with ``_external=True``),
defaults to ``app.config.SERVER_NAME``
If you want the PORT to appear in your URL, you should set it in:
.. code-block::
app.config.SERVER_NAME = "myserver:7777"
`See user guide `See user guide
<https://sanicframework.org/guide/basics/routing.html#generating-a-url>`__ <https://sanicframework.org/guide/basics/routing.html#generating-a-url>`__