commit
28bd09a2ea
|
@ -1,5 +1,5 @@
|
|||
from sanic import Sanic
|
||||
from sanic.response import json
|
||||
from sanic import response
|
||||
|
||||
import aiohttp
|
||||
|
||||
|
@ -9,20 +9,18 @@ async def fetch(session, url):
|
|||
"""
|
||||
Use session object to perform 'get' request on url
|
||||
"""
|
||||
async with session.get(url) as response:
|
||||
return await response.json()
|
||||
async with session.get(url) as result:
|
||||
return await result.json()
|
||||
|
||||
|
||||
@app.route("/")
|
||||
async def test(request):
|
||||
"""
|
||||
Download and serve example JSON
|
||||
"""
|
||||
@app.route('/')
|
||||
async def handle_request(request):
|
||||
url = "https://api.github.com/repos/channelcat/sanic"
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
response = await fetch(session, url)
|
||||
return json(response)
|
||||
result = await fetch(session, url)
|
||||
return response.json(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="0.0.0.0", port=8000, workers=2)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
"""
|
||||
Example intercepting uncaught exceptions using Sanic's error handler framework.
|
||||
|
||||
This may be useful for developers wishing to use Sentry, Airbrake, etc.
|
||||
or a custom system to log and monitor unexpected errors in production.
|
||||
|
||||
First we create our own class inheriting from Handler in sanic.exceptions,
|
||||
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
|
||||
|
@ -39,7 +37,7 @@ server's error_handler to an instance of our CustomHandler
|
|||
"""
|
||||
|
||||
from sanic import Sanic
|
||||
from sanic.response import json
|
||||
from sanic import response
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
|
@ -52,7 +50,7 @@ async def test(request):
|
|||
# Here, something occurs which causes an unexpected exception
|
||||
# This exception will flow to our custom handler.
|
||||
1 / 0
|
||||
return json({"test": True})
|
||||
return response.json({"test": True})
|
||||
|
||||
|
||||
app.run(host="0.0.0.0", port=8000, debug=True)
|
|
@ -2,7 +2,7 @@
|
|||
# curl -d '{"name": "John Doe"}' localhost:8000
|
||||
|
||||
from sanic import Sanic
|
||||
from sanic.response import html
|
||||
from sanic import response
|
||||
from jinja2 import Template
|
||||
|
||||
template = Template('Hello {{ name }}!')
|
||||
|
@ -12,7 +12,7 @@ app = Sanic(__name__)
|
|||
@app.route('/')
|
||||
async def test(request):
|
||||
data = request.json
|
||||
return html(template.render(**data))
|
||||
return response.html(template.render(**data))
|
||||
|
||||
|
||||
app.run(host="0.0.0.0", port=8000)
|
||||
app.run(host="0.0.0.0", port=8080, debug=True)
|
26
examples/modify_header_example.py
Normal file
26
examples/modify_header_example.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
Modify header or status in response
|
||||
"""
|
||||
|
||||
from sanic import Sanic
|
||||
from sanic import response
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
@app.route('/')
|
||||
def handle_request(request):
|
||||
return response.json(
|
||||
{'message': 'Hello world!'},
|
||||
headers={'X-Served-By': 'sanic'},
|
||||
status=200
|
||||
)
|
||||
|
||||
@app.route('/unauthorized')
|
||||
def handle_request(request):
|
||||
return response.json(
|
||||
{'message': 'You are not authorized'},
|
||||
headers={'X-Served-By': 'sanic'},
|
||||
status=404
|
||||
)
|
||||
|
||||
app.run(host="0.0.0.0", port=8000, debug=True)
|
|
@ -1,6 +1,5 @@
|
|||
from sanic import Sanic
|
||||
from sanic.response import text
|
||||
import json
|
||||
from sanic import response
|
||||
import logging
|
||||
|
||||
logging_format = "[%(asctime)s] %(process)d-%(levelname)s "
|
||||
|
@ -18,6 +17,6 @@ sanic = Sanic()
|
|||
@sanic.route("/")
|
||||
def test(request):
|
||||
log.info("received request; responding with 'hey'")
|
||||
return text("hey")
|
||||
return response.text("hey")
|
||||
|
||||
sanic.run(host="0.0.0.0", port=8000)
|
||||
|
|
85
examples/plotly_example/plotlyjs_example.py
Normal file
85
examples/plotly_example/plotlyjs_example.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
from sanic import Sanic
|
||||
|
||||
from sanic_session import InMemorySessionInterface
|
||||
from sanic_jinja2 import SanicJinja2
|
||||
|
||||
import json
|
||||
import plotly
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
jinja = SanicJinja2(app)
|
||||
session = InMemorySessionInterface(cookie_name=app.name, prefix=app.name)
|
||||
|
||||
@app.middleware('request')
|
||||
async def print_on_request(request):
|
||||
print(request.headers)
|
||||
await session.open(request)
|
||||
|
||||
@app.middleware('response')
|
||||
async def print_on_response(request, response):
|
||||
await session.save(request, response)
|
||||
|
||||
|
||||
|
||||
@app.route('/')
|
||||
async def index(request):
|
||||
rng = pd.date_range('1/1/2011', periods=7500, freq='H')
|
||||
ts = pd.Series(np.random.randn(len(rng)), index=rng)
|
||||
|
||||
graphs = [
|
||||
dict(
|
||||
data=[
|
||||
dict(
|
||||
x=[1, 2, 3],
|
||||
y=[10, 20, 30],
|
||||
type='scatter'
|
||||
),
|
||||
],
|
||||
layout=dict(
|
||||
title='first graph'
|
||||
)
|
||||
),
|
||||
|
||||
dict(
|
||||
data=[
|
||||
dict(
|
||||
x=[1, 3, 5],
|
||||
y=[10, 50, 30],
|
||||
type='bar'
|
||||
),
|
||||
],
|
||||
layout=dict(
|
||||
title='second graph'
|
||||
)
|
||||
),
|
||||
|
||||
dict(
|
||||
data=[
|
||||
dict(
|
||||
x=ts.index, # Can use the pandas data structures directly
|
||||
y=ts
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
# Add "ids" to each of the graphs to pass up to the client
|
||||
# for templating
|
||||
ids = ['graph-{}'.format(i) for i, _ in enumerate(graphs)]
|
||||
|
||||
# Convert the figures to JSON
|
||||
# PlotlyJSONEncoder appropriately converts pandas, datetime, etc
|
||||
# objects to their JSON equivalents
|
||||
graphJSON = json.dumps(graphs, cls=plotly.utils.PlotlyJSONEncoder)
|
||||
|
||||
return jinja.render('index.html', request,
|
||||
ids=ids,
|
||||
graphJSON=graphJSON)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=8000, debug=True)
|
5
examples/plotly_example/requirements.txt
Normal file
5
examples/plotly_example/requirements.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
pandas==0.19.2
|
||||
plotly==2.0.7
|
||||
sanic==0.5.0
|
||||
sanic-jinja2==0.5.1
|
||||
sanic-session==0.1.3
|
0
examples/plotly_example/templates/index.html
Normal file
0
examples/plotly_example/templates/index.html
Normal file
17
examples/redirect_example.py
Normal file
17
examples/redirect_example.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from sanic import Sanic
|
||||
from sanic import response
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def handle_request(request):
|
||||
return response.redirect('/redirect')
|
||||
|
||||
@app.route('/redirect')
|
||||
async def test(request):
|
||||
return response.json({"Redirected": True})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="0.0.0.0", port=8000)
|
|
@ -1,6 +1,6 @@
|
|||
from sanic import Sanic
|
||||
import asyncio
|
||||
from sanic.response import text
|
||||
from sanic import Sanic
|
||||
from sanic import response
|
||||
from sanic.config import Config
|
||||
from sanic.exceptions import RequestTimeout
|
||||
|
||||
|
@ -11,11 +11,11 @@ app = Sanic(__name__)
|
|||
@app.route('/')
|
||||
async def test(request):
|
||||
await asyncio.sleep(3)
|
||||
return text('Hello, world!')
|
||||
return response.text('Hello, world!')
|
||||
|
||||
|
||||
@app.exception(RequestTimeout)
|
||||
def timeout(request, exception):
|
||||
return text('RequestTimeout from error_handler.', 408)
|
||||
return response.text('RequestTimeout from error_handler.', 408)
|
||||
|
||||
app.run(host='0.0.0.0', port=8000)
|
|
@ -1,5 +1,5 @@
|
|||
from sanic import Sanic
|
||||
from sanic.response import json
|
||||
from sanic import response
|
||||
from multiprocessing import Event
|
||||
from signal import signal, SIGINT
|
||||
import asyncio
|
||||
|
@ -9,10 +9,10 @@ app = Sanic(__name__)
|
|||
|
||||
@app.route("/")
|
||||
async def test(request):
|
||||
return json({"answer": "42"})
|
||||
return response.json({"answer": "42"})
|
||||
|
||||
asyncio.set_event_loop(uvloop.new_event_loop())
|
||||
server = app.create_server(host="0.0.0.0", port=8001)
|
||||
server = app.create_server(host="0.0.0.0", port=8000)
|
||||
loop = asyncio.get_event_loop()
|
||||
task = asyncio.ensure_future(server)
|
||||
signal(SIGINT, lambda s, f: loop.stop())
|
||||
|
|
|
@ -5,7 +5,7 @@ motor==1.1
|
|||
sanic==0.2.0
|
||||
"""
|
||||
from sanic import Sanic
|
||||
from sanic.response import json
|
||||
from sanic import response
|
||||
|
||||
|
||||
app = Sanic('motor_mongodb')
|
||||
|
@ -25,7 +25,7 @@ async def get(request):
|
|||
for doc in docs:
|
||||
doc['id'] = str(doc['_id'])
|
||||
del doc['_id']
|
||||
return json(docs)
|
||||
return response.json(docs)
|
||||
|
||||
|
||||
@app.route('/post', methods=['POST'])
|
||||
|
@ -34,8 +34,8 @@ async def new(request):
|
|||
print(doc)
|
||||
db = get_db()
|
||||
object_id = await db.test_col.save(doc)
|
||||
return json({'object_id': str(object_id)})
|
||||
return response.json({'object_id': str(object_id)})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='127.0.0.1', port=8000)
|
||||
app.run(host='0.0.0.0', port=8000, debug=True)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from sanic import Sanic
|
||||
from sanic.response import json
|
||||
from sanic import response
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
async def test(request):
|
||||
return json({"test": True})
|
||||
return response.json({"test": True})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -2,7 +2,7 @@ import os
|
|||
|
||||
from sanic import Sanic
|
||||
from sanic.log import log
|
||||
from sanic.response import json, text, file
|
||||
from sanic import response
|
||||
from sanic.exceptions import ServerError
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
@ -10,17 +10,17 @@ app = Sanic(__name__)
|
|||
|
||||
@app.route("/")
|
||||
async def test_async(request):
|
||||
return json({"test": True})
|
||||
return response.json({"test": True})
|
||||
|
||||
|
||||
@app.route("/sync", methods=['GET', 'POST'])
|
||||
def test_sync(request):
|
||||
return json({"test": True})
|
||||
return response.json({"test": True})
|
||||
|
||||
|
||||
@app.route("/dynamic/<name>/<id:int>")
|
||||
def test_params(request, name, id):
|
||||
return text("yeehaww {} {}".format(name, id))
|
||||
return response.text("yeehaww {} {}".format(name, id))
|
||||
|
||||
|
||||
@app.route("/exception")
|
||||
|
@ -31,11 +31,11 @@ def exception(request):
|
|||
async def test_await(request):
|
||||
import asyncio
|
||||
await asyncio.sleep(5)
|
||||
return text("I'm feeling sleepy")
|
||||
return response.text("I'm feeling sleepy")
|
||||
|
||||
@app.route("/file")
|
||||
async def test_file(request):
|
||||
return await file(os.path.abspath("setup.py"))
|
||||
return await response.file(os.path.abspath("setup.py"))
|
||||
|
||||
|
||||
# ----------------------------------------------- #
|
||||
|
@ -44,7 +44,7 @@ async def test_file(request):
|
|||
|
||||
@app.exception(ServerError)
|
||||
async def test(request, exception):
|
||||
return json({"exception": "{}".format(exception), "status": exception.status_code}, status=exception.status_code)
|
||||
return response.json({"exception": "{}".format(exception), "status": exception.status_code}, status=exception.status_code)
|
||||
|
||||
|
||||
# ----------------------------------------------- #
|
||||
|
@ -53,17 +53,17 @@ async def test(request, exception):
|
|||
|
||||
@app.route("/json")
|
||||
def post_json(request):
|
||||
return json({"received": True, "message": request.json})
|
||||
return response.json({"received": True, "message": request.json})
|
||||
|
||||
|
||||
@app.route("/form")
|
||||
def post_json(request):
|
||||
return 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")
|
||||
def query_string(request):
|
||||
return json({"parsed": True, "args": request.args, "url": request.url, "query_string": request.query_string})
|
||||
return response.json({"parsed": True, "args": request.args, "url": request.url, "query_string": request.query_string})
|
||||
|
||||
|
||||
# ----------------------------------------------- #
|
||||
|
|
18
examples/url_for_example.py
Normal file
18
examples/url_for_example.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
from sanic import Sanic
|
||||
from sanic import response
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
@app.route('/')
|
||||
async def index(request):
|
||||
# generate a URL for the endpoint `post_handler`
|
||||
url = app.url_for('post_handler', post_id=5)
|
||||
# the URL is `/posts/5`, redirect to it
|
||||
return response.redirect(url)
|
||||
|
||||
@app.route('/posts/<post_id>')
|
||||
async def post_handler(request, post_id):
|
||||
return response.text('Post - {}'.format(post_id))
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="0.0.0.0", port=8000, debug=True)
|
|
@ -1,4 +1,4 @@
|
|||
from sanic.response import text
|
||||
from sanic import response
|
||||
from sanic import Sanic
|
||||
from sanic.blueprints import Blueprint
|
||||
|
||||
|
@ -15,23 +15,23 @@ bp = Blueprint("bp", host="bp.example.com")
|
|||
"somethingelse.com",
|
||||
"therestofyourdomains.com"])
|
||||
async def hello(request):
|
||||
return text("Some defaults")
|
||||
return response.text("Some defaults")
|
||||
|
||||
@app.route('/', host="example.com")
|
||||
async def hello(request):
|
||||
return text("Answer")
|
||||
return response.text("Answer")
|
||||
|
||||
@app.route('/', host="sub.example.com")
|
||||
async def hello(request):
|
||||
return text("42")
|
||||
return response.text("42")
|
||||
|
||||
@bp.route("/question")
|
||||
async def hello(request):
|
||||
return text("What is the meaning of life?")
|
||||
return response.text("What is the meaning of life?")
|
||||
|
||||
@bp.route("/answer")
|
||||
async def hello(request):
|
||||
return text("42")
|
||||
return response.text("42")
|
||||
|
||||
app.register_blueprint(bp)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
aiofiles
|
||||
aiohttp==1.3.5
|
||||
chardet<=2.3.0
|
||||
beautifulsoup4
|
||||
coverage
|
||||
httptools
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from sanic.app import Sanic
|
||||
from sanic.blueprints import Blueprint
|
||||
|
||||
__version__ = '0.4.1'
|
||||
__version__ = '0.5.1'
|
||||
|
||||
__all__ = ['Sanic', 'Blueprint']
|
||||
|
|
|
@ -26,7 +26,7 @@ from sanic.websocket import WebSocketProtocol, ConnectionClosed
|
|||
class Sanic:
|
||||
|
||||
def __init__(self, name=None, router=None, error_handler=None,
|
||||
load_env=True):
|
||||
load_env=True, request_class=None):
|
||||
# Only set up a default log handler if the
|
||||
# end-user application didn't set anything up.
|
||||
if not logging.root.handlers and log.level == logging.NOTSET:
|
||||
|
@ -44,6 +44,7 @@ class Sanic:
|
|||
|
||||
self.name = name
|
||||
self.router = router or Router()
|
||||
self.request_class = request_class
|
||||
self.error_handler = error_handler or ErrorHandler()
|
||||
self.config = Config(load_env=load_env)
|
||||
self.request_middleware = deque()
|
||||
|
@ -668,6 +669,7 @@ class Sanic:
|
|||
|
||||
server_settings = {
|
||||
'protocol': protocol,
|
||||
'request_class': self.request_class,
|
||||
'host': host,
|
||||
'port': port,
|
||||
'sock': sock,
|
||||
|
|
|
@ -129,7 +129,7 @@ class StreamingHTTPResponse(BaseHTTPResponse):
|
|||
data = self._encode_body(data)
|
||||
|
||||
self.transport.write(
|
||||
b"%b\r\n%b\r\n" % (str(len(data)).encode(), data))
|
||||
b"%x\r\n%b\r\n" % (len(data), data))
|
||||
|
||||
async def stream(
|
||||
self, version="1.1", keep_alive=False, keep_alive_timeout=None):
|
||||
|
|
|
@ -64,12 +64,13 @@ class HttpProtocol(asyncio.Protocol):
|
|||
'parser', 'request', 'url', 'headers',
|
||||
# request config
|
||||
'request_handler', 'request_timeout', 'request_max_size',
|
||||
'request_class',
|
||||
# connection management
|
||||
'_total_request_size', '_timeout_handler', '_last_communication_time')
|
||||
|
||||
def __init__(self, *, loop, request_handler, error_handler,
|
||||
signal=Signal(), connections=set(), request_timeout=60,
|
||||
request_max_size=None):
|
||||
request_max_size=None, request_class=None):
|
||||
self.loop = loop
|
||||
self.transport = None
|
||||
self.request = None
|
||||
|
@ -82,11 +83,16 @@ class HttpProtocol(asyncio.Protocol):
|
|||
self.error_handler = error_handler
|
||||
self.request_timeout = request_timeout
|
||||
self.request_max_size = request_max_size
|
||||
self.request_class = request_class or Request
|
||||
self._total_request_size = 0
|
||||
self._timeout_handler = None
|
||||
self._last_request_time = None
|
||||
self._request_handler_task = None
|
||||
|
||||
@property
|
||||
def keep_alive(self):
|
||||
return self.parser.should_keep_alive() and not self.signal.stopped
|
||||
|
||||
# -------------------------------------------- #
|
||||
# Connection
|
||||
# -------------------------------------------- #
|
||||
|
@ -151,7 +157,7 @@ class HttpProtocol(asyncio.Protocol):
|
|||
self.headers.append((name.decode().casefold(), value.decode()))
|
||||
|
||||
def on_headers_complete(self):
|
||||
self.request = Request(
|
||||
self.request = self.request_class(
|
||||
url_bytes=self.url,
|
||||
headers=CIDict(self.headers),
|
||||
version=self.parser.get_http_version(),
|
||||
|
@ -180,9 +186,7 @@ class HttpProtocol(asyncio.Protocol):
|
|||
Writes response content synchronously to the transport.
|
||||
"""
|
||||
try:
|
||||
keep_alive = (
|
||||
self.parser.should_keep_alive() and not self.signal.stopped)
|
||||
|
||||
keep_alive = self.keep_alive
|
||||
self.transport.write(
|
||||
response.output(
|
||||
self.request.version, keep_alive,
|
||||
|
@ -216,9 +220,7 @@ class HttpProtocol(asyncio.Protocol):
|
|||
"""
|
||||
|
||||
try:
|
||||
keep_alive = (
|
||||
self.parser.should_keep_alive() and not self.signal.stopped)
|
||||
|
||||
keep_alive = self.keep_alive
|
||||
response.transport = self.transport
|
||||
await response.stream(
|
||||
self.request.version, keep_alive, self.request_timeout)
|
||||
|
@ -320,7 +322,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
|||
request_timeout=60, ssl=None, sock=None, request_max_size=None,
|
||||
reuse_port=False, loop=None, protocol=HttpProtocol, backlog=100,
|
||||
register_sys_signals=True, run_async=False, connections=None,
|
||||
signal=Signal()):
|
||||
signal=Signal(), request_class=None):
|
||||
"""Start asynchronous HTTP Server on an individual process.
|
||||
|
||||
:param host: Address to host on
|
||||
|
@ -345,6 +347,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
|||
:param reuse_port: `True` for multiple workers
|
||||
:param loop: asyncio compatible event loop
|
||||
:param protocol: subclass of asyncio protocol class
|
||||
:param request_class: Request class to use
|
||||
:return: Nothing
|
||||
"""
|
||||
if not run_async:
|
||||
|
@ -366,6 +369,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
|
|||
error_handler=error_handler,
|
||||
request_timeout=request_timeout,
|
||||
request_max_size=request_max_size,
|
||||
request_class=request_class,
|
||||
)
|
||||
|
||||
server_coroutine = loop.create_server(
|
||||
|
|
|
@ -48,14 +48,18 @@ def register(app, uri, file_or_directory, pattern,
|
|||
# Merge served directory and requested file if provided
|
||||
# Strip all / that in the beginning of the URL to help prevent python
|
||||
# from herping a derp and treating the uri as an absolute path
|
||||
file_path = file_or_directory
|
||||
root_path = file_path = file_or_directory
|
||||
if file_uri:
|
||||
file_path = path.join(
|
||||
file_or_directory, sub('^[/]*', '', file_uri))
|
||||
|
||||
# URL decode the path sent by the browser otherwise we won't be able to
|
||||
# match filenames which got encoded (filenames with spaces etc)
|
||||
file_path = unquote(file_path)
|
||||
file_path = path.abspath(unquote(file_path))
|
||||
if not file_path.startswith(root_path):
|
||||
raise FileNotFound('File not found',
|
||||
path=file_or_directory,
|
||||
relative_url=file_uri)
|
||||
try:
|
||||
headers = {}
|
||||
# Check if the client has been sent this file before
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import traceback
|
||||
|
||||
from sanic.log import log
|
||||
|
||||
HOST = '127.0.0.1'
|
||||
|
@ -50,6 +52,8 @@ class SanicTestClient:
|
|||
**request_kwargs)
|
||||
results[-1] = response
|
||||
except Exception as e:
|
||||
log.error(
|
||||
'Exception:\n{}'.format(traceback.format_exc()))
|
||||
exceptions.append(e)
|
||||
self.app.stop()
|
||||
|
||||
|
|
4
setup.py
4
setup.py
|
@ -64,7 +64,3 @@ except DistutilsPlatformError as exception:
|
|||
print("Installing without uJSON or uvLoop")
|
||||
setup_kwargs['install_requires'] = requirements
|
||||
setup(**setup_kwargs)
|
||||
|
||||
# Installation was successful
|
||||
print(u"\n\n\U0001F680 "
|
||||
"Sanic version {} installation suceeded.\n".format(version))
|
||||
|
|
Loading…
Reference in New Issue
Block a user