Merge pull request #27 from huge-success/master
Merge upstream master branch
This commit is contained in:
commit
4cb107aedc
@ -54,6 +54,8 @@ class Blueprint:
|
|||||||
yield i
|
yield i
|
||||||
bps = []
|
bps = []
|
||||||
for bp in chain(blueprints):
|
for bp in chain(blueprints):
|
||||||
|
if bp.url_prefix is None:
|
||||||
|
bp.url_prefix = ''
|
||||||
bp.url_prefix = url_prefix + bp.url_prefix
|
bp.url_prefix = url_prefix + bp.url_prefix
|
||||||
bps.append(bp)
|
bps.append(bp)
|
||||||
return bps
|
return bps
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
import types
|
import types
|
||||||
|
|
||||||
|
from sanic.exceptions import PyFileError
|
||||||
|
|
||||||
|
|
||||||
SANIC_PREFIX = 'SANIC_'
|
SANIC_PREFIX = 'SANIC_'
|
||||||
|
|
||||||
@ -83,6 +85,9 @@ class Config(dict):
|
|||||||
except IOError as e:
|
except IOError as e:
|
||||||
e.strerror = 'Unable to load configuration file (%s)' % e.strerror
|
e.strerror = 'Unable to load configuration file (%s)' % e.strerror
|
||||||
raise
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
raise PyFileError(filename) from e
|
||||||
|
|
||||||
self.from_object(module)
|
self.from_object(module)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from sanic.http import STATUS_CODES
|
from sanic.helpers import STATUS_CODES
|
||||||
|
|
||||||
TRACEBACK_STYLE = '''
|
TRACEBACK_STYLE = '''
|
||||||
<style>
|
<style>
|
||||||
@ -223,6 +223,11 @@ class InvalidRangeType(ContentRangeError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PyFileError(Exception):
|
||||||
|
def __init__(self, file):
|
||||||
|
super().__init__('could not execute config file %s', file)
|
||||||
|
|
||||||
|
|
||||||
@add_status_code(401)
|
@add_status_code(401)
|
||||||
class Unauthorized(SanicException):
|
class Unauthorized(SanicException):
|
||||||
"""
|
"""
|
||||||
|
@ -10,7 +10,7 @@ except BaseException:
|
|||||||
from aiofiles import open as open_async
|
from aiofiles import open as open_async
|
||||||
from multidict import CIMultiDict
|
from multidict import CIMultiDict
|
||||||
|
|
||||||
from sanic import http
|
from sanic.helpers import STATUS_CODES, has_message_body, remove_entity_headers
|
||||||
from sanic.cookies import CookieJar
|
from sanic.cookies import CookieJar
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ class StreamingHTTPResponse(BaseHTTPResponse):
|
|||||||
if self.status is 200:
|
if self.status is 200:
|
||||||
status = b'OK'
|
status = b'OK'
|
||||||
else:
|
else:
|
||||||
status = http.STATUS_CODES.get(self.status)
|
status = STATUS_CODES.get(self.status)
|
||||||
|
|
||||||
return (b'HTTP/%b %d %b\r\n'
|
return (b'HTTP/%b %d %b\r\n'
|
||||||
b'%b'
|
b'%b'
|
||||||
@ -141,7 +141,7 @@ class HTTPResponse(BaseHTTPResponse):
|
|||||||
timeout_header = b'Keep-Alive: %d\r\n' % keep_alive_timeout
|
timeout_header = b'Keep-Alive: %d\r\n' % keep_alive_timeout
|
||||||
|
|
||||||
body = b''
|
body = b''
|
||||||
if http.has_message_body(self.status):
|
if has_message_body(self.status):
|
||||||
body = self.body
|
body = self.body
|
||||||
self.headers['Content-Length'] = self.headers.get(
|
self.headers['Content-Length'] = self.headers.get(
|
||||||
'Content-Length', len(self.body))
|
'Content-Length', len(self.body))
|
||||||
@ -150,14 +150,14 @@ class HTTPResponse(BaseHTTPResponse):
|
|||||||
'Content-Type', self.content_type)
|
'Content-Type', self.content_type)
|
||||||
|
|
||||||
if self.status in (304, 412):
|
if self.status in (304, 412):
|
||||||
self.headers = http.remove_entity_headers(self.headers)
|
self.headers = remove_entity_headers(self.headers)
|
||||||
|
|
||||||
headers = self._parse_headers()
|
headers = self._parse_headers()
|
||||||
|
|
||||||
if self.status is 200:
|
if self.status is 200:
|
||||||
status = b'OK'
|
status = b'OK'
|
||||||
else:
|
else:
|
||||||
status = http.STATUS_CODES.get(self.status, b'UNKNOWN RESPONSE')
|
status = STATUS_CODES.get(self.status, b'UNKNOWN RESPONSE')
|
||||||
|
|
||||||
return (b'HTTP/%b %d %b\r\n'
|
return (b'HTTP/%b %d %b\r\n'
|
||||||
b'Connection: %b\r\n'
|
b'Connection: %b\r\n'
|
||||||
|
@ -499,3 +499,40 @@ def test_bp_group(app):
|
|||||||
|
|
||||||
request, response = app.test_client.get('/mid/deep1/bottom')
|
request, response = app.test_client.get('/mid/deep1/bottom')
|
||||||
assert response.text == 'D1B_OK'
|
assert response.text == 'D1B_OK'
|
||||||
|
|
||||||
|
|
||||||
|
def test_bp_group_with_default_url_prefix(app):
|
||||||
|
|
||||||
|
from sanic.response import json
|
||||||
|
bp_resources = Blueprint('bp_resources')
|
||||||
|
@bp_resources.get('/')
|
||||||
|
def list_resources_handler(request):
|
||||||
|
resource = {}
|
||||||
|
return json([resource])
|
||||||
|
|
||||||
|
bp_resource = Blueprint('bp_resource', url_prefix='/<resource_id>')
|
||||||
|
@bp_resource.get('/')
|
||||||
|
def get_resource_hander(request, resource_id):
|
||||||
|
resource = {'resource_id': resource_id}
|
||||||
|
return json(resource)
|
||||||
|
|
||||||
|
bp_resources_group = Blueprint.group(bp_resources, bp_resource, url_prefix='/resources')
|
||||||
|
bp_api_v1 = Blueprint('bp_api_v1')
|
||||||
|
@bp_api_v1.get('/info')
|
||||||
|
def api_v1_info(request):
|
||||||
|
return text('api_version: v1')
|
||||||
|
|
||||||
|
bp_api_v1_group = Blueprint.group(bp_api_v1, bp_resources_group, url_prefix='/v1')
|
||||||
|
bp_api_group = Blueprint.group(bp_api_v1_group, url_prefix='/api')
|
||||||
|
app.blueprint(bp_api_group)
|
||||||
|
|
||||||
|
request, response = app.test_client.get('/api/v1/info')
|
||||||
|
assert response.text == 'api_version: v1'
|
||||||
|
|
||||||
|
request, response = app.test_client.get('/api/v1/resources')
|
||||||
|
assert response.json == [{}]
|
||||||
|
|
||||||
|
from uuid import uuid4
|
||||||
|
resource_id = str(uuid4())
|
||||||
|
request, response = app.test_client.get('/api/v1/resources/{0}'.format(resource_id))
|
||||||
|
assert response.json == {'resource_id': resource_id}
|
||||||
|
@ -6,6 +6,7 @@ from textwrap import dedent
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
|
from sanic.exceptions import PyFileError
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
@ -87,6 +88,15 @@ def test_load_from_missing_envvar(app):
|
|||||||
"could not be loaded.")
|
"could not be loaded.")
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_config_from_file_invalid_syntax(app):
|
||||||
|
config = "VALUE = some value"
|
||||||
|
with temp_path() as config_path:
|
||||||
|
config_path.write_text(config)
|
||||||
|
|
||||||
|
with pytest.raises(PyFileError):
|
||||||
|
app.config.from_pyfile(config_path)
|
||||||
|
|
||||||
|
|
||||||
def test_overwrite_exisiting_config(app):
|
def test_overwrite_exisiting_config(app):
|
||||||
app.config.DEFAULT = 1
|
app.config.DEFAULT = 1
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user