Fix examples to work as expected (#2305)

* Fix examples to work as expected

* Clean up examples

* Update worker test

* Merge in from main and cleanup example
This commit is contained in:
Adam Hopkins 2021-11-23 23:00:25 +02:00 committed by GitHub
parent 2c03eee329
commit 55c36e0240
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 267 additions and 174 deletions

View File

@ -4,12 +4,14 @@ import asyncio
from sanic import Sanic from sanic import Sanic
app = Sanic()
app = Sanic(__name__)
async def notify_server_started_after_five_seconds(): async def notify_server_started_after_five_seconds():
await asyncio.sleep(5) await asyncio.sleep(5)
print('Server successfully started!') print("Server successfully started!")
app.add_task(notify_server_started_after_five_seconds()) app.add_task(notify_server_started_after_five_seconds())

View File

@ -1,30 +1,29 @@
from sanic import Sanic
from sanic.response import text
from random import randint from random import randint
app = Sanic() from sanic import Sanic
from sanic.response import text
@app.middleware('request') app = Sanic(__name__)
@app.middleware("request")
def append_request(request): def append_request(request):
# Add new key with random value request.ctx.num = randint(0, 100)
request['num'] = randint(0, 100)
@app.get('/pop') @app.get("/pop")
def pop_handler(request): def pop_handler(request):
# Pop key from request object return text(request.ctx.num)
num = request.pop('num')
return text(num)
@app.get('/key_exist') @app.get("/key_exist")
def key_exist_handler(request): def key_exist_handler(request):
# Check the key is exist or not # Check the key is exist or not
if 'num' in request: if hasattr(request.ctx, "num"):
return text('num exist in request') return text("num exist in request")
return text('num does not exist in reqeust') return text("num does not exist in reqeust")
app.run(host="0.0.0.0", port=8000, debug=True) app.run(host="0.0.0.0", port=8000, debug=True)

View File

@ -1,10 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from sanic import Sanic
from functools import wraps from functools import wraps
from sanic import Sanic
from sanic.response import json from sanic.response import json
app = Sanic()
app = Sanic(__name__)
def check_request_for_authorization_status(request): def check_request_for_authorization_status(request):
@ -27,14 +29,16 @@ def authorized(f):
return response return response
else: else:
# the user is not authorized. # the user is not authorized.
return json({'status': 'not_authorized'}, 403) return json({"status": "not_authorized"}, 403)
return decorated_function return decorated_function
@app.route("/") @app.route("/")
@authorized @authorized
async def test(request): async def test(request):
return json({'status': 'authorized'}) return json({"status": "authorized"})
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

@ -1,43 +1,53 @@
from sanic import Sanic, Blueprint from sanic import Blueprint, Sanic
from sanic.response import text from sanic.response import text
'''
"""
Demonstrates that blueprint request middleware are executed in the order they Demonstrates that blueprint request middleware are executed in the order they
are added. And blueprint response middleware are executed in _reverse_ order. are added. And blueprint response middleware are executed in _reverse_ order.
On a valid request, it should print "1 2 3 6 5 4" to terminal On a valid request, it should print "1 2 3 6 5 4" to terminal
''' """
app = Sanic(__name__) app = Sanic(__name__)
bp = Blueprint("bp_"+__name__) bp = Blueprint("bp_" + __name__)
@bp.middleware('request')
@bp.on_request
def request_middleware_1(request): def request_middleware_1(request):
print('1') print("1")
@bp.middleware('request')
@bp.on_request
def request_middleware_2(request): def request_middleware_2(request):
print('2') print("2")
@bp.middleware('request')
@bp.on_request
def request_middleware_3(request): def request_middleware_3(request):
print('3') print("3")
@bp.middleware('response')
@bp.on_response
def resp_middleware_4(request, response): def resp_middleware_4(request, response):
print('4') print("4")
@bp.middleware('response')
@bp.on_response
def resp_middleware_5(request, response): def resp_middleware_5(request, response):
print('5') print("5")
@bp.middleware('response')
@bp.on_response
def resp_middleware_6(request, response): def resp_middleware_6(request, response):
print('6') print("6")
@bp.route('/')
@bp.route("/")
def pop_handler(request): def pop_handler(request):
return text('hello world') return text("hello world")
app.blueprint(bp, url_prefix='/bp')
app.blueprint(bp, url_prefix="/bp")
app.run(host="0.0.0.0", port=8000, debug=True, auto_reload=False) app.run(host="0.0.0.0", port=8000, debug=True, auto_reload=False)

View File

@ -1,6 +1,7 @@
from sanic import Blueprint, Sanic from sanic import Blueprint, Sanic
from sanic.response import file, json from sanic.response import file, json
app = Sanic(__name__) app = Sanic(__name__)
blueprint = Blueprint("name", url_prefix="/my_blueprint") blueprint = Blueprint("name", url_prefix="/my_blueprint")
blueprint2 = Blueprint("name2", url_prefix="/my_blueprint2") blueprint2 = Blueprint("name2", url_prefix="/my_blueprint2")

View File

@ -2,17 +2,20 @@ from asyncio import sleep
from sanic import Sanic, response from sanic import Sanic, response
app = Sanic(__name__, strict_slashes=True) app = Sanic(__name__, strict_slashes=True)
@app.get("/") @app.get("/")
async def handler(request): async def handler(request):
return response.redirect("/sleep/3") return response.redirect("/sleep/3")
@app.get("/sleep/<t:number>") @app.get("/sleep/<t:number>")
async def handler2(request, t=0.3): async def handler2(request, t=0.3):
await sleep(t) await sleep(t)
return response.text(f"Slept {t:.1f} seconds.\n") return response.text(f"Slept {t:.1f} seconds.\n")
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

@ -7,8 +7,10 @@ and pass in an instance of it when we create our Sanic instance. Inside this
class' default handler, we can do anything including sending exceptions to class' default handler, we can do anything including sending exceptions to
an external service. an external service.
""" """
from sanic.handlers import ErrorHandler
from sanic.exceptions import SanicException from sanic.exceptions import SanicException
from sanic.handlers import ErrorHandler
""" """
Imports and code relevant for our CustomHandler class Imports and code relevant for our CustomHandler class
(Ordinarily this would be in a separate file) (Ordinarily this would be in a separate file)
@ -16,7 +18,6 @@ Imports and code relevant for our CustomHandler class
class CustomHandler(ErrorHandler): class CustomHandler(ErrorHandler):
def default(self, request, exception): def default(self, request, exception):
# Here, we have access to the exception object # Here, we have access to the exception object
# and can do anything with it (log, send to external service, etc) # and can do anything with it (log, send to external service, etc)
@ -38,17 +39,17 @@ server's error_handler to an instance of our CustomHandler
from sanic import Sanic from sanic import Sanic
app = Sanic(__name__)
handler = CustomHandler() handler = CustomHandler()
app.error_handler = handler app = Sanic(__name__, error_handler=handler)
@app.route("/") @app.route("/")
async def test(request): async def test(request):
# Here, something occurs which causes an unexpected exception # Here, something occurs which causes an unexpected exception
# This exception will flow to our custom handler. # This exception will flow to our custom handler.
raise SanicException('You Broke It!') raise SanicException("You Broke It!")
if __name__ == '__main__':
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True) app.run(host="0.0.0.0", port=8000, debug=True)

View File

@ -1,4 +1,6 @@
from sanic import Sanic, response, text from sanic import Sanic, response, text
from sanic.handlers import ErrorHandler
from sanic.server.async_server import AsyncioServer
HTTP_PORT = 9999 HTTP_PORT = 9999
@ -32,20 +34,40 @@ def proxy(request, path):
return response.redirect(url) return response.redirect(url)
@https.listener("main_process_start") @https.main_process_start
async def start(app, _): async def start(app, _):
global http http_server = await http.create_server(
app.http_server = await http.create_server(
port=HTTP_PORT, return_asyncio_server=True port=HTTP_PORT, return_asyncio_server=True
) )
app.http_server.after_start() app.add_task(runner(http, http_server))
app.ctx.http_server = http_server
app.ctx.http = http
@https.listener("main_process_stop") @https.main_process_stop
async def stop(app, _): async def stop(app, _):
app.http_server.before_stop() await app.ctx.http_server.before_stop()
await app.http_server.close() await app.ctx.http_server.close()
app.http_server.after_stop() for connection in app.ctx.http_server.connections:
connection.close_if_idle()
await app.ctx.http_server.after_stop()
app.ctx.http = False
async def runner(app: Sanic, app_server: AsyncioServer):
app.is_running = True
try:
app.signalize()
app.finalize()
ErrorHandler.finalize(app.error_handler)
app_server.init = True
await app_server.before_start()
await app_server.after_start()
await app_server.serve_forever()
finally:
app.is_running = False
app.is_stopping = True
https.run(port=HTTPS_PORT, debug=True) https.run(port=HTTPS_PORT, debug=True)

View File

@ -1,26 +1,30 @@
import asyncio
import httpx
from sanic import Sanic from sanic import Sanic
from sanic.response import json from sanic.response import json
import asyncio
import aiohttp
app = Sanic(__name__) app = Sanic(__name__)
sem = None sem = None
@app.listener('before_server_start') @app.before_server_start
def init(sanic, loop): def init(sanic, _):
global sem global sem
concurrency_per_worker = 4 concurrency_per_worker = 4
sem = asyncio.Semaphore(concurrency_per_worker, loop=loop) sem = asyncio.Semaphore(concurrency_per_worker)
async def bounded_fetch(session, url): async def bounded_fetch(session, url):
""" """
Use session object to perform 'get' request on url Use session object to perform 'get' request on url
""" """
async with sem, session.get(url) as response: async with sem:
return await response.json() response = await session.get(url)
return response.json()
@app.route("/") @app.route("/")
@ -28,9 +32,9 @@ async def test(request):
""" """
Download and serve example JSON Download and serve example JSON
""" """
url = "https://api.github.com/repos/channelcat/sanic" url = "https://api.github.com/repos/sanic-org/sanic"
async with aiohttp.ClientSession() as session: async with httpx.AsyncClient() as session:
response = await bounded_fetch(session, url) response = await bounded_fetch(session, url)
return json(response) return json(response)

View File

@ -1,6 +1,6 @@
import logging import logging
import aiotask_context as context from contextvars import ContextVar
from sanic import Sanic, response from sanic import Sanic, response
@ -11,8 +11,8 @@ log = logging.getLogger(__name__)
class RequestIdFilter(logging.Filter): class RequestIdFilter(logging.Filter):
def filter(self, record): def filter(self, record):
try: try:
record.request_id = context.get("X-Request-ID") record.request_id = app.ctx.request_id.get(None) or "n/a"
except ValueError: except AttributeError:
record.request_id = "n/a" record.request_id = "n/a"
return True return True
@ -49,8 +49,7 @@ app = Sanic(__name__, log_config=LOG_SETTINGS)
@app.on_request @app.on_request
async def set_request_id(request): async def set_request_id(request):
request_id = request.id request.app.ctx.request_id.set(request.id)
context.set("X-Request-ID", request_id)
log.info(f"Setting {request.id=}") log.info(f"Setting {request.id=}")
@ -61,14 +60,14 @@ async def set_request_header(request, response):
@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", request.id)
log.info("Hello from test!") log.info("Hello from test!")
return response.json({"test": True}) return response.json({"test": True})
@app.before_server_start @app.before_server_start
def setup(app, loop): def setup(app, loop):
loop.set_task_factory(context.task_factory) app.ctx.request_id = ContextVar("request_id")
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1,5 +1,6 @@
import logging import logging
import socket import socket
from os import getenv from os import getenv
from platform import node from platform import node
from uuid import getnode as get_mac from uuid import getnode as get_mac
@ -7,10 +8,11 @@ from uuid import getnode as get_mac
from logdna import LogDNAHandler from logdna import LogDNAHandler
from sanic import Sanic from sanic import Sanic
from sanic.response import json
from sanic.request import Request from sanic.request import Request
from sanic.response import json
log = logging.getLogger('logdna')
log = logging.getLogger("logdna")
log.setLevel(logging.INFO) log.setLevel(logging.INFO)
@ -30,10 +32,12 @@ logdna_options = {
"index_meta": True, "index_meta": True,
"hostname": node(), "hostname": node(),
"ip": get_my_ip_address(), "ip": get_my_ip_address(),
"mac": get_mac_address() "mac": get_mac_address(),
} }
logdna_handler = LogDNAHandler(getenv("LOGDNA_API_KEY"), options=logdna_options) logdna_handler = LogDNAHandler(
getenv("LOGDNA_API_KEY"), options=logdna_options
)
logdna = logging.getLogger(__name__) logdna = logging.getLogger(__name__)
logdna.setLevel(logging.INFO) logdna.setLevel(logging.INFO)
@ -49,13 +53,8 @@ def log_request(request: Request):
@app.route("/") @app.route("/")
def default(request): def default(request):
return json({ return json({"response": "I was here"})
"response": "I was here"
})
if __name__ == "__main__": if __name__ == "__main__":
app.run( app.run(host="0.0.0.0", port=getenv("PORT", 8080))
host="0.0.0.0",
port=getenv("PORT", 8080)
)

View File

@ -59,31 +59,31 @@ async def handler_stream(request):
return response.stream(body) return response.stream(body)
@app.listener("before_server_start") @app.before_server_start
async def listener_before_server_start(*args, **kwargs): async def listener_before_server_start(*args, **kwargs):
print("before_server_start") print("before_server_start")
@app.listener("after_server_start") @app.after_server_start
async def listener_after_server_start(*args, **kwargs): async def listener_after_server_start(*args, **kwargs):
print("after_server_start") print("after_server_start")
@app.listener("before_server_stop") @app.before_server_stop
async def listener_before_server_stop(*args, **kwargs): async def listener_before_server_stop(*args, **kwargs):
print("before_server_stop") print("before_server_stop")
@app.listener("after_server_stop") @app.after_server_stop
async def listener_after_server_stop(*args, **kwargs): async def listener_after_server_stop(*args, **kwargs):
print("after_server_stop") print("after_server_stop")
@app.middleware("request") @app.on_request
async def print_on_request(request): async def print_on_request(request):
print("print_on_request") print("print_on_request")
@app.middleware("response") @app.on_response
async def print_on_response(request, response): async def print_on_response(request, response):
print("print_on_response") print("print_on_response")

View File

@ -1,9 +1,12 @@
from sanic import Sanic
from sanic import response
from signal import signal, SIGINT
import asyncio import asyncio
from signal import SIGINT, signal
import uvloop import uvloop
from sanic import Sanic, response
app = Sanic(__name__) app = Sanic(__name__)
@ -11,12 +14,18 @@ app = Sanic(__name__)
async def test(request): async def test(request):
return response.json({"answer": "42"}) return response.json({"answer": "42"})
asyncio.set_event_loop(uvloop.new_event_loop()) asyncio.set_event_loop(uvloop.new_event_loop())
server = app.create_server(host="0.0.0.0", port=8000, return_asyncio_server=True) server = app.create_server(
host="0.0.0.0", port=8000, return_asyncio_server=True
)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
task = asyncio.ensure_future(server) task = asyncio.ensure_future(server)
server = loop.run_until_complete(task)
loop.run_until_complete(server.startup())
signal(SIGINT, lambda s, f: loop.stop()) signal(SIGINT, lambda s, f: loop.stop())
try: try:
loop.run_forever() loop.run_forever()
except: finally:
loop.stop() loop.stop()

View File

@ -11,9 +11,24 @@ from sanic.server import AsyncioServer
app = Sanic(__name__) app = Sanic(__name__)
@app.listener("after_server_start") @app.before_server_start
async def after_start_test(app, loop): async def before_server_start(app, loop):
print("Async Server Started!") print("Async Server starting")
@app.after_server_start
async def after_server_start(app, loop):
print("Async Server started")
@app.before_server_stop
async def before_server_stop(app, loop):
print("Async Server stopping")
@app.after_server_stop
async def after_server_stop(app, loop):
print("Async Server stopped")
@app.route("/") @app.route("/")
@ -28,20 +43,20 @@ serv_coro = app.create_server(
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
serv_task = asyncio.ensure_future(serv_coro, loop=loop) serv_task = asyncio.ensure_future(serv_coro, loop=loop)
signal(SIGINT, lambda s, f: loop.stop()) signal(SIGINT, lambda s, f: loop.stop())
server: AsyncioServer = loop.run_until_complete(serv_task) # type: ignore server: AsyncioServer = loop.run_until_complete(serv_task)
server.startup() loop.run_until_complete(server.startup())
# When using app.run(), this actually triggers before the serv_coro. # When using app.run(), this actually triggers before the serv_coro.
# But, in this example, we are using the convenience method, even if it is # But, in this example, we are using the convenience method, even if it is
# out of order. # out of order.
server.before_start() loop.run_until_complete(server.before_start())
server.after_start() loop.run_until_complete(server.after_start())
try: try:
loop.run_forever() loop.run_forever()
except KeyboardInterrupt: except KeyboardInterrupt:
loop.stop() loop.stop()
finally: finally:
server.before_stop() loop.run_until_complete(server.before_stop())
# Wait for server to close # Wait for server to close
close_task = server.close() close_task = server.close()
@ -50,4 +65,4 @@ finally:
# Complete all tasks on the loop # Complete all tasks on the loop
for connection in server.connections: for connection in server.connections:
connection.close_if_idle() connection.close_if_idle()
server.after_stop() loop.run_until_complete(server.after_stop())

View File

@ -1,42 +1,41 @@
from sanic import Sanic from sanic import Sanic
from sanic.views import HTTPMethodView
from sanic.response import text from sanic.response import text
from sanic.views import HTTPMethodView
app = Sanic('some_name')
app = Sanic("some_name")
class SimpleView(HTTPMethodView): class SimpleView(HTTPMethodView):
def get(self, request): def get(self, request):
return text('I am get method') return text("I am get method")
def post(self, request): def post(self, request):
return text('I am post method') return text("I am post method")
def put(self, request): def put(self, request):
return text('I am put method') return text("I am put method")
def patch(self, request): def patch(self, request):
return text('I am patch method') return text("I am patch method")
def delete(self, request): def delete(self, request):
return text('I am delete method') return text("I am delete method")
class SimpleAsyncView(HTTPMethodView): class SimpleAsyncView(HTTPMethodView):
async def get(self, request): async def get(self, request):
return text('I am async get method') return text("I am async get method")
async def post(self, request): async def post(self, request):
return text('I am async post method') return text("I am async post method")
async def put(self, request): async def put(self, request):
return text('I am async put method') return text("I am async put method")
app.add_route(SimpleView.as_view(), '/') app.add_route(SimpleView.as_view(), "/")
app.add_route(SimpleAsyncView.as_view(), '/async') app.add_route(SimpleAsyncView.as_view(), "/async")
if __name__ == '__main__': if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True) app.run(host="0.0.0.0", port=8000, debug=True)

View File

@ -1,9 +1,9 @@
import os import os
from sanic import Sanic from sanic import Sanic, response
from sanic.log import logger as log
from sanic import response
from sanic.exceptions import ServerError from sanic.exceptions import ServerError
from sanic.log import logger as log
app = Sanic(__name__) app = Sanic(__name__)
@ -13,7 +13,7 @@ async def test_async(request):
return response.json({"test": True}) return response.json({"test": True})
@app.route("/sync", methods=['GET', 'POST']) @app.route("/sync", methods=["GET", "POST"])
def test_sync(request): def test_sync(request):
return response.json({"test": True}) return response.json({"test": True})
@ -31,6 +31,7 @@ def exception(request):
@app.route("/await") @app.route("/await")
async def test_await(request): async def test_await(request):
import asyncio import asyncio
await asyncio.sleep(5) await asyncio.sleep(5)
return response.text("I'm feeling sleepy") return response.text("I'm feeling sleepy")
@ -42,8 +43,10 @@ async def test_file(request):
@app.route("/file_stream") @app.route("/file_stream")
async def test_file_stream(request): async def test_file_stream(request):
return await response.file_stream(os.path.abspath("setup.py"), return await response.file_stream(
chunk_size=1024) os.path.abspath("setup.py"), chunk_size=1024
)
# ----------------------------------------------- # # ----------------------------------------------- #
# Exceptions # Exceptions
@ -52,14 +55,17 @@ async def test_file_stream(request):
@app.exception(ServerError) @app.exception(ServerError)
async def test(request, exception): async def test(request, exception):
return response.json({"exception": "{}".format(exception), "status": exception.status_code}, return response.json(
status=exception.status_code) {"exception": str(exception), "status": exception.status_code},
status=exception.status_code,
)
# ----------------------------------------------- # # ----------------------------------------------- #
# Read from request # Read from request
# ----------------------------------------------- # # ----------------------------------------------- #
@app.route("/json") @app.route("/json")
def post_json(request): def post_json(request):
return response.json({"received": True, "message": request.json}) return response.json({"received": True, "message": request.json})
@ -67,38 +73,51 @@ def post_json(request):
@app.route("/form") @app.route("/form")
def post_form_json(request): def post_form_json(request):
return response.json({"received": True, "form_data": request.form, "test": request.form.get('test')}) return response.json(
{
"received": True,
"form_data": request.form,
"test": request.form.get("test"),
}
)
@app.route("/query_string") @app.route("/query_string")
def query_string(request): def query_string(request):
return response.json({"parsed": True, "args": request.args, "url": request.url, return response.json(
"query_string": request.query_string}) {
"parsed": True,
"args": request.args,
"url": request.url,
"query_string": request.query_string,
}
)
# ----------------------------------------------- # # ----------------------------------------------- #
# Run Server # Run Server
# ----------------------------------------------- # # ----------------------------------------------- #
@app.listener('before_server_start')
@app.before_server_start
def before_start(app, loop): def before_start(app, loop):
log.info("SERVER STARTING") log.info("SERVER STARTING")
@app.listener('after_server_start') @app.after_server_start
def after_start(app, loop): def after_start(app, loop):
log.info("OH OH OH OH OHHHHHHHH") log.info("OH OH OH OH OHHHHHHHH")
@app.listener('before_server_stop') @app.before_server_stop
def before_stop(app, loop): def before_stop(app, loop):
log.info("SERVER STOPPING") log.info("SERVER STOPPING")
@app.listener('after_server_stop') @app.after_server_stop
def after_stop(app, loop): def after_stop(app, loop):
log.info("TRIED EVERYTHING") log.info("TRIED EVERYTHING")
if __name__ == '__main__': if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True) app.run(host="0.0.0.0", port=8000, debug=True)

View File

@ -1,7 +1,8 @@
from sanic import Sanic
from sanic import response
import socket
import os import os
import socket
from sanic import Sanic, response
app = Sanic(__name__) app = Sanic(__name__)
@ -10,8 +11,9 @@ app = Sanic(__name__)
async def test(request): async def test(request):
return response.text("OK") return response.text("OK")
if __name__ == '__main__':
server_address = './uds_socket' if __name__ == "__main__":
server_address = "./uds_socket"
# Make sure the socket does not already exist # Make sure the socket does not already exist
try: try:
os.unlink(server_address) os.unlink(server_address)

View File

@ -1,20 +1,21 @@
from sanic import Sanic from sanic import Sanic, response
from sanic import response
app = Sanic(__name__) app = Sanic(__name__)
@app.route('/') @app.route("/")
async def index(request): async def index(request):
# generate a URL for the endpoint `post_handler` # generate a URL for the endpoint `post_handler`
url = app.url_for('post_handler', post_id=5) url = app.url_for("post_handler", post_id=5)
# the URL is `/posts/5`, redirect to it # the URL is `/posts/5`, redirect to it
return response.redirect(url) return response.redirect(url)
@app.route('/posts/<post_id>') @app.route("/posts/<post_id>")
async def post_handler(request, post_id): async def post_handler(request, post_id):
return response.text('Post - {}'.format(post_id)) return response.text("Post - {}".format(post_id))
if __name__ == '__main__':
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True) app.run(host="0.0.0.0", port=8000, debug=True)

View File

@ -8,7 +8,9 @@ app = Sanic(name="blue-print-group-version-example")
bp1 = Blueprint(name="ultron", url_prefix="/ultron") bp1 = Blueprint(name="ultron", url_prefix="/ultron")
bp2 = Blueprint(name="vision", url_prefix="/vision", strict_slashes=None) bp2 = Blueprint(name="vision", url_prefix="/vision", strict_slashes=None)
bpg = Blueprint.group([bp1, bp2], url_prefix="/sentient/robot", version=1, strict_slashes=True) bpg = Blueprint.group(
bp1, bp2, url_prefix="/sentient/robot", version=1, strict_slashes=True
)
@bp1.get("/name") @bp1.get("/name")
@ -31,5 +33,5 @@ async def bp2_revised_name(request):
app.blueprint(bpg) app.blueprint(bpg)
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

@ -1,25 +1,27 @@
from sanic import Sanic from sanic import Sanic
from sanic.response import redirect from sanic.response import redirect
app = Sanic(__name__) app = Sanic(__name__)
app.static('index.html', "websocket.html") app.static("index.html", "websocket.html")
@app.route('/')
@app.route("/")
def index(request): def index(request):
return redirect("index.html") return redirect("index.html")
@app.websocket('/feed')
@app.websocket("/feed")
async def feed(request, ws): async def feed(request, ws):
while True: while True:
data = 'hello!' data = "hello!"
print('Sending: ' + data) print("Sending: " + data)
await ws.send(data) await ws.send(data)
data = await ws.recv() data = await ws.recv()
print('Received: ' + data) print("Received: " + data)
if __name__ == '__main__': if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True) app.run(host="0.0.0.0", port=8000, debug=True)

View File

@ -52,7 +52,7 @@ class RouteMixin:
self, self,
uri: str, uri: str,
methods: Optional[Iterable[str]] = None, methods: Optional[Iterable[str]] = None,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
stream: bool = False, stream: bool = False,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
@ -189,7 +189,7 @@ class RouteMixin:
handler: RouteHandler, handler: RouteHandler,
uri: str, uri: str,
methods: Iterable[str] = frozenset({"GET"}), methods: Iterable[str] = frozenset({"GET"}),
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
name: Optional[str] = None, name: Optional[str] = None,
@ -254,7 +254,7 @@ class RouteMixin:
def get( def get(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
name: Optional[str] = None, name: Optional[str] = None,
@ -290,7 +290,7 @@ class RouteMixin:
def post( def post(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
stream: bool = False, stream: bool = False,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
@ -326,7 +326,7 @@ class RouteMixin:
def put( def put(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
stream: bool = False, stream: bool = False,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
@ -362,7 +362,7 @@ class RouteMixin:
def head( def head(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
name: Optional[str] = None, name: Optional[str] = None,
@ -406,7 +406,7 @@ class RouteMixin:
def options( def options(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
name: Optional[str] = None, name: Optional[str] = None,
@ -450,7 +450,7 @@ class RouteMixin:
def patch( def patch(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
stream=False, stream=False,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
@ -496,7 +496,7 @@ class RouteMixin:
def delete( def delete(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
name: Optional[str] = None, name: Optional[str] = None,
@ -532,7 +532,7 @@ class RouteMixin:
def websocket( def websocket(
self, self,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
subprotocols: Optional[List[str]] = None, subprotocols: Optional[List[str]] = None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,
@ -573,7 +573,7 @@ class RouteMixin:
self, self,
handler, handler,
uri: str, uri: str,
host: Optional[str] = None, host: Optional[Union[str, List[str]]] = None,
strict_slashes: Optional[bool] = None, strict_slashes: Optional[bool] = None,
subprotocols=None, subprotocols=None,
version: Optional[Union[int, str, float]] = None, version: Optional[Union[int, str, float]] = None,

View File

@ -13,7 +13,7 @@ class FutureRoute(NamedTuple):
handler: str handler: str
uri: str uri: str
methods: Optional[Iterable[str]] methods: Optional[Iterable[str]]
host: str host: Union[str, List[str]]
strict_slashes: bool strict_slashes: bool
stream: bool stream: bool
version: Optional[int] version: Optional[int]

View File

@ -21,7 +21,7 @@ def gunicorn_worker():
"gunicorn " "gunicorn "
f"--bind 127.0.0.1:{PORT} " f"--bind 127.0.0.1:{PORT} "
"--worker-class sanic.worker.GunicornWorker " "--worker-class sanic.worker.GunicornWorker "
"examples.simple_server:app" "examples.hello_world:app"
) )
worker = subprocess.Popen(shlex.split(command)) worker = subprocess.Popen(shlex.split(command))
time.sleep(2) time.sleep(2)
@ -35,7 +35,7 @@ def gunicorn_worker_with_access_logs():
"gunicorn " "gunicorn "
f"--bind 127.0.0.1:{PORT + 1} " f"--bind 127.0.0.1:{PORT + 1} "
"--worker-class sanic.worker.GunicornWorker " "--worker-class sanic.worker.GunicornWorker "
"examples.simple_server:app" "examples.hello_world:app"
) )
worker = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE) worker = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
time.sleep(2) time.sleep(2)
@ -50,7 +50,7 @@ def gunicorn_worker_with_env_var():
f"--bind 127.0.0.1:{PORT + 2} " f"--bind 127.0.0.1:{PORT + 2} "
"--worker-class sanic.worker.GunicornWorker " "--worker-class sanic.worker.GunicornWorker "
"--log-level info " "--log-level info "
"examples.simple_server:app" "examples.hello_world:app"
) )
worker = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE) worker = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
time.sleep(2) time.sleep(2)