async def test_set_context(self): ctx = Context() ctx.body = { 'a': 1, } ctx.req = await Request.from_asgi_interface({ 'channel': 'http.request', 'server': ('127.0.0.1', 9999), 'client': ('127.0.0.1', 58175), 'scheme': 'http', 'http_version': '0.0', 'method': 'POST', 'path': '/', 'query_string': b'', 'headers': [ [b'content-type', b'application/x-www-form-urlencoded'], [b'cache-control', b'no-cache'], [b'postman-token', b'e279159d-6af2-45da-87ac-1a331f317a60'], [b'user-agent', b'PostmanRuntime/7.1.1'], [b'accept', b'*/*'], [b'host', b'127.0.0.1:9999'], [b'accept-encoding', b'gzip, deflate'], [b'content-length', b'11'], [b'connection', b'keep-alive'], ] }, {}) assert ctx.body['a'] == 1 assert ctx.res.body['a'] == 1 assert id(ctx.res.body) == id(ctx.body) assert id(ctx.res.status) == id(ctx.status)
async def err_middleware(ctx: Context, nxt): ctx.body = {'msg': 'err_middleware'} try: await nxt() except Exception: ctx.body = {'msg': 'error handled'} ctx.status = 400
async def cors_middleware(ctx: Context, nxt: typing.Callable): # settings LEMON_CORS_ORIGIN_WHITELIST = settings.LEMON_CORS_ORIGIN_WHITELIST LEMON_CORS_ORIGIN_REGEX_WHITELIST = settings.LEMON_CORS_ORIGIN_REGEX_WHITELIST LEMON_CORS_ALLOW_METHODS = settings.LEMON_CORS_ALLOW_METHODS LEMON_CORS_ALLOW_HEADERS = settings.LEMON_CORS_ALLOW_HEADERS LEMON_CORS_EXPOSE_HEADERS = settings.LEMON_CORS_EXPOSE_HEADERS LEMON_CORS_ALLOW_CREDENTIALS = settings.LEMON_CORS_ALLOW_CREDENTIALS LEMON_CORS_MAX_AGE = settings.LEMON_CORS_MAX_AGE headers = ctx.req.headers origin = headers.get('origin', None) # pass request if origin is None: return await nxt() # preflight request if ctx.req.method == 'OPTIONS': acrm = headers.get('access-control-request-method', None) acrh = headers.get('access-control-request-headers', None) if acrm is None: return await nxt() matched = False for domain in LEMON_CORS_ORIGIN_WHITELIST: if domain == origin: matched = True for domain_pattern in LEMON_CORS_ORIGIN_REGEX_WHITELIST: if re.match(domain_pattern, origin): matched = True if matched is False: ctx.status = 200 return ctx.res.headers['access-control-allow-origin'] = origin if LEMON_CORS_ALLOW_CREDENTIALS: ctx.res.headers['access-control-allow-credentials'] = 'true' ctx.res.headers['access-control-max-age'] = LEMON_CORS_MAX_AGE ctx.res.headers['access-control-allow-methods'] = ','.join(LEMON_CORS_ALLOW_METHODS) ctx.res.headers['access-control-allow-headers'] = ','.join(LEMON_CORS_ALLOW_HEADERS) or acrh # stop request ctx.status = 204 return # cross origin request ctx.res.headers['access-control-allow-origin'] = origin if LEMON_CORS_ALLOW_CREDENTIALS: ctx.res.headers['access-control-allow-credentials'] = 'true' if LEMON_CORS_EXPOSE_HEADERS: ctx.res.headers['access-control-expose-headers'] = ','.join(LEMON_CORS_EXPOSE_HEADERS) return await nxt()
async def lemon_error_middleware(ctx: Context, nxt): """Catch the final exception""" try: await nxt() except HttpError as e: ctx.body = e.body ctx.status = e.status except Exception as e: error_logger.error(e) ctx.status = 500 ctx.body = ctx.body or 'INTERNAL ERROR'
async def exception_middleware(ctx: Context, nxt: typing.Callable) -> typing.Any: """Catch the final exception""" try: return await nxt() except GeneralException as e: ctx.body = e.body ctx.status = e.status except Exception as e: traceback.print_exc() ctx.status = 500 ctx.body = ctx.body or { 'lemon': 'INTERNAL ERROR', }
async def _wrapper(message, channels): """ :param message: is an ASGI message. :param channels: is a dictionary of <unicode string>:<channel interface>. :return: asgi application """ if message['channel'] == 'http.request': # init context ctx = Context() # prepare request ctx.req = await Request.from_asgi_interface(message=message, channels=channels) try: await exec_middleware(ctx=ctx, middleware_list=self.middleware_list) except MiddlewareParamsError as e: await channels['reply'].send({ 'status': 500, 'headers': MIME_TYPES.APPLICATION_JSON, 'content': json.dumps({ 'lemon': 'Your application middleware ' 'has wrong num of params', }), }) except Exception as e: logger.error(e) await channels['reply'].send({ 'status': 500, 'headers': MIME_TYPES.APPLICATION_JSON, 'content': json.dumps({ 'lemon': 'INTERNAL ERROR', }), }) else: await channels['reply'].send(ctx.res.message) # TODO: websocket support elif message['channel'] == 'websocket.connect': pass elif message['channel'] == 'websocket.receive': pass elif message['channel'] == 'websocket.disconnect': pass
async def handle(ctx: Context): my_cookie = ctx.req.cookies.get('my_cookie') my_cookie2 = ctx.req.cookies.get('my_cookie2') ctx.body = { 'my_cookie': my_cookie, 'my_cookie2': my_cookie2, }
async def correct(ctx: Context): data = ctx.req.json content = data['content'] ret = zh_checker.correct(content=content) ret = [r.to_json() for r in ret] ctx.body = { 'data': ret, }
async def handler(ctx: Context): server_recv = int(time.time() * 1000) # do something server_resp = int(time.time() * 1000) ctx.body = { 'server_recv': server_recv, 'server_resp': server_resp, }
async def _wrapper(message: dict, channels: dict) -> typing.Any: """ :param message: is an ASGI message. :param channels: is a dictionary of """ if message['channel'] == 'http.request': # init context ctx = Context() # prepare request ctx.req = await Request.from_asgi_interface(message=message, channels=channels) middleware_chain = \ self.pre_process_middleware_list \ + self.middleware_list \ + self.post_process_middleware_list try: await exec_middleware(ctx=ctx, middleware_list=middleware_chain) except MiddlewareParamsError as e: return await channels['reply'].send({ 'status': 500, 'headers': MIME_TYPES.APPLICATION_JSON, 'content': json.dumps({ 'lemon': 'Your application middleware ' 'has wrong num of params', }).encode(), }) else: return await channels['reply'].send(ctx.res.message) # TODO: websocket support elif message['channel'] == 'websocket.connect': return None elif message['channel'] == 'websocket.receive': return None elif message['channel'] == 'websocket.disconnect': return None
async def handler2(ctx: Context): ctx.body['ack'] = 'yeah !' ctx.body['data'] = ctx.req.json
async def handle(ctx: Context): ctx.body = { 'ok': True, }
async def middleware(ctx: Context): ctx.throw(status=403, body={'msg': '403'})
async def handle(ctx: Context): ctx.body['ack'] = 'yeah !' ctx.body['random'] = random()
async def handle(ctx: Context): ctx.body = { 'ack': 'ok', }
async def handle(ctx: Context): ctx.body['ack'] = 'yeah !'
async def handle(ctx: Context): ctx.body = { 'ack': 'yeah !', }
async def handle(ctx: Context): data = ctx.req.data ctx.body = { 'ack': data['xxx'].read().decode(), }
async def handle(ctx: Context): data = ctx.req.json ctx.body = { 'hi': data['hi'], }
async def handle(ctx: Context): ctx.body = ctx.req.json
async def handle(ctx: Context): ctx.body = 'xxxxxx'
async def handle(ctx: Context): ctx.body = {"msg": "hello world"}
async def handle(ctx: Context): data = ctx.req.data ctx.body = { 'file_content': data['file'].read().decode(), }
async def middleware(ctx: Context, nxt): ctx.body = { 'msg': 'hello world' } await nxt()
async def health(ctx: Context): ctx.body = {'success': True}